Reputation: 141
I have a groovy code which accepts xpath expression and find the value of nodes (both XML and JSON), but I am not able to filter by attributes. Below is my code, please can I get some help?
def message = '''
<payload>
<division name="DivisionCodes">
<param name="DivisionCode">FFM-VKM</string>
<param name="DivisionGroupCode">FFM</string>
<param name="DivisionCountryCode">DE</string>
</division>
</payload>
'''
def xpathEx='*/param[@name="DivisionCountryCode"]'
def result = ''
if(xpathEx) {
def gPaths = xpathEx?.split(",") as LinkedList
def extractedData=[:]
gPaths.eachWithIndex { String entry, int idx ->
def inputData = ''
def headerKey = ''
def path = entry?.replace('/', '.')?.replace(':','')?.split('\\.') as LinkedList
if (path) {
if (message.trim().charAt(0) == '<') {
inputData = new XmlSlurper().parseText(message)
}
path.forEach({ inputData = inputData."${it}" })
}
extractedData.put(path.getLast().toString(),inputData)
}
if(extractedData.isEmpty()) {
result = ' '
} else {
result = ', XPath reference: '+extractedData?.toMapString()
}
}
println result
I am interested to get the value of param child node where attribute is "DivisionGroupCode". My xpath expression is only able to filter by child node.
What should be the correct xpathEx? OR What should correct groovy code which can take xpathEx as parameter and process on any XML payload
Upvotes: 0
Views: 1343
Reputation: 141
import groovy.json.JsonSlurper
def result = ''
def message = '''
<payload>
<division name="DivisionCodes">
<param name="DivisionCode">FFM-VKM</param>
<param name="DivisionGroupCode">FFM</param>
<param name="DivisionCountryCode">DE</param>
</division>
<division value="SectorCodes">
<param value="SectorCode">SEC-LOC-23</param>
<param value="SectorGroupCode">DUK-001002</param>
<param value="SectorCountryCode">PH</param>
</division>
</payload>
'''
def xpathEx='*@name="DivisionCode",*@value="SectorCode",*@name="DivisionCountryCode",*@value="SectorCountryCode"'
if(xpathEx) {
def gPaths = xpathEx?.split(",") as LinkedList
def extractedData=[:]
gPaths.eachWithIndex { String entry, int idx ->
def inputData = ''
def path = entry?.replace('/', '.')?.replace('@', '.@')?.replace(':','')?.split('\\.') as LinkedList
if (path) {
if (message.trim().charAt(0) == '<') {
inputData = new XmlSlurper().parseText(message)
} else if (message.trim().charAt(0) == '{') {
inputData = new JsonSlurper().parseText(message)
}
path.forEach({
if ("${it}".contains("=")) {
def attName = "${it}".substring(1, "${it}".indexOf("="))
def attValue = "${it}".substring("${it}".indexOf("=") + 2, "${it}".length() - 1)
inputData = inputData.depthFirst().find {arg -> if (arg.attributes().get(attName) == attValue) { arg } }
} else {
inputData = inputData."${it}"
}
})
}
extractedData.put(path.getLast().toString(),inputData)
}
if(extractedData.isEmpty()) {
result = ' '
} else {
result = ', XPath reference: '+extractedData?.toMapString()
}
}
println result
Upvotes: 0
Reputation: 2133
If yourt only requirement is like you stated: "I am interested to get the value of param child node where attribute is 'DivisionGroupCode'",
then this will work. However, your XML is not valid, the closing tags: </string>
should be </param>
.
def message = '''
<payload>
<division name="DivisionCodes">
<param name="DivisionCode">FFM-VKM</param>
<param name="DivisionGroupCode">FFM</param>
<param name="DivisionCountryCode">DE</param>
</division>
</payload>
'''
def payload = new XmlSlurper().parseText(message)
def name = payload.depthFirst().find { param ->
param.@name == 'DivisionGroupCode'
}
println name
Upvotes: 0