-- 作者:chaseh
-- 发布时间:5/18/2006 2:08:00 PM
-- DOM (Document Object Model)
一.概述 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 version="1.0"?> <?xml-stylesheet href="xsl\StuInfo.xsl" type="text/xsl"?> <!DOCTYPE LIT:StuInfo SYSTEM "dtd\student.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 ---------- <?xml version="1.0"?> <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 ---------- <!ELEMENT LIT:StuInfo ((LIT:student, LIT:breakLine)*, LIT:master)> <!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 org.w3c.dom.*; 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("\n"); } 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的应用。
|