Java StAX
就像SAX API一样,用于XML处理的StAX Java API旨在解析XML流。 StAX和SAX API之间的主要区别是:
- StAX是"拉" API。 SAX是"推送" API。
- StAX可以进行XML读取和写入。 SAX只能读取XML。
很明显,具有"读+写"函数的API与具有"读"函数的API之间的区别是什么。但是"拉"式和"推"式API之间的区别不太明显,因此我将对此稍作讨论。有关SAX和StAX的逐项特征比较,请参见文本SAX vs. StAX。
注意:本文使用SVG(可缩放矢量图形)图。如果我们使用的是Internet Explorer,则需要Adobe SVG插件显示这些图。 Firefox 3.0.5+用户和Google Chrome用户应该没有问题。
"拉"与"推"样式API
SAX是推式API。这意味着SAX解析器遍历XML,并在我们提供的处理程序对象上调用方法。例如,当SAX解析器遇到XML元素的开头时,它将在处理程序对象上调用startElement
。它将信息从XML"推送"到对象中。因此,名称为" push"样式的API。这也称为"事件驱动" API。当在XML文档中发现有趣的内容时,将通过事件调用通知处理程序对象("有趣的" =元素,文本,注释等)。
SAX解析器推送样式解析如下所示:
SAX解析器应用
App StAX是拉式API。这意味着我们必须自己将StAX解析器从XML文件中的一个项目移动到另一个项目,就像使用标准的"迭代器"或者JDBC"结果集"一样。然后,我们可以通过StAX解析器访问XML文件中遇到的每个此类"项目"(" item" =元素,文本,注释等)的XML信息。
StAX解析器实际上,StAX具有两个不同的读取器API。一个看起来最像使用Iterator
,一个看起来最像使用ResultSet
。这些被称为"迭代器"和"游标"阅读器。
那么,这两个读者有什么区别?
迭代器返回读者从它的nextEvent()
调用的XML事件对象。从该事件对象中,我们可以看到遇到的事件类型(元素,文本,注释等)。此事件元素是不可变的,可以将其解析为应用程序的其他部分。我们还可以在迭代到下一个事件时挂起较早的事件对象。如我们所见,这非常类似于迭代集合时使用普通的Iterator的方式。在这里,我们只是遍历XML事件。这是一个草图:
XMLEventReader reader = ...; while(reader.hasNext()){ XMLEvent event = reader.nextEvent(); if(event.getEventType() == XMLEvent.START_ELEMENT){ StartElement startElement = event.asStartElement(); System.out.println(startElement.getName().getLocalPart()); } //... more event types handled here... }
游标阅读器不会从其next()
调用返回事件。而是这个调用将光标移动到XML的下一个"事件"。然后,我们可以直接在游标上调用方法以获得有关当前事件的更多信息。这非常类似于迭代JDBCResultSet
的记录,并调用getString()
或者getLong()
之类的方法从ResultSet
指向的当前记录中获取值的方式。这是一个草图:
XMLStreamReader streamReader = ...; while(streamReader.hasNext()){ int eventType = streamReader.next(); if(eventType == XMLStreamReader.START_ELEMENT){ System.out.println(streamReader.getLocalName()); } //... more event types handled here... }
因此,主要区别之一是,使用迭代器样式API时,我们可以保留早期的XML事件对象。使用游标样式API时,我们不能执行此操作。一旦将光标移动到XML流中的下一个事件,就没有关于上一个事件的信息。这表示赞成使用迭代器样式的API。
但是,游标样式的API被认为比迭代器样式的API在内存效率上更高。因此,如果应用程序需要绝对的顶级性能,请使用游标样式的API。
二者皆的StAX的API将在后面的文章更详细地覆盖。请参阅此页面右侧的目录。
Java StAX实现
在撰写本文时(Java 6),只有StAX接口与JDK捆绑在一起。 Java中没有内置StAX实现。但是,有一个标准的实现可以在这里找到:
http://stax.codehaus.org/