1、操作XML文件的開源軟件包括DOM、SAX、JDOM等,程序員需要熟悉并掌握這些常用的接口的使用,能夠通過這些接口編寫java語句來實現對XML文件的處理。
2、DTD主要有下列幾方面的作用:
1)可以驗證XML文件數據的有效性。
2)可以為某類XML文件提供統一的格式和相同的結構。
3)可以保證在一定的范圍內,XML文件數據的交流和共享。
4)應用程序設計人員根據DTD就能夠知道對應XML文件的邏輯結構,從而編寫出相應的處理應用程序。
3、在DTD中引進Namespaces這個概念是為了解決命名沖突問題,設置url并不是說真的要到那個網址去讀取,僅僅作為一種區別的標志而已。
4、DOM
1)DOM的類
目前主流的解析器有:JAXP(Java Api for XML Processing)、Xerces(Apache)、XML4J(IBM)和xalan等,主流的解析器都支持SAX和DOM,支持JDOM的解析器目前只有SUN公司發布的jdom包。DOM即文件對象模型。在應用程序中,基于DOM的XML分析器將一個XML文件轉換成了一個對象模型的集合(通常被稱為DOM樹),應用程序可以通過對該對象模型的操作,實現對XML文件中數據的操作。
§Document類,描述了整個XML的文件語法結構,它包含了一系列Node類形成的樹形結構。程序員可以先掃描XML源文件,得到相應的Document對象,遍歷這顆樹來得到XML文件的所有內容,這是對XML文件操作的起點。
§Node對象,Node類是DOM結構中最為基本的類,經描述了文件樹中的一個抽象的節點。它包含類型為Element、Attr、Text和其他類的特征。Node對象引用其成員的變量來操作XML文件。
§NodeList對象,代表了一個包含了一個或者多個Node的列表。
§Element對象,Element類描述XML文件中的標志元素,繼承于Node,也是Node的最主要的子對象。標志中要以包含屬性,因而Element對象中有存取其屬性的方法,而任何Node中定義的方法,Element都繼承下來。
§Attribute對象,它代表了某個標志的屬性。繼承Node,但因為Attr實際上包含在Element中,不能被看作Element的子對。在DOM中Attributer并不是DOM樹的一個節點,所以Node中的getparentNode()、getpreviousSibling()和getnextSibling()返回的都將是null。即,Attribute是Element類的一部分,并不作為DOM樹中單獨的一個節點出現。
DOM類在DOM中都是用接口語言IDL定義的,因而,DOM可以映射到任何面向對象的語言,只要它實現了DOM所定義的接口就可以了。許多公司和廠家都提供了符合DOM規范的DOM接口和程序包。以微軟的DOM接口為例:
2)DOM讀取XML文件,通常用到以下5個基本步驟:
?建立一個解析器工廠。
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstace();
‚利用工廠獲得一個具體的解析器對象。
DocumentBuilder builder=factory.newDocumentBuilder();
ƒ利用DocumentBuilder的parse()方法接受一個XML文件名作為輸入參數,返回一個Document對象。Document對象代表了一個XML文件的樹模型。
Document doc=builder.parse("file.xml");
„使用Document對象的getElementsByTagName()方法,我們可以得到一個NodeList對象,它是XML文件中的標簽元素列表,可以使用NodeList對象的item()方法來得到列表中的每一個Node對象。
NodeList nl=doc.getElementsByTagName("person");
Element node=(Element)nl.item(i);
…通過Node對象的getNodeValue()方法提取某個標簽內的內容。
node.getElementsByTagName("NAME").item(0).getFirstChild().getNodeValue();
3)DOM讀取XML文件實例:本實例有兩個文件(book.xml與bookDisplay.jsp)
book.xml的代碼如下:
<?xml version="1.0" encoding="gb2312"?>
<books>
<book>
<name>J2EE編程技術</name>
<author>郝玉龍等</author>
<price cointype="¥">27.00元</price>
<publish>清華大學出版社</publish>
<date>
<day>15</day>
<month>3</month>
<year>2005</year>
</date>
</book>
<book>
<name>JSP大學實用教程</name>
<author>耿祥義等</author>
<price cointype="¥">24.00元</price>
<publish>電子工業出版社</publish>
<date>
<day>21</day>
<month>9</month>
<year>2007</year>
</date>
</book>
<book>
<name>JAVA2游戲編程</name>
<author>Thomas Petchel</author>
<price cointype="$">10.00元</price>
<publish>清華大學出版社</publish>
<date>
<day>1</day>
<month>8</month>
<year>2005</year>
</date>
</book>
<book>
<name>JSP應用開發</name>
<author>鄧子云等</author>
<price cointype="¥">49.00元</price>
<publish>機械工業出版社</publish>
<date>
<day>11</day>
<month>12</month>
<year>2007年</year>
</date>
</book>
</books>
bookDisplay.jsp的代碼如下:
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="javax.xml.parsers.*,org.w3c.dom.*"%>
<html>
<head>
<title> DOM讀取book.xml</title>
</head>
<body>
<table border=1 align="center">
<!--輸出表頭-->
<tr bgcolor="yellow">
<td>書名</td>
<td>作者</td>
<td>定價</td>
<td>出版社</td>
<td>出版日期</td>
</tr>
<%
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
//此處用的是絕對路徑,相對路徑不太好使。
Document doc=builder.parse("C:/Program Files/Apache Software Foundation/Tomcat 6.0/webapps/readXml/book.xml");
doc.normalize();
NodeList books=doc.getElementsByTagName("book");
for(int i=0;i<books.getLength();i++){
Element book=(Element)books.item(i);
out.print("<tr>");
out.print("<td>"+book.getElementsByTagName("name").item(0).getFirstChild().getNodeValue()+"</td>");
out.print("<td>"+book.getElementsByTagName("author").item(0).getFirstChild().getNodeValue()+"</td>");
out.print("<td>"+book.getElementsByTagName("price").item(0).getFirstChild().getNodeValue()+"</td>");
out.print("<td>"+book.getElementsByTagName("publish").item(0).getFirstChild().getNodeValue()+"</td>");
Element bookdate=(Element)book.getElementsByTagName("date").item(0);
String day=bookdate.getElementsByTagName("day").item(0).getFirstChild().getNodeValue();
String month=bookdate.getElementsByTagName("month").item(0).getFirstChild().getNodeValue();
String year=bookdate.getElementsByTagName("year").item(0).getFirstChild().getNodeValue();
out.print("<td>"+year+"年"+month+"月"+day+"日"+"</td>");
out.println();
}
%>
</table>
</body>
</html>
<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="javax.xml.parsers.*, javax.xml.transform.*,javax.xml.transform.dom.*"%>
<%@ page import="javax.xml.transform.stream.*,java.io.*, org.w3c.dom.*"%>
<html>
<head>
<title>DOM修改XML文件實例</title>
</head>
<body>
<%
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document doc=builder.parse("C:/Program Files/Apache Software Foundation/Tomcat 6.0/webapps/readXml/book.xml");
doc.normalize();
//---取得變量---
String name="精通Java EE項目案例";
String author="劉乃麗";
String price="85.00元";
String publish="人民郵電出版社";
//---創建一個book對象---
Text textseg;
Element book=doc.createElement("book");
//XML文件中添加一個book項目的具體元素
Element bookname=doc.createElement("name");
textseg=doc.createTextNode(name);
bookname.appendChild(textseg);
book.appendChild(bookname);
Element bookauthor=doc.createElement("author");
textseg=doc.createTextNode(author);
bookauthor.appendChild(textseg);
book.appendChild(bookauthor);
Element bookprice=doc.createElement("price");
textseg=doc.createTextNode(price);
bookprice.appendChild(textseg);
book.appendChild(bookprice);
Element bookpublish=doc.createElement("publish");
textseg=doc.createTextNode(publish);
bookpublish.appendChild(textseg);
book.appendChild(bookpublish);
String day="01";
String month="01";
String year="2008";
Element bookdate=doc.createElement("date");
Element bookdateday=doc.createElement("day");
textseg=doc.createTextNode(day);
bookdateday.appendChild(textseg);
Element bookdatemonth=doc.createElement("month");
textseg=doc.createTextNode(month);
bookdatemonth.appendChild(textseg);
Element bookdateyear=doc.createElement("year");
textseg=doc.createTextNode(year);
bookdateyear.appendChild(textseg);
bookdate.appendChild(bookdateday);
bookdate.appendChild(bookdatemonth);
bookdate.appendChild(bookdateyear);
book.appendChild(bookdate);
//創建好的節點添加到DOM樹中
doc.getDocumentElement().appendChild(book);
//用xslt把DOM樹輸出
TransformerFactory tFactory=TransformerFactory.newInstance();
Transformer transformer=tFactory.newTransformer();
DOMSource source=new DOMSource(doc);
StreamResult result=new StreamResult(new File("C:/Program Files/Apache Software Foundation/Tomcat 6.0/webapps/readXml/book.xml"));
transformer.transform(source,result);
%>
<table border=1 align="center">
<!--輸出表頭-->
<tr bgcolor="yellow">
<td>書名</td>
<td>作者</td>
<td>定價</td>
<td>出版社</td>
<td>出版日期</td>
</tr>
<%
//修改后讀取數據
NodeList books=doc.getElementsByTagName("book");
for(int i=0;i<books.getLength();i++){
book=(Element)books.item(i);
out.print("<tr>");
out.print("<td>"+book.getElementsByTagName("name").item(0).getFirstChild().getNodeValue()+"</td>");
out.print("<td>"+book.getElementsByTagName("author").item(0).getFirstChild().getNodeValue()+"</td>");
out.print("<td>"+book.getElementsByTagName("price").item(0).getFirstChild().getNodeValue()+"</td>");
out.print("<td>"+book.getElementsByTagName("publish").item(0).getFirstChild().getNodeValue()+"</td>");
bookdate=(Element)book.getElementsByTagName("date").item(0);
day=bookdate.getElementsByTagName("day").item(0).getFirstChild().getNodeValue();
month=bookdate.getElementsByTagName("month").item(0).getFirstChild().getNodeValue();
year=bookdate.getElementsByTagName("year").item(0).getFirstChild().getNodeValue();
out.print("<td>"+year+"年"+month+"月"+day+"日"+"</td>");
out.println();
}
%>
</table>
</body>
</html>
5、SAX
1). SAX ( Simple Application interface for XML ), 是一組程序設計接口,采用 observer 模式,將XML文件視為一個文字流的數據,在讀取XML 元素時觸發一系列的事件
2). 使用DOM 時是將xml 文件解析為一個樹狀結構,并對樹中的節點進行操作
使用SAX 加載XML文件時,他的操作像打開一個“順序的文件字符流”,在讀到XML元素的開始標記,結尾標記和內容標記時將產生一系列的事件
如一個簡單的XML文件:<hello><message>hello XML!</message></hello>
會相應的觸發:startDocument, startElement, characters, endElement, endDocument, 只需編寫這些事件處理程序就可以解析XML文件了
3). SAX 可以高效的使用內存,因為SAX 只是順序的讀取XML 文件的內容,并不會將XML 文件完全加載,這樣就比DOM 的處理效率高
但SAX 只能讀取XML 文件的內容,而不能更改XML 的內容,也不能隨機訪問XML 元素
4). 在SAX 中有4個處理器是要實現的:ContentHandler,DTDHandler,EntityResolver,ErrorHandler,以處理不同的事件,這是比較麻煩的,
幸好SAX 定義了一個 DefaultHandler 類把這幾個實現了,我們只需在 DefaultHandler中定義事件處理方法,然后注冊到XMLReader,而SAXParser封裝了XMLReader的實現類,
SAXParser又是由SAXParserFactory提供的,所以我們實際用到的類只有:SAXParserFactory,SAXParser,DefaultHandler
5). SAX 的解析步驟:
(1)寫一個類繼承 DefaultHandler, 實現自己的事件處理方法
(2)在主程序中建立 SAXParserFactory
(3)可以設置這個factory 的參數
(4)從這個factory 得到SAXParser
(5)解析XML文件
6)SAX解析XML實例,被解析的文件依然是book.xml,用以解析的文件是bookSaxDisplay.jsp,其代碼如下:
<%@ page contentType="text/html;charset=GB2312" %>
<%@ page import="javax.xml.parsers.*,
org.xml.sax.*,
org.xml.sax.helpers.*,
org.xml.sax.helpers.DefaultHandler,
java.io.*"%>

<html>
<head><title>用SAX解析并遍歷user.xml</title></head>
<body>
<%!
static class SAXParseUser extends DefaultHandler{
StringBuffer tempString=new StringBuffer();
//文檔解析開始
public void startDocument() throws SAXException {
tempString.append("開始解析xml文件
<br>");
}
//標簽解析開始
public void startElement(String namespaceURI, String localName,String qName, Attributes atts) throws SAXException{
tempString.append("開始解析結點,結點名稱:"+qName+"<br>");
//解析得到標簽所有的屬性
for(int i=0;i<atts.getLength();i++){
tempString.append(" 屬性"+atts.getQName(i)+",值為:"+atts.getValue(i)+"<br>");
}
}
//標簽解析結束
public void endElement(String namespaceURI,String localName,String qName) throws SAXException{
tempString.append("解析結點結束,結點名稱:"+qName+"<br>");
}
//字符串解析
public void characters(char[] ch,int start,int length){
tempString.append(" 解析出字符串,值為:'"+(new String(ch,start,length))+"'<br>");
}
//文檔解析結束
public void endDocument() throws SAXException {
tempString.append("解析xml文件結束!<br>");
}
//得到解析結果
public StringBuffer getPrintXML(){
return tempString;
}
}
%>
<% //生成SAX解析器工廠長
SAXParserFactory spf = SAXParserFactory.newInstance();
XMLReader xmlReader = null;
SAXParser saxParser=null;
SAXParseUser saxParseUser=new SAXParseUser();
String filename=pageContext.getServletContext().getRealPath("/book.xml");
try {
// 創建一個解析器SAXParser對象
saxParser = spf.newSAXParser();
// 得到SAXParser中封裝的SAX XMLReader
xmlReader = saxParser.getXMLReader();
//設置解析時處理事件的對象
xmlReader.setContentHandler(saxParseUser);
//開始解析XML文件
xmlReader.parse(filename);
}catch (Exception ex) {
System.out.println(ex);
}
%>
<!--輸出解析結果-->
<table border=1>
<!--輸出表頭-->
<tr >
<td align="center">內容</td>
</tr>
<%
out.println("<td>"+saxParseUser.getPrintXML()+"</td>");
%>
</table>
</body>
</html>
2、DTD主要有下列幾方面的作用:
1)可以驗證XML文件數據的有效性。
2)可以為某類XML文件提供統一的格式和相同的結構。
3)可以保證在一定的范圍內,XML文件數據的交流和共享。
4)應用程序設計人員根據DTD就能夠知道對應XML文件的邏輯結構,從而編寫出相應的處理應用程序。
3、在DTD中引進Namespaces這個概念是為了解決命名沖突問題,設置url并不是說真的要到那個網址去讀取,僅僅作為一種區別的標志而已。
4、DOM
1)DOM的類
目前主流的解析器有:JAXP(Java Api for XML Processing)、Xerces(Apache)、XML4J(IBM)和xalan等,主流的解析器都支持SAX和DOM,支持JDOM的解析器目前只有SUN公司發布的jdom包。DOM即文件對象模型。在應用程序中,基于DOM的XML分析器將一個XML文件轉換成了一個對象模型的集合(通常被稱為DOM樹),應用程序可以通過對該對象模型的操作,實現對XML文件中數據的操作。
§Document類,描述了整個XML的文件語法結構,它包含了一系列Node類形成的樹形結構。程序員可以先掃描XML源文件,得到相應的Document對象,遍歷這顆樹來得到XML文件的所有內容,這是對XML文件操作的起點。
§Node對象,Node類是DOM結構中最為基本的類,經描述了文件樹中的一個抽象的節點。它包含類型為Element、Attr、Text和其他類的特征。Node對象引用其成員的變量來操作XML文件。
§NodeList對象,代表了一個包含了一個或者多個Node的列表。
§Element對象,Element類描述XML文件中的標志元素,繼承于Node,也是Node的最主要的子對象。標志中要以包含屬性,因而Element對象中有存取其屬性的方法,而任何Node中定義的方法,Element都繼承下來。
§Attribute對象,它代表了某個標志的屬性。繼承Node,但因為Attr實際上包含在Element中,不能被看作Element的子對。在DOM中Attributer并不是DOM樹的一個節點,所以Node中的getparentNode()、getpreviousSibling()和getnextSibling()返回的都將是null。即,Attribute是Element類的一部分,并不作為DOM樹中單獨的一個節點出現。
DOM類在DOM中都是用接口語言IDL定義的,因而,DOM可以映射到任何面向對象的語言,只要它實現了DOM所定義的接口就可以了。許多公司和廠家都提供了符合DOM規范的DOM接口和程序包。以微軟的DOM接口為例:
2)DOM讀取XML文件,通常用到以下5個基本步驟:
?建立一個解析器工廠。






book.xml的代碼如下:


































































//此處用的是絕對路徑,相對路徑不太好使。





















4)DOM修改XML文件
修改XML文件就是在修改了DOM樹后重新寫入到XML文件中去,通常會遇到兩個方面的問題:
Œ在XML文件中增加記錄:首先要在DOM樹中增加一個節點元素,然后在這個節點元素上增加子節點元素,并給相應的葉節點賦值,最后把DOM樹保存到XML文件中。
?在XML文件中修改節點的值,要修改XML文件中節點的值,需要先將XML文件讀入到DOM樹中,再遍歷DOM樹,并在遍歷的過程中找到相應的節點并修改其值,并把修改的DOM保存到XML文件中。
5)DOM修改XML文件實例,所操作的XML文件依然是book.xml,用以創修改book.xml文件的文件是bookChange.jsp,代碼如下:






























































































1). SAX ( Simple Application interface for XML ), 是一組程序設計接口,采用 observer 模式,將XML文件視為一個文字流的數據,在讀取XML 元素時觸發一系列的事件
2). 使用DOM 時是將xml 文件解析為一個樹狀結構,并對樹中的節點進行操作
使用SAX 加載XML文件時,他的操作像打開一個“順序的文件字符流”,在讀到XML元素的開始標記,結尾標記和內容標記時將產生一系列的事件
如一個簡單的XML文件:<hello><message>hello XML!</message></hello>
會相應的觸發:startDocument, startElement, characters, endElement, endDocument, 只需編寫這些事件處理程序就可以解析XML文件了
3). SAX 可以高效的使用內存,因為SAX 只是順序的讀取XML 文件的內容,并不會將XML 文件完全加載,這樣就比DOM 的處理效率高
但SAX 只能讀取XML 文件的內容,而不能更改XML 的內容,也不能隨機訪問XML 元素
4). 在SAX 中有4個處理器是要實現的:ContentHandler,DTDHandler,EntityResolver,ErrorHandler,以處理不同的事件,這是比較麻煩的,
幸好SAX 定義了一個 DefaultHandler 類把這幾個實現了,我們只需在 DefaultHandler中定義事件處理方法,然后注冊到XMLReader,而SAXParser封裝了XMLReader的實現類,
SAXParser又是由SAXParserFactory提供的,所以我們實際用到的類只有:SAXParserFactory,SAXParser,DefaultHandler
5). SAX 的解析步驟:
(1)寫一個類繼承 DefaultHandler, 實現自己的事件處理方法
(2)在主程序中建立 SAXParserFactory
(3)可以設置這個factory 的參數
(4)從這個factory 得到SAXParser
(5)解析XML文件
6)SAX解析XML實例,被解析的文件依然是book.xml,用以解析的文件是bookSaxDisplay.jsp,其代碼如下:












































































