在JDK 6.0中基于StAX分析XML数据 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
StAX是JDK6.0中包含的新特性。在推式模型中,直到整个XML文件全部被解析,解析器才会产生解析事件。而拉式解析由应用程序来控制,也就是说解析事件由应用程序产生。这就意味着,你可以暂缓解析、解析时跳过某个元素或者同时解析多个文件。用DOM解析式要先将XML文件解析成DOM结构,因此降低了解析效率。使用StAX,解析事件在XML文件解析过程中产生。
你要从一个XMLOutputFactory中得到你的XMLStreamWriter。因此,首先你必须创建一个新的XMLOutputFactory:
接下来,创建一个FileWriter以输出XML文档-它将被生成到一个XML文件中:
接下来,创建一个XMLStreamWriter:
现在,使用writeStartDocument()方法创建一个文档开头。添加要在XML声明中指定的编码和版本(记住,指定的编码并不是生成的XML文档的编码)。如果你需要指定XML文档的编码,该怎么办呢?当从一个XMLOutputFactory对象创建一个XMLStreamWriter对象时,你会这样做:
使用writeComment()方法以输出一个注释:
使用writeProcessingInstruction()方法以输出一条处理指令:
使用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进行分析 通过使用XMLStreamReader API分析列表1中的文档,我们来详细分析一下其工作原理。XMLStreamReader使用一种光标分析XML文档。它的接口包含一个next()方法-由它分析下一个分析事件。getEventType()方法返回事件类型。后面的代码片断来自于XMLParser.java应用程序,详见列表3。 在这个XMLParser.java应用程序中,首先,你要导入StAX类:
然后,创建一个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进行分析 本节将向你展示如何使用XMLEventReader来分析catalog.xml。XMLEventReader接口使用一个事件对象迭代算子分析一个XML文档;通过这种方式,一个XML事件生成一个XMLEvent对象。XMLEventReader类似于XMLStreamReader-分析事件是由StAX分析器生成的。然而,XMLEventReader比XMLStreamReader有一个优点:通过使用XMLEventReader,一个应用程序可以使用peek()方法来"偷看"下一个事件,而不必从流中读取事件。这样,一个应用程序客户端可以决定是否有必要分析下一个事件。本节中的代码片断节选自XMLEventParser.java应用程序,请参见列表5。 首先,导入StAX类:
接下来,创建一个XMLInputFactory,由它获得一个XMLEventReader对象:
在StAX中,XML文档事件是通过XMLEvent对象描述的。使用nextEvent()方法来遍历XMLEventReader对象以获得下一个事件:
使用getEventType()方法来获得事件类型(请参考表格1)。XMLEvent接口还提供布尔方法来获得事件类型。例如,isStartDocument()返回true,如果事件是开始文档类型。在下列代码中,事件是开始元素类型,因此一个StartElement对象可以从这个XMLEvent接口获得:
使用getAttributes()方法获得元素属性:
这个Iterator描述了一个javax.xml.stream.events.Attribute对象。使用next()方法遍历该Iterator。
最后,使用getName()方法获得属性命名,使用getValue()方法获得属性值。 列表5显示出分析该XML文档的Java应用程序。应用程序XMLEventReader可以作为一个命令行应用程序运行,或在一种例如Eclipse这样的IDE中运行。记住:如果你运行XMLWriter.java或XMLParser.java应用程序而不首先运行XMLEventParser.java应用程序,那么你将需要把catalog.xml复制到C:/StAX目录下。 最终,基于拉的事件生成把事件规则提供到分析器应用程序而不是提供到分析器。 |
StAX
最新推荐文章于 2021-03-21 03:32:17 发布