100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > stax解析xml_使用StAX部分解析XML文档

stax解析xml_使用StAX部分解析XML文档

时间:2020-01-04 17:07:51

相关推荐

stax解析xml_使用StAX部分解析XML文档

stax解析xml

解析XML文档时,XMLEventReader实例通过其next()方法将事件对象传递给客户端应用程序-文档中每个语法单元一个。 但是,应用程序并不总是对接收所有事件类感兴趣。 仅查看XML元素及其属性的应用程序不关心表示注释或处理指令的事件。 幸运的是,StAX允许您通过实现事件过滤器来跳过某些事件类。

清单1显示了一个跳过所有XML处理指令的事件过滤器。 这些事件不会传递给事件读取器的hasNext()next()peek()方法。 要将过滤器添加到给定的事件阅读器,必须构造一个新的阅读器。 这是通过工厂方法createFilteredReader()。 此方法接受原始阅读器和EventFilter作为参数。 然后,我将使用这个新的过滤后的事件阅读器来解析文档。

清单1.过滤XML事件

import java.io.*;import javax.xml.stream.*;import javax.xml.stream.events.XMLEvent;public class ParseFilteredByEvent {public static void main(String[] args)throws FileNotFoundException, XMLStreamException {// Use reference implementationSystem.setProperty("javax.xml.stream.XMLInputFactory","com.bea.xml.stream.MXParserFactory");// Create the XML input factoryXMLInputFactory factory = XMLInputFactory.newInstance();// Create event readerFileReader reader = new FileReader("somefile.xml");XMLEventReader eventReader = factory.createXMLEventReader(reader);// Create a filtered readerXMLEventReader filteredEventReader =factory.createFilteredReader(eventReader, new EventFilter() {public boolean accept(XMLEvent event) {// Exclude PIsreturn (!event.isProcessingInstruction());}});// Main event loopwhile (filteredEventReader.hasNext()) {XMLEvent e = filteredEventReader.next();System.out.println(e);}}}

您可以用相同的方式从主应用程序逻辑中隐藏其他事件类。 您甚至可以通过相互叠加构造经过过滤的事件读取器,以分层的方式组合多个EventFilter

隐藏文档分支

在下一个示例中,我将显示一个跳过XML文档整个分支的过滤器。 这次,我将使用基于游标的API和经过筛选的流阅读器,而不是事件阅读器,因为我发现最好将复杂的筛选器实现为流筛选器。 与上面的示例类似,在基本流读​​取器的顶部构造了一个新的过滤流读取器:

清单2.创建一个过滤的流阅读器

// Create stream readerXMLStreamReader xmlr =xmlif.createXMLStreamReader(new FileReader("somefile.xml"));// Create a filtered stream readerXMLStreamReader xmlfr = xmlif.createFilteredReader(xmlr, filter);

清单3中显示了第二个参数中使用的StreamFilter。 它作用于XML元素的开始和结束,并将各个元素的名称与路径段进行比较。 该路径指定应跳过文档的哪些部分,并以QName数组的形式实现。 在此示例中,路径发票/项目中的所有元素都将被跳过。

在实现这样的过滤器时,您需要意识到以下事实:每当hasNext()next()peek()方法时,都会调用过滤器的accept()方法。 因此,对于同一事件,可以多次调用accept()方法。 在这里,我确保过滤器逻辑对于每个事件仅执行一次; 仅当文档中的字符位置已更改时才执行此操作。

清单3.流过滤器

// Exclusion pathprivate static QName[] exclude = new QName[] { new QName("invoice"), new QName("item")};private static StreamFilter filter = new StreamFilter() {// Element levelint depth = -1;// Last matching path segmentint match = -1;// Filter resultboolean process = true;// Character position in documentint currentPos = -1;public boolean accept(XMLStreamReader reader) {// Get character positionLocation loc = reader.getLocation();int pos = loc.getCharacterOffset();// Inhibit double executionif (pos != currentPos) {currentPos = pos;switch (reader.getEventType()) {case XMLStreamConstants.START_ELEMENT :// Increment element depthif (++depth < exclude.length && match == depth - 1) {// Compare path segment with current elementif (reader.getName().equals(exclude[depth]))// Equal - set segment pointermatch = depth;}// Process all elements not in pathprocess = match < exclude.length - 1;break;// End of XML elementcase XMLStreamConstants.END_ELEMENT :// Process all elements not in pathprocess = match < exclude.length - 1;// Decrement element depthif (--depth < match)// Update segment pointermatch = depth;break;}}return process;}};

下一步

本技巧说明了StAX解析器中过滤器的使用。 在下一个技巧中,我将展示如何使用这些技术和其他技术来有效地筛选XML文档。

翻译自: /developerworks/xml/library/x-tipstx2/index.html

stax解析xml

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。