是否有人知道是否可以以某种方式使用XMLSlurper,这意味着可以从非常大的XML文档中提取单个子树并单独处理?
想象一下,您有一个包含根元素的巨大XML Feed,该元素包含数千个可以单独处理的直接子元素。显然,将整个文档读入内存是一个禁忌,但是,因为根的每个子项本身都是适度的大小,所以流式传输文档但是依次将XMLSlurper的好处应用于每个子元素会更好。在处理每个子元素时,垃圾收集可以清理用于处理它的内存。通过这种方式,我们可以轻松获得XMLSlurper(这种简洁的语法),并且内存占用空间很小(例如SAX)。
我有兴趣知道是否有人有这方面的想法和/或你是否已经遇到过这个要求。
答案 0 :(得分:2)
初始化XmlSlurper
实例意味着调用其中一个重载的parse(..)
方法(或parseText(String)
方法)。在此调用之后,XmlSlurper将(至少使用SAX事件)构造一个内存中GPathResult
,其中包含有关XML元素和属性及其结构的完整信息。
所以,不,XmlSlurper
不只提供解析XML文档部分的API。
可以做的是extend
XmlSlurper
,覆盖parse*(..)
方法,通过using a custom SAX handler预处理XML,收集所需的XML部分,以及将这些转发给XmlSlurper.parse*(..)
方法之一。
答案 1 :(得分:2)
您可以将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}"
}
}
}