一.概述
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的应用。