|
Java API for XML处理(JAXP)用于使用以Java程序语言编写的应用来处理XML数据。JAXP使用解析器标准SAX(Simple API for XML Rarsing)和DOM(Document
Object Model),这样就可以以事件流的形式解析数据,或者数据的对象表示。JAXP还支持XSLT (XML Stylesheet Language Teansformations)标准,使你可以控制数据的表示并且能够将数据转换成其他XML文档或其他格式,例如HTML。JAXP还提供命名空间支持,允许使用本来可能产生名称冲突的DTD。
由于JAXP被设计得更具灵活性,你可以使用任何XML-编译解析器。这一点是通过一个所谓的可插入层实现的,可插入层不仅允许你插入SAX或DOM API的一个实现,还允许插入一个XSL处理器,使得你可以控制XML的显示。
JAXP API
主要的JAXP API定义在javax.xml.parsers包中。javax.xml.parsers包含有两个提供商无关的工厂类:SAXParserFactory和DocumentBuilderFactory,它们分别提供了一个SAXParser和一个DocumentBuilder。而DocumentBuilder又创建DOM-compliant
Document对象。
通过工厂API,你可以插入其他提供商提供的XML实现,并且无需更改源代码。这个实现取决于javax.xml.parsers.SAXParserFactory和javax.xml.parsers.DocumentBuilderFactory系统属性的设置。默认的值(除非在运行时重设)是JWSDP实现。
本章节余下的部分将演示在编写应用时不同JAXP所起的作用。
包的概述
SAX和DOM API分别由XML-DEV和W3C定义。定义这些API的库有:
javax.xml.parsers
这是JAXP API,它为不同提供商提供的SAX和DOM解析器提供了通用接口。
org.w3c.dom
定义了Document类(一个DOM),还定义了对应于DOM的所有组件的所有类。
org.xml.sax
定义了基本SAX API。
javax.xml.transform
定义了XSLT API,通过这些API你可以将XML转换成其他格式。
这个“Simple API”for XML(SAX)是事件驱动的、持续访问的机制,它使用的是一个元件接一个元件的处理方式。这一级的API负责读取XML或者将XML写到数据仓库或Web中。对于服务器端和高性能的应用,需要完全了解这一级。但是对于很多的应用,只需要知道一点点就足够了。
一般来说,DOM API 是一种更易于使用的API。它提供了一种大家比较熟悉的对象的树型结构。我们可以使用这种DOM API来操纵封装的应用对象的层次。对于交互式的应用来说,DOM API相当理想,因为所有的对象模型都在内存中,用户可以访问和操纵这些对象模型。
另一方面,构造DOM时,要求读取整个XML结构并且将对象树放在内存中,因此CPU和内存资源的开销较大。因为这个原因,对于服务器端应用和数据过滤器来说,由于它们不要求在内存中有数据的表示,因此SAX API将是首选。
最后,通过在java.xml.transform中定义的XSLT API,你可以将XML数据写入到一个文件中,或者将其转换成其他格式。而且,将在本指南的XSLT一节中你将看到,你甚至可以将其与SAX API一起使用,来将遗留数据(legacy data)转换成XML。
The Simple API for XML(SAX)API
SAX解析API的概要如下图所示。要开始这一过程,首先需使用一个SAXParserFactory类的实例来产生解析器实例。
图5-1
SAX API
该解析器包装了一个SAXReader对象。当解析器的parse()方法被调用时,reader调用在该应用中实现的若干回调方法中的某个方法。这些方法由ContentHandler, ErrorHandler,
DTDHandler和EntityResolver接口定义。
下面是几个关键的SAX API的简介:
SAXParserFactory
根据系统特性(javax.xml.parsers.SAXParerFacatory),对象创建一个解析器实例。
SAXParser
SAXParser接口定义了若干种parser()方法。一般情况下,将XML数据源和DefaultHandler对象传递给解析器,解析器处理XML,并且调用handler对象的适当的方法。
SAXReader
SAXRarser包装了SAXReader。一般地,你无需留意这一点,但是偶尔你也会需要通过使用SAX Paerser’s getXMLReder( )来用到它,因此也要对它进行配置。你定义的SAX事件处理器是由SAXReader来运行的。
DefaultHandler
DefaultHandler没有显示在图中,它实现了ContentHandler、ErrotHandler、DEDHandler和EntityResolver接口(带有未实现的方法),因此你可以选择重载感兴趣的方法。
ContentHandler
当XML标签被识别出来时,startDocument、endDocument、startElement以及endElement等方法将被调用。这个接口还定义了characters和peocessingInstruction方法,当解析器在XML元素中碰到文本或者内部处理指令时,这两个方法将分别被调用。
ErrorHandler
在响应各种不同的解析错误时,将调用error、fatetalError以及warning等方法。对于重大的错误,默认的错误处理器将抛出一个异常,而其他错误(包括确认错误)则被忽略。这就是你需要了解一些关于SAX解析器的原因之一,即使你使用的是DOM。有时,可能需要产生一个异常。为了确保处理的正确性,需要为解析器提供自己的错误处理器。
DTDHandler
定义那些不常用的方法。通常在处理DTD时用于识别和作为一个未析实体的声明。
EntityResolver
当解析器必须识别由URI标识的数据时, 就需要调用resolverEntity方法。大多数情况下,URI仅仅就是一个URL,它指定了文档的位置。但是,有些情况下,文档可能是由URN-a public或名字来标识的,且该名字在Web空间内是唯一的。除了URL外,还可能会指定公共标识符。从而,EntityResolver就可以使用公共标识符,而不是URL,来找到这个文档,例如访问一个已有的本地文档的拷贝。
一个典型的应用,在最简单的情况下,将实现大多数的ContentHandler方法。由于接口的默认实现忽略了除重大错误之外的所有输入异常,一个健壮的实现还应该实现ErrorHandler方法。
SAX包
SAX解析器被定义在下列包中,如表 5-1所示:
|
表5-1 SAX包
|
|
包
|
描述
|
|
org.xml.sax
|
定义SAX接口。包前缀org.xml是由定义了SAX API的组设定的
|
|
org.xml.sax.ext
|
定义SAX扩展名,在进行高级的SAX处理时要用到,例如处理文档类型定义或者查看文件的详细语法
|
|
org.xml.sax.helpers
|
定义帮助类,使其能更方便地使用SAX。例如,为所有接口定义未实现的方法,这样你只需选择重载感兴趣的方法
|
|
javax.xml.parsers
|
定义SAXParserFactory类,该类将返回SAXParser,还定义了异常类,用于报告错误
|
文档对象模型(DOM)API
图 5-2 演示了JAXP API的行为:
图5-2
DOM API
使用java.xml.parsers.DocumentBuilderFactory类来获得DocumentBuilder实例, 再用该实例来产生一个遵从DOM规范的Document(一个DOM)。实际上,你所得到的builder(建立者),是由系统属性(java.xml.parsers.DocumentBuilderFactory)决定的,它选择用于产生builder的工厂的实现。(通过命令行,可以重设平台的默认值)。
还可以使用DjocumentBuilder newDocument( )方法来创建一个实现了org.w3c.dom.Document接口的空Document。你可以交替地使用builder的解析方法来从已有的XML数据创建Document。最后的结果是一个如图中显示的DOM树。
注意:尽管被称为对象,在DOM树中的条目实际是相当低级的数据结构。例如,在每个元素节点(对应于一个XML元素)下,都有一个文本节点,它含有该元素的标签。这些问题将在本指南的DOM一节详细讨论, 但是调用元素对象的text()方法后,并没有返回用户期望的对象,事实上,什么也没有返回。关于真正的面向对象树,参见JDOM API(http://www.jdom.org).。
DOM包
文档对象模型的实现被定义在表 5-2中列出的包中:
|
表5-2 DOM包
|
|
包
|
描述
|
|
org.w3c.dom
|
按照W3C的规定,为XML(或者,HTML)文档定义了DOM编程接口
|
|
javax.xml.parsers
|
定义DocumentBuilerFactort类和DocumentBuilder类,它将返回一个实现了W3C Document接口的对象。用于创建builder的工厂是由javax.xml.parsers系统属性决定的,该属性可以在调用new Instance方法时,通过命令行重新设置。 这个包还定义了ParserConfigurationException类,用于报告错误
|
用于转换的XML样式表语言(XSLT) API
图 5-3 展示了XSLT API的行为。
图
5-3 XSLT API
实例化一个TransformerFactory对象,然后使用该实例创建一个Transformer。将源对象作为转换过程的输入。源对象可以从SAX reader、DOM或者一个输入流创建。
同样地,结果对象就是转换过程的产出。这种对象可以是一个SAX事件处理器、DOM或者输出流。
可以通过一系列转换指令来创建转换器,这时可以进行特定的转换。如果创建时没有使用任何特定的指令,则转换器对象只是将源码拷贝到结果中。
XSLT包
XSLT
API 被定义在下列包中:
|
表5-3 XSLT包
|
|
包
|
描述
|
|
javax.xml.transform
|
定义了TransFormerFactory类和Transformer类,通过它们可以使用对象的方式来进行转换。在创建了转换器对象后,调用它的transform(
)方法,并为其提供输入(源)和输出(结果)
|
|
javax.xml.transform.dom
|
从一个DOM创建输入(源)和输出(结果)的类
|
|
javax.xml.transform.sax
|
从一个SAX解析器创建输入(源),从一个SAX事件处理器创建输出(结果)的类
|
|
javax.xml.transform.stream
|
从I/O流类创建输入(源)和输出(结果)的类
|
编译和运行程序
在Java WSDP中,JAXP库被放在<JWSDP_HOME>/common/lib目录中。为了编译和运行示例程序,首先需要将JAXP库安装在适当的位置。(取决于当前使用的JVM的版本。)参见JAXP版本注释:<JWSDP_HOME>/docs/jaxp/ReleaseNotes.html
下一步要做的
现在,你已经掌握了足够的信息,你可以用自己的方式来使用JAXP库。下一步取决于你想要完成的任务。或许你想转到:
XML线程
如果想了解更多关于XML的知识,那么尽可能在Java
API上少花时间。在本教程的标准课程中,你可以看见所有XML的相关章节。如果你想绕过 API 编程,那么按照以下步骤进行学习:
·
理解XML
·
编写简单的XML文件
·
替换和插入文本
·
创建文档类型定义(DTD)
·
定义DTD中的属性和实体
·
引用二进制实体
·
定义参数实体和条件段
设计XML数据结构
如果你正想为某个应用创建XML数据结构,并且想了解这一过程的步骤,请参看这一部分。
Simple API for XML
如果已经决定了数据结构,并且你正在编写要求尽可能快的一个服务器应用或者XML过滤器,参看这一部分。本节还手把手地教你建立XML文档。
文档对象模型
如果需要从XML数据构建XML数据对象树,以便在应用中操纵这些数据,或者将内存中的对象树转换成XML。这一部分指南以关于命名空间的一节结束。
用于转换的XML样式表语言(XSLT)
如果需要将XML标签转换成其他一些格式,如果想生成XML输出,或者相将遗留数据结构转换成XML,参看该部分。
|