Let's say I have the following XML at hand
<Envelope>
<Body>
<analyzeEffectOfReplaceOfferResponse>
<productOfferings>
<productOffering>
<id>some value</id>
</productOffering>
</productOfferings>
</analyzeEffectOfReplaceOfferResponse>
</Body>
</Envelope>
I also have the input XML in form of GPathResult after retrieving the file and parsing it:
inputXML = new XmlSlurper().parse(inputFile)
when I try to find the node like this:
inputXML."Body"."analyzeEffectOfReplaceOfferResponse"."productOfferings"."productOffering".depthFirst().findAll {it.value}
I get the required child "id"
however if I use a string that holds this text:
"Body"."analyzeEffectOfReplaceOfferResponse"."productOfferings"."productOffering"
and use it like so:
inputXML."${xPath}".depthFirst().findAll {it.value}
It doesn't work... what am I doing wrong?
In your current attempt, Groovy is calling the getProperty method on the inputXML
object with argument "Body"."analyzeEffectOfReplaceOfferResponse"."productOfferings"."productOffering"
.
Since there is no XML child element with that specific name, nothing is found.
Instead, your aim is to dynamically chain the calls along the lines of this:
inputXML.getProperty('Body')
.getProperty('analyzeEffectOfReplaceOfferResponse')
.getProperty('productOfferings')
.getProperty('productOffering')
.depthFirst().findAll {it.value}
You could do this by creating a method that recursively creates this chaining, e.g.
def xPath = '"Body"."analyzeEffectOfReplaceOfferResponse"."productOfferings"."productOffering"'
def getProperties(gpathResult, dotProp) {
def props = dotProp?.split(/\./)
props.length <= 1 ? gpathResult : getProperties(gpathResult[props.head() - '"' - '"'], (props.tail().join('.')))
}
getProperties(inputXML, xPath).depthFirst().findAll {it.value}
Or you could use a full-fledged XPath library.