当前位置:文档之家› XML解析技术研究

XML解析技术研究

XML解析技术研究
XML解析技术研究

XML解析技术研究

摘要:XML作为过去十年中出现的最流行的技术之一,得到了广泛的应用,而其中XML解析技术是XML应用的关键。本文介绍了XML解析技术的研究动向,分析和比较了4种XML解析技术的优劣,并归纳总结了应用系统设计中选取合适的XML解析技术的原则。

1 引言

XML(eXtensible Markup Language,可扩展标记语言)是由World Wide Web 联盟(W3C)定义的元语言,即一种关于语言的语言。XML的设计源于SGML (Standard Generalized Markup Language,标淮通用标记语言),是SGML

的子集,其目的是为了促进Internet上结构化文档的交换。简单的说,XML是一组规则和准则的集合,用于以无格式文本来描述结构化数据[1].1996年W3C联盟就开始从事XML的标准化工作,并于1998年2月10日发布了XML1.0.

XML的出现给分布式计算领域带来了重大影响,其力量源于它的数据独立性[1].XML是纯数据描述,与编程语言、操作系统或传输协议无关,从而将数据从以代码为中心的基础结构所产生的约束中解放出来,让数据能够在Web上更自由的流通。

然而XML本身只是以纯文本对数据进行编码的一种格式,要想利用XML,或者说利用XML文件中所编码的数据,必须先将数据从纯文本中解析出来,因此,必须有一个能够识别XML文档中信息的解析器,用来解释XML文档并提取其中的数据。然而,根据数据提取的不同需求,又存在着多种解析方式,不同的解析方式有着各自的优缺点和适用环境。选择合适的XML解析技术能够有效提升应用系统的整体性能,因此,了解和区分各种不同的XML解析技术就显得尤为重要。

2 XML解析技术分析

所有的XML处理都从解析开始,无论是使用XSLT或Java语言,第一步都是要读入XML文件,解码结构和检索信息等等,这就是解析,即把代表XML文档的一个无结构的字符序列转换为满足XML语法的结构化组件的过程。

2.1 XML解析技术的分类

根据从XML中获取数据的简易性,性能和最终所得到的数据模型的不同,XML 解析技术大致可分为以下四类:

1)面向文档的流式解析;

2)面向文档的对象式解析;

3)面向文档的指针式解析;

4)面向应用的对象式解析;

这四类解析技术分别处于不同的抽象层次,适用于不同的应用场景,有着各自的优缺点。针对具体的应用需求,选择合适的解析技术,往往能够减少内存消耗,缩短处理时间,更方便地获取数据,提高应用系统的整体性能。

2.2 面向文档的流式解析技术

流式解析是一种基于事件的解析过程,解析器顺序读取XML文档,产生一个对应的事件流,并向事件处理程序发送所捕获的各种事件,如元素开始和元素结束等,而事件处理程序则通过不同的方法处理这些事件。

流式解析是将XML文档作为一个数据流来处理,因此,它具有类似于流媒体的优点,能够立即开始读取数据,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,不需要将整个文档一次加载到内存中,使得在处理大型文档时具有较好的时间和空间上的效率。然而效率的代价是易用性的降低,流式解析编程较为复杂,程序员需要负责更多的操作。并且由于应用程序没有以任何方式存储数据,所以使得更改数据或在数据流中往后移是不可能的。再加上它的单遍解析特性,意味着它也不支持随机访问。

流式解析又分为两种解析方式:推式解析(SAX)和拉式解析(StAX)。这两种方式的主要区别在于是由解析器还是应用程序控制读循环(读入文件的循环)。

2.2.1 推式解析(SAX解析技术)SAX(Simple API for XML)解析技术就是一种推式解析,在这种解析方式中,解析器控制着读循环,在文档结束之前控制权不会返回给应用程序[3].解析器通过回调的方式进行数据处理。

SAX提供了一个用于处理XML的,基于事件驱动的简单API.它的设计开始于XML-DEV邮件列表成员间的讨论,他们开发出的第一个接口草案SAX1.0于1998年1月发布,其后在2000年5月发布了SAX2.0,目前最新版本是2004年4月发布的SAX2.0.2.SAX没有经过官方的标准机构认可,它不由W3C联盟或其它任何官方机构维护(现在,SAX由David Megginson维护) [4],但它被广泛使用并视为XML社区事实上的标准。SAX最初是为Java而定义的,但也可以用于Python、Perl、C++等其它语言。

SAX是基于事件驱动的,即SAX解析器在读取XML文档的过程中生成一个事件流,并且对于每个事件通过回调事件处理程序中相应的方法来进行处理。比如元素开始和结束标记,元素内容,实体,语法分析错误等事件。针对下面的简单XML文档,所产生的事件如图1所示,注意针对元素内的空格或回车也会生成一个文本事件。

图1 SAX解析器生成的事件

SAX中的核心事件处理程序是一个实现了ContentHandler接口的类。此接口中定义了处理与XML文档本身关联的事件的方法,如 startDocument、endDocument、startElement、endElement、Characters等

SAX解析技术具有所有流式解析技术的优点和缺点,但是由于在整个解析过程中,解析器掌握着控制权直到文档结束,应用程序很难在获得所需的部分数据后停止解析过程(可以通过抛出异常的方式终止解析过程,但较为复杂,而且终止后也无法继续解析过程),因此产生了由应用程序掌握控制权的拉式解析方式。

2.2.2 拉式解析(StAX解析技术)

StAX(Streaming API for XML)解析技术是一种拉式解析,在这种解析方式中,应用程序控制着读循环。循环中,应用程序负责反复调用解析器获得下一个事件,直到文档结束。通过保留解析过程的控制权,可以简化调用代码来准确地处理它预期的内容,并且可随时停止解析。此外,由于该方式没有基于处理程序回调,应用程序也不需要像SAX中那样模拟解析器的状态。

StAX针对同样的XML文档所获得事件类型和SAX基本相同,但是StAX包含了两套处理XML的API:基于指针的API和基于迭代器的API,分别提供了不同程度的抽象[5].

基于指针的API简单的返回事件,此时事件用数值形式来表示。这是一种低层API,没有提供底层XML结构的抽象,所有的状态信息直接从流读取器获得,不需要创建额外的对象。从而节约内存,拥有较高的效率。

而较为高级的基于迭代器的API则以对象方式返回事件,每个事件对象都封装了它所表示的特定XML结构固有的信息,因此可直接利用其方法获得属于该结构的信息,但也需要额外的对象创建开销。相对于基于指针的API,基于迭代器的API具有更多的面向对象特征,因此更便于应用于模块化的体系结构。

StAX也是用Java定义的,其StAX1.0于2004年3月发布,并且成为了JSR-173 规范,最新版本为2006年6月发布的StAX1.2.StAX作为用Java语言处理XML的最新标准,比早期出现的XPP (Xml Pull Parser)拉式解析器功能更为强大,也得到了更为广泛的应用。

2.3 面向文档的对象式解析技术

由于流式解析方式固有的无法更改数据和不支持随机访问特性,尤其是没有对XML文档的结构建模,使得应用程序很难对XML文档进行搜索、修改、添加和删除等操作。为了解决这些问题,产生了面向文档的对象式解析技术——DOM.

DOM(Document Object Model)是用与平台和语言无关的方式对XML文档进行建模的官方W3C标准[6],其目标是提供一个可以通用于各种程序语言、操作系统和应用程序的接口。DOM最初被当作Web浏览器识别和处理页面元素的方式,即在W3C介入之前的功能,称为“DOM Level 0”。W3C于1998年10月提出了“DOM Level 1”建议,支持XML1.0和HTML处理。随后于2000年11月提出了“DOM Level 2”建议,对Level 1进行了扩展,支持XML1.0、命名空间和CSS,也支持用户接口和树形操作事件,并且添加了DOM树形操作功能。最新的“DOM Lev el 3”建议于2003年6月提出,在level 2的基础上添加了对DTD、XML模式和XPath的支持[1].

DOM作为一种对象式解析技术,定义了层次化对象模型来表示XML文档。即为XML语法中的每个概念(如元素,属性,实体,文档等)定义对应的类,而解析器在读入XML文档的时候,会建立XML语法和类之间的一一映射。实际上,DOM 的层次化对象模型是一个树形结构,它将一个XML文档看作一棵节点树,每个节点代表一个XML文档中的元素。DOM的基本节点对象有5个[1]:(1)Document 对象:是树的最高节点,也是对整个文档操作的入口;(2)Element和Attr对象:对文档中元素和元素属性的映射;(3)Text对象:作为Element和Attr 对象的子节点,代表了元素或属性的文本内容;(4)NodeList对象:对节点按指定的方式进行遍历。

例如对于2.2.1中的XML文档,其对应的DOM节点树如下图所示(注意元素内的空格或回车也会被当作文本对象):

图2 DOM节点树(矩形框表示元素节点,椭圆表示文本节点)

利用DOM在内存中建立的完整的XML文档的树形结构,开发人员就可以方便的对XML文档进行一系列操作,如遍历、增加、删除、修改文档内容等,且具有良好的导航能力。同时DOM所具有的对象特性也非常便于面向对象编程。然而,由于DOM在使用数据前需要完整的遍历XML文档,在内存中构建树形结构表示,因此需要消耗大量的内存,尤其是对于大型文档,性能下降的很快。而且必须一次解析整个XML文档,不可能只做部分解析,当只关注XML文档的小部分数据时,效率很低。(Axis2项目中的Axiom对象模型实现了对XML文档的部分解析,可构建不完整的节点树,但实现较为复杂)

由于DOM是与语言无关的,当DOM接口进入指定语言的数据结构时,会产生不必要的复杂性,无法利用语言本身的优势。因此出现了许多与DOM类似的针对特定语言的对象模型。如JDOM就是针对Java的特定文档对象模型,JDOM使用具体类而不使用接口,简化了API,并在API中大量使用了Java集合类。DOM4J 则是JDOM的一种智能分支,它提供了对XPath和XML Schema的支持,并且通过DOM4J API和标准DOM接口使其具有并行访问功能[5].它们都属于面向文档的对象式解析技术。

2.4 面向文档的指针式解析技术

前面提到的面向文档的流式解析效率较高,但易用性差,而对象式解析易用性强,却效率较低,这两种方式似乎处于两个极端。其效率问题主要在于两种方式都是提取解析模式,即解析时,提取一部分源文件,一般来说是一个字符串,然后在内存中进行解析构建。这种解析模式注定了需要大量的创建和销毁对象,而且还存在更新效率问题,在DOM中(SAX并不支持更新),每一次改动都需要将DOM模型重新完整的解析成XML字符串,原文件并没有被利用,即DOM并不支持增量更新。为了解决这些问题,提出了一种较新颖的指针式解析技术,即VTD-XML.

VTD-XML是一种无提取的XML解析方法,它较好的解决了DOM占用内存过大的缺点,并且还提供了快速的解析与遍历、对XPath的支持和增量更新等特性。VTD-XML是一个开源项目,目前有Java、C两种平台支持,第一个版本是2004年6月发布的VTD-XML0.5,其VTD- XML1.0版本于2005年10月发布,最新的版本为2007年10月发布的VTD-XML2.2.

VTD(Virtual Token Descriptor,虚拟令牌描述符)是一个64bits长度的数值类型,记录了每个元素的起始位置,长度,深度以及令牌的类型等信息,如图3所示。64bits固定长度使得可以用数组这种高效的结构来组织VTD,大幅提高性能。VTD是实现无提取解析的关键,它类似于XML文档中元素的指针,通过它可以快速定位到某个元素。

图3 VTD记录的比特层格式

令牌开始偏移量(即相对于XML文档头部的距离)是30 bits,也就是说它能解析的最大文件是1G.令牌长度为20 bits,即一个令牌的最大长度是1M.令牌类型4bits,说明支持16种词汇类型。

为了实现无提取这个目的,VTD-XML将原XML文件原封不动的以二进制的方式读进内存,不做解码,然后在这个比特数组上解析每个元素的位置并把一些信息,如XML令牌的开始偏移量、长度、深度和令牌类型,记录下来,保存为VTD 数组,之后的遍历操作便可在VTD数组上进行。如果需要提取XML内容,就查找VTD数组,利用VTD记录中的位置等信息在原始比特数组上进行解码并返回字符串。

而且VTD-XML还可以高效的实现增量更新,例如,如果想在一个大型XML

文档中找出一个节点元素并删除它,那么只需要找到这个元素的VTD,将这个VTD 从VTD数组中删除,然后再利用所有的VTD写出到另一个二进制数组中就可以了,因为删除的VTD标明了要删除的元素的位置,所以在新写入的二进制数组中就不会出现这段元素了。用VTD写入新的二进制数组的过程实际上就是一个二进制数组的拷贝过程,其效率是非常高的[2].

由此可见,VTD很好的解决了前两种解析方式的缺点,通过其巧妙的设计使得在解析XML文档时内存占用少,效率高,并且还能够实现XML文档的快速解析与遍历、提供对XPath的支持。VTD的出现是XML解析技术的一大进步,会对XML 解析技术的发展产生巨大影响。

2.5 面向应用的对象式解析技术

前面所谈到的三种解析技术都是从XML的角度来处理文档和建立模型,这对于主要关心文档的XML结构的应用程序来说是适用的,但是有很多应用程序仅仅将XML作为数据交换的媒介,它们更关心的是文档数据本身。此时,面向应用的对象式解析(或称为XML数据绑定)可以使应用程序在很大程度上忽略XML文档的实际结构,而直接使用文档的数据内容。

数据绑定是指将数据从一些存储媒介(如XML文档、文本文件和数据库)中取出,并通过应用程序表示这些数据的过程,即把数据绑定到虚拟机能够理解并且可以操作的某种内存中的结构[9].数据绑定并不是一个新鲜的概念,其在关系数据库上早已得到了广泛的应用,如Hibernate就是针对数据库的轻量级数据绑定框架。而针对XML数据绑定的Castor框架在2000年就已经出现,目前已经涌现出了许多类似的框架,如JBind、JAXB、JiBX、Quick和Zeus等。

其中JAXB(Java Architecture for XML Binding)是一个处于不断发展中的应用于Java平台的数据绑定框架,提供了一套在XML文档和Java对象之间自动映射的API,符合JSR31——XML数据绑定规范(XML Data Binding Specification)。该项目始于1999年8月,由Java Community Process开发,其1.0版本于2002年10月发布,目前最新版本为2007年9月17日发布的JAXB2.1.5.

如图4,显示了数据绑定在数据库和XML文档中的应用。

图4 数据绑定

在数据绑定中有三个重要概念[9]:

l 编组(Marshalling):把内存中的数据转换到存储介质中的过程。在Java和XML环境中,编组就是把一些Java对象转化为一个(或多个)XML文档。其核心就在于把Java中的面向对象结构转化成适用于XML的扁平结构。

l 解组(Unmarshalling):把数据从存储媒介转换到内存中的过程。在Java和XML环境中,即将XML文档解组到Java虚拟机中,其复杂性在于从数据到Java代码变量的映射。

l 映射(Mapping):用于编组和解组的一套规则。

初看起来XML数据绑定和面向文档的对象式解析较为相似,都在内存中构建文档表示,同时内部表示和标准的XML文档之间可以互相转换。但两者之间的不同在于文档模型尽可能接近的保存XML的文档结构,而数据绑定只关心应用程序

使用的文档数据[7].如图5所示,同一个XML文档的文档模型和数据绑定模型是完全不同的。

图5 文档模型和数据绑定模型比较

如果应用程序使用文档模型方法,那么获得所需要的数据就必须在节点树中根据父子节点关系进行遍历。而使用数据绑定方法,只需进行正常的Java编程,访问数据更加容易,速度也比文档模型快得多。而且,XML数据绑定并不只是简化编程,由于它把许多文档细节抽象出来,所以数据绑定所需的内存通常少于文档模型所需的内存,如上图中,文档模型方法使用了10个单独的对象,而数据绑定才使用2个。此外,由于要构建的对象少得多,所以为XML文档构建数据绑定表示还可能更快[7].

在XML数据绑定中最为核心的是怎样由XML文档生成Java对象。目前有两种方式:映射绑定方式和代码生成方式[8].在映射绑定方式中,构建自己的Java 类,并向绑定框架指定这些类如何与XML文档相关联。如框架Castor和Quick 就支持这种方式。而代码生成方式则根据XML文档结构(即DTD或Schema形式的文法)自动构建相应的Java类,如JAXB、Castor和JBind提供了根据XML

文档的Schema描述生成Java代码,Quick和Zeus可根据DTD描述生成Java代码。

代码生成方式所构造的类可以包括完整的数据类型信息,还能够对所构造的类进行验证。但该方式使得程序代码和文档结构之间紧密耦合,如果文档结构发生变化,就需要重新生成代码。而映射绑定方式则具有更大的灵活性,其使用自己构建的对象类将数据和行为组合在一起,通过修改映射定义(而不是改变应用程序代码)来处理XML文档结构中的微小变化,可以在一定程度上解除对象类与实际XML文档之间的耦合[8].其缺点在于需要编写较为复杂的映射文件。

2.6 四种XML解析技术的特性比较

根据以上对四种XML解析技术的介绍和分析,对其特性进行总结和比较,如下表所示:

表1 XML解析技术特性比较

3 XML解析技术的选取

通过上述对四种XML解析技术的分析,可以大致看出XML解析技术的发展历程,在不同的时期,针对不同的应用需求,产生了不同的解析技术。这些解析技术具有各自的优缺点,在应用中,如何选择正确的解析技术,往往成为提高应用系统整体性能和效率的关键。

3.1 面向文档与面向应用的解析方式的选取

上述的四种解析技术又可分为两类:面向文档的和面向应用的。如果应用程序只是将XML文档作为数据交换的媒介,关心文档中包含的数据胜于关心文档的XML结构,那么选择面向应用的解析方式将能够在数据获取上得到很大的简化,虽然在效率上有点损失,但相对于整个应用系统的模块化设计是值得的。

相反,如果应用程序真正关心文档结构的细节,如编写一个XML文档编辑器,又或应用程序正在处理的XML文档不遵守固定的结构,那么选择面向文档的解析方式不仅能够提高效率,还可以降低编程的复杂性。

3.2 面向文档的解析方式的选取

在面向文档的三种解析方式中,流式解析和对象式解析是出现较早的两种解析方式,提供了不同层面上的解析抽象。

流式解析是一种低级的解析方式,它能够提供比对象式解析更多的控制,并且效率更高。然而,由于流式解析没有对文档结构进行建模,使得很难对文档进行搜索、修改、添加和删除等操作,而且也无法进行随机访问。因此如果应用程序仅仅想高效率的获得XML文档中的某部分数据,并且希望对解析过程进行更多的控制,而不需要对文档进行添加和修改,那么选取流式解析更能满足需求。在流式解析中,StAX技术使得应用程序能够更方便的控制解析过程,并且其作为Java的官方规范,得到了更广泛的应用。

对象式解析作为一种高级的解析方式,它的重点在于对文档结构进行建模,而完全不关心文档的解析过程(对象式解析往往建立在流式解析的基础上,在流式解析的过程中逐步建立模型)。而一旦在内存中建立了文档的树形结构模型,那么就可以方便的通过模型对文档进行搜索,修改、添加和删除等操作,并且更适合于面向对象的编程。然而,这种便利性是以内存和效率为代价的,因此,如果应用程序需要频繁的对XML文档中的数据进行检索和修改,而对内存和效率没有过多要求,那么对象式解析将是一种很好的选择。

而指针式解析的提出是以提高效率,减少内存消耗为主要目的,可看作是介于流式解析和对象式解析之间的一种解析方式。它巧妙的设计方式使得不需要对文档建立树形模型,就可以实现搜索,修改、添加和删除等操作,同时向应用程序屏蔽了底层的解析过程,编程更加简便。因此,当应用程序不关心解析过程,而对性能有较高要求时,可以选择使用指针式解析。

3.2.1 面向文档解析方式的性能比较

根据VTD-XML的官方网站的数据[11],VTD-XML的解析速度是DOM的5x-10x,是SAX(with NULL content handler)的1.5x - 2.0x(With NULL content handler 意味着SAX解析中没有插入任何额外的处理逻辑,也就是SAX的最高速度)。VTD-XML的内存占用仅为原XML的1.3x-1.5x(其中1.0x部分是原XML),而DOM 的内存占用则是原XML的4x-8x,对于一些大型的XML文档,使用DOM方式处理往往会出现内存溢出的错误。

以下是SAX,DOM和VTD-XML三种XML解析方式的性能测试结果[10],如下表所示:

表2 SAX,DOM和VTD-XML性能比较

4、结论

随着XML的广泛应用,XML解析技术作为XML文档处理过程中关键的一环,对应用系统的整体性能有着重要影响。本文通过分析和比较4种主流XML解析技术的优缺点,使得开发人员能够针对具体的应用需求选择最为合适的解析技术。此外,对XML解析技术的深入研究对于促进XML的应用也有着积极的作用。

参考文献:

[1] Frank P.Coyle著,袁勤勇,莫青等译。 XML、Web服务和数据革命[M]. 北京:清华大学出版社,2003

[2] 鱼雷。 VTD-XML解析技术研究[硕士学位论文]. 西安:西安电子科技大学, 2007

[3] Benoit Marchal. Working XML: Understand the various approaches to XML parsing [EB/OL].

https://www.doczj.com/doc/43728340.html,/developerworks/xml/library/x-wxxm38.html . 2007

[4] Benoit Marchal. SAX, the power API [EB/OL].

https://www.doczj.com/doc/43728340.html,/developerworks/library/x-saxapi/ index.html . 2001

[5] Peter Nehrer. StAX'ing up XML, Part 1: An introduction to Streaming API for XML (StAX) [EB/OL].

https://www.doczj.com/doc/43728340.html,/developerworks/xml/library/x-stax1.html . 2006

[6] Dennis Sosnoski. XML and Java technologies: Java document model usage [EB/OL]. https://www.doczj.com/doc/43728340.html,

/developerworks/library/x-injava2/index.html. 2002

[7] Dennis M. Sosnoski. XML Data Binding with Castor [EB/OL]. https://www.doczj.com/doc/43728340.html,/developerworks/cn/java /j-x-bindcastor /. 2002

[8] Dennis Sosnoski. XML and Java technologies: Data binding [EB/OL]. https://www.doczj.com/doc/43728340.html,/developerworks /library/x-databdopt

/index.html. 2003

[9] Brett McLaughlin. Practical data binding: Get your feet wet in the real world [EB/OL]. https://www.doczj.com/doc/43728340.html,

/developerworks/library/x-pracdb1.html. 2004

[10] Jimmy Zhang. A Step in the Right Direction VTD-XML Improves XML Processing [EB/OL]. https://www.doczj.com/doc/43728340.html,/xml/Article/30484. 2006

[11] Project Homepage of VTD-XML. https://www.doczj.com/doc/43728340.html,/

Dom4j遍历解析XML测试

Dom4j遍历解析XML测试 近来老和XML打交道,不深挖不行了。。 这是一个Dom4j解析XML的例子,为做复杂递归处理前期所写的例子。涵盖了XML的解析方面大部分核心API。 环境: Dom4j-1.6.1 Dom4j解析需要XML需要的最小类库为: dom4j-1.6.1.jar jaxen-1.1-beta-6.jar 目标: 解析一个xml,输出所有的属性和元素值。 测试代码: XML文件: zhangsan 32 home add com add lisi 22 home add com add com add

解析代码: package com.topsoft.test; import org.dom4j.io.SAXReader; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.Node; import java.util.Iterator; import java.util.List; import java.io.InputStream; /** * Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-3-26 15:53:51
* Note: Dom4j遍历解析XML测试 */ public class TestDom4j { /** * 获取指定xml文档的Docum ent对象,xml文件必须在classpath中可以找到 * * @param xmlFilePath xml文件路径 * @return Document对象 */ public static Docum ent parse2Document(String xmlFilePath) { SAXReader reader = new SAXReader(); Docum ent docum ent = null; try { InputStream in =TestDom4j.class.getResourceAsStream(xmlFilePath); docum ent =reader.read(in); } catch (Docum entException e) { System.out.println(e.getMessage()); System.out.println("读取classpath下xmlFileName文件发生异常,请检查CL ASSPATH和文件名是否存在!"); e.printStackTrace(); }

java_Dom4j解析XML详解

学习:Dom4j 1、DOM4J简介 DOM4J是https://www.doczj.com/doc/43728340.html, 出品的一个开源XML 解析包。DOM4J应用于Java 平台,采用了Java 集合框架并完全支持DOM,SAX 和JAXP。 DOM4J 使用起来非常简单。只要你了解基本的XML-DOM 模型,就能使用。 Dom:把整个文档作为一个对象。 DOM4J 最大的特色是使用大量的接口。它的主要接口都在org.dom4j里面定义:

接口之间的继承关系如下: interface https://www.doczj.com/doc/43728340.html,ng.Cloneable interface org.dom4j.Node interface org.dom4j.Attribute interface org.dom4j.Branch interface org.dom4j.Document interface org.dom4j.Element interface org.dom4j.CharacterData interface org.dom4j.CDATA interface https://www.doczj.com/doc/43728340.html,ment interface org.dom4j.Text interface org.dom4j.DocumentType interface org.dom4j.Entity interface org.dom4j.ProcessingInstruction 2、XML文档操作1 2.1、读取XML文档: 读写XML文档主要依赖于org.dom4j.io包,有DOMReader和SAXReader两种方式。因为利用了相同的接口,它们的调用方式是一样的。 public static Docum ent load(String filenam e) { Document docum ent =null; try { SAXReader saxReader = new SAXReader(); docum ent =saxReader.read(new File(filename)); //读取XML文件,获得docum ent 对象 } catch (Exception ex) { ex.printStackTrace();

XML报文解析测试

XML报文解析测试 在平时工作中,难免会遇到把 XML 作为数据存储格式。面对目前种类繁多的解决方案,哪个最适合我们呢?在这篇文章中,我对这四种主流方案做一个不完全评测,仅仅针对遍历 XML 这块来测试,因为遍历 XML 是工作中使用最多的(至少我认为)。 预备 测试环境: AMD 毒龙1.4G OC 1.5G、256M DDR333、Windows2000 Server SP4、Sun JDK 1.4.1+Eclipse 2.1+Resin 2.1.8,在 Debug 模式下测试。 XML 文件格式如下: <?xml version="1.0" encoding="GB2312"?> <RESULT> <VALUE> <NO>A1234</NO> <ADDR>四川省XX县XX镇XX路X段XX号</ADDR> </VALUE> <VALUE> <NO>B1234</NO> <ADDR>四川省XX市XX乡XX村XX组</ADDR> </VALUE> </RESULT> 测试方法: 采用 JSP 端调用Bean(至于为什么采用JSP来调用,请参考: https://www.doczj.com/doc/43728340.html,/rosen/archive/2004/10/15/138324.aspx),让每一种方案分别解析10K、100K、1000K、10000K的 XML 文件,计算其消耗时间(单位:毫秒)。 JSP 文件: <%@ page contentType="text/html; charset=gb2312" %> <%@ page import="com.test.*"%> <html> <body> <% String args[]={""}; MyXMLReader.main(args); %>

android 中对xml 进行解析

DOM解析器是通过将XML文档解析成树状模型并将其放入内存来完成解析工作的,而后对文档的操作都是在这个树状模型上完成的。这个在内存中的文档树将是文档实际大小的几倍。这样做的好处是结构清除、操作方便,而带来的麻烦就是极其耗费系统资源。而SAX正好克服了DOM的缺点,分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中,这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。 选择DOM 还是选择SAX,这取决于下面几个因素: 应用程序的目的:如果打算对数据作出更改并将它输出为XML,那么在大多数情况下,DOM 是适当的选择。并不是说使用SAX 就不能更改数据,但是该过程要复杂得多,因为您必须对数据的一份拷贝而不是对数据本身作出更改。 数据容量:对于大型文件,SAX 是更好的选择。 数据将如何使用:如果只有数据中的少量部分会被使用,那么使用SAX 来将该部分数据提取到应用程序中可能更好。另一方面,如果您知道自己以后会回头引用已处理过的大量信息,那么SAX 也许不是恰当的选择。 对速度的需要:SAX 实现通常要比DOM 实现更快。 基于上面的分析,在基于Android系统的内存和CPU资源比较有限的手持设备上,只要我们不需要修改XML数据或者随机的访问XML数据,SAX尽管可能需要更多的编码工作,但是为了更小的内存和CPU 消耗,还是值得的。 另外,Android SDK中已经包含了JAXP对应的javax.xml.parsers包,和SAX对应org.xml.sax(当然DOM对应的org.w3c.dom包也包含在内),加上Android还提供了android.sax这样的包来方便SAX Handle的开发,基于JAXP和SAX这样的标准方法来开发不仅复杂度不高,即使出现问题在讨论组中寻求解决方案也是比较容易的。 android 中的xml解析应该是和java中一条道路主要分为sax 解析和的Dom 解析。 如下的介绍的相关的包和类均为android 环境下: sax解析对应为: org\xml\sax 包:xml解析 javax.xml.parsers.SAXParserFactory javax.xml.parsers.SAXParser 两个主要用于SAXParser的上下文建立

XML的四种解析器(dom,sax,jdom,dom4j)原理及性能比较[收藏]

1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM 是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。DOM以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。 2)SAX SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX还比它的替代者DOM快许多。 选择DOM还是选择SAX?对于需要自己编写代码来处理XML文档的开发人员来说,选择DOM还是SAX解析模型是一个非常重要的设计决策。DOM 采用建立树形结构的方式访问XML文档,而SAX采用的事件模型。 DOM解析器把XML文档转化为一个包含其内容的树,并可以对树进行遍历。用DOM解析模型的优点是编程容易,开发人员只需要调用建树的指令,然

后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用DOM解析器的时候需要处理整个XML文档,所以对性能和内存的要求比较高,尤其是遇到很大的XML文件的时候。由于它的遍历能力,DOM解析器常用于XML文档需要频繁的改变的服务中。 SAX解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag。特别是当开发人员只需要处理文档中所包含的部分数据时,SAX这种扩展能力得到了更好的体现。但用SAX解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。 3)JDOM https://www.doczj.com/doc/43728340.html,/ JDOM的目的是成为Java特定文档模型,它简化与XML的交互并且比使用DOM实现更快。由于是第一个Java特定模型,JDOM一直得到大力推广和促进。正在考虑通过“Java规范请求JSR-102”将它最终用作“Java标准扩展”。从2000年初就已经开始了JDOM开发。 JDOM与DOM主要有两方面不同。首先,JDOM仅使用具体类而不使用接口。这在某些方面简化了API,但是也限制了灵活性。第二,API大量使用了Collections类,简化了那些已经熟悉这些类的Java开发者的使用。

XML创建与解析常用方法介绍

XML解析方式介绍 1.DOM4J(Document Object Model for Java) 虽然DOM4J代表了完全独立的开发结果,但最初,它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能,包括集成的XPath支持、XML Schema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,它通过DOM4J API和标准DOM接口具有并行访问功能。从2000下半年开始,它就一直处于开发之中。 为支持所有这些功能,DOM4J使用接口和抽象基本类方法。DOM4J大量使用了API中的Collections 类,但是在许多情况下,它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是,虽然DOM4J付出了更复杂的API的代价,但是它提供了比JDOM大得多的灵活性。 在添加灵活性、XPath集成和对大文档处理的目标时,DOM4J的目标与JDOM是一样的:针对Java 开发者的易用性和直观操作。它还致力于成为比JDOM更完整的解决方案,实现在本质上处理所有Java/XML问题的目标。在完成该目标时,它比JDOM更少强调防止不正确的应用程序行为。 DOM4J是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML,特别值得一提的是连Sun的JAXM也在用DOM4J. 【优点】 ①大量使用了Java集合类,方便Java开发人员,同时提供一些提高性能的替代方法。 ②支持XPath。 ③有很好的性能。 【缺点】 ①大量使用了接口,API较为复杂。 2.SAX(Simple API for XML) SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX还比它的替代者DOM快许多。 选择DOM还是选择SAX?对于需要自己编写代码来处理XML文档的开发人员来说,选择DOM还是SAX解析模型是一个非常重要的设计决策。 DOM采用建立树形结构的方式访问XML文档,而SAX 采用的是事件模型。

org.w3c.dom(java dom)解析XML文档

位于org.w3c.dom操作XML会比较简单,就是将XML看做是一颗树,DOM就是对这颗树的一个数据结构的描述,但对大型XML文件效果可能会不理想 首先来了解点Java DOM 的API: 1.解析器工厂类:DocumentBuilderFactory 创建的方法:DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 2.解析器:DocumentBuilder 创建方法:通过解析器工厂类来获得DocumentBuilder db = dbf.newDocumentBuilder(); 3.文档树模型Document 创建方法:a.通过xml文档 Document doc = db.parse("bean.xml"); b.将需要解析的xml文档转化为输入流InputStream is = new FileInputStream("bean.xml"); Document doc = db.parse(is); Document对象代表了一个XML文档的模型树,所有的其他Node都以一定的顺序包含在Document对象之内,排列成一个树状结构,以后对XML文档的所有操作都与解析器无关, 直接在这个Document对象上进行操作即可; 包含的方法:

4.节点列表类NodeList NodeList代表了一个包含一个或者多个Node的列表,根据操作可以将其简化的看做为数组 5.节点类Node

Node对象是DOM中最基本的对象,代表了文档树中的抽象节点。但在实际使用中很少会直接使用Node对象,而是使用Node对象的子对象Element,Attr,Text等 6.元素类Element 是Node类最主要的子对象,在元素中可以包含属性,因而Element中有存取其属性的方法

四中最常用的XML文件解析总结

XML文件学习总结 掌握了XML文件解析的常用的4中方式:DOM解析、SAX 解析、STAX解析以及DOM4j解析XML文件。 一、DOM 解析xml文件 public List parse(String url) throws Exception{ // 1、创建解析工厂 D ocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();//创建工厂是单例模式,不能直接new对象,需要调用newInstance来创建对象。 // 2、创建解析器 D ocumentBuilder builder = factory.newDocumentBuilder(); // 3、创建解析器的url F ile file = new File(url); // 4、得到解析后的Document对象 D ocument doncument = builder.parse(file); // 5、通过得到节点名字得到所有同名节点的集合NodeList N odeList nodeList = doncument.getElementsByTagName("student"); // 6、遍历NodeList集合 f or (int i = 0; i < nodeList.getLength(); i++) { // 得到每个节点对象 Node studentNode = nodeList.item(i); Student st = new Student(); NamedNodeMap map = studentNode.getAttributes(); //for(int j=0;j

java读写xml文件的方法

在java环境下读取xml文件的方法主要有4种:DOM、SAX、JDOM、JAXB 1. DOM(Document Object Model) 此方法主要由W3C提供,它将xml文件全部读入内存中,然后将各个元素组成一棵数据树,以便快速的访问各个节点。因此非常消耗系统性能,对比较大的文档不适宜采用DOM方法来解析。 DOM API 直接沿袭了 XML 规范。每个结点都可以扩展的基于 Node 的接口,就多态性的观点来讲,它是优秀的,但是在Java 语言中的应用不方便,并且可读性不强。 实例: Java代码 1.import javax.xml.parsers.*; 2.//XML解析器接口 3.import org.w3c.dom.*; 4.//XML的DOM实现 5.import org.apache.crimson.tree.XmlDocument; 6.//写XML文件要用到 7.DocumentBuilderFactory factory = DocumentBuilderFactory.newInst ance(); 8. //允许名字空间 9. factory.setNamespaceAware(true); 10. //允许验证 11. factory.setValidating(true); 12. //获得DocumentBuilder的一个实例 13.try { 14. DocumentBuilder builder = factory.newDocumentBuilder(); 15.} catch (ParserConfigurationException pce) { 16.System.err.println(pce); 17.// 出异常时输出异常信息,然后退出,下同 18.System.exit(1); 19.} 20.//解析文档,并获得一个Document实例。 21.try { 22.Document doc = builder.parse(fileURI); 23.} catch (DOMException dom) { 24.System.err.println(dom.getMessage()); 25.System.exit(1); 26.} catch (IOException ioe) { 27.System.err.println(ioe); 28.System.exit(1); 29.}

使用DOM4j解析xml文件

Xml文件: studentname 78 78 98 studentname 77 68 88 JAVA文件: import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Iterator; import java.util.List; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; /** *DOM4j对xml文件的操作 *操作DOM4j的时候注意要导入3个jar包,否则会报异常 *dom4j-1.6.1.jar *jaxen-1.1-beta-6.jar *saxpath.jar **/ public class ReaderDom4j {

xml文件解析

查找结点,读取结点属性------------------------------------------------------ 获取结点的属性------------------------------------- 设置结点的属性------------------------------------------------ 给结点添加新属性------------------------------------------- 设置一个结点的内容---------------------------------------------------- 添加新节点---------------------------------------------------- 编码问题------------------------------------------------------------------ XML树: John Fleck June 2, 2002 example keyword This is the headline This is the body text. 1:查找结点 #include #include #include #include #include Void parseStory (xmlDocPtr doc, xmlNodePtr cur) { xmlChar *key; cur = cur->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"keyword")))

Java解析XML文件

Java解析XML文件 ========================================== xml文件 <?xml version="1.0" encoding="GB2312"?> <RESULT> <VALUE> <NO>A1234</NO> <ADDR>四川省XX县XX镇XX路X段XX号</ADDR> </VALUE> <VALUE> <NO>B1234</NO> <ADDR>四川省XX市XX乡XX村XX组</ADDR> </VALUE> </RESULT> ========================================== 1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。DOM以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。 import java.io.*; import java.util.*; import org.w3c.dom.*; import javax.xml.parsers.*; public class MyXMLReader{ public static void main(String arge[]){ long lasting =System.currentTimeMillis(); try{ File f=new File("data_10k.xml"); DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); DocumentBuilder builder=factory.newDocumentBuilder(); Document doc = builder.parse(f); NodeList nl = doc.getElementsByT agName("VALUE"); for (int i=0;i<nl.getLength();i++){ System.out.print("车牌号码:" +

java dom解析xml

java dom解析xml 010000 00000CC3 20100629173405 1 000001 import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; public class FileTest { /** * @param args */ public static void main(String[] args) { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse("d:/test.xml"); //得到根节点 Element root = doc.getDocumentElement(); NodeList nl = root.getElementsByTagName("HLR"); Element e = (Element) nl.item(0); String hlrId=e.getAttribute("HlrId"); System.out.println(hlrId); }catch(Exception e){

xml的四种解析方法及源代码

xml的四种解析方法及源代码(SAX、DOM、JDOM、DOM4J) 第一种:SAX解析 SAX处理机制:SAX是一种基于事件驱动的API。利用SAX解析XML文档,牵涉到两个部分:解析器和事件处理器。解析器负责读取XML文档,并向事件处理器发生事件,如元素开始和元素结束事件;而事件处理器则负责对事件做出响应,对传递的XML数据进行处理。 测试用的xml文件:db.xml Xml代码 oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@localhost:1521:oracle scott tiger DTD文件db.dtd Xml代码

SAX解析实例一 org.xml.sax.DefalutHandler类: 可以扩展该类,给出自己的解析实现SAXPrinter.java Java代码 import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class SAXPrinter extends DefaultHandler { /** *//** * 文档开始事件 */ public void startDocument() throws SAXException { System.out.println("");

java解析XML详解

详解Java解析XML的四种方法 XML现在已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便。对于XML本身的语法知识与技术细节,需要阅读相关的技术文献,这里面包括的内容有DOM(Document Object Model),DTD(Document Type Definition),SAX(Simple API for XML),XSD(Xml Schema Definition),XSLT(Extensible Stylesheet Language Transformations),具体可参阅w3c官方网站文档https://www.doczj.com/doc/43728340.html,获取更多信息。 XML在不同的语言里解析方式都是一样的,只不过实现的语法不同而已。基本的解析方式有两种,一种叫SAX,另一种叫DOM。SAX是基于事件流的解析,DOM是基于XML文档树结构的解析。假设我们XML的内容和结构如下: ddviplinux m 30 本文使用JAVA语言来实现DOM与SAX的XML文档生成与解析。 首先定义一个操作XML文档的接口XmlDocument 它定义了XML文档的建立与解析的接口。 package com.alisoft.facepay.framework.bean; /** * * @author hongliang.dinghl * 定义XML文档建立与解析的接口 */ public interface XmlDocument { /** * 建立XML文档 * @param fileName 文件全路径名称 */ public void createXml(String fileName); /** * 解析XML文档 * @param fileName 文件全路径名称 */ public void parserXml(String fileName); } 1. DOM生成和解析XML文档 为 XML 文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 DOM 接口来操作这个树结构。优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。 import java.io.FileInputStream; import java.io.FileNotFoundException;

java 解析xml 并导入数据库(dom4j )

java 解析xml 并导入数据库(dom4j ) import java.io.File; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class TestXMLImport { /** * @param args */ public static void main(String[] args) { String sql = "insert into T_XML(NUMERO, REPOSICION, NOMBRE, TURNOS) values (?, ?, ?, ?)"; Connection conn = null; PreparedStatement pstmt = null; try {

conn = DbUtil.getConnection(); pstmt = conn.prepareStatement(sql); Document doc = new SAXReader().read(new File("D:/share/JavaProjects/drp/test_xmlImport/xml/test01.XML ")); List itemList = doc.selectNodes("/ACCESOS/item/SOCIO"); for (Iterator iter=itemList.iterator(); iter.hasNext();) { Element el = (Element)iter.next(); String numero = el.elementText("NUMERO"); String reposicion = el.elementText("REPOSICION"); String nombre = el.elementText("NOMBRE"); List turnosList = el.elements("TURNOS"); StringBuffer sbString = new StringBuffer(); for (Iterator iter1=turnosList.iterator(); iter1.hasNext();) { Element turnosElt = (Element)iter1.next(); String lu = turnosElt.elementText("LU"); String ma = turnosElt.elementText("MA"); String mi = turnosElt.elementText("MI"); String ju = turnosElt.elementText("JU"); String vi = turnosElt.elementText("VI"); String sa = turnosElt.elementText("SA");

jdom读取解析XML文件

jdom学习读取XML文件 用JDOM读取XML文件需先用org.jdom.input.SAXBuilder对象的build()方法创建Document对象,然后用Document类、Element类等的方法读取所需的内容。 例如: 8G 200 1580 10G 500 3000 则解析类: import java.util.*; import org.jdom.*; import org.jdom.input.SAXBuilder; publicclass Sample { publicstaticvoid main(String[] args) throws Exception{ SAXBuildersb=new SAXBuilder(); Document doc=sb.build(Sample.class.getClassLoader().getResourceAsStream("test. xml")); //构造文档对象 Element root=doc.getRootElement(); //获取根元素 List list=root.getChildren("disk");//取名字为disk的所有元素 for(int i=0;i

XML文档对象模型解析

XML文档对象模型 1)DOMDocument对象:该对象描述全部的文档映射表,文档映射表包含了XML 文档里的所有信息。 常用方法 常用属性 2)IXMLDOMNode对象:该对象描述XML文档里的节点。这个节点可以是元素、属性、处理指令、文本或者其他存储在XML文档里的信息。 常用方法 常用属性 3)IXMLDOMNodeList对象:该对象描述IXMLDOMNode对象的集合,并可使用该对象遍历这个集合。IXMLDOMNodeList对象里的节点集合可以用数值该问。 常用方法 常用属性 4)IXMLDOMParseError对象:该对象用来验证XML文档对于Schema或DTD的正确性,并且取得在验证过程中产生的错误信息。 常用方法 常用属性 * DOMDocument对象常用方法: a)createElement(elementName) ---- 该方法以元素名为参数创建一个用此参数命名的元素节点。(不能创建名称空间受限制的元素。如果要创建名称空间受限制的元素,必须使用createNode()方法) 例: doc.createElement("PRODUCT"),有些用到:doc-> creatElement('item') b)createAttribute(attributeName) ---- 该方法以属性名为参数创建一个用此参数命名的属性节点。 例: doc.createAttribute("PRODID") xml中表现形式:下载通道名称 c)createComment(text) ---- 该方法以字符串为参数创建一个包含此字符串的注释节点。

相关主题
文本预览
相关文档 最新文档