【问题标题】:Using variables in XmlSlurper's GPath在 XmlSlurper 的 GPath 中使用变量
【发布时间】:2009-08-20 18:12:00
【问题描述】:

有没有办法让 XmlSlurper 通过变量获取任意元素? 例如所以我可以做类似的事情 输入文件:

<file>
    <record name="some record" />
    <record name="some other record" />
</file>

def xml = new XmlSlurper().parse(inputFile)
String foo = "record"
return xml.{foo}.size()

我尝试过使用 {} 和 ${} 和 () 我如何转义这样的变量?还是没有办法? 是否也可以使用闭包的结果作为参数?所以我可以做类似的事情

String foo = file.record
int numRecords = xml.{foo.find(/.\w+$/)}

【问题讨论】:

    标签: xml groovy


    【解决方案1】:
    import groovy.xml.*
    
    def xmltxt = """<file>
        <record name="some record" />
        <record name="some other record" />
    </file>"""
    
    def xml = new XmlSlurper().parseText(xmltxt)
    String foo = "record"
    return xml."${foo}".size()
    

    【讨论】:

    • 这不适用于不是根的直接子元素的元素。观察:def xmltxt = """ """ def xml = new XmlSlurper().parseText(xmltxt) String foo = "something.record" return xml."${foo}".size() 还有其他建议吗?
    • 我不知道有什么好办法,你可以拆分字符串:def aNode = xml foo.split("\\.").each { aNode = aNode."${it} " } return aNode.size()
    • +1。谢谢,评论也帮助了我。但是请把它放到答案正文中,因为它几乎不可读
    • 它必须在根中并不完全正确,更多的是你只能做一个部分,而不是在一个变量中指定多个部分:def xml = new XmlSlurper().parseText (xmltxt) String part1 = "something" String part2 = "record" println(xml."${part1}"."${part2}".size())
    • @JohnWagenleitner 在您的评论中为node.another 路径提供了很好的解决方法,IMO 我认为您必须将其添加到您的答案中 +1 :)
    【解决方案2】:

    这个答案提供了一个代码示例,并且很大程度上归功于 John W 在他的答案中的评论。

    考虑一下:

    import groovy.util.* 
    
    def xml = """<root>
      <element1>foo</element1>
      <element2>bar</element2>
      <items>
         <item>
           <name>a</name>
           <desc>b</desc>
         </item>
         <item>
            <name>c</name>
            <desc>x</desc>
         </item>
      </items>
    </root>"""
    
    def getNodes = { doc, path ->
        def nodes = doc
        path.split("\\.").each { nodes = nodes."${it}" }
        return nodes
    }
    
    def resource = new XmlSlurper().parseText(xml)
    def xpaths = ['/root/element1','/root/items/item/name']
    
    xpaths.each { xpath ->
        def trimXPath = xpath.replace("/root/", "").replace("/",".")
        println "xpath = ${trimXPath}"
        getNodes(resource, trimXPath).each { println it }
    }
    

    【讨论】:

    • 各位,赋值呢?我的意思是:String foo = "something.record" xml."${foo}"= value 你的 [甚至@Keegan 和@John.W] 的建议都不起作用:(,有什么线索吗?
    • 伙计们,我找到了解决方案,我使用了def node= getNodes(..) node.replaceBody value .. 我看到我是 XMLSlurper 的实习生 :( .
    【解决方案3】:

    基于 Michael 的解决方案,这提供了对索引的支持,例如 '/root/element1[1]'

    def getNodes = { doc, path ->
        def nodes = doc
        path.split("\\.").each {
          if (it.endsWith(']'))
          {
            def name_index = it.tokenize('[]') // "attributes[1]" => ["attributes", "1"]
            nodes = nodes."${name_index[0]}"[name_index[1].toInteger()]
          }
          else nodes = nodes."${it}"
        }
        return nodes
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多