有没有更好的方法在使用Groovy Gpath在xml中查找祖先?

时间:2017-06-30 01:34:37

标签: xml 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>

2 个答案:

答案 0 :(得分:1)

如果你不潜水太深,你不需要得到祖先。如果你想要材质节点,那就让那些在孩子身上有条件而不是得到孩子的孩子然后再上去。您的整个代码可以压缩到这一行:

System.out.println new StreamingMarkupBuilder().bind { out << new XmlSlurper().parseText(record).material.findAll { it.books.title.size() } }

答案 1 :(得分:1)

在这里,内联评论:

//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()