在XmlSlurper中使用变量作为GPath表达式

时间:2017-02-24 23:03:56

标签: xml groovy xmlslurper

给出以下XML文档:

<root>
  <Person>
    <Name>JOHN DOE</Name>
  </Person>
</root>

使用Groovy脚本我解析文档如下:

def xmlFile = new File("mydocument.xml")
def root = new XmlSlurper().parse(xmlFile)
println(root.Person.Name)

是否可以使GPath表达式变量,以便它能像这样?

def xmlFile = new File("mydocument.xml")
def root = new XmlSlurper().parse(xmlFile)
def gpathExpr = "root.Person.Name"
println(gpathExpr) // <-- Evaluate this during runtime

1 个答案:

答案 0 :(得分:1)

这是两个有效的解决方案(以JUnit Groovy测试的形式)。前者来自this answer;后者我试验并自己找到。我认为后者与你想要的更紧密地对齐,但前者可能更强大。

旁注:我不知道您打算如何阅读“变量路径”表达式,但您应该非常小心来彻底清理它,因为您想要在任意,未经过优化的用户提供的输入上运行Eval.me()

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