DOM文档操作和XML文件互相转换的java实现
郭洪锋 ([email protected])
2001 年 8 月简介:该文简要描述了DOM的概念和内部逻辑结构,给出了DOM文档操作和XML文件互相转换的java实现过程。
1. DOM简介
目前,W3C已于2000年11月13日推出了规范DOM level 2。文档对象模型(DOM)是HTML和XML文档的编程接口规范,它与平台和语言是无关的,因而可以用各种语言在各种平台上实现。该模型定义了THML和XML文件在内存中的逻辑结构(即为文档),提供了访问、存取THML和XML文件的方法。利用DOM规范,可以实现DOM 文档和XML之间的相互转换,遍历、操作相应DOM文档的内容。可以说,要自由的操纵XML文件,就要用到DOM规范。2. DOM内部逻辑结构
DOM文档中的逻辑结构可以用节点树的形式进行表述。通过对XML文件的解析处理,XML文件中的元素便转化为DOM文档中的节点对象。DOM的文档节点有Document、Element、Comment、Type等等节点类型,其中每一个DOM文档必须有一个Document节点,并且为节点树的根节点。它可以有子节点,或者叶子节点如Text节点、Comment节点等。任何的格式良好的XML文件中的每一个元素均有DOM文档中的一个节点类型与之对应。利用DOM接口将XML文件转化成DOM文档后,我们就可以自由的处理XML文件了。3. java中的DOM接口
DOM规范提供的API的规范,目前Sun公司推出的jdk1.4测试版中的java API遵循了 DOM level 2 Core推荐接口的语义说明,提供了相应的java语言的实现。在org.xml.dom中,jkd1.4提供了Document、DocumentType、Node、NodeList、Element、Text等接口,这些接口均是访问DOM文档所必须的。我们可以利用这些接口创建、遍历、修改DOM文档。在javax.xml.parsers中,jkd1.4提供的DoumentBuilder和DocumentBuilderFactory组合可以对XML文件进行解析,转换成DOM文档。在javax.xml.transform.dom和javax.xml.transform.stream中,jdk1.4提供了DOMSource类和StreamSource类,可以用来将更新后的DOM文档写入生成的XML文件中。4. 例程4.1 将XML文件转化成DOM文档
这个过程是获得一个XML文件解析器,解析XML文件转化成DOM文档的过程。Jdk1.4中,Document接口描述了对应于整个XML文件的文档树,提供了对文档数据的访问,是该步骤的目标。Document接口可以从类DocumentBuilder中获取,该类包含了从XML文档获得DOM文档实例的API。XML的解析器可以从类DocumentBuilderFactory中获取。在jdk1.4中,XML文件转化成DOM文档可以有如下代码实现:
//获得一个XML文件的解析器
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//解析XML文件生成DOM文档的接口类,以便访问DOM。
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse( new File(FileName) );
4.2 遍历DOM文档
获得接口类document实例后,可以对DOM的文档树进行访问。要遍历DOM文档,首先要获得Root元素。然后获得Root元素的子节点列表。这里通过递归的方法实现遍历的目的。
//获得Root元素
Element element = document.getDocumentElement();
//获得Root元素的子节点列表
nodelist = element.getChildNodes();
//用递归方法实现DOM文档的遍历
GetElement(nodelist);
其中GetElement方法实现如下:
public void GetElement(NodeList nodelist){
Node cnode;
int i,len;
String str;
if(nodelist.getLength() == 0){
// 该节点没有子节点
return;
}
for(i=0;i 1)
System.out.println(" "+str+" "+len);
}
}
}
注意:上面的代码只是显示Node类型和Text类型的对象。它们的类型标识分别是1和3。4.3 修改DOM文档
修改DOM文档的API在DOM level 2 Core规范中做了说明,jkd1.4中的org.xml.dom中实现了这些API。修改DOM文档操作主要集中在Document、Element、Node、Text等类中,这里给出的例子中是在解析出的DOM文档中增加一系列对象,对应与在XML文件中增加一条记录。
// 获得Root对象
Element root = document.getDocumentElement();
// 在DOM文档中增加一个Element节点
Element booktype = document.createElement("COMPUTES");
//将该节点转化成root对象的子节点
root.appendChild(cdrom);
//在DOM文档中增加一个Element节点
Element booktitle = document.createElement("Title");
//将该节点转化成booktype对象的子节点
booktype.appendChild(booktitle);
//在DOM文档中增加一个Text节点
Text bookname = document.createTextNode("understand Corba");
//将该节点转化成bookname对象的子节点
booktitle.appendChild(bookname);
4.4 将DOM文档转化成XML文件
// 获得将DOM文档转化为XML文件的转换器,在jdk1.4中,有类TransformerFactory
// 来实现,类Transformer实现转化API。
TransformerFactory tfactory = TransformerFactory.newInstance();
Transformer transformer = tfactory.newTransformer();
// 将DOM对象转化为DOMSource类对象,该对象表现为转化成别的表达形式的信息容器。
DOMSource source = new DOMSource(document);
// 获得一个StreamResult类对象,该对象是DOM文档转化成的其他形式的文档的容器,可以是XML文件,文本文件,HTML文件。这里为一个XML文件。
StreamResult result = new StreamResult(new File(“text.xml”));
// 调用API,将DOM文档转化成XML文件。
transformer.transform(source,result);
这里提供了该例程的完整程序,该例程在windows 2000中jdk1.4环境中运行通过。以上给出了一个例子,读者可以从中了解到对DOM操作的思路。因为对DOM的操作均遵循了DOM规范,所以也适用于其它语言对DOM的处理。
郭洪锋 ([email protected])
2001 年 8 月简介:该文简要描述了DOM的概念和内部逻辑结构,给出了DOM文档操作和XML文件互相转换的java实现过程。
1. DOM简介
目前,W3C已于2000年11月13日推出了规范DOM level 2。文档对象模型(DOM)是HTML和XML文档的编程接口规范,它与平台和语言是无关的,因而可以用各种语言在各种平台上实现。该模型定义了THML和XML文件在内存中的逻辑结构(即为文档),提供了访问、存取THML和XML文件的方法。利用DOM规范,可以实现DOM 文档和XML之间的相互转换,遍历、操作相应DOM文档的内容。可以说,要自由的操纵XML文件,就要用到DOM规范。2. DOM内部逻辑结构
DOM文档中的逻辑结构可以用节点树的形式进行表述。通过对XML文件的解析处理,XML文件中的元素便转化为DOM文档中的节点对象。DOM的文档节点有Document、Element、Comment、Type等等节点类型,其中每一个DOM文档必须有一个Document节点,并且为节点树的根节点。它可以有子节点,或者叶子节点如Text节点、Comment节点等。任何的格式良好的XML文件中的每一个元素均有DOM文档中的一个节点类型与之对应。利用DOM接口将XML文件转化成DOM文档后,我们就可以自由的处理XML文件了。3. java中的DOM接口
DOM规范提供的API的规范,目前Sun公司推出的jdk1.4测试版中的java API遵循了 DOM level 2 Core推荐接口的语义说明,提供了相应的java语言的实现。在org.xml.dom中,jkd1.4提供了Document、DocumentType、Node、NodeList、Element、Text等接口,这些接口均是访问DOM文档所必须的。我们可以利用这些接口创建、遍历、修改DOM文档。在javax.xml.parsers中,jkd1.4提供的DoumentBuilder和DocumentBuilderFactory组合可以对XML文件进行解析,转换成DOM文档。在javax.xml.transform.dom和javax.xml.transform.stream中,jdk1.4提供了DOMSource类和StreamSource类,可以用来将更新后的DOM文档写入生成的XML文件中。4. 例程4.1 将XML文件转化成DOM文档
这个过程是获得一个XML文件解析器,解析XML文件转化成DOM文档的过程。Jdk1.4中,Document接口描述了对应于整个XML文件的文档树,提供了对文档数据的访问,是该步骤的目标。Document接口可以从类DocumentBuilder中获取,该类包含了从XML文档获得DOM文档实例的API。XML的解析器可以从类DocumentBuilderFactory中获取。在jdk1.4中,XML文件转化成DOM文档可以有如下代码实现:
//获得一个XML文件的解析器
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//解析XML文件生成DOM文档的接口类,以便访问DOM。
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse( new File(FileName) );
4.2 遍历DOM文档
获得接口类document实例后,可以对DOM的文档树进行访问。要遍历DOM文档,首先要获得Root元素。然后获得Root元素的子节点列表。这里通过递归的方法实现遍历的目的。
//获得Root元素
Element element = document.getDocumentElement();
//获得Root元素的子节点列表
nodelist = element.getChildNodes();
//用递归方法实现DOM文档的遍历
GetElement(nodelist);
其中GetElement方法实现如下:
public void GetElement(NodeList nodelist){
Node cnode;
int i,len;
String str;
if(nodelist.getLength() == 0){
// 该节点没有子节点
return;
}
for(i=0;i 1)
System.out.println(" "+str+" "+len);
}
}
}
注意:上面的代码只是显示Node类型和Text类型的对象。它们的类型标识分别是1和3。4.3 修改DOM文档
修改DOM文档的API在DOM level 2 Core规范中做了说明,jkd1.4中的org.xml.dom中实现了这些API。修改DOM文档操作主要集中在Document、Element、Node、Text等类中,这里给出的例子中是在解析出的DOM文档中增加一系列对象,对应与在XML文件中增加一条记录。
// 获得Root对象
Element root = document.getDocumentElement();
// 在DOM文档中增加一个Element节点
Element booktype = document.createElement("COMPUTES");
//将该节点转化成root对象的子节点
root.appendChild(cdrom);
//在DOM文档中增加一个Element节点
Element booktitle = document.createElement("Title");
//将该节点转化成booktype对象的子节点
booktype.appendChild(booktitle);
//在DOM文档中增加一个Text节点
Text bookname = document.createTextNode("understand Corba");
//将该节点转化成bookname对象的子节点
booktitle.appendChild(bookname);
4.4 将DOM文档转化成XML文件
// 获得将DOM文档转化为XML文件的转换器,在jdk1.4中,有类TransformerFactory
// 来实现,类Transformer实现转化API。
TransformerFactory tfactory = TransformerFactory.newInstance();
Transformer transformer = tfactory.newTransformer();
// 将DOM对象转化为DOMSource类对象,该对象表现为转化成别的表达形式的信息容器。
DOMSource source = new DOMSource(document);
// 获得一个StreamResult类对象,该对象是DOM文档转化成的其他形式的文档的容器,可以是XML文件,文本文件,HTML文件。这里为一个XML文件。
StreamResult result = new StreamResult(new File(“text.xml”));
// 调用API,将DOM文档转化成XML文件。
transformer.transform(source,result);
这里提供了该例程的完整程序,该例程在windows 2000中jdk1.4环境中运行通过。以上给出了一个例子,读者可以从中了解到对DOM操作的思路。因为对DOM的操作均遵循了DOM规范,所以也适用于其它语言对DOM的处理。
作者:薛泾为何需要XML Schema
在当今的IT行业中,XML被赋予了越来越多的职责和功能,例如,作为文本数据库存储数据,作为某一行业中数据交换的标准表示,等等。这些都需要相应的XML文件中对数据的描述,如数据类型、长度进行严格的定义,这样才能真正做到数据的安全性和行业统一标准并有通用的规则对其进行解析。然而,XML在其产生的时候就被定义为高开放性,用文本方式浏览,用标签来定义的标记语言,鉴于XML的这些特点,就像HTML文件一样,XML文件本身无法对文件中的数据进行严格的定义。为了解决以上的矛盾,XML Schema应运而生了,它是用来定义XML文件的文本结构,数据类型等XML文件描述规则的。何为XML Schema
其实,XML Schema本身也是一个xml文件,所不同的是,Schema文件所描述的是对引用它的xml文件的element和attribute的具体类型的。作为一个Schema文件,其特殊的文件头格式为:
<?xml version="1.0"?> ------------------------------------------xml文件头<Schema name="schema_sample_1" ------------------------ 名称(可省略)xmlns="urn:schemas-microsoft-com:xml-data" --------- 引用微软Schema类型定义(可省略)xmlns:dt="urn:schemas-microsoft-com:datatypes"> -----引用微软Schema数据类型定义(可省略)<!--…………..- 〉 ---------------------------------------------- 具体文件内容</Schema>
必须注意的是,在一个定义Schema的xml文件中,文件的root一定为<Schema>…</Schema>,在文件的具体内容中,你可以添加你对某个xml结构、数据类型的定义,请看下例:
<?xml version="1.0"?><catalog><book><title>Presenting XML</title><author>Richard Light</author><pages>334</pages></book><book><title>XML</title><author>Jane Lee</author><pages>450</pages></book></catalog>
这是一个表示书目录的xml文件,对每一本书的介绍,我们都要有一些数据上的规定,如,“书名”、“作者名”和“页数”都应该是唯一的,“作者名”应该为字符串类型,而“页数”应该为整数类型的,对每本“book”来说,只能有所指定的三个元素。
为了能实现上述要求,我们定义了如下schema:
<?xml version="1.0"?><Schema><ElementType name="title" content="textOnly" model="closed" /><ElementType name="author" content="textOnly" dt:type=”string” model="closed" /><ElementType name="pages" content="textOnly" dt:type=”int” model="closed" /><ElementType name="book" content="eltOnly" model="closed" order=”seq”><element type="title" /><element type="author" /><element type="pages" /> </ElementType></Schema>
在以下的文章中,将详细的描述内容中的具体意义。ElementType
ElementType是schema中最基本的,它用来定义xml文件中元素的格式,数据类型等。定义一个ElementType的基本格式为:
<ElementTypecontent="{empty | textOnly | eltOnly | mixed}" dt:type="datatype" model="{open | closed}" name="idref" order="{one | seq | many}" ></ElementType>
content
Content用于描述元素中的内容类型。
empty
元素内容为空
textOnly
元素只包含文本类型的内容
eltOnly
元素只包含元素类型的内容
mixed
元素内容包含上述任何情况
<ElementType name="x" content="empty"/><ElementType name="x" content="textOnly"/><ElementType name="x" content="eltOnly"><element type="y"></ElementType><ElementType name="x" content="mixed"><element type='q'><element type='r'></ElementType>
model
Model定义元素的内容是否要严格的遵守schema中的定义。
open
元素内容可添加未特殊定义过的元素,特征,文本等
closed
元素内容只能添加特殊定义过的元素,特征,文本等
<ElementType name="x" model="open"/><ElementType name="y" model="close"/>
name
定义该元素的名称
<ElementType name="x"></ElementType> order
定义该元素子元素的排列顺序
one
只允许元素内容按一种方式排列
seq
允许元素内容按指定的方式排列
many
按任意方式排列
<ElementType name='z' order="one"><element type="x"><element type="y"></ElementType><ElementType name="x" order="one"><group order="seq"><element type="x1"><element type="y1"></group><group order="seq"><element type="x2"><element type="y2"></group></ElementType><ElementType name="x" content="eltOnly" order="many"><element type='q'><element type='r'></ElementType>特别注明,seq只元素内容可以按特殊列出的排列顺序中任选一种。
Dt:type
用于指定元素文本的数据类型
boolean
布尔型
char
字符型
date
日期型
Date time
日期时间型
Float
实型
Int
整型
Number
数字型
Time
时间型
Uri
Universal Resource Identifier,如"urn:schemas-microsoft-com:Office9"
Uuid
例如"333C7BC4-460F-11D0-BC04-0080C7055A83".
entity
xml补充类型
entities
xml补充类型
enumeration
xml补充类型
id
xml补充类型
idref
xml补充类型
idrefs
xml补充类型
nmtoken
xml补充类型
nmtokens
xml补充类型
notation
xml补充类型
string
字符串类型
<ElementType dt:type=”int”></Element>上表中只列举了一部分常见数据类型,如果您想得到关于dt:type更详细的信息,请浏览MSDN。
除此之外,元素类型可以有另外一种方式,即引用一个已有的ElementType,请看下例:
<ElementType name="pages" content="textOnly" dt:type=”int” model="closed" /><ElementType name="book" content="eltOnly" model="closed" order=”seq”><element type="pages" /> </ElementType>
在元素book的定义中,为其定义了一个子元素,子元素的类型引用元素pages的定义。 AttrributeType
Attribute也是xml的元素之一,用它可以表示Element中的某些特征,自然,我们也希望对attribute的数据结构和数据类型作定义。定义AttributeType的基本格式为
<AttributeTypedefault="default-value" dt:type="primitive-type" dt:values="enumerated-values" name="idref" required="{yes | no}" >
default
设定attribute的默认值,必须注意的是,default的值也必须符合AttributeType中其他对数据结构的定义
Dt:type
用于指定Attribute的数据类型
boolean
布尔型
char
字符型
date
日期型
Date time
日期时间型
Float
实型
Int
整型
Number
数字型
Time
时间型
Uri
Universal Resource Identifier,如"urn:schemas-microsoft-com:Office9"
Uuid
例如"333C7BC4-460F-11D0-BC04-0080C7055A83".
entity
xml补充类型
entities
xml补充类型
enumeration
xml补充类型
id
xml补充类型
idref
xml补充类型
idrefs
xml补充类型
nmtoken
xml补充类型
nmtokens
xml补充类型
notation
xml补充类型
string
字符串类型
<AttributeType dt:type=”int”>AttributeType的datatype类型与ElementType的datatype类型是相同的,上表中只列举了一部分常见数据类型,如果您想得到关于dt:type更详细的信息,请浏览MSDN。
Dt:values
当dt:type为enumeration型时,定义attribute的可能值列表,attribute的值将在这些值中选取
<AttributeType name="colors" dt:type="enumeration"dt:values="red green blue">
name
定义attribute的名称
required
定义该attribute是否一定要包含在element中
yes
一定要包含
no
不一定要包含
AttributeType与ElementType一样,也可以引用已有的AttributeType定义: description
description是一种注释,用于说明Schema的定义内容。
<ElementType name="Book"><description>This is how we describe the books we sell. Be sure to specifythe ageGroup!</description><element type="ageGroup"><default>ADULT</default></element></ElementType> group Element
group用来按一定序列,将element组织成group group的表达形式为<groupmaxOccurs="{1 | *}" minOccurs="{0 | 1}" order="{one | seq | many}" >
maxOccurs
定义该group出现的最多次数
1
只能调用一次
*
可以调用任意次
minOccurs
定义该group出现的最少次数
0
无要求
1
至少调用一次
order
定义该group中element的排列顺序
one
只允许元素内容按一种方式排列
seq
允许元素内容按指定的方式排列
many
按任意方式排列
<ElementType name="x" order="one"><group order="seq"><element type="x1"><element type="y1"></group><group order="seq"><element type="x2"><element type="y2"></group></ElementType> Extensibility
Xml Schema时刻扩展的,他们建立在一个开放的内容模式上,在Schema文档上可以任意的添加elemtnt和attribute,如下例,你可以利用其extensibility机制,对element “page”加以限制条件,由namespace “myEXT”扩展的tag,限制了书本的页数必须在50至100页之间。
<ElementType name="pages" xmlns:myExt="urn:myschema-extensions"><datatype dt:type="int" /><myExt:min>50</myExt:min><myExt:max>100</myExt:max></ElementType> 如何在XML文件中引用XML Schema
要在一个XML文件中引用一个Schema,只需在相应的element处注明,一般格式为:
<”elementname” xmlns=” x-schema:[the url of the schema file]” >
例如:
<book xmlns="x-schema:http://www.microsoft.com/xml/schema/book.xml"><title>Presenting XML</title><author>Richard Light</author><pages>334</pages></book> Schema 与 DTDs
在Schema之前,另有一种定义XML结构的方式,即DTDs,两者的区别在于:
1 XML Schemas是XML文档,而DTDs有自己的特殊语法,这样,你只需懂得XML的语法规则即可编写Schema,无需学习其他语法规则;xml文件与xml schema文件可以用相同的语法分析器来解析,而无须写两套分析器;xml schema有强大、易用的扩展功能。
2 XML Schema利用名域将文档中特殊的节点与schema说明相联系,一个xml文件可以有多个对应的schema,而用DTDs的话,一个xml文件只能由一个相对应的DTDs。
3 XML schemas内容模型是开放的,可以随意扩充,而DTDs将无法解析扩充的内容。
4 DTDs只能把内容类型定义为一个字符串。而XML schemas允许你把内容类型定义为整型、浮点型、数据型、布尔型或者许多其他的简单数据类型,而无须重定义。 实例分析
现在我们来分析一下第二节中所举的schema例子定义了什么:
<?xml version="1.0"?><Schema><ElementType name="title" content="textOnly" model="closed" /><ElementType name="author" content="textOnly" dt:type=”string” model="closed" /><ElementType name="pages" content="textOnly" dt:type=”int” model="closed" /><ElementType name="book" content="eltOnly" model="closed" order=”seq”><element type="title" /><element type="author" /><element type="pages" /> </ElementType></Schema>
该schema文件定义了四种element type:title:只能有文本内容author:只能有文本内容,数据类型为字符串型pages:只能有文本内容,数据类型为整型book:只能包含子元素,并且子元素的排列顺序必须按照schema所规定的顺序book元素包含分别用,title,author,pages所定义的三个子元素。
你让大家"向小可学习",就是让大家向你学习.
"小可"跟"敝人"一样,是对自己的谦称.I 服了 You!To panq():
我正在学习XML,能在这里看到这篇贴子,真是太好了!
谢谢
我也是正在学习中,大家共同提高吧。
任何 XML 应用的核心是一个 XML 解析器。要处理一个 XML 文档,您的应用将创建一个 parser 对象,将一个 XML document 传递给它,然后处理从 parser 对象返回的结果。
我们讨论了不同类型的 XML 解析器,以及您为何选取其一。我们用不同方式来对解析器分类:
· 验证或非验证解析器
· 支持 Document Object Model (DOM) 的解析器
· 支持 Simple API for XML (SAX) 的解析器
· 用特定语言编写的解析器 (Java, C++, Perl 等)
在我们的下一章节,我们将探讨 DOM 解析器和如何使用它们。
DOM 是一个操作文档结构的通用接口。它设计的一个目标是为一个 DOM 兼容解析器所编写的 Java 代码应该可以使用其它任意 DOM 兼容的解析器而不需要修改代码。(我们稍后将展示这个。)
正如我们前面所提的,一个 DOM 解析器将以树形式返回您整个文档的结构
DOM 接口
DOM 定义了多个 Java 接口。下列是常用的:
· Node: DOM 基本的数据类型。
· Element: 您将最主要处理的对象是 Element。
· Attr: 代表一个元素的属性。
· Text: 一个 Element 或 Attr 的实际内容。
· Document: 代表整个 XML 文档。一个 Document 对象通常也被称为一棵 DOM 树。
常用的 DOM 方法
当您使用 DOM 时,下列是您将常会使用的方法:
· Document.getDocumentElement()
返回文档的根(root)元素。
· Document. GetNodeType()
返回文档的元素的类型
· Node.getFirstChild() and Node.getLastChild()
返回给定 Node 的第一个子女。
· Node.getNextSibling() and Node.getPreviousSibling()
这些方法返回下一个或前一个给定 Node 的同胞。
· Node.getAttribute(attrName)
对给定的 Node,返回给定名称的属性。例如,如果您要获得名为 id 属性 的对象,可调用 getAttribute("id")。
我们的第一个 DOM 应用!
介绍了很多概念,让我们继续吧。我们的第一个应用简单地读入一个 XML 文档并将其内容输出到标准输出。
domOne.java
这是我们的第一个 DOM 应用。它解析一个 XML 文档并将其内容输出到标准输出。/*
* (C) Copyright IBM Corp. 1999 All rights reserved.
*
* US Government Users Restricted Rights Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/ import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException; import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.ibm.xml.parsers.*; /**
* domOne.java
* Illustrates how to go through a DOM tree.
*/ public class domOne
{
public void parseAndPrint(String uri)
{
Document doc = null; try
{
DOMParser parser = new DOMParser();
parser.parse(uri);
doc = parser.getDocument();
}
catch (Exception e)
{
System.err.println("Sorry, an error occurred: " + e);
} // We've parsed the document now, so let's print it.
if (doc != null)
printDOMTree(doc);
} /** Prints the specified node, then prints all of its children. */
public void printDOMTree(Node node)
{
int type = node.getNodeType();
switch (type)
{
// print the document element
case Node.DOCUMENT_NODE:
{
System.out.println("<?xml version=\"1.0\" ?>");
printDOMTree(((Document)node).getDocumentElement());
break;
} // print element with attributes
case Node.ELEMENT_NODE:
{
System.out.print("<");
System.out.print(node.getNodeName());
NamedNodeMap attrs = node.getAttributes();
for (int i = 0; i < attrs.getLength(); i++)
{
Node attr = attrs.item(i);
System.out.print(" " + attr.getNodeName() +
"=\"" + attr.getNodeValue() +
"\"");
}
System.out.println(">"); NodeList children = node.getChildNodes();
if (children != null)
{
int len = children.getLength();
for (int i = 0; i < len; i++)
printDOMTree(children.item(i));
} break;
} // handle entity reference nodes
case Node.ENTITY_REFERENCE_NODE:
{
System.out.print("&");
System.out.print(node.getNodeName());
System.out.print(";");
break;
} // print cdata sections
case Node.CDATA_SECTION_NODE:
{
System.out.print("<![CDATA[");
System.out.print(node.getNodeValue());
System.out.print("]]>");
break;
} // print text
case Node.TEXT_NODE:
{
System.out.print(node.getNodeValue());
break;
} // print processing instruction
case Node.PROCESSING_INSTRUCTION_NODE:
{
System.out.print("<?");
System.out.print(node.getNodeName());
String data = node.getNodeValue();
{
System.out.print(" ");
System.out.print(data);
}
System.out.print("?>");
break;
}
} if (type == Node.ELEMENT_NODE)
{
System.out.println();
System.out.print("</");
System.out.print(node.getNodeName());
System.out.print('>');
}
} /** Main program entry point. */
public static void main(String argv[])
{
if (argv.length == 0)
{
System.out.println("Usage: java domOne uri");
System.out.println(" where uri is the URI of the XML document you want to print.");
System.out.println(" Sample: java domOne sonnet.xml");
System.exit(1);
} domOne d1 = new domOne();
d1.parseAndPrint(argv[0]);
}
}
在一个命令行窗口,运行下面的命令:
java domOne sonnet.xml
这个命令将载入我们的应用然后让它解析 sonnet.xml 文件。如果一切运行正常,您将看到 XML 文档的内容被输出到标准输出。
注意:该程序需要ibm的xml4j来解析。请加入该包。
sonnet.xml文件:
<?xml version="1.0"?>
<!DOCTYPE sonnet SYSTEM "sonnet.dtd">
<sonnet type="Shakespearean">
<author>
<last-name>Shakespeare</last-name>
<first-name>William</first-name>
<nationality>British</nationality>
<year-of-birth>1564</year-of-birth>
<year-of-death>1616</year-of-death>
</author>
<title>Sonnet 130</title>
<lines>
<line>My mistress' eyes are nothing like the sun,</line>
<line>Coral is far more red than her lips red.</line>
<line>If snow be white, why then her breasts are dun,</line>
<line>If hairs be wires, black wires grow on her head.</line>
<line>I have seen roses damasked, red and white,</line>
<line>But no such roses see I in her cheeks.</line>
<line>And in some perfumes is there more delight</line>
<line>Than in the breath that from my mistress reeks.</line>
<line>I love to hear her speak, yet well I know</line>
<line>That music hath a far more pleasing sound.</line>
<line>I grant I never saw a goddess go,</line>
<line>My mistress when she walks, treads on the ground.</line>
<line>And yet, by Heaven, I think my love as rare</line>
<line>As any she belied with false compare.</line>
</lines>
</sonnet>
sonnet.dtd文件:
<!-- sonnet.dtd -->
<!-- sonnet is the root of the document -->
<!ELEMENT sonnet (author,title?,lines)>
<!-- the default sonnet type is "Shakespearean" -->
<!ATTLIST sonnet type (Shakespearean | Petrarchan)
"Shakespearean"><!-- author contains information about the author -->
<!ELEMENT author (last-name,first-name,nationality,
year-of-birth?,year-of-death?)><!-- last-name, first-name, nationality, year-of-birth,
and year-of-death are all elements inside author. --><!ELEMENT last-name (#PCDATA)>
<!ELEMENT first-name (#PCDATA)>
<!ELEMENT nationality (#PCDATA)>
<!ELEMENT year-of-birth (#PCDATA)>
<!ELEMENT year-of-death (#PCDATA)><!-- The title of the sonnet -->
<!ELEMENT title (#PCDATA)><!-- The lines element contains the 14 lines of the
sonnet. -->
<!ELEMENT lines (line,line,line,line,
line,line,line,line,
line,line,line,line,
line,line)><!ELEMENT line (#PCDATA)>
domCounter.java
这段代码解析一个 XML 文档,然后遍历 DOM 树来采集有关该文档的数据。当数据采集后将其输出到标准输出。
/*
* (C) Copyright IBM Corp. 1999 All rights reserved.
*
* US Government Users Restricted Rights Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/ import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException; import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.ibm.xml.parsers.DOMParser; /**
* domCounter.java
* This code creates a DOM parser, parses a document, then
* prints statistics about the number and type of nodes
* found in the document.
*/ public class domCounter
{
int documentNodes = 0;
int elementNodes = 0;
int entityReferenceNodes = 0;
int cdataSections = 0;
int textNodes = 0;
int processingInstructions = 0; public void parseAndCount(String uri)
{
Document doc = null;
try
{
DOMParser parser = new DOMParser();
parser.parse(uri);
doc = parser.getDocument();
}
catch (Exception e)
{
System.err.println("Sorry, an error occurred: " + e);
} // We've parsed the document now, so let's scan the DOM tree and
// print the statistics.
if (doc != null)
{
scanDOMTree(doc);
System.out.println("Document Statistics for " + uri + ":");
System.out.println("====================================");
System.out.println("Document Nodes: " + documentNodes);
System.out.println("Element Nodes: " + elementNodes);
System.out.println("Entity Reference Nodes: " + entityReferenceNodes);
System.out.println("CDATA Sections: " + cdataSections);
System.out.println("Text Nodes: " + textNodes);
System.out.println("Processing Instructions: " + processingInstructions);
System.out.println(" ----------");
int totalNodes = documentNodes + elementNodes + entityReferenceNodes +
cdataSections + textNodes + processingInstructions;
System.out.println("Total: " + totalNodes + " Nodes");
}
} /** Scans the DOM tree and counts the different types of nodes. */
public void scanDOMTree(Node node)
{
int type = node.getNodeType();
switch (type)
{
case Node.DOCUMENT_NODE:
documentNodes++;
scanDOMTree(((Document)node).getDocumentElement());
break; case Node.ELEMENT_NODE:
elementNodes++;
NodeList children = node.getChildNodes();
if (children != null)
{
int len = children.getLength();
for (int i = 0; i < len; i++)
scanDOMTree(children.item(i));
}
break; case Node.ENTITY_REFERENCE_NODE:
entityReferenceNodes++;
break; case Node.CDATA_SECTION_NODE:
cdataSections++;
break; case Node.TEXT_NODE:
textNodes++;
break; case Node.PROCESSING_INSTRUCTION_NODE:
processingInstructions++;
break;
}
} /** Main program entry point. */
public static void main(String argv[])
{
if (argv.length == 0)
{
System.out.println("Usage: java domCounter uri");
System.out.println(" where uri is the URI of your XML document.");
System.out.println(" Sample: java domCounter sonnet.xml");
System.exit(1);
} domCounter dc = new domCounter();
dc.parseAndCount(argv[0]);
}
}