是否有可能使用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*(..)
方法之一。
您可以使用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}"
}
}
}
我刚才在Twitter上回答了这个问题https://twitter.com/lhotari/status/694002023562416128所以我决定给SO添加答案。 – 2016-02-09 16:25:35
谢谢 - 我得出结论,我必须做这样的事情。但是,这确实意味着我基本上必须进行双重传球,因此确实会影响表现。 – DrewEaster 2010-11-05 15:50:16