如何使用Groovy将XPath表达式值绑定到模板

时间:2016-04-04 16:08:21

标签: templates xpath groovy

我有一个名为“zzz”的小型Groovy类。这个类的目的是首先演示成功地将绑定传递给模板引擎以产生输出,然后使用看似相同的绑定集来绑定到另一个模板引擎。

V1.template包含将与绑定一起使用以生成最终输出的基本消息。 V1.properties包含一个XPath表达式,它应该从XML文档中获取值并将其添加到绑定中。 T1.xml是原始xml输入文件。

在zzz Groovy类中,我在bindings1中对LastName进行了硬编码,并且可以正常工作。但是,当我从XML文件中获取lastName值并将其添加到bindings2时,它将失败。两个绑定似乎都具有完全相同的文本,但我注意到bindings1的类型为Bindings,binding2的类型为Reference。

我认为bindings2属于Reference是造成我问题的原因,但我不知道如何将其转换或转换为Binding。请让我知道我做错了什么。

我正在使用Java 1.8和groovy-all-2.3.10.jar

zzz.groovy:

import java.io.File;
import javax.xml.xpath.*
import javax.xml.parsers.DocumentBuilderFactory

class zzz {

    def xpath
    def records
    def loadDocToCheck(File docToCheck) {
        xpath = XPathFactory.newInstance().newXPath()
        def builder =   DocumentBuilderFactory.newInstance().newDocumentBuilder()
        def inputStream = new FileInputStream( docToCheck )
        records = builder.parse(inputStream).documentElement
    }

    def validateXpath(String xpathQuery ) {
        def nodes = xpath.evaluate( xpathQuery, records, XPathConstants.NODESET )
        nodes.collect { node -> node.textContent }
        def nodeCount = 0
        nodes.each { nodeCount++ }
        nodeCount
    }

    def getXpath(String xpathQuery ) {
        String retVal = ""
        def nodes = xpath.evaluate( xpathQuery, records, XPathConstants.NODESET )
        nodes.collect { node ->
            retVal += node.getTextContent()
        }
        (retVal)
    }


    static main(args) {
        def zzz = new zzz()

        def testFile = new File("T1.xml")
        zzz.loadDocToCheck(testFile)

        def config = new ConfigSlurper().parse(new File("V1.properties").toURI().toURL())
        String testFileNameOnly = testFile.getName()-testFile.getParent()

        def bindings1 = [
            "InputFile" : "$testFileNameOnly",
            "LastName" : "Smith"
        ]

        def templateFile1 = new File('V1.template')
        println "templateFile1=${templateFile1.getAbsolutePath()}"
        def engine1 = new groovy.text.GStringTemplateEngine()
        def template1 = engine1.createTemplate(templateFile1).make(bindings1)

        println template1.toString()


        println "******************************"


        def bindings2 = [:]
        bindings2 << ["InputFile":"$testFileNameOnly"]
        config.params.each { paramName, param ->
            bindings2 << ["$paramName" : "${zzz.getXpath(param)}"]
        }

        println "bindings2=$bindings2"
        def templateFile2 = new File('V1.template')
        println "templateFile=${templateFile2.getAbsolutePath()}"
        def engine2 = new groovy.text.GStringTemplateEngine()
        def template2 = engine2.createTemplate(templateFile2).make(bindings2)

        println template2.toString()
    }
}

T1.xml:

<?xml version="1.0"?>
<MyRoot specVersion="3.03">
    <employee>
        <lastName>Smith</lastName>
        <firstName>John</firstName>
    </employee>
</MyRoot>

V1.template:

Input file: ${InputFile}
LastName: ${LastName}

V1.properties:

params {
    LastName = '//MyRoot/employee/lastName/text()'
}

1 个答案:

答案 0 :(得分:0)

我找到了第二个模板可以执行的原因。绑定必须是Map的形式,但我传入一个GString作为地图的关键。注意:“$ parameterName”是一个GString。将密钥转换为String后,第二个模板正确执行。