转自:http://hi.baidu.com/1shome/blog/item/5baaee01db2609051d958302.html
J2EE/XML开发者通常都是使用文档对象模型(DOM)API或简单的API for XML(SAX) API来分析XML文档。然而,这些API都有其缺点。其中,DOM API的缺点之一是消耗大量的内存,因为在该XML文档可以被导航之前,必须创建一个完整的XML文档的内存结构。而SAX API的缺点在于,它实例了一种推分析模型API,其中分析事件是由分析器生成的。比较之下,StAX则是基于一种拉分析模型。在本文中,你将首先创建你自己的XML文档,然后学习使用各种不同方法来对之进行分析;最后,我们使用事件生成的StAX拉方法。
一、 推分析之于拉分析
比较于推分析,拉分析具有如下一些优点:
1. 在拉分析中,事件是由分析应用程序生成的,因此把分析规则提供到客户端而不是分析器。
2. 拉分析的代码更简单并且它比推分析有更少的库。
3. 拉分析客户端能同时读多个XML文档。
4. 拉分析允许你过滤XML文档并且跳过分析事件。
二、 了解StAX
针对于XML的流式API(StAX),是在2004年3月的JSR 173规范中引入,这是一种针对XML的流式拉分析API。StAX是JDK 6.0提供的一种新特征,你可以从此处下载它的测试版本试用。
一个推模型分析器不断地生成事件,直到XML文档被完全分析结束。但是,拉分析由应用程序进行调整;因此,分析事件是由应用程序生成的。这意味着,使用StaX,你可以推迟分析-在分析时跳过元素并且分析多个文档。在使用DOM API的时候,你必须把整个的XML文档分析成一棵DOM结构,这样也就降低了分析效率。而借助于StAX,在分析XML文档时生成分析事件。有关于StAX分析器与其它分析器的比较在此不多介绍。
StAX API的实现是使用了Java Web服务开发(JWSDP)1.6,并结合了Sun Java流式XML分析器(SJSXP)-它位于javax.xml.stream包中。XMLStreamReader接口用于分析一个XML文档,而XMLStreamWriter接口用于生成一个XML文档。XMLEventReader负责使用一个对象事件迭代子分析XML事件-这与XMLStreamReader所使用的光标机制形成对照。本教程将基于JDK 6.0中的StAX实现来完成对一个XML文档的分析。
其实,StaX仅仅是JDK 6.0所提供的XML新特征之一。新的JDK 6.0还提供了对针对于XML-Web服务的Java架构(JAX-WS)2.0,针对于XML绑定的Java API(JAXB) 2.0,XML数字签名API的支持,甚至还支持SQL:2003 'XML'数据类型。
三、 初步安装
如果你正在使用JDK 6.0,那么默认情况下,StAX API位于Classpath中。如果你在使用JWSDP 1.6,请把JWSDP 1.6 StAX API添加到classpath中。这需要把<jwsdp-1.6>\sjsxp\lib\ jsr173_api.jar和<jwsdp-1.6>\sjsxp\lib\sjsxp.jar添加到CLASSPATH变量中。在<jwsdp-1.6>目录下安装JWSDP 1.6。Jsr173_api.jar相应于JSR-173 API JAR,Sjsxp.jar相应于SJXSP实现JAR。
四、 使用XMLStreamWriter进行写操作
首先,你要创建将待分析的XML文档。由StAX的XMLStreamWriter生成XML。然而,XMLStreamWriter的一个限制是,它不一定会生成良构的文档-而且生成的文档也不一定是有效的。你需要确保生成的XML文档是良构的。列表1是一个由XMLStreamWriter生成的原始XML文档的示例。
在此,你试图使用XMLStreamWriter API生成列表1中的catalog.xml。在本节中的代码片断节选自XMLWriter.java应用程序,显示于列表2中。首先,你将导入StAX包类,请参考下列编码:
import javax.xml.stream.*;
import javax.xml.stream.events.*;
import javax.xml.stream.XMLOutputFactory;
你要从一个XMLOutputFactory中得到你的XMLStreamWriter。因此,首先你必须创建一个新的XMLOutputFactory:
XMLOutputFactory outputFactory=XMLOutputFactory.newInstance();
接下来,创建一个FileWriter以输出XML文档-它将被生成到一个XML文件中:
FileWriter output=new FileWriter(new File("C:/STAX/catalog.xml"));
接下来,创建一个XMLStreamWriter:
XMLStreamWriter XMLStreamWriterr=outputFactory.createXMLStreamWriter(output);
现在,使用writeStartDocument()方法创建一个文档开头。添加要在XML声明中指定的编码和版本(记住,指定的编码并不是生成的XML文档的编码)。如果你需要指定XML文档的编码,该怎么办呢?当从一个XMLOutputFactory对象创建一个XMLStreamWriter对象时,你会这样做:
XMLStreamWriter.writeStartDocument("UTF-8","1.0");
使用writeComment()方法以输出一个注释:
XMLStreamWriter.writeComment("A OReilly Journal Catalog");
使用writeProcessingInstruction()方法以输出一条处理指令:
XMLStreamWriter.writeProcessingInstruction("catalog","journal='OReilly'");
使用writeStartElement()方法以输出'catalog'元素的开始(元素前缀和命名空间URI也可以在这个方法中指定的):
XMLStreamWriter.writeStartElement("journal","catalog","http://OnJava.com/Journal");
使用writeNamespace()方法以添加'journal'命名空间声明(命名空间前缀和命名空间URI也是在这个方法中指定的):
XMLStreamWriter.writeNamespace("journal","http://OnJava.com/Journal");
再次使用writeNamespace()方法添加xsi命名空间:
XMLStreamWriter.writeNamespace("xsi","http://www.w3.org/2001/XMLSchema-instance");
使用writeAttribute()方法添加xsi:namespaceSchemaLocation属性:
XMLStreamWriter.writeAttribute("xsi:noNamespaceSchemaLocation","file://c:/Schemas/catalog.xsd");
使用writeAttribute()方法添加'publisher'属性:
XMLStreamWriter.writeAttribute("publisher","OReilly");
输出'journal'元素的开始。当增加一个新元素时,前一个元素的'>'括号也被添加上:
XMLStreamWriter.writeStartElement("journal","journal","http:
//OnJava.com/Journal");
使用writeAttribute()方法以添加'date'和'title'属性。然后,使用writeElement()方法以添加'article'和'title'元素。然后,使用writeCharacters()方法输出'title'元素的文本:
XMLStreamWriter.writeCharacters("Data Binding with XMLBeans");
任何包含文本或子元素的元素都要有一个结束标签。使用writeEndElement()元素来添加'title'元素的结束标签:
XMLStreamWriter.writeEndElement();
添加'author'元素和'journal'元素的结束标签。在writeEndElement()方法中,不必要指定元素前缀和命名空间URI。以类似方式添加另一个'journal'元素。然后,添加'catalog'元素的结束标签。最后,输出缓冲的数据:
XMLStreamWriter.flush();
最后一步,关闭XMLStreamWriter。
XMLStreamWriter.close();
这就是生成catalog.xml的过程。
源码中的列表2展示了完整的Java应用程序-XMLWriter.java。这个应用程序可以作为一个命令行应用程序运行或在一种例如Eclipse这样的IDE中运行。
五、 使用XMLStreamReader进行分析
通过使用XMLStreamReader API分析列表1中的文档,我们来详细分析一下其工作原理。XMLStreamReader使用一种光标分析XML文档。它的接口包含一个next()方法-由它分析下一个分析事件。getEventType()方法返回事件类型。后面的代码片断来自于XMLParser.java应用程序,详见列表3。
在这个XMLParser.java应用程序中,首先,你要导入StAX类:
import javax.xml.stream.*;
import javax.xml.stream.events.*;
import javax.xml.stream.XMLInputFactory;
然后,创建一个XMLInputFactory,由此你会得到一个XMLStreamReader:
XMLInputFactory inputFactory=XMLInputFactory.newInstance();
现在,你需要创建一个InputStream,作为一个输入流,它描述了将被分析的文件。另外,还要从前面创建的XMLInputFactory对象中创建一个XMLStreamReader。
InputStream input=new FileInputStream(new File("C:/STAX/catalog.xml"));
XMLStreamReader xmlStreamReader =inputFactory.createXMLStreamReader(input);
如果更多分析事件可用,hasNext()方法返回true。然后,使用next()方法获得下一个分析事件:
int event=xmlStreamReader.next();
比较于SAX分析,StAX分析的优点是,一个分析事件可以被跳过-通过调用next()方法,详见下面的代码。例如,如果分析事件类型为ENTITY_DECLARATION,那么开发者可以决定是要从当前事件中获得事件信息,还是检索下一个事件:
If(event.getEventType()==XMLStreamConstants.ENTITY_DECLARATION){
int event=xmlStreamReader.next();
}
通过不调用next()方法,分析也可以被推迟。next()方法返回int,它代表了一个分析事件-通过使用一个XMLStreamConstants常量指定。
XMLStreamReader所返回的不同的事件类型列举于表格1中。
事件类型 描述
START_DOCUMENT 一个文档的开始
START_ELEMENT 一个元素的开始
ATTRIBUTE 一个元素属性
NAMESPACE 一个命名空间声明
CHARACTERS 字符可以是文本,或是一个空格
COMMENT 一个注释
SPACE 可忽略的空格
PROCESSING_INSTRUCTION 处理指令
DTD 一个DTD
ENTITY_REFERENCE 一个实体参考
CDATA Cdata节
END_ELEMENT 结束元素
END_DOCUMENT 结束文档
ENTITY_DECLARATION 一个实体声明
NOTATION_DECLARATION 一个标志声明
表格1.XMLStreamReader事件
这些不同的分析事件能够使你获得XML文档中的数据和元数据。如果分析事件类型是START_DOCUMENT,那么你将使用getEncoding()方法获得XML文档中的指定编码,而你将使用getVersion()方法返回XML文档的XML版本。
同样,如果你在使用一个START_ELEMENT事件类型工作,那么你将使用getPrefix()方法来返回元素前缀并且使用getNamespaceURI来返回元素前缀命名空间或默认命名空间。为了获得元素的本地命名,你将使用getLocalName()方法并且使用getAttributesCount()方法获得属性数目。你将使用getAttributePrefix(i)方法得到一个指定的属性索引i的属性前缀,而使用getAttributeNamespace(i)方法取得属性命名空间。使用getAttributeLocalName(i)方法获得属性本地命名,使用getAttributeValue(i)方法获得属性值。如果事件类型是CHARACTERS或COMMENT,则使用getText()方法获得相应的文本。
列表4显示了示例XML文档,catalog.xml,的分析输出结果。
列表3显示了用于分析XML文档的Java应用程序。你可以从命令行上或在一种例如Eclipse这样的IDE中来运行该应用程序。记住:如果你没有首先运行XMLWriter.java应用程序而运行XMLParser.java(见源码中的列表2),那么你需要把catalog.xml(见源码中的列表1)复制到C:/StAX目录下。
六、 使用XMLEventReader进行分析
本节将向你展示如何使用XMLEventReader来分析catalog.xml。XMLEventReader接口使用一个事件对象迭代算子分析一个XML文档;通过这种方式,一个XML事件生成一个XMLEvent对象。XMLEventReader类似于XMLStreamReader-分析事件是由StAX分析器生成的。然而,XMLEventReader比XMLStreamReader有一个优点:通过使用XMLEventReader,一个应用程序可以使用peek()方法来"偷看"下一个事件,而不必从流中读取事件。这样,一个应用程序客户端可以决定是否有必要分析下一个事件。本节中的代码片断节选自XMLEventParser.java应用程序,请参见列表5。
首先,导入StAX类:
import javax.xml.stream.*;
import javax.xml.stream.events.*;
import javax.xml.stream.XMLInputFactory;
接下来,创建一个XMLInputFactory,由它获得一个XMLEventReader对象:
XMLInputFactory inputFactory=XMLInputFactory.newInstance();
InputStream input=new FileInputStream(new File("C:/STAX/catalog.xml"));
XMLEventReader xmlEventReader =inputFactory.createXMLEventReader(input);
在StAX中,XML文档事件是通过XMLEvent对象描述的。使用nextEvent()方法来遍历XMLEventReader对象以获得下一个事件:
XMLEvent event=xmlEventReader.nextEvent();
使用getEventType()方法来获得事件类型(请参考表格1)。XMLEvent接口还提供布尔方法来获得事件类型。例如,isStartDocument()返回true,如果事件是开始文档类型。在下列代码中,事件是开始元素类型,因此一个StartElement对象可以从这个XMLEvent接口获得:
if(event.isStartElement()){
StartElement startElement=event.asStartElement();
}
使用getAttributes()方法获得元素属性:
Iterator attributes=startElement.getAttributes();
这个Iterator描述了一个javax.xml.stream.events.Attribute对象。使用next()方法遍历该Iterator。
Attribute attribute=(javax.xml.stream.events.Attribute)(attributes.next());
最后,使用getName()方法获得属性命名,使用getValue()方法获得属性值。
列表5显示出分析该XML文档的Java应用程序。应用程序XMLEventReader可以作为一个命令行应用程序运行,或在一种例如Eclipse这样的IDE中运行。记住:如果你运行XMLWriter.java或XMLParser.java应用程序而不首先运行XMLEventParser.java应用程序,那么你将需要把catalog.xml复制到C:/StAX目录下。
最终,基于拉的事件生成把事件规则提供到分析器应用程序而不是提供到分析器。
分享到:
相关推荐
11. **增强的JConsole**:JDK 6中的JConsole提供了更强大的监控和管理功能,可以实时查看和分析Java应用程序的运行状态。 12. **安全增强**:增加了对数字证书和SSL/TLS协议的支持,增强了网络安全。 在解压“JDK ...
6. **XML处理改进**:JAXB 2.0引入了更强大的XML绑定功能,StAX(Streaming API for XML)提供了一种新的流式处理XML的方式。 7. **Scripting API**:JDK 6.0引入了JSR 223脚本引擎接口,允许在Java中嵌入和执行...
9. **XML处理**:`javax.xml`包提供了处理XML的API,如解析器、DOM、SAX和StAX,用于读取、写入和操作XML文档。 10. **数据库连接**:JDBC(Java Database Connectivity)API在`java.sql`包中,提供了与各种数据库...
DOM将XML文档解析成树形结构,SAX基于事件驱动,而StAX允许以流式方式读写XML,适合处理大型XML文件。 八、JavaScript支持 通过javax.script包,Java 6引入了对脚本语言的支持,包括JavaScript,使得在Java应用中...
JDK 6.0引入了全新的StAX(Streaming API for XML)API,允许开发者以事件驱动的方式解析和生成XML文档,减少了内存占用,提高了处理大型XML文档的效率。 六、数据库连接池 JDBC连接池的API(java.sql.DataSource)...
9. **XML处理**:JDK6.0对XML处理进行了优化,如SAX和StAX解析器的性能提升,以及JAXB(Java Architecture for XML Binding)的改进,使得XML数据绑定更加便捷。 10. **Java应用程序启动器**:JDK6.0改进了`javaw....
7. **XML处理改进**:包括StAX API的增强,以及JAXB 2.0的支持,提升了XML数据的处理效率和灵活性。 8. **改进的JDBC**:引入了JDBC 4.0,提供了自动连接管理、改进的RowSet支持和增强的异常处理。 9. **动态注解*...
7. **XML处理增强**:StAX(Streaming API for XML)的集成,提供了高效的XML处理方式。 8. **改进的JDBC API**:增加了对数据库连接池的更好支持和新的SQL功能。 了解这些特性有助于开发者更好地利用JDK 6.0进行...
JDK 6.0对XML处理进行了优化,例如增加了StAX(Streaming API for XML)支持,允许开发者以事件驱动的方式处理XML文档,从而减少内存占用和提高处理速度。同时,DOM解析器性能也有所提升。 5. **WebSocket服务** ...
2. **类库**:JDK 6.0引入了许多新的API,如Swing的改进、NIO.2(New IO)框架、动态代理、XML处理API(如StAX)等。这些API扩展了Java的功能,使得开发者能更高效地进行开发。 3. **语言特性**:JDK 6.0支持了枚举...
JDK 6.0的安装文件名为“JDK6.0-windows-i586.exe”,这表明它是适用于Windows操作系统32位版本的安装程序。用户需双击该文件,按照安装向导的指示完成安装过程。安装后,系统环境变量如`JAVA_HOME`、`PATH`等需要...
5. **改进的XML处理**:JAXB(Java Architecture for XML Binding)和StAX(Streaming API for XML)得到了增强,使得XML的解析和生成更加便捷。 **二、API参考** JDK 6.0帮助文档中的API参考部分详尽地列出了所有...
4. **XML处理**:JDK 6.0支持DOM、SAX和StAX等多种XML解析方式,同时增加了XPath和XSLT的支持,方便开发者进行XML数据的处理和转换。 5. **Java EE相关API**:虽然JDK 6.0主要是针对桌面应用,但它也包含了一些Java...
在Java 6.0中,StAX被包含在`javax.xml.stream`包下,可以方便地通过JDK自带的API来使用。例如,以下是一个简单的StAX读取XML文档的示例: ```java import javax.xml.stream.XMLInputFactory; import javax.xml....
JDK6的新特性之二_使用JAXB2来实现对象与XML之间的映射 JDK6的新特性之三_理解StAX JDK6的新特性之四_使用Compiler API JDK6的新特性之五_轻量级HttpServer JDK6的新特性之七_用Console开发控制台程序 JDK6的...
6. **改进的XML处理**:包括SAX 2.0.2、DOM Level 3和StAX API,使得XML处理更加高效和易于使用。 7. **增强的安全性**:加强了加密算法,提升了默认安全策略,并改进了证书管理。 8. **动态代理类**:JSR 292允许...
Java 6.0强化了对XML的支持,包括DOM、SAX和StAX解析器,以及JAXB用于对象与XML之间的绑定。`javax.xml.transform`包提供了转换XML文档的能力。 总结来说,"JAVA6.0帮助文档"涵盖了Java 6.0的各个方面,从基本语法...
描述中的“jdk jdk6.0 32bit, jdk1.6_45_32bit”进一步明确了这是JDK 1.6更新45(Update 45)的32位版本。 JDK 1.6,也被称为Java SE 6(标准版),是在2006年12月11日正式发布的,包含了许多增强功能和改进,例如...
- **应用场景**:在网络应用中,常用于将业务对象转换为XML格式的数据,或者从XML格式的数据中反序列化出Java对象。 #### 四、StAX (Streaming API for XML) StAX是一种流式的XML解析API,相比于DOM和SAX,StAX提供...