使用StAX解析XML
http://blog.sina.com.cn/s/blog_5b8c66750100a7yc.html StAX 概述 从一开始,Java API for XML Processing (JAXP) 就提供了两种方法来处理XML:文档对象模型(DOM)方法是用标准的对象模型表示 XML 文档;Simple API for XML (SAX)方法使用应用程序提供的事件处理程序来处理 XML。JSR-173 提出了一种面向流的新方法:Streaming API for XML(StAX)。其最终版本于 2004 年 3 月发布,并成为了 JAXP 1.4(将包含在即将发布的 Java 6中)的一部分。 如其名称所暗示的那样,StAX 把重点放在流上。实际上,StAX 与其他方法的区别就在于应用程序能够把 XML作为一个事件流来处理。将 XML 作为一组事件来处理的想法并不新颖(事实上 SAX 已经提出来了),但不同之处在于 StAX允许应用程序代码把这些事件逐个拉出来,而不用提供在解析器方便时从解析器中接收事件的处理程序。 StAX 实际上包括两套处理 XML 的 API,分别提供了不同程度的抽象。基于指针的 API 允许应用程序把 XML作为一个标记(或事件)流来处理;应用程序可以检查解析器的状态,获得解析的上一个标记的信息,然后再处理下一个标记,依此类推。这是一种低层API,尽管效率高,但是没有提供底层 XML 结构的抽象。较为高级的基于迭代器的 API 允许应用程序把 XML作为一系列事件对象来处理,每个对象和应用程序交换 XML结构的一部分。应用程序只需要确定解析事件的类型,将其转换成对应的具体类型,然后利用其方法获得属于该事件的信息。 J2EE/XML开发者通常都是使用文档对象模型(DOM)API或简单的API for XML(SAX)API来分析XML文档。然而,这些API都有其缺点。其中,DOMAPI的缺点之一是消耗大量的内存,因为在该XML文档可以被导航之前,必须创建一个完整的XML文档的内存结构。而SAXAPI的缺点在于,它实例了一种推分析模型API,其中分析事件是由分析器生成的。比较之下,StAX则是基于一种拉分析模型。在本文中,你将首先创建你自己的XML文档,然后学习使用各种不同方法来对之进行分析;最后,我们使用事件生成的StAX拉方法。
你要从一个XMLOutputFactory中得到你的XMLStreamWriter。因此,首先你必须创建一个新的XMLOutputFactory:
接下来,创建一个FileWriter以输出XML文档-它将被生成到一个XML文件中:
接下来,创建一个XMLStreamWriter:
现在,使用writeStartDocument()方法创建一个文档开头。添加要在XML声明中指定的编码和版本(记住,指定的编码并不是生成的XML文档的编码)。如果你需要指定XML文档的编码,该怎么办呢?当从一个XMLOutputFactory对象创建一个XMLStreamWriter对象时,你会这样做:
使用writeComment()方法以输出一个注释:
使用writeProcessingInstructi
使用writeStartElement()方法以输出'catalog'元素的开始(元素前缀和命名空间URI也可以在这个方法中指定的):
使用writeNamespace()方法以添加'journal'命名空间声明(命名空间前缀和命名空间URI也是在这个方法中指定的):
再次使用writeNamespace()方法添加xsi命名空间:
使用writeAttribute()方法添加xsi:namespaceSchemaLocation属性:
使用writeAttribute()方法添加'publisher'属性:
输出'journal'元素的开始。当增加一个新元素时,前一个元素的'>'括号也被添加上:
使用writeAttribute()方法以添加'date'和'title'属性。然后,使用writeElement()方法以添加'article'和'title'元素。然后,使用writeCharacters()方法输出'title'元素的文本:
任何包含文本或子元素的元素都要有一个结束标签。使用writeEndElement()元素来添加'title'元素的结束标签:
添加'author'元素和'journal'元素的结束标签。在writeEndElement()方法中,不必要指定元素前缀和命名空间URI。以类似方式添加另一个'journal'元素。然后,添加'catalog'元素的结束标签。最后,输出缓冲的数据:
最后一步,关闭XMLStreamWriter。
这就是生成catalog.xml的过程。 源码中的列表2展示了完整的Java应用程序-XMLWriter.java。这个应用程序可以作为一个命令行应用程序运行或在一种例如Eclipse这样的IDE中运行。 五、 使用XMLStreamReader进行分析
然后,创建一个XMLInputFactory,由此你会得到一个XMLStreamReader:
现在,你需要创建一个InputStream,作为一个输入流,它描述了将被分析的文件。另外,还要从前面创建的XMLInputFactory对象中创建一个XMLStreamReader。
如果更多分析事件可用,hasNext()方法返回true。然后,使用next()方法获得下一个分析事件:
比较于SAX分析,StAX分析的优点是,一个分析事件可以被跳过-通过调用next()方法,详见下面的代码。例如,如果分析事件类型为ENTITY_DECLARATION,那么开发者可以决定是要从当前事件中获得事件信息,还是检索下一个事件:
通过不调用next()方法,分析也可以被推迟。next()方法返回int,它代表了一个分析事件-通过使用一个XMLStreamConstants常量指定。 XMLStreamReader所返回的不同的事件类型列举于表格1中。
这些不同的分析事件能够使你获得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进行分析
接下来,创建一个XMLInputFactory,由它获得一个XMLEventReader对象:
在StAX中,XML文档事件是通过XMLEvent对象描述的。使用nextEvent()方法来遍历XMLEventReader对象以获得下一个事件:
使用getEventType()方法来获得事件类型(请参考表格1)。XMLEvent接口还提供布尔方法来获得事件类型。例如,isStartDocument()返回true,如果事件是开始文档类型。在下列代码中,事件是开始元素类型,因此一个StartElement对象可以从这个XMLEvent接口获得:
使用getAttributes()方法获得元素属性:
这个Iterator描述了一个javax.xml.stream.events.Attribute对象。使用next()方法遍历该Iterator。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |