一.概述
DOM(Document Object Model),它將XML文件全部讀入內存中,然後將各個元素組成一棵數據樹,以便快速的訪問各個節點。由於將文檔全部讀入內存非常消耗系統性能,因此對比較大的文檔不適宜採用DOM方法來解析。而是採用基於事件處理方式的SAX。但正是由於SAX是基於事件的,所以它只能分析文檔而不能修改文檔。這時我們可以考慮應用JDOM,這是一種基於Java2的完整API,它既有SAX在速度和性能上的優勢,也跟DOM一樣將文檔讀入內存,從整體上解析XML文檔,特別他提供的操作數據節點的方法比DOM還要簡潔。
JAXP(Java API for XML Parsing),Sun公司用來解析XML的API,通過使用這個API可以在解析XML文檔時候不必明確的指出XML解析器類的名字,從而使我們寫出的Java代碼具有可移植性。
二.常用DOM API
org.w3c.dom.Document
這個接口定義分析,創建DOM文檔的一系列方法,是操作DOM的基礎。
org.w3c.dom.Element
這個接口提供了獲取,修改XML元素名字和屬性的方法。
org.w3c.dom.Node
這個接口提供了處理節點和子節點的方法。
org.w3c.dom.NodeList
提供了獲得節點個數和當前節點的方法,這樣就可以迭代的訪問各個節點。
完整的DOM API參考手冊請訪問
http://www.w3.org/dom/
三.常用JAXP API
javax.xml.parsers.DocumentBuilder
這是一個抽象類,它定義了可以通過解析XML後獲得Document實例的API。
javax.xml.parsers.DocumentBuilderFactory
用來產生DocumnetBuilder實例的抽象工廠類
javax.xml.parsers.ParserConfigurationException
解析器配置錯誤,如果工廠類不能提供一個有效的解析器實例,則拋出此異常。
完整的JAXP API參考手冊請訪問
http://java.sun.com/xml/jaxp/
四.解析的例子
這個例子跟上次SAX的一樣,也是讀取一個XML文檔,解析後輸出結果。所使用的XML,XSL,DTD文件都不變。
---------- SutInfo.xml ----------
<?xml-stylesheet href="xslStuInfo.xsl" type="text/xsl"?>
<!DOCTYPE LIT:StuInfo SYSTEM "dtdstudent.dtd">
<LIT:StuInfo xmlns:LIT="http://www.lit.edu.cn/student/">
<LIT:student>
<LIT:name>bigmouse</LIT:name>
<LIT:sex>male</LIT:sex>
<LIT:lesson>
<LIT:lessonName>math</LIT:lessonName>
<LIT:lessonScore>60</LIT:lessonScore>
</LIT:lesson>
<LIT:lesson>
<LIT:lessonName>Englist</LIT:lessonName>
<LIT:lessonScore>59</LIT:lessonScore>
</LIT:lesson>
<LIT:lesson>
<LIT:lessonName>autoCAD</LIT:lessonName>
<LIT:lessonScore>80</LIT:lessonScore>
</LIT:lesson>
<LIT:lesson>
<LIT:lessonName>SCM</LIT:lessonName>
<LIT:lessonScore>90</LIT:lessonScore>
</LIT:lesson>
<LIT:lesson>
<LIT:lessonName>mechanics</LIT:lessonName>
<LIT:lessonScore>61</LIT:lessonScore>
</LIT:lesson>
</LIT:student>
<LIT:breakLine/>
<LIT:student>
<LIT:name>coco</LIT:name>
<LIT:sex>female</LIT:sex>
<LIT:lesson>
<LIT:lessonName>math</LIT:lessonName>
<LIT:lessonScore>90</LIT:lessonScore>
</LIT:lesson>
<LIT:lesson>
<LIT:lessonName>Englist</LIT:lessonName>
<LIT:lessonScore>95</LIT:lessonScore>
</LIT:lesson>
<LIT:lesson>
<LIT:lessonName>C++</LIT:lessonName>
<LIT:lessonScore>80</LIT:lessonScore>
</LIT:lesson>
<LIT:lesson>
<LIT:lessonName>Java</LIT:lessonName>
<LIT:lessonScore>85</LIT:lessonScore>
</LIT:lesson>
</LIT:student>
<LIT:breakLine/>
<LIT:master>&masterName;</LIT:master>
</LIT:StuInfo>
---------- StuInfo.xsl ----------
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:LIT="http://www.lit.edu.cn/student/"
version="1.0">
<xsl:template match="LIT:StuInfo">
<html>
<head>
<title>Student Information</title>
</head>
<body>
<xsl:apply-templates select="*"/>
</body>
</html>
</xsl:template>
<xsl:template match="LIT:student">
<li>Name:<xsl:value-of select="LIT:name"/></li>
<li>Sex:<xsl:value-of select="LIT:sex"/></li>
<xsl:for-each select="LIT:lesson">
<li>Lesson:<xsl:value-of select="LIT:lessonName"/>(<xsl:value-of select="LIT:lessonScore"/>)</li>
</xsl:for-each>
</xsl:template>
<xsl:template match="LIT:breakLine">
<hr/>
</xsl:template>
<xsl:template match="master">
<xsl:copy-of select="*"/>
</xsl:template>
</xsl:stylesheet>
---------- student.dtd ----------
<!ATTLIST LIT:StuInfo xmlns:LIT CDATA #REQUIRED>
<!ELEMENT LIT:student (LIT:name, LIT:sex, LIT:lesson*)>
<!ELEMENT LIT:name (#PCDATA)>
<!ELEMENT LIT:sex (#PCDATA)>
<!ELEMENT LIT:lesson (LIT:lessonName, LIT:lessonScore)>
<!ELEMENT LIT:lessonName (#PCDATA)>
<!ELEMENT LIT:lessonScore (#PCDATA)>
<!ELEMENT LIT:breakLine EMPTY>
<!ELEMENT LIT:master (#PCDATA)>
<!ENTITY masterName SYSTEM "master.txt">
---------- MyDOMParser.java ----------
import javax.xml.parsers.*;
import org.xml.sax.*;
import java.io.*;
import java.util.*;
public class MyDOMParser
{
//名字空間
private String strNamespace = "http://www.lit.edu.cn/student/";
//一個學生的資料
private Hashtable htbStudent = new Hashtable();
//所有學生的向量列表
private Vector vStuInfo = new Vector();
public MyDOMParser()
{
}
public static void main(String[] args)
{
if (args.length != 1)
{
System.out.println("Usage:java MyDOMParser [XML File URI]");
}
MyDOMParser myDOMParser = new MyDOMParser();
myDOMParser.parseXMLFile(args[0]);
}
/**
* 解析文檔
* @param fileURI
*/
public void parseXMLFile(String fileURI)
{
try
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//允許名字空間
factory.setNamespaceAware(true);
//允許驗證
factory.setValidating(true);
//獲得DocumentBuilder的一個實例
DocumentBuilder builder = factory.newDocumentBuilder();
//解析文檔,並獲得一個Document實例。
Document doc = builder.parse(fileURI);
//獲得根節點StuInfo
Element elmtStuInfo = doc.getDocumentElement();
//得到所有student節點
NodeList nlStudent = elmtStuInfo.getElementsByTagNameNS(strNamespace, "student");
System.out.println("**** Student information start ****");
//循環輸出每一個學生資料
for (int i = 0; i < nlStudent.getLength(); i++)
{
//當前student節點元素
Element elmtStudent = (Element)nlStudent.item(i);
NodeList nlCurrent = elmtStudent.getElementsByTagNameNS(strNamespace, "name");
System.out.println("Name:" + nlCurrent.item(0).getFirstChild().getNodeValue());
nlCurrent = elmtStudent.getElementsByTagNameNS(strNamespace, "sex");
System.out.println("Sex:" + nlCurrent.item(0).getFirstChild().getNodeValue());
nlCurrent = elmtStudent.getElementsByTagNameNS(strNamespace, "lesson");
for (int j = 0; j < nlCurrent.getLength(); j++)
{
Element elmtLesson = (Element)nlCurrent.item(j);
NodeList nlLesson = elmtLesson.getElementsByTagNameNS(strNamespace, "lessonName");
System.out.print(nlLesson.item(0).getFirstChild().getNodeValue());
System.out.print(":");
nlLesson = elmtLesson.getElementsByTagNameNS(strNamespace, "lessonScore");
System.out.print(nlLesson.item(0).getFirstChild().getNodeValue());
System.out.print(" ");
}
System.out.println("------------------------------------");
}
System.out.println("**** Student information end ****");
}
catch (SAXException saxe)
{
System.out.println(saxe.getMessage());
}
catch (IOException ioe)
{
System.out.println(ioe.getMessage());
}
catch (ParserConfigurationException pce)
{
System.out.println(pce.getMessage());
}
}
}
---------- 解析後得到結果 ----------
**** Student information start ****
name:bigmouse
sex:male
math:60
Englist:59
autoCAD:80
SCM:90
mechanics:61
------------------------------------
name:coco
sex:female
math:90
Englist:95
C++:80
Java:85
------------------------------------
**** Student information end ****
五.其他
可以看出DOM比SAX解析文檔確實方便直觀,以後我將介紹在解析XML文檔上性能更佳JDOM技術以及XSP的應用。