随着Internet的飞速发展,HTML因扩展困难、交互性差和语义模糊等缺点在日益增长的网络设计需求面前呈现出弱势。标准、简洁、结构严谨、可扩展性高的XML应运而生。在推出之初,XML提供通用数据交换、改变Web发布、改变分布式计算的功能。如今,XML不仅对软件开发的各个方面都产生了巨大影响,而且在各行各业都得到了充分应用。
XML是Extensible Markup Language的缩写,是一种类似于HTML的标记语言。XML文档的主要作用是传输数据。例如,Web应用中客户端从服务器请求到XML文档或服务器接收到客户端上传的XML文档,此时应该如何获取其中的数据? XML文档中除数据本身外,还有许多元素、属性、实体或备注等,应用程序应该如何判断数据的类型以及数据之间的关系?这些问题都属于XML文档的解析功能。本章将讲解如何使用XML DOM解析XML文档。首先,了解W3C组织对于DOM的定义及结构。其次,使用DOM提供的接口解析XML文档.包括加载XML文档到内存、获取XML文档数据、创建、修改DOM节点等。
1.1 . XML简介
1.1.1 XML发展历史及作
1. XML的发展历史
XML是指可扩展标记语言(Extensible Markup Language),类似于HTML。早在1969年,IBM公司开发了一种文档描述语言GML,用于解决不同系统文档格式的问题。该语言在1986年演变为国际标准(ISO8879),被称为SGML。SGML是许多大型组织(如飞机、汽车公司和军队)的文档标准,它是与语言无关、结构化可扩展的语言,受到许多公司的欢迎,被用于创建、处理和发布大量的文本信息。
1989年,CERN欧洲粒子物理研究中心的研究人员开发了基于SGML的超文本版本,称为HTML。HTML继承了SGML的许多重要优点,如结构化、独立性和可描述性;但同时也存在较多缺陷,如只能使用固定、有限的标记,而且只侧重于显示内容等。
随着数据的增多,HTML的缺点演变成无法忽略的问题。W3C提供了HTML的扩展来解决这些问题,最后形成了新的SGML的子集——XML。
XML的出现是为了解决HTML中的弊病,它保留了许多SGML标准的优点,更易于操作以及在WWW环境下实现。1998年,XML成为W3C的标准。
XML与SGML、HTML之间的发展关系如图1.1.1所示。
图1.1.1 XML的发展示意图
XML是W3C的推荐标准,其设计宗旨是传输数据而非显示数据。XML标签没有被预定义,需要自定义标签。XML具有自我描述性。
XML与HTML的主要差异体现在以下3个方面:
(1) XML不是HTML的替代。
(2) XML和HTML为了不同的目的而设计使用。
(3) XML用于传输和存储数据,旨在传输信息,关注的焦点是数据的内容;HTML用于显示数据,旨在显示信息,关注的焦点是数据的外观。
2. XML的作用
被誉为“万维网标准之王”的Jeffrey Zeldman曾说:“当XML(扩展标记语言)于1998年2月被引入软件工业界时,它给整个行业带来了一场风暴。有史以来第一次,这个世界拥有了一种用来结构化文档和数据的通用且适应性强的格式,它不仅仅可以用于Web,而且可以被用于任何地方”。
XML的主要作用可以概括为以下6个:
(1)使数据从HTML分离。
如果需要在HTML文档中显示动态数据,则每次数据改变时将花费大量的时间来编辑HTML。通过XML,数据能够存储在独立的XML文件中,从而专注地使用HTML进行布局和显示,且修改底层数据时无须再次对HTML进行任何改变。通过几行JavaScript即可读取一个外部XML文件,然后更新HTML中的数据内容。
(2)简化数据共享。
XML数据以纯文本格式进行存储,提供了一种独立软件和硬件的数据存储方法,使创建不同应用程序共享的数据变得更加容易。
(3)简化数据传输。
通过XML可以在不兼容的系统之间轻松交换数据。对于开发人员而言,在因特网上不兼容的系统之间交换数据特别耗费时间。可以通过各种不兼容的应用程序来读取数据,使用XML交换数据可以降低这种复杂性。
(4)简化平台的变更。
升级到新系统(硬件或软件平台)相对费时的情况下,不兼容的数据在转换大量的数据时经常丢失。XML数据以文本格式存储,这使XML可以在不丢失数据的前提下更易于扩展或升级到新的操作系统、应用程序或浏览器。
(5)延伸了数据使用。
XML独立于硬性、软件以及应用程序之外,使数据更可用、有用。不同的应用程序都能够在HTML页面以及XML数据源中访问。通过XML的数据不仅可以供各种阅读设备(手持计算机、语音设备、新闻阅读器等)使用,还可以供盲人等残障人士使用。
(6)创建新的Internet语言。通过XML创建的新的Internet语言如下:
1)XHTML:最新的HTML版本。
2)WSDL:用于描述可用的Web Service。
3)WAP和WML:用于手持设备的标记语言。
4)RSS:用于RSS Feed的语言。
5)RDF和OWL:用于描述资源和本体。
6)SMIL:用于描述针对Web的多媒体。
1.1.2 XML的语法和结构
1. XML 的结构
note.xml:
<?xml version="1.0" encoding="gb2312"?>
<note>
<to>张明</to>
<from>小红</from>
<heading>Message</heading>
<body>今晚8点公司全体员工一起聚餐!</body>
</note>
对示例1.1的说明如下:
(1) 第一行是XML声明其定义XML的版本(1.0)和所使用的编码(字符集)。
(2) 第二行是文档的根元素,根据标签名称理解本文档的作用(便签)。
(3) 第三行到第六行描述了根元素的4个子元素——to、from、heading和body。
(4) 最后一行定义根元素的结尾:</note>。
由上述说明可知,该XML文档包含一张小红写给张明的便签,可以从中领略到XML出色的自我描述能力。
XML文档形成树状结构。表述书籍XML文档见示例1.2,分析该文档可以了解文档的树结构。
books.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K.Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="Web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
文档形成的树结构如图1.1.2所示。
图1.1.2 XML文档树结构
示例1.2中根元素是 <bookstore>,文档中所有的<book>元素都被包含在<bookstore>中。<book>元素包含4个子元素。分别为<title>、<author>、<year>和<price>。<book>元素具有属性category,<title>元素具有属性lang。
2.XML的语法规则
(1)XML文档应该遵循以下规则:
1) XML文档必须有根元素。
2) XML文档必须有关闭标签。
3) XML标签对大小写敏感。
4) XML元素必须被正确地嵌套。
5) XML属性必须加引号。与HTML相同,XML的属性由“名称/值”对组成。
6) XML中的注释使用“<!——注释的内容——>”标注。
7) XML中的空格将被保留。
HTML可以将多个连续的空格字符裁减为一个。而在XML中,文档中的空格不会被裁减,例如:
Hello world
在HTML中输出:
Hello world
在XML中输出:
Hello world
(2)XML文档的元素。
XML元素是从开始标签(且包括)直到结束标签(且包括)的部分。元素可以包含其他元素、文本或者二者的混合物。元素可以拥有属性。
在示例1.2中,<bookstore>和<book>都拥有元素内容,因为它们包含其他元素;<author>只有文本内容,因为它仅包含文本;<book>元素拥有属性category。
XML元素是可扩展的。示例1.3对示例1.l中的根元素<note>扩展<date>元素,表示发便签的日期。
exnote.xml:
<?xml version="1.0" encoding="gb2312"?>
<note>
<date>2011年2月14日</date><!——扩展的新元素——>
<to>张明</to>
<from>小红</from>
<heading>Message</heading>
<body>今晚8点公司全体员工一起聚餐!</body>
</note>
XML元素名称必须遵循以下命名规则:
Ø 可以包含字母、数字以及其他字符。
Ø 不能以数字或标点符号开始。
Ø 不能以字符“xml”(或者XML、xml)开始。
Ø 不能包含空格。
(3)XML文档的属性。
与HTML类似,XML元素可以在开始标签中包含属性,属性(Attribute)提供关于元素的额外信息。属性值必须加双引号,XML元素通常可以在开始标签中包含属性。绝大部分的属性都可以使用元素替代。
Persons.xml:
<?xml version="1.0" encoding="gb2312"?>
<persons>
<person sex="male">
<name>Jack</name>
</person>
<person>
<sex>male</sex>
<name>Jack</name>
</person>
</persons>
XML中并未规定使用属性以及需要使用元素的场合,一般可以使用属性的位置都可以使用子元素替换。
<!--1.使用date属性-->
<?xml version="1.0" encoding="UTF-8"?>
<note date="2011年2月14日">
<to>Ben</to>
<from>Jack</from>
<heading>Message</heading>
<body>今晚8点公司全体员工一起聚餐!</body>
</note>
<!--2.使用date子元素-->
<?xml version="1.0" encoding="UTF-8"?>
<note>
<date>2011年2月14日</date>
<to>Ben</to>
<from>Jack</from>
<heading>Message</heading>
<body>今晚8点公司全体员工一起聚餐!</body>
</note>
<!-- 3.扩展date元素 -->
<?xml version="1.0" encoding="UTF-8"?>
<note>
<date>
<day>14</day>
<month>2</month>
<year>2011</year>
</date>
<to>Ben</to>
<from>Jack</from>
<heading>Message</heading>
<body>今晚8点公司全体员工一起聚餐!</body>
</note>
属性存在以下缺点:
1) 无法包含多个值(子元素可以)。
2) 无法描述树结构(子元素可以)。
3) 不易扩展、不利于后续复用。
4) 难以阅读和维护。
所以,实际应用中建议尽量使用元素描述数据,而使用属性提供与数据无关的信息。
综上所述,元数据(有关数据的数据)应当存储为属性,而数据本身应当存储为元素。例如,
实际应用中向元素分配ID引用,这些lD可用于标识XML元素。其用法与HTML中lD属性相同,作用仅仅是标识符,而非组成数据的一部分,此时应该使用属性。
students.xml:
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student ID="s01">
<name>Tom</name>
<sex>male</sex>
<age>20</age>
<class>G2—24</class>
</student>
<student ID="s02">
<name>Anna</name>
<sex>female</sex>
<age>19</age>
<class>G3—30</class>
</student>
</students>
(4) XML文档的实体。
在XML中,部分字符具有特殊的意义。例如,将字符“<”放在XML元素中会发生错误,因为解析器会将它作为新元素的开始。以下代码行会产生XML错误:
<message>if salary < 1000 then</messaqe>
为了避免此类错误,可以使用一个实体引用代替“<”字符,代码如下:
<message>if salary &1t; 1000 then</message>
XML中包含5个预定义的实体引用,见表1-1-1。
实体 | 数据 | 说明 |
< | < | 小于 |
> | > | 大于 |
& | & | 与 |
' | ' | 单引号 |
" | " | 双引号 |
实体引用类似于编程语言中的引用型变量,用户也可以自定义实体。
1.2 DOM及其模型
1.2.1 DOM简介
1.什么是DOM
DOM即文档对象模型,是Document Obiect Model的缩写,定义了访问XML和XHTML等文档的标准。DOM是W3C标准,W3C将DOM定义为“一个使程序和脚本有能力动态地访问和更新文档的内容、结构以及样式的平台和语言中立的接口”。DOM分为核心DOM、HTML DOM和XML DOM。其中,核心DOM是用于任何结构化文档的标准模型。
2.什么是HTML DOM
HTML DOM定义了所有HTML文档元素的对象和属性以及访问它们的方法(接口),是用于HTML文档的标准模型。
3.什么是XML DOM
与HTML DOM相似,XML DOM定义了所有XML元素的对象和属性以及访问它们的方法(接口),是用于获取、更改、添加或删除XML元素的标准。XML DOM包括以下4个含义:
(1)用于XML的标准对象模型。
(2)用于XML的标准编程接口。
(3)独立于平台和语言。
(4)W3C的标准。
XML DOM的作用如图1.1.3所示。
图1.1.3 XML DOM的作用
4.DOM级别
DOM级别指W3C组织的DOM规范。W3C组织为DOM规范定义了3个级别:
(1)DOM级别1:专注于HTML和XML文档模型,含有文档导航和处理功能。
(2)DOM级别2:在DOM级别1的基础上添加了样式表对象模型,并定义了操作文档样式信息的功能。同时,DOM级别2定义了一个事件模型,并提供对XML命名空间的支持。
1)DOM Level 2 Core:规定了访问和更改文档内容及结构的API,该API同时包含用于XML的接口。
2)DOM Level 2 HTML:规定了操作HTML文档结构和内容的API。
3)DOM Level 2 Views:规定了对文档视图进行访问和更改的API。视图是与原文档相关联的表现形式或某种备用的表现形式。
4)DOM Level 2 Style:规定了动态访问及更改内容样式表的API。
5)DOM Level 2 Events:规定了访问文档事件的API。
6)DOM Level 2 Traversal-Range:规定了动态遍历和识别文档中内容范围的API。
(3)DOM级别3:定义了内容模型(DTD与Schema)和文档验证。同时,规定了文档加载和保存、文档查看、文档格式化和关键事件。DOM Level 3建立在DOM Level 2核心之上。
1)DOM Level 3 Core:规定了访问和更改文档内容、结构及样式的API。
2)DOM Level 3 Events:通过添加新的接口和事件集,DOM Level 3 Events API对Level 2 Event API的功能进行了扩展.
3)DOM Level 3 Content Model:规定了用于内容加载和保存、内容模型(DTD与Schema)和文档验证支持的API。
4)DOM Level 3 Views:规定了对文档视图进行访问和更改的API。
1.2.2 节点和节点树
依据DOM的规定.XML文档中每个单元(元素、属性、实体、备注等)都是节点。.例如:
(1)整个文档是一个文档节点。
(2)每个XML标签是一个元素节点。
(3)包含在XML元素中的文本是文本节点。
(4)每个XML属性是一个属性节点。
(5)注释属于注释节点。
XML DOM将XML文档视为树结构.这种树结构被称为节点树。程序通过节点树访问所有节点、修改或删除其内容以及创建新元素。节点树展示了节点的集合以及它们之间的关系。节点树从根节点开始,在树的最低层级向文本节点长出“枝条”。
XML节点树中的节点如图1.1.4所示。
图1.1.4 XML文档节点树
books.xml:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
<publish pubdate="2011-01-09"/>
</book>
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
<book category="web">
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
</bookstore>
将示例1.7中的books.xml使用节点树表示.如图1.1.5所示。
图1.1.5XML DOM节点树
对books.xml文件的说明如下:
(1)根节点是<bookstore>,文档中所有的其他节点都包含在<bookstore>中。
(2)根节点<bookstore>包含4个<book>节点。
(3)第一个<book>节点包含4个节点:<title>、<author>、<year>和<price>。其中,每个节点包含一个文本节点(分别为Harry Potter、J K.Rowling、2005和29.99)。
(4)元素节点的文本存储在文本节点中。<year>2005</year>中,元素节点<year>拥有一个值为“2005”的文本节点,“2005”不是<year>元素的值。
(5) 属性节点与子元素属于同一级别的节点。例如,<book>元素的属性“category”与<book>
的子元素<title>同级。
1.父级、子级和同级节点
节点树中的节点彼此之间存在等级关系,可以使用父级、子级和同级节点描述这种关系。父节点拥有子节点,位于相同层级上的子节点称为同级节点。
(1)在节点树中,顶端的节点为根节点。
(2)根节点之外的每个节点都有一个父节点。
(3)节点可以有任何数量的子节点。
(4)叶节点是没有子节点的节点。
(5)同级节点是拥有相同父节点的节点。
节点之间的关系如图1.1.6所示。
图1.1.6节点树中节点之间的关系
2.第一个子节点和最后一个子节点
<book category="web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
在示例1.8中,<title>元素是<book>元素的第一个子节点,而<price>元素是<book>元素的最
后一个子节点。
XML数据按照节点树的形式进行构造,可以在不了解节点树的确切结构以及其中包含的数据类型的情况下,对其进行遍历。
1.3 DOM编程接口
1.3.1 XML DOM对象
XML DOM对象中封装了常用的操作XML文档的属性和方法。常用的XML DOM对象如下:
(1)XML DOM Attr对象:表示Element对象的属性。
(2)XML DOM CDATASection对象:表示文档中的CDATA段。
(3)XML DOM Comment对象:表示文档中注释节点的内容。
(4)XML DOM Document对象:表示整个XML文档。
(5)XML DOM DOMParser对象:该对象通过解析XML标记创建一个文档。
(6)XML DOM Element对象:表示XML文档中的元素。
(7)XML DOM NamedNodeMap对象:表示一个无序的节点列表。
(8)XML DOM Node对象:表示文档树中的一个节点。
(9)XML DOM NodeList对象:表示一个有序的节点列表。
(10)XML DOM Text对象:表示元素或属性的文本内容。
(11) XML DOM XMLHttpRequest对象:提供对HTTP协议的访问,包括发出POST、HEAD以及普通GET请求的能力。XMLHttpRequest可以同步或异步地返回Web服务器的响应,并且通过文本或者一个DOM文档的形式返回内容。此对象并不限于和XML文档一起使用,可以接收任何形式的文本文档。
1.3.2 加载XML文档
浏览器都内建了用于读取和操作XML的XML解析器。解析器将XML读人内存,并转换为可以被JavaScript访问的XML DOM对象。
XML数据可以通过XML文档保存在磁盘介质上,或者通过XML字符串在内存中创建。XMLDocument对象将XML文档和XML字符串加载到内存,然后通过JavaScript实现DOM解析。如果XML文档需要在服务端解析,还可以使用C#、Java等编程语言通过DOM API进行解析。
使用JavaScript实现DOM时,不同浏览器的加载方式有所不同。可以通过异常处理来编写通用浏览器的加载方法。
1.使用load()方法加载XML文档
//IE浏览器
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.load("books.xml");
//Firefox、Mozilla等浏览器
xmlDoc = document.implementation.createDocument("", "", null);
xmlDoc.async = false;
xmlDoc.load("books.xml");
在示例1.9和示例1.10中,第一行代码用于在浏览器中创建空的XML Document对象;第二行关闭异步加载,可以确保在文档完整加载之前,解析器不会继续执行脚本;第三行通知解析器加载名为“books.xml”的文档。
示例1.11通过异常处理模块编写跨浏览器的XML文档加载代码。
<script type="text/javascript">
try {
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
} catch (e) {
try {
xmlDoc = document.implementation.createDocument("", "", null);
} catch (e) {
alert(e.message)
}
}
try {
xmlDoc.async = false;
xmlDoc.load("books.xml");
document.write("XML文档加载完毕,节点数已经创建,可以进行解析了.")
} catch (e) {
alert(e.message);
}
</script>
示例1.11在浏览器中的运行效果如图1.1.7所示。
图1.1.7 XML文档加载
在Java语言中,DOM是使用与平台和语言无关的方式表示XML文档的官方W3C标准,是以层次结构组织的节点或信息片断的集合。该层次结构允许开发人员在树中寻找特定信息,分析该结构通常需要加载整个文档和构造层次结构,然后才能执行其他工作。该结构基于信息层次,因而DOM被认为是基于树或基于对象的。
//使用DOM 加载XML文件
public static void loadXmlDom() throws Exception {
//查找工程相对目录下的XML文件
File f = new java.io.File("WebRoot/books.xml");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse(f);
System.out.println("XML文档加载完毕,节点数已经创建,可以进行解析了.");
}
示例1.12的运行效果如图1.1.8所示。
图1.1.8 XML Document对象加载XML文档
2.使用loadXML ()方法加载XML字符串
在IE浏览器中使用XML Document对象的loadXML() 方法加载XML字符串,在Firefox等浏览器中使用DOM解析器对象DOMParser的parseFromString() 方法加载XML字符串。
<script type="text/javascript">
//定义XML字符串
var text = "<bookstore>";
text = text+"<book>";
text = text + "<title>Learning jQuery</title>";
text = text + "<author>Jonathan Chaffer</author>";
text = text + "<year>2008</year>";
text = text + "</book>";
text = text + "</bookstore>";
try {
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
} catch (e) {
try {
xmlDoc = document.implementation.createDocument("", "", null);
} catch (e) {
alert(e.message)
}
}
try {
xmlDoc.async = false;
xmlDoc.loadXML(text);
document.write("XML文档加载完毕,节点数已经创建,可以进行解析了.")
} catch (e) {
alert(e.message);
}
</script>
在Java语言中,可以使用DOM4J类库的SAXReader类的read()方法加载XML字符串。
//使用DOM4J类库加载XML字符串
public static void loadXmlStringDom() throws Exception {
//定义XML字符串
String text = "<bookstore>";
text = text+"<book>";
text = text + "<title>Learning jQuery</title>";
text = text + "<author>Jonathan Chaffer</author>";
text = text + "<year>2008</year>";
text = text + "</book>";
text = text + "</bookstore>";
Document doc =DocumentHelper.parseText(text); // 将字符串转为XML;
Element rootElt = doc.getRootElement(); // 获取根节点
Iterator iters = rootElt.elementIterator("book");
while (iters.hasNext()) {
Element itemEle = (org.dom4j.Element) iters.next();
String title = itemEle.elementTextTrim("title");
String year = itemEle.elementTextTrim("year");
System.out.println("title:" + title);
System.out.println("year:" + year);
}
}
public void testRead() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new FileInputStream("src/output.xml"));
Element root = document.getRootElement();
for (Iterator iter = root.elementIterator(); iter.hasNext();) {
Element element = (Element) iter.next();
System.out.println(element.getText());
System.out.println(element.attributeValue("name"));
System.out.println(element.attributeValue("blog"));
}
}
public void testWrite() throws Exception{
Document document = DocumentHelper.createDocument();
Element root = document.addElement("root");
for(int i=0;i<10;i++){
Element element1 = root.addElement("user")
.addAttribute("name","Alex"+i)
.addAttribute("id", "id"+i)
.addText("我是信息");
}
XMLWriter writer = new XMLWriter(new FileOutputStream("src/output.xml"));
writer.write(document);
writer.close();
}
1.3.3 节点操作
节点操作通过XML DOM对象的属性和方法实现。对象多达几十个,且每个对象都有各自的属性和方法,常用对象的属性和方法见表1-1-2、表1-1-3。
表1-1-2 XML DOM对象常用属性
属性 | 说明 |
nodeName | 获取节点名称 |
nodeValue | 获取节点的值 |
parentNode | 获取节点的父节点 |
childNodes | 获取节点的所有子节点集合 |
attributes | 获取当前节点所有的属性节点 |
documentElement | 获取文档的根节点 |
表1-1-3 XML DOM对象常用方法
方法 | 说明 |
getElementsByTagName(name) | 获取带有指定标签名(name)的所有元素 |
CreateElement(name) | 创建指定标签名的元素节点 |
appendChild(node) | 向调用节点末尾插入子节点node |
removeChild(node) | 从调用节点中删除子节点node |
//使用属性和方法从books.xml中的<title>元素中获取文本的JavaScript代码
var txt=xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue;
对示例1.15的说明如下:
(1)xmlDoc:由解析器创建的XML Document对象,创建方式见示例1.11。
(2)getElementsByTagName("title")[0]:获取第一个<title>元素。
(3)childNodes[0]:获取<title>元素的第一个子节点(文本节点)。
(4)nodeValue:获取节点的值(文本自身)。
//使用属性和方法从books.xml中的<title>元素中获取文本的Java代码
String title=doc.getElementsByTagName("title")
.item(0).getFirstChiid().getNodeValue();
示例1.16中,使用getNodeValue方法获取节点的值。
另外,DOM对象的许多属性和方法并没有列出。DOM只提供接口和API,不同语言有不同的实现方式,但一般区别较小。例如,JavaScript与Java语言的DOM实现只有部分属性或方法的名称存在差异。
1.访问节点
访问节点包括遍历节点、定位节点、获取节点的详细信息等操作,这些操作都通过XML DOM
的属性和方法实现。通常,访问节点需要使用对象XML Node List和XML Node。前者表示一个节点列表(集合),后者表示一个节点。每个节点都具有nodeName、nodeValue和nodeType属性,分别用于获得节点名称、节点值和节点的类型。
(1)XML Node List。
XML Node List代表一个节点集合,具有length属性,通过该属性可以获取节点的个数,并对节点进行遍历。在Java语言中,使用NodeList类的对象表示一个节点集合。
(2)XML Node。
XML Node表示一个节点。具有nodeName、nodeType和nodeValue属性。元素节点还可以通过attributes属性返回属性节点的列表。在Java语言中,使用Node类的对象表示XML Node。
1)nodeName。其特点是:①nodeName是只读的;②元素节点的nodeName与标签名相同;③属性节点的nodeName是属性的名称。
2)nodeType。nodeType属性规定节点的类型,是只读的。nodeType常用的值包括:①“1”表示节点是元素节点:②“2”表示节点是属性节点;③“3”表示节点是文本节点;④“8”表示节点是注释节点:⑤“9”表示节点是文档节点。
3)nodeValue。特点:①元素节点的nodeValue是不可用的;②文本节点的nodeValue是文本自身;③属性节点的nodeValue是属性的值。
可以通过以下3种方法访问节点:
(1)使用getElementsByTagName()方法。
(2)循环(遍历)节点树。
(3)通过节点的关系在节点树中导航。
在DOM中,节点的关系被定义为节点的属性,定位节点的属性见表1-1-4。
表1-1-4 DOM中表示节点关系的常用属性
属性 | 功能 |
parentNode | 获取父节点 |
childNodes | 获取子节点集合 |
firstChild | 获取第一个子节点 |
lastChild | 获取最后一个子节点 |
nextSibling | 获取同级别中后一个节点 |
previousSibling | 获取同级别中前一个节点 |
<script type="text/javascript">
try {
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
} catch (e) {
try {
xmlDoc = document.implementation.createDocument("", "", null);
} catch (e) {
alert(e.message)
}
}
try {
xmlDoc.async = false;
xmlDoc.load("books.xml");
document.write("XML文档加载完毕,节点数已经创建,可以进行解析了.")
} catch (e) {
alert(e.message);
}
var nlist=xmlDoc.getElementsByTagName("book")[0].childNodes;
document.write("<br>book节点长度: " + nlist.length );
document.write("<br>");
for (var i=0;i<nlist.length;i++){
var node = nlist[i];
if (node.nodeType==1){ //元素节点
document.write("元素节点:" + node.nodeName);
}
var att=node.attributes;//获取该元素的全部属性节点
for(var j=0;j<att.length;j++){
document.writeln("<br/>元素"+node.nodeName+
"有属性"+att[i].nodeName+"="+att[i].nodeValue);
}
document.write("<br/>");
}
</script>
示例1.17在浏览器中的执行效果如图1.1.9所示。
图1.1.9使用JavaScript实现DOM访问节点
使用Java语言编程,实现与示例1.17相同的功能,代码见示例1.18。
//访问节点
public static void loadXmlDomNode() throws Exception {
loadXmlDom();//调用加载XML方法
String title = document.getElementsByTagName("title").item(0)
.getFirstChild().getNodeValue();
System.out.println("title: " + title);
//获得book节点集合
NodeList bookList = document.getElementsByTagName("book");
System.out.println("book节点的长度: " +bookList.getLength());
int size = bookList.item(0).getChildNodes().getLength();
NodeList firstBook = bookList.item(0).getChildNodes();
for (int i = 0; i < size; i++) {
Node bookNode = firstBook.item(i);
if (bookNode.getNodeType() == 1) {
System.out.println("元素节点: " + bookNode.getNodeName() + " = "
+ bookNode.getTextContent());
}
try {
NamedNodeMap att = bookNode.getAttributes();
for (int j = 0; j < att.getLength(); j++) {
System.out.println("元素: " + bookNode.getNodeName()
+ " 有属性 "
+ att.item(j).getNodeName() + "="
+ att.item(j).getNodeValue());
}
} catch (Exception e) { e.getMessage(); }
}
}
示例1.18的执行结果如图1.1.10所示。
图1.1.10使用Java语言实现DOM访问节点
另外,使用Java语言可以遍历元素节点的值,代码如下:
//使用JAVA遍历元素节点值
public static void queryXmlDom() throws Exception {
loadXmlDom();//调用加载XML方法
//获得book节点集合
NodeList bookList = document.getElementsByTagName("book");
for (int i = 0; i < bookList.getLength(); i++) {
Element student = (Element) bookList.item(i);
NodeList bookTempList = student.getChildNodes();
System.out.println("title: " + bookTempList.item(1).getTextContent());
System.out.println("auth: " + bookTempList.item(3).getTextContent());
System.out.println("year: " + bookTempList.item(5).getTextContent());
System.out.println("price: " + bookTempList.item(7).getTextContent());
System.out.println("----------------------");
}
}
遍历XML节点的效果如图1.1.11所示。
图1.1.11使用Java语言实现DOM遍历节点
本章总结
Ø XML是W3C的推荐标准,其设计宗旨是传输数据而非显示数据。XML标签没有被预定义,需要自定义标签。XML具有自我描述性。
Ø XML语法规则。
n XML文档必须有根元素。
n XML文档必须有关闭标签。
n XML标签对大小写敏感。
n XML元素必须被正确地嵌套。
n XML属性必须加引号。与HTML相同,XML的属性由“名称/值”对组成。
n XML中的注释使用“<!——注释的内容——>”标注。
n XML中的空格将被保留。
Ø DOM即文档对象模型,是Document Obiect Model的缩写,定义了访问XML和XHTML等文档的标准。
Ø DOM是W3C标准,W3C将DOM定义为“一个使程序和脚本有能力动态地访问和更新文档的内容、结构以及样式的平台和语言中立的接口”。
Ø XML数据可以通过XML文档保存在磁盘介质上,或者通过XML字符串在内存中创建。XMLDocument对象将XML文档和XML字符串加载到内存,然后通过JavaScript实现DOM解析。
Ø 如果XML文档需要在服务端解析,还可以使用C#、Java等编程语言通过DOM API进行解析。
任务实训部分
1:编写XML文件
训练技能点
Ø 编写XML文档
Ø 熟悉XML文档的格式要求
需求说明
编写XML文档,存储表1-2-1中的数据。
表1-2-1 数据内容
分类编号 | 产品编号 | 产品名称 |
1 | 1 | 奥迪 |
1 | 2 | 宝马 |
1 | 24 | 花冠 |
1 | 34 | 雷克萨斯 |
1 | 35 | 林肯 |
1 | 38 | 雪佛兰 |
1 | 39 | 标致 |
1 | 43 | 法拉利 |
1 | 67 | 凌志 |
1 | 70 | 帕萨特 |
1 | 75 | 高尔夫 |
1 | 76 | 别克 |
实现步骤
(1) 新建文本文件,重命名为products.xml,使用记事本打开该文件。
(2) 在文件中输入XML声明:
<?xml version="1.0" encoding="UTF-8"?>
(3) 在XML声明后输入以下代码,并保存文件products.xml:
<?xml version="1.0" encoding="gb2312" ?>
<Categories 分类编号="1">
<Products>
<Product 产品编号="1" 产品名称="奥迪"/>
<Product 产品编号="2" 产品名称="宝马"/>
<Product 产品编号="24" 产品名称="花冠"/>
<Product 产品编号="34" 产品名称="雷克萨斯"/>
<Product 产品编号="35" 产品名称="林肯"/>
<Product 产品编号="38" 产品名称="雪佛兰"/>
<Product 产品编号="39" 产品名称="标致"/>
<Product 产品编号="43" 产品名称="法拉利"/>
<Product 产品编号="67" 产品名称="凌志"/>
<Product 产品编号="70" 产品名称="帕萨特"/>
<Product 产品编号="75" 产品名称="高尔夫"/>
<Product 产品编号="76" 产品名称="别克"/>
</Products>
</Categories>
(4)使用浏览器打开文件 products.xml ,显示效果如图
图1.2.1 products.xml在浏览器中的显示
2:使用JavaScript加载并解析XML文档
训练技能点
Ø 使用load()方法加载XML文档并解析。
需求说明
根据提供的XML文档,使用JavaScript语言实现加载该XML文档到XML解析器。遍历所有节点并在浏览器显示。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<students>
<student no="m01">
<name>Tom</name>
<class>G3-67</class>
<sex>男</sex>
<birth>
<year>1990</year>
<month>2</month>
<day>21</day>
</birth>
<skill>XHTML</skill>
<skill>.NET</skill>
<skill>JAVA</skill>
<skill>Oracle</skill>
</student>
<student no="m02">
<name>Katherine</name>
<class>G3-65</class>
<sex>男</sex>
<birth>
<year>1989</year>
<month>10</month>
<day>3</day>
</birth>
<skill>XHTML</skill>
<skill>.NET</skill>
<skill>JAVA</skill>
</student>
</students>
实现步骤
(1) 区分IE浏览器和FireFox浏览器中创建文档对象的方式。
(2) IE使用xmlDoc=new ActiveXObject("Microsoft.XMLDOM"); 创建空XML DOM对象。
(3) Firefox使用xmlDoc=document.implementation.createDocument("","",null); 创建空XML DOM对象。
(4) 使用浏览器打开loadXml.html,显示效果如图2.2.1所示。
图1.2.2加载解析的XML文件
参考代码
<script type="text/javascript">
try{
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
}catch(e){
try{
xmlDoc=document.implementation.createDocument("","",null);
}catch(e){
alert(e.message);
}
}
try{
xmlDoc.async=false;
xmlDoc.load("students.xml");
var output="";
var node=xmlDoc.getElementsByTagName("student");
for(var i=0;i<node.length;i++){
output+="<"+node[i].nodeName;
output+=" "+node[i].attributes[0].nodeName+"=""+node[i].getAttribute("no")+""";
output+="><br/>";
for(var j=0;j<node[i].childNodes.length;j++){
output+=" ";
output+="<"+node[i].childNodes[j].nodeName+">";
output+=node[i].childNodes[j].childNodes[0].nodeValue;
output+="</"+node[i].childNodes[j].nodeName+">";
output+="<br/>";
}
output+="</"+node[i].nodeName+">"+"<br/>";
}
document.writeln(output);
}catch(e){
alert(e.message);
}
</script>
3:使用JavaScript操作XML文档
需求说明
(1) 创建并添加一个节点。
(2) 添加节点<student>,节点内容如下:
<student no="m04">
<name>Mary</name>
<class>G3-70</class>
<sex>女</sex>
<birth>
<year>1991</year>
<month>6</month>
<day>22</day>
</birth>
<skill>JAVA</skill>
</student>
实现步骤
(1) 使用createElement()方法创建元素节点。
(2) 使用createTextNode()方法创建文本节点,使用nodeValue属性为文本节点赋值,使用appendChild()方法添加节点。
参考代码
添加student节点的代码片段:
<script type="text/javascript">
try{
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
}catch(e){
try{
xmlDoc=document.implementation.createDocument("","",null);
}catch(e){
alert(e.message);
}
}
try{
xmlDoc.async=false;
xmlDoc.load("students.xml");
var student=xmlDoc.createElement("student");
var att=xmlDoc.createAttribute("no");
att.nodeValue="m04";
student.setAttributeNode(att);
var name=xmlDoc.createElement("name");
name.appendChild(xmlDoc.createTextNode("Mary"));
student.appendChild(name);
var clas=xmlDoc.createElement("class");
clas.appendChild(xmlDoc.createTextNode("G3-70"));
student.appendChild(clas);
var sex=xmlDoc.createElement("sex");
sex.appendChild(xmlDoc.createTextNode("女"));
student.appendChild(sex);
var birth=xmlDoc.createElement("birth");
var year=xmlDoc.createElement("year");
year.appendChild(xmlDoc.createTextNode("1991"));
birth.appendChild(year);
var month=xmlDoc.createElement("month");
month.appendChild(xmlDoc.createTextNode("6"));
birth.appendChild(month);
var day=xmlDoc.createElement("day");
day.appendChild(xmlDoc.createTextNode("22"));
birth.appendChild(day);
student.appendChild(birth);
var skill1=xmlDoc.createElement("skill");
skill1.appendChild(xmlDoc.createTextNode("JAVA"));
student.appendChild(skill1);
xmlDoc.documentElement.appendChild(student);
var output="";
var node=xmlDoc.getElementsByTagName("student");
for(var i=0;i<node.length;i++){
output+="<"+node[i].nodeName;
output+=" "+node[i].attributes[0].nodeName+"=""+node[i].getAttribute("no")+""";
output+="><br/>";
for(var j=0;j<node[i].childNodes.length;j++){
output+=" ";
output+="<"+node[i].childNodes[j].nodeName+">";
output+=node[i].childNodes[j].childNodes[0].nodeValue;
output+="</"+node[i].childNodes[j].nodeName+">";
output+="<br/>";
}
output+="</"+node[i].nodeName+">"+"<br/>";
}
document.writeln(output);
}catch(e){
alert(e.message);
}
</script>
4:使用JAVA解析XML文档
训练技能点
Ø 使用JAVA实现解析XML文档。
需求说明
(1) XML文档内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="cdsort.xsl"?>
<catalog>
<cd>
<title>Made in India</title>
<artist>Jack</artist>
<country>India</country>
<company>Bollywood</company>
<price>10</price>
<year>2011</year>
</cd>
<cd>
<title>摩羯座</title>
<artist>Alun</artist>
<country>China</country>
<company>Bollywood</company>
<price>5</price>
<year>2010</year>
</cd>
</catalog>
(2) 要求得到所有CD的title、artist、price、year这些节点值。
实现步骤
(1) 加载XML文档。
(2) 使用DOM解析XML文档。
巩固练习
一、选择题
1.以下针对XML文档的定义和规范的有( )。
A.DTD
B.SGML
C.Schema
D.complexType
2.以下关于XML的语法规则的说法中,错误的有( )。
A.XML文档必须有且只有一个根元素
B.XML文档中的标签(元素)区分大小写
C.XML文档中的元素和属性都必须加引号
D.XML文档中一个属性可以包含多个值
3.以下关于DOM级别的说法中,正确的有( )。
A.DOM级别是W3C组织的DOM规范
B.DOM级别l专注于文档模型
C.DOM级别2专注于文档模型
D.DOM级别2规定了DTD和Schema
4.以下关于XML节点树的描述,错误的是( )。
A.同级节点拥有相同的父节点
B.除根节点外,所有节点都有一个父节点
C.有且须只有一个根节点
D所有节点都必须有子节点
5.以下对XML DOM对象的属性描述中,正确的有( )。
A.通过nodeName获取文本节点的名称,其名称全部都是“#text”
B.nodeType=l表示当前节点是属性节点
C.元素节点的nodeValue的值是undefined
D.nextSibling属性获取相同级别、名称的下一个节点
二、简答题
1.简述XML的作用。
2.简述节点树中节点之间的关系。
作者:zhangchen124 发表于2017/3/19 15:32:10
原文链接