Here are two working solutions (in the form of JUnit Groovy tests). The former was derived from this answer; the latter I experimented with and found on my own. I think the latter is more closely aligned with what you were looking for, but the former is probably more robust.
Side note: I don't know how you intend to read in the "variable path" expression, but you should be very careful to sanitize it completely because you do not want to run Eval.me()
on arbitrary, unsanitized, user-provided input.
@Test
void testShouldUseVariableGPathExpression() {
// Arrange
def xmlContent = """<root>
<Person>
<Name>JOHN DOE</Name>
</Person>
</root>"""
def getNodes = { doc, path ->
def nodes = doc
path.split("\\.").each { nodes = nodes."${it}" }
return nodes
}
def root = new XmlSlurper().parseText(xmlContent)
// Don't reference 'root' here
def path = "Person.Name"
// Act
def personName = getNodes(root, path)
logger.info("Parsed ${path}: ${personName}")
// Assert
assert personName == "JOHN DOE"
}
@Test
void testShouldUseVariableGPathExpressionAndEval() {
// Arrange
def xmlContent = """<root>
<Person>
<Name>JOHN DOE</Name>
</Person>
</root>"""
def root = new XmlSlurper().parseText(xmlContent)
def path = "root.Person.Name"
def expression = "evaluatedPath = ${path}"
logger.info("Generated expression: ${expression}")
// Act
def evaluatedPath = Eval.me('root', root, path)
logger.info("Evaluated result: ${evaluatedPath}")
def personName = evaluatedPath
logger.info("Parsed ${path}: ${personName}")
// Assert
assert personName == "JOHN DOE"
}