3

Does anyone know whether it is possible to utilise XMLSlurper in a fashion that means individual sub-trees can be pulled from a very large XML document and processed individually?

Imagine you've got a huge XML feed containing a root element that has thousands of direct child elements that you can process individually. Obviously, reading the whole document into memory is a no-no but, as each child of the root is itself modestly sized, it would be nice to stream through the document but apply XMLSlurper niceness to each of the child elements in turn. As each child element is processed, garbage collection can clean up memory used to process it. In this way we get the great ease of XMLSlurper (such concise syntax) with the low memory footprint of streaming (e.g. SAX).

I'd be interested to know if anyone has ideas on this and/or whether you've come across this requirement yourselves.

4

2 回答 2

2

初始化一个XmlSlurper实例意味着,调用它的一个重载parse(..)方法(或parseText(String)方法)。在此调用后,XmlSlurper 将(至少使用 SAX 事件)构造一个内存中的内容,该内存GPathResult中包含有关 XML 元素和属性及其结构的完整信息。

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

可以做的是,extend覆盖XmlSlurper方法,使用自定义 SAX 处理程序parse*(..)预处理 XML ,收集 XML 的所需部分,并将这些转发到方法之一。XmlSlurper.parse*(..)

于 2010-11-05T13:02:59.450 回答
2

您可以结合使用 StAX APIXmlSlurper来解析子树。

// 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}"
        }
    }
}
于 2016-02-09T16:20:57.573 回答