是否有可能使用Groovy解析子树XMLSlurper

问题描述:

有谁知道是否有可能以某种方式利用XMLSlurper,这意味着可以从一个非常大的XML文档中提取各个子树并单独进行处理?是否有可能使用Groovy解析子树XMLSlurper

想象一下,您已经获得了一个巨大的XML feed,其中包含一个具有数千个可以单独处理的直接子元素的根元素。很明显,将整个文档读入内存是一个不容否认的问题,但由于每个子节点的大小本身不大,因此在整个文档中进行流式处理会很好,但可以依次对每个子元素应用XMLSlurper。在处理每个子元素时,垃圾回收可以清理用于处理它的内存。通过这种方式,我们可以非常轻松地使用XMLSlurper(如此简洁的语法)和低流量的内存占用(例如SAX)。

我很想知道,如果有人对此有任何想法和/或你是否已经遇到了这个要求。

初始化一个XmlSlurper实例表示调用其超载的parse(..)方法之一(或方法parseText(String))。在这次调用之后,XmlSlurper将(至少使用SAX事件)构造一个内存为GPathResult的存储XML元素和属性及其结构的完整信息。

所以,不,不XmlSlurper提供的API来解析XML文档的部分,只。

什么可以做到,extend荷兰国际集团XmlSlurper,覆盖parse*(..)方法通过using a custom SAX handler预处理所述XML,XML收集的所需部分,并转发这些到的XmlSlurper.parse*(..)方法之一。

+0

谢谢 - 我得出结论,我必须做这样的事情。但是,这确实意味着我基本上必须进行双重传球,因此确实会影响表现。 – DrewEaster 2010-11-05 15:50:16

您可以使用StAX API和XmlSlurper来解析子树。

// Example of using StAX to split a large XML document and parse a single element using XmlSlurper 

import javax.xml.stream.XMLInputFactory 
import javax.xml.stream.XMLStreamReader 
import javax.xml.transform.Transformer 
import javax.xml.transform.TransformerFactory 
import javax.xml.transform.sax.SAXResult 
import javax.xml.transform.stax.StAXSource 

def url = new URL("http://repo2.maven.org/maven2/archetype-catalog.xml") 
url.withInputStream { inputStream -> 
    def xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream) 
    def transformer = TransformerFactory.newInstance().newTransformer() 
    while (xmlStreamReader.hasNext()) { 
     xmlStreamReader.next() 
     if (xmlStreamReader.isStartElement() && xmlStreamReader.getLocalName() == 'archetype') { 
      // Example of splitting a large XML document and parsing a single element with XmlSlurper at a time 
      def xmlSlurper = new XmlSlurper() 
      transformer.transform(new StAXSource(xmlStreamReader), new SAXResult(xmlSlurper)) 
      def archetype = xmlSlurper.document 
      println "${archetype.groupId} ${archetype.artifactId} ${archetype.version}" 
     } 
    } 
} 
+0

我刚才在Twitter上回答了这个问题https://twitter.com/lhotari/status/694002023562416128所以我决定给SO添加答案。 – 2016-02-09 16:25:35