有没有更好的方法使用 Groovy Gpath 在 xml 中查找祖先?
Is there a better way to find ancestors in xml using Groovy Gpath?
请查看我下面的 groovy 代码,它按预期工作 - 但想知道是否有更好的方法来获取祖先信息?
我的样本xml记录:
String record = '''
<collections>
<material>
<books>
<title>Italy</title>
</books>
</material>
<material>
<books>
<title>Greece</title>
</books>
</material>
<material>
<books>
<author>Germany</author>
</books>
</material>
<material>
<cd>
<author>France</author>
</cd>
</material>
</collections>
'''
请问有没有什么更好的方法来优化这个取祖点?
GPathResult extractedMaterialBlocks = extractAllMaterialBlocks(record)
String finalXml = serializeXml(extractedMaterialBlocks.parent().parent(), 'UTF-8')
println "finalXml : ${finalXml}"
我的方法:
GPathResult extractAllMaterialBlocks(String record) {
GPathResult result = new XmlSlurper().parseText(record)
return result ? result.'material'?.'books'?.'title'?.findAll { it } : null
}
String serializeXml(GPathResult xmlToSerialize, String encoding) {
def builder = new StreamingMarkupBuilder()
builder.encoding = encoding
builder.useDoubleQuotes = true
return builder.bind {
out << xmlToSerialize
}.toString()
}
预期输出:
<material>
<books>
<title>Italy</title>
</books>
</material>
<material>
<books>
<title>Greece</title>
</books>
</material>
如果你不潜得太深,你不需要得到祖先。如果您想要 material 节点,请获取那些在其 children 上有条件的节点,而不是获取子节点然后再次上升。您的整个代码可以浓缩为这一行:
System.out.println new StreamingMarkupBuilder().bind { out << new XmlSlurper().parseText(record).material.findAll { it.books.title.size() } }
给你,在线评论:
//Get all the collection of materials which has titles
def materials = new XmlSlurper().parseText(record).material.findAll { it.books.title.size() }
//Print each node
materials.each { println groovy.xml.XmlUtil.serialize(it) }
输出:
<?xml version="1.0" encoding="UTF-8"?><material>
<books>
<title>Italy</title>
</books>
</material>
<?xml version="1.0" encoding="UTF-8"?><material>
<books>
<title>Greece</title>
</books>
</material>
您可以快速在线试用Demo
编辑:基于 OP 评论
def materials = new XmlSlurper().parseText(record).material.findAll { it.books.title.size() }
println new groovy.xml.StreamingMarkupBuilder().bind {
mkp.yield materials
}.toString()
请查看我下面的 groovy 代码,它按预期工作 - 但想知道是否有更好的方法来获取祖先信息?
我的样本xml记录:
String record = '''
<collections>
<material>
<books>
<title>Italy</title>
</books>
</material>
<material>
<books>
<title>Greece</title>
</books>
</material>
<material>
<books>
<author>Germany</author>
</books>
</material>
<material>
<cd>
<author>France</author>
</cd>
</material>
</collections>
'''
请问有没有什么更好的方法来优化这个取祖点?
GPathResult extractedMaterialBlocks = extractAllMaterialBlocks(record)
String finalXml = serializeXml(extractedMaterialBlocks.parent().parent(), 'UTF-8')
println "finalXml : ${finalXml}"
我的方法:
GPathResult extractAllMaterialBlocks(String record) {
GPathResult result = new XmlSlurper().parseText(record)
return result ? result.'material'?.'books'?.'title'?.findAll { it } : null
}
String serializeXml(GPathResult xmlToSerialize, String encoding) {
def builder = new StreamingMarkupBuilder()
builder.encoding = encoding
builder.useDoubleQuotes = true
return builder.bind {
out << xmlToSerialize
}.toString()
}
预期输出:
<material>
<books>
<title>Italy</title>
</books>
</material>
<material>
<books>
<title>Greece</title>
</books>
</material>
如果你不潜得太深,你不需要得到祖先。如果您想要 material 节点,请获取那些在其 children 上有条件的节点,而不是获取子节点然后再次上升。您的整个代码可以浓缩为这一行:
System.out.println new StreamingMarkupBuilder().bind { out << new XmlSlurper().parseText(record).material.findAll { it.books.title.size() } }
给你,在线评论:
//Get all the collection of materials which has titles
def materials = new XmlSlurper().parseText(record).material.findAll { it.books.title.size() }
//Print each node
materials.each { println groovy.xml.XmlUtil.serialize(it) }
输出:
<?xml version="1.0" encoding="UTF-8"?><material>
<books>
<title>Italy</title>
</books>
</material>
<?xml version="1.0" encoding="UTF-8"?><material>
<books>
<title>Greece</title>
</books>
</material>
您可以快速在线试用Demo
编辑:基于 OP 评论
def materials = new XmlSlurper().parseText(record).material.findAll { it.books.title.size() }
println new groovy.xml.StreamingMarkupBuilder().bind {
mkp.yield materials
}.toString()