是否可以使用Groovy XMLSlurper解析子树
有人知道是否有可能以一种方式使用XMLSlurper,即可以从一个非常大的XML文档中提取单个子树并单独处理 假设您有一个巨大的XML提要,其中包含一个根元素,该根元素有数千个可以单独处理的直接子元素。显然,将整个文档读入内存是不可能的,但是,由于根元素的每个子元素本身的大小都比较小,所以最好在文档中进行流式处理,但依次将XMLSlurper niceness应用于每个子元素。在处理每个子元素时,垃圾收集可以清理用于处理它的内存。通过这种方式,我们可以非常轻松地使用XMLSlurper(如此简洁的语法),并且流式处理(例如SAX)的内存占用很低是否可以使用Groovy XMLSlurper解析子树,groovy,xmlslurper,Groovy,Xmlslurper,有人知道是否有可能以一种方式使用XMLSlurper,即可以从一个非常大的XML文档中提取单个子树并单独处理 假设您有一个巨大的XML提要,其中包含一个根元素,该根元素有数千个可以单独处理的直接子元素。显然,将整个文档读入内存是不可能的,但是,由于根元素的每个子元素本身的大小都比较小,所以最好在文档中进行流式处理,但依次将XMLSlurper niceness应用于每个子元素。在处理每个子元素时,垃圾收集可以清理用于处理它的内存。通过这种方式,我们可以非常轻松地使用XMLSlurper(如此简洁
我想知道是否有人对此有想法和/或您自己是否遇到过此要求。初始化
XmlSlurper
实例意味着调用其重载的parse(…)
方法(或parseText(String)
方法)。在这个调用中,XmlSlurper将(至少使用SAX事件)构造一个内存中的GPathResult
,它保存关于XML元素和属性及其结构的完整信息
因此,不,XmlSlurper
只提供解析XML文档部分的API
可以做的是,
extend
ingXmlSlurper
,覆盖parse*(..)
方法,通过预处理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上回答了这个问题,所以我决定将答案也添加到这个问题上。