如何将 GPath 与变量一起使用?

How to use GPath with variable?

假设我手头有以下XML

<Envelope>
  <Body>
    <analyzeEffectOfReplaceOfferResponse>
      <productOfferings>
        <productOffering>
          <id>some value</id>
        </productOffering>
      </productOfferings>
    </analyzeEffectOfReplaceOfferResponse>
  </Body>
</Envelope>

在检索文件并解析后,我还有 GPathResult 形式的输入 XML:

inputXML = new XmlSlurper().parse(inputFile)

当我试图找到这样的节点时:

inputXML."Body"."analyzeEffectOfReplaceOfferResponse"."productOfferings"."productOffering".depthFirst().findAll {it.value}

我得到了要求的 child "id"

但是,如果我使用包含此文本的字符串:

"Body"."analyzeEffectOfReplaceOfferResponse"."productOfferings"."productOffering"

并像这样使用它:

inputXML."${xPath}".depthFirst().findAll {it.value}

没用... 我做错了什么?

在您当前的尝试中,Groovy 使用参数 "Body"."analyzeEffectOfReplaceOfferResponse"."productOfferings"."productOffering"inputXML 对象上调用 getProperty 方法。

由于没有 XML 个具有该特定名称的子元素,因此未找到任何内容。

相反,您的目标是按照以下方式动态链接调用:

inputXML.getProperty('Body')
        .getProperty('analyzeEffectOfReplaceOfferResponse')
        .getProperty('productOfferings')
        .getProperty('productOffering')
        .depthFirst().findAll {it.value}

您可以通过创建一个递归创建此链接的​​方法来做到这一点,例如

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}

或者您可以使用 full-fledged XPath 库。

可以使用Eval.me:

def inputXML = new XmlSlurper().parseText( '''<Envelope>
  <Body>
    <analyzeEffectOfReplaceOfferResponse>
      <productOfferings>
        <productOffering>
          <id>some value</id>
        </productOffering>
      </productOfferings>
    </analyzeEffectOfReplaceOfferResponse>
  </Body>
</Envelope>''')

println inputXML."Body"."analyzeEffectOfReplaceOfferResponse"."productOfferings"."productOffering".depthFirst().findAll {it.value}

//use Eval.me groovy code evaluation
def gpath = ' XML."Body"."analyzeEffectOfReplaceOfferResponse"."productOfferings"."productOffering" '
println Eval.me( 'XML', inputXML, gpath ).depthFirst().findAll {it.value}

//or even like this:
gpath = ' XML."Body"."analyzeEffectOfReplaceOfferResponse"."productOfferings"."productOffering".depthFirst().findAll {it.value} '
println Eval.me( 'XML', inputXML, gpath )

您是否必须使用字符串,或者您只是在寻找一种方法来存储元素的路径以便以后不必再次键入它?

String xml = '<Envelope><Body><analyzeEffectOfReplaceOfferResponse><productOfferings><productOffering><id>some value</id></productOffering></productOfferings></analyzeEffectOfReplaceOfferResponse></Body></Envelope>'
def Envelope = new XmlSlurper().parseText(xml)
Closure takeMyPathFrom = {node -> node."Body"."analyzeEffectOfReplaceOfferResponse"."productOfferings"."productOffering"}
assert takeMyPathFrom(Envelope) == "some value"