【问题标题】:How to invoke "dynamic" XPaths with count() in Karate? [duplicate]如何在空手道中使用 count() 调用“动态”XPath? [复制]
【发布时间】:2019-04-18 09:31:18
【问题描述】:

我正在尝试在空手道中调用一个“动态”XPath,它使用 XPath count() 函数返回一个数字(或字符串表示)。

[使用 Karate 0.9.2] 我正在尝试在 XML 文档上调用“动态”XPath 表达式(最初从基于 JSON 的配置文件中读取)。

有(可能)多个 XPath 表达式,所以我使用空手道的 karate.forEach() 在空手道中重复调用 XPath 实用 Javascript 函数。

在嵌入的 Javascript 函数中,我使用 karate.xmlPath() 来调用“动态”XPath 表达式字符串。

这适用于检索单个节点、节点列表等,但当表达式使用 XPath 的 count() 函数时它会失败,因为结果是数字而不是 XML 节点或 XML NodeList。

Feature:  General XPath based evaluator
Scenario: ....

 # Omitting details around performing HTTP request to obtain XML response....
  * xml payload = ..... $.requests[0].body ... 
 #
 # A JS Function to invoke each XPath Query in our query dictionary 
 #
 # queryDictionaryItem has a single XPath query in it with an expected 
 value
 # { "xpath": <query>, "expectedValue", <string> } 
 # 
  * def checkXPathQueryFn =
  """
    function(queryDictionaryItem) {
      var requestXML = karate.get("payload");

      var xpathQuery = queryDictionaryItem.xpath;
      var expectedValue = queryDictionaryItem.expectedValue;

      // [!!] This will blow up if the xpathQuery is of the form:
      // "count(........)" 
      // --> Cannot return a NUMERIC value rather than a NODELIST
      var actualValue = karate.xmlPath( requestXML, xpathQuery );

      var match = karate.match( actualValue, expectedValue );

      if (!match.pass) 
      { 
          karate.abort("Failed to match expectation..."); }
      }
  """

 # queryDictionary is a list of JSON objects of the form:
 # { "xpath": <query>, "expectedValue", <string> } 

    * eval karate.forEach(queryDictionary, checkXPathQueryFn)

预期结果:

在动态调用基于 count() 的 XPath 时接收字符串/数字。

实际结果:

错误:

javax.xml.xpath.XPathExpressionException: com.sun.org.apache.xpath.internal.XPathException: Can not convert #NUMBER to a NodeList!

javascript evaluation failed: karate.forEach(requestExpectations, oldCheckExpectation), javax.xml.xpath.XPathExpressionException: com.sun.org.apache.xpath.internal.XPathException: Can not convert #NUMBER to a NodeList!

对于 Intuit Karate 开发人员:[@ptrthomas]

在 v0.9.2 版本的 karate-core 中,Script#evalXmlPathOnXmlNode() 中的 XPaths 中有使用 count() 的规定:

https://github.com/intuit/karate/blob/master/karate-core/src/main/java/com/intuit/karate/Script.java#L367L367

但是当我们使用动态 XPath 时,调用序列不使用那个“保护”,而是使用 ScriptBridge#xmlPath()

https://github.com/intuit/karate/blob/master/karate-core/src/main/java/com/intuit/karate/core/ScriptBridge.java#L230L230

这个方法有一行:

        Node result = XmlUtils.getNodeByPath((Node) o, path, false);  

当 XPath 表达式不返回 NODESET 形数据时抛出 RuntimeExceptions。

https://github.com/intuit/karate/blob/master/karate-core/src/main/java/com/intuit/karate/XmlUtils.java#L152L152.

【问题讨论】:

  • 您回答自己的问题是完全正确的。但不要对问题本身这样做。
  • 感谢您的礼仪建议。很高兴根据当前的空手道版本提出解决建议。我的建议(对框架作者)是: * 尝试从 Java 的 XPath API 中捕获类型强制 XPathException 并在没有假定的 NodeList 返回类型的情况下重新调用,或者, * 允许开发人员提供返回类型的提示,类似于 XPath API。
  • 您可以为您的建议创建一个issue,或者 - 更好的是 - 创建一个拉取请求。
  • 谢谢彼得。我正在整理一个代码示例来重现空手道指南中建议的场景,并会引发问题。
  • @MattHavilah 感谢您的错误报告,它应该在develop 中修复

标签: xpath karate


【解决方案1】:

确认此空手道框架问题已通过最新(截至 2019 年 4 月 23 日)空手道核心(开发分支构建)修复。

此修复程序计划在 Intuit Karate v0.9.3 发布。

Java/Karate 源进一步详细说明了该问题以及通过直接 Java XPath 互操作的替代(临时)Java 原生解决方法列于: https://github.com/mhavilah/karateDynamicXPath

注意:上述项目中 XPathHelper 的行为与 karate.xmlPath() DSL 服务的行为略有不同。

特别是对于检索单个 XML 元素,空手道 DSL 自动提取底层 text() 节点,而 Java 原生 Helper 需要显式引用 XML 元素中嵌入的文本节点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 2018-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多