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 implementation
      System.setProperty(
         "javax.xml.stream.XMLInputFactory",
         "com.bea.xml.stream.MXParserFactory");
      // Create the XML input factory
      XMLInputFactory factory = XMLInputFactory.newInstance();
      // Create event reader
      FileReader reader = new FileReader("somefile.xml");
      XMLEventReader eventReader = factory.createXMLEventReader(reader);
      // Create a filtered reader
      XMLEventReader filteredEventReader =
         factory.createFilteredReader(eventReader, new EventFilter() {
         public boolean accept(XMLEvent event) {
            // Exclude PIs
            return (!event.isProcessingInstruction());
         }
      });
      // Main event loop
      while (filteredEventReader.hasNext()) {
         XMLEvent e = filteredEventReader.next();
         System.out.println(e);
      }
   }
}

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

隐藏文档分支

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

清单2.创建一个过滤的流阅读器
// Create stream reader
      XMLStreamReader xmlr =
         xmlif.createXMLStreamReader(new FileReader("somefile.xml"));

      // Create a filtered stream reader
      XMLStreamReader xmlfr = xmlif.createFilteredReader(xmlr, filter);

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

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

清单3.流过滤器
// Exclusion path
   private static QName[] exclude = new QName[] { 
      new QName("invoice"), new QName("item")};

   private static StreamFilter filter = new StreamFilter() {
      // Element level
      int depth = -1;
      // Last matching path segment
      int match = -1;
      // Filter result
      boolean process = true;
      // Character position in document
      int currentPos = -1;
      
      public boolean accept(XMLStreamReader reader) {
         // Get character position
         Location loc = reader.getLocation();
         int pos = loc.getCharacterOffset();
         // Inhibit double execution
         if (pos != currentPos) {
            currentPos = pos;
            switch (reader.getEventType()) {
               case XMLStreamConstants.START_ELEMENT :
                  // Increment element depth
                  if (++depth < exclude.length && match == depth - 1) {
                     // Compare path segment with current element
                     if (reader.getName().equals(exclude[depth]))
                        // Equal - set segment pointer
                        match = depth;
                  }
                  // Process all elements not in path
                  process = match < exclude.length - 1;
                  break;
               // End of XML element
               case XMLStreamConstants.END_ELEMENT :
                  // Process all elements not in path
                  process = match < exclude.length - 1;
                  // Decrement element depth
                  if (--depth < match)
                     // Update segment pointer
                     match = depth;
                  break;
            }
         }
         return process;
      }
   };

下一步

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


翻译自: https://www.ibm.com/developerworks/xml/library/x-tipstx2/index.html

stax解析xml

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值