1。xml背景
格式良好的(web-fromed)xml可以不需要文档类型定义(DTD),只要满足基本的xml格式规范就可以认为是格式良好的xml文档。但是格式标准,只能说明元素、标签、格式是合法的,并不能说明元素是有意义的,或者说规范的。
有效的xml文档,首先要求是格式良好的文档,同时遵守相应的DTD文件约束。
2。xml解析
xml文档解析的大致使用过程如下图:
由xml解析器解析和操作指定的xml文档,然后提供接口供应用程序使用。如果解析器不同,那么提供的接口就有可能不同。庆幸的是,目前所有的xml解析器对两套标准的api提供了支持,这两套标准api就是dom和sax。
dom:即document object model,文档对象模型,它是w3c组织推荐的处理xml的标准接口。dom是基于xml文档结构树的解析。
sax:即simple api for xml,它是非官方的、xml社区事实上的标准。sax是基于事件流的解析。
dom和sax只是定义了一些接口以及某些接口的缺省实现,应用程序要想利用dom或sax访问xml文档,还需要真正实现dom或sax接口的xml解析器。apache的xerces是一个使用非常广泛的解析器,它实现了dom和sax的调用接口,并提供了多种语言的实现版本。
3。java语言对xml文档的解析
首先介绍jaxp:
基于dom或sax提供的api接口,使用相应的解析器实现类我们已经可以对xml进行解析处理了。如下所示:
org.xml.sax.XMLReader sp=new org.apache.xerces.parser.SAXParser();
FileInputStream fis=new FileInputStream(“hello.xml”);
InputSource is=new InputSource(fis);
sp.setContentHandler(new MyConentHandler());
sp.parse(is);
为了屏蔽xml解析器的变化对代码的影响,java提供了一套标准的处理xml文件的接口(实际上是一些抽象的工厂类),使得java开发人员以一种标准的方式对xml进行编程,即jaxp(java api for xml processing)。jaxp没有提供解析xml的新方法,只是在解析器之上封装一个抽象层。在jdk1.6的文档中,我们可以看到javax.xml,org.w3c.dom,org.xml.sax包及其子包都属于jaxp的部分。jaxp由接口、抽象类和一些辅助类组成,符合jaxp规范的解析器实现其中的接口和抽象类,开发时只需要使用jaxp的api编程,底层的解析器对开发者时透明的,可以随意的切换。
那么jaxp出现后,java应用程序处理xml文档的过程就如下图:
那实际采用哪种解析器的jaxp实现,可以通过系统属性、properties文件等方式来配置。
下面具体介绍几种java解析xml的方法:
3.1 DOM方式(jaxp)
在javax.xml.parsers包中,定义了dom的抽象工厂类DocumentBuilderFactory,在这个类中有一个静态的方法newInstance(),通过它产生一个DocumentBuilderFactory的实例。前面提到过jaxp编程,解析器提供商必须继承该抽象类产生一个具体的解析器工厂,然后由这个工厂类实例出一个解析器对象,再通过该解析器对象处理xml文档。那么这个newInstance方法就是用来产生一个具体的解析器工厂类实例,查找生成解析器工厂类实例的方式可参考jdk文档。
在获取到解析器工厂类实例类之后,就可以调用newDocumentBuilder()方法创建一个dom解析器实例;dom解析器实例就可以调用parser()方法获取整个xml问答的Document对象。
3 .2 SAX方式(jaxp)
sax是基于事件驱动的api,sax解析xml文档时会向事件处理器发送不同的事件。sax解析器接口和事件处理器接口都在org.xml.sax包中定义。XMLReader即为sax定义的解析器接口,由解析器提供商实现该借口,应用程序需要做的是编写一个事件处理器。可以通过XMLReader的setContentHandler()方法来设置一个事件处理器的实例。
与dom类似,jaxp也为sax解析器提供了抽象工厂类SAXParserFactory类,sax解析器工厂类的实例与dom解析器工厂类的实例类似,都是通过newInstance()方法来创建,不同的是SAXParserFactory的newInstance()方法查找的工厂类属性是:javax.xml.parsers.SAXParserFactory。同样,获取sax解析器实例的方法,可以通过调用newSAXParser()。
使用SAXParser和XMLReader都可以用来对xml文档进行解析,前者只是对后者又一次的包装。
3.3 JDOM
dom被设计用于完成几乎所有的xml操作任务,同时又是与语言无关的,这就导致dom的api庞大而且复杂。为了使java程序员更方便地处理xml文档,两位国外的java技术专家创建了jdom。用developerworks上的一句话,“延续开源社群有需要就创建工具的历史传统,Java 技术专家 Jason Hunter 和 Brett McLaughlin 缔造了 JDOM”。所以可以认为,jdom是一种专门用于java语言解析xml文档的开放源代码框架。
jdom也使用对象树来表示xml文档,底层使用sax解析器分析xml文档,形成jdom树。
3.4 DOM4J
同jdom一样,dom4j也是应用于java平台,提供简单、灵活的处理xml文档的开发源代码库。很有意思的是,dom4j是由早期开发jdom的人分离出来而后独立开发的,(利益或意见不和?呵呵)与jdom相比,dom4j提供了更好的灵活性。从网上的评论可以看出,dom4j从性能、功能、易用性上都优于jdom,可以作为解析xml文件的首选。(看来后来分离出的那拨人选择还是正确的!)流行的hibernate,jaxm都采用了dom4j处理xml文件。
dom4j也使用sax解析器来分析xml文档,形成dom4j树;它也提供了用于大文档的基于事件的处理模型。
所以可以看出,jdom和dom4j只是开源社区产生出来的方便地解析xml的框架或工具,并没有创造新的xml解析方式。如果拿
拿以上四种解析xml的方法比较,用孙鑫老师的话,如果你需要频繁更换解析器就是jaxp方式,否则推荐使用dom4j。