Keegan
Keegan

Reputation: 12197

Using variables in XmlSlurper's GPath

Is there a way to have XmlSlurper get arbitrary elements through a variable? e.g. so I can do something like input file:

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

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

I've tried using {} and ${} and () how do I escape variables like that? Or isn't there a way? and is it possible to use results from closures as the arguments as well? So I could do something like

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

Upvotes: 8

Views: 5341

Answers (3)

Pablo Pazos
Pablo Pazos

Reputation: 3216

Based on Michael's solution, this provides support for indexes, like '/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
}

Upvotes: 0

Michael Easter
Michael Easter

Reputation: 24468

This answer offers a code example, and owes a lot to John W's comment in his answer.

Consider this:

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 }
}

Upvotes: 6

John Wagenleitner
John Wagenleitner

Reputation: 11035

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

Upvotes: 9

Related Questions