Script { public static void evalXmlEmbeddedExpressions(Node node, ScenarioContext context) { if (node.getNodeType() == Node.DOCUMENT_NODE) { node = node.getFirstChild(); } NamedNodeMap attribs = node.getAttributes(); int attribCount = attribs == null ? 0 : attribs.getLength(); Set<Attr> attributesToRemove = new HashSet(attribCount); for (int i = 0; i < attribCount; i++) { Attr attrib = (Attr) attribs.item(i); String value = attrib.getValue(); value = StringUtils.trimToEmpty(value); if (isEmbeddedExpression(value)) { boolean optional = isOptionalMacro(value); try { ScriptValue sv = evalJsExpression(value.substring(optional ? 2 : 1), context); if (optional && sv.isNull()) { attributesToRemove.add(attrib); } else { attrib.setValue(sv.getAsString()); } } catch (Exception e) { context.logger.trace("embedded xml-attribute eval failed, path: {}, reason: {}", attrib.getName(), e.getMessage()); } } } for (Attr toRemove : attributesToRemove) { attribs.removeNamedItem(toRemove.getName()); } NodeList nodeList = node.getChildNodes(); int childCount = nodeList.getLength(); List<Node> nodes = new ArrayList(childCount); for (int i = 0; i < childCount; i++) { nodes.add(nodeList.item(i)); } Set<Node> elementsToRemove = new HashSet(childCount); for (Node child : nodes) { String value = child.getNodeValue(); if (value != null) { value = StringUtils.trimToEmpty(value); if (isEmbeddedExpression(value)) { boolean optional = isOptionalMacro(value); try { ScriptValue sv = evalJsExpression(value.substring(optional ? 2 : 1), context); if (optional && sv.isNull()) { elementsToRemove.add(child); } else { if (sv.isMapLike()) { Node evalNode; if (sv.getType() == XML) { evalNode = sv.getValue(Node.class); } else { evalNode = XmlUtils.fromMap(sv.getAsMap()); } if (evalNode.getNodeType() == Node.DOCUMENT_NODE) { evalNode = evalNode.getFirstChild(); } if (child.getNodeType() == Node.CDATA_SECTION_NODE) { child.setNodeValue(XmlUtils.toString(evalNode)); } else { evalNode = node.getOwnerDocument().importNode(evalNode, true); child.getParentNode().replaceChild(evalNode, child); } } else { child.setNodeValue(sv.getAsString()); } } } catch (Exception e) { context.logger.trace("embedded xml-text eval failed, path: {}, reason: {}", child.getNodeName(), e.getMessage()); } } } else if (child.hasChildNodes() || child.hasAttributes()) { evalXmlEmbeddedExpressions(child, context); } } for (Node toRemove : elementsToRemove) { Node parent = toRemove.getParentNode(); Node grandParent = parent.getParentNode(); grandParent.removeChild(parent); } } private  Script(); static final boolean isCallSyntax(String text); static final boolean isCallOnceSyntax(String text); static final boolean isGetSyntax(String text); static final boolean isJson(String text); static final boolean isJsonPath(String text); static final boolean isXml(String text); static final boolean isXmlPath(String text); static final boolean isXmlPathFunction(String text); static final boolean isEmbeddedExpression(String text); static final boolean isWithinParentheses(String text); static final boolean isContainsMacro(String text); static final boolean isContainsOnlyMacro(String text); static final boolean isContainsAnyMacro(String text); static final boolean isNotContainsMacro(String text); static final boolean isDollarPrefixedJsonPath(String text); static final boolean isDollarPrefixedParen(String text); static final boolean isDollarPrefixed(String text); static final boolean isVariable(String text); static final boolean isVariableAndSpaceAndPath(String text); static StringUtils.Pair parseVariableAndPath(String text); static ScriptValue evalKarateExpressionForMatch(String text, ScenarioContext context); static ScriptValue getIfVariableReference(String text, ScenarioContext context); static ScriptValue evalKarateExpression(String text, ScenarioContext context); static ScriptValue evalXmlPathOnVarByName(String name, String path, ScenarioContext context); static ScriptValue evalXmlPathOnXmlNode(Node doc, String path); static ScriptValue evalJsonPathOnVarByName(String name, String exp, ScenarioContext context); static ScriptValue evalJsExpression(String exp, ScenarioContext context); static ScriptValue evalJsExpression(String exp, ScenarioContext context, ScriptValue selfValue, Object root, Object parent); static boolean isValidVariableName(String name); static void evalJsonEmbeddedExpressions(DocumentContext doc, ScenarioContext context); static void evalXmlEmbeddedExpressions(Node node, ScenarioContext context); static ScriptValue copy(String name, String exp, ScenarioContext context, boolean validateName); static ScriptValue assign(String name, String exp, ScenarioContext context); static ScriptValue assign(AssignType assignType, String name, String exp, ScenarioContext context, boolean validateName); static DocumentContext toJsonDoc(ScriptValue sv, ScenarioContext context); static AssertionResult matchNamed(MatchType matchType, String expression, String path, String expected, ScenarioContext context); static AssertionResult matchScriptValue(MatchType matchType, ScriptValue actual, String path, String expected, ScenarioContext context); static AssertionResult matchString(MatchType matchType, ScriptValue actual, String expected, String path, ScenarioContext context); static boolean isMacro(String text); static boolean isOptionalMacro(String text); static AssertionResult matchStringOrPattern(char delimiter, String path, MatchType stringMatchType,
            Object actRoot, Object actParent, ScriptValue actValue, String expected, ScenarioContext context); static AssertionResult matchXml(MatchType matchType, ScriptValue actual, String path, String expression, ScenarioContext context); static AssertionResult matchJsonOrObject(MatchType matchType, ScriptValue actual, String path, String expression, ScenarioContext context); static AssertionResult matchFailed(MatchType matchType, String path,
            Object actObject, Object expObject, String reason); static AssertionResult matchNestedObject(char delimiter, String path, MatchType matchType,
            Object actRoot, Object actParent, Object actObject, Object expObject, ScenarioContext context); static boolean isPrimitive(Class clazz); static void removeValueByPath(String name, String path, ScenarioContext context); static void setValueByPath(String name, String path, ScriptValue value, ScenarioContext context); static void setValueByPath(String name, String path, String exp, ScenarioContext context); static void setValueByPath(String name, String path, String exp, boolean delete, ScenarioContext context, boolean viaTable); static void setValueByPath(String name, String path, ScriptValue value, boolean delete, ScenarioContext context, boolean viaTable); static ScriptValue call(ScriptValue called, String argString, ScenarioContext context, boolean reuseParentConfig); static ScriptValue evalJavaFunctionCall(Function function, Object callArg, ScenarioContext context); static ScriptValue evalJsFunctionCall(ScriptObjectMirror som, Object callArg, ScenarioContext context); static ScriptValue evalFeatureCall(Feature feature, Object callArg, ScenarioContext context, boolean reuseParentConfig); static StringUtils.Pair parseCallArgs(String line); static void callAndUpdateConfigAndAlsoVarsIfMapReturned(boolean callOnce, String name, String arg, ScenarioContext context); static AssertionResult assertBoolean(String expression, ScenarioContext context); static String replacePlaceholderText(String text, String token, String replaceWith, ScenarioContext context); static String replacePlaceholders(String text, List<Map<String, String>> list, ScenarioContext context); static List<Map<String, Object>> evalTable(List<Map<String, String>> list, ScenarioContext context); static void setByPathTable(String name, String path, List<Map<String, String>> list, ScenarioContext context); static final String VAR_SELF; static final String VAR_ROOT; static final String VAR_PARENT; static final String VAR_LOOP; static final String VAR_ARG; static final String VAR_HEADER; static final Map<String, Validator> VALIDATORS; }
@Test public void testEvalXmlEmbeddedExpressions() { ScenarioContext ctx = getContext(); ctx.vars.put("a", 1); ctx.vars.put("b", 2); Document doc = XmlUtils.toXmlDoc("<root><foo>#(a + b)</foo></root>"); Script.evalXmlEmbeddedExpressions(doc, ctx); ctx.vars.put("myXml", doc); ScriptValue value = Script.evalXmlPathOnVarByName("myXml", "/root/foo", ctx); assertEquals(ScriptValue.Type.STRING, value.getType()); assertEquals("3.0", value.getAsString()); }