Я пытаюсь вызвать «динамический» XPath в карате, который использует функцию XPath count () для возврата числа (или строкового представления).
[С карате 0.9.2] Япытаюсь вызвать «динамические» выражения XPath (первоначально считанные из файла конфигурации на основе JSON) в документе XML.
(потенциально) существует несколько выражений XPath, поэтому я использую karate.forEach () для карате для вызовафункция Javascript утилиты XPath несколько раз в карате.
Во встроенной функции Javascript я использую karate.xmlPath () для вызова «динамической» строки выражения XPath.
Это прекрасно работает для извлечения отдельных узлов, списки узлов и т. д., но происходит сбой, когда выражение использует функцию count () в XPath, поскольку результатом является число, а не узел XML или NodeList XML.
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)
Ожидаемый результат:
Receivea Строка / Число, когда XPath на основе count () вызывается динамически.
Фактический результат:
Ошибка:
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 предусмотрены возможности использования count () в XPaths в Script # evalXmlPathOnXmlNode ():
https://github.com/intuit/karate/blob/master/karate-core/src/main/java/com/intuit/karate/Script.java#L367 L367
но поскольку мы используем динамический XPath, последовательность вызовов не использует эту «защиту», а вместо этого использует ScriptBridge # xmlPath ()
https://github.com/intuit/karate/blob/master/karate-core/src/main/java/com/intuit/karate/core/ScriptBridge.java#L230 L230
Этот метод имеет строку:
Node result = XmlUtils.getNodeByPath((Node) o, path, false);
, которая генерирует исключения RuntimeException, когда выражения XPath не возвращают данные в форме NODESET.
https://github.com/intuit/karate/blob/master/karate-core/src/main/java/com/intuit/karate/XmlUtils.java#L152 L152.