当前位置: 首页 > 工具软件 > StAX > 使用案例 >

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

曾枫
2023-12-01

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

 类似资料: