3

我想将参数传递给 XPath 表达式。

(//a/b/c[x=?],myParamForXAttribute)

我可以用 XPath 1.0 做到这一点吗?(我试过了string-join了,但在 XPath 1.0 中没有)

那我该怎么做呢?

我的 XML 看起来像

<a>
 <b>
  <c>
   <x>val1</x>
   <y>abc</y>
  </c>
  <c>
   <x>val2</x>
   <y>abcd</y>
  </c>
</b>
</a>

我想获取<y>x 元素值所在的元素值val1

我试过//a/b/c[x='val1']/y了,但没有用。

4

2 回答 2

6

鉴于您使用的是 Axiom XPath 库,而后者又使用 Jaxen,您需要按照以下三个步骤以完全健壮的方式执行此操作:

  • 创建一个SimpleVariableContext,并调用context.setVariableValue("val", "value1")为该变量分配一个值。
  • 在您的BaseXPath对象上,调用.setVariableContext()以传入您分配的上下文。
  • 在您的表达式中,使用/a/b/c[x=$val]/y来引用该值。

考虑以下:

package com.example;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.common.AxiomText;
import org.apache.axiom.om.util.AXIOMUtil;
import org.apache.axiom.om.xpath.DocumentNavigator;
import org.jaxen.*;

import javax.xml.stream.XMLStreamException;

public class Main {

    public static void main(String[] args) throws XMLStreamException, JaxenException {
        String xmlPayload="<parent><a><b><c><x>val1</x><y>abc</y></c>" +
                                        "<c><x>val2</x><y>abcd</y></c>" +
                          "</b></a></parent>";
        OMElement xmlOMOBject = AXIOMUtil.stringToOM(xmlPayload);

        SimpleVariableContext svc = new SimpleVariableContext();
        svc.setVariableValue("val", "val2");

        String xpartString = "//c[x=$val]/y/text()";
        BaseXPath contextpath = new BaseXPath(xpartString, new DocumentNavigator());
        contextpath.setVariableContext(svc);
        AxiomText selectedNode = (AxiomText) contextpath.selectSingleNode(xmlOMOBject);
        System.out.println(selectedNode.getText());
    }
}

...作为输出发出:

abcd
于 2015-05-20T15:17:44.083 回答
5

这取决于您使用 XPath 的语言。

在 XSLT 中:

 "//a/b/c[x=$myParamForXAttribute]"

请注意,与上面的方法不同,以下三种方法对XPath 注入攻击是开放的,并且永远不应与不受控制或不受信任的输入一起使用;为避免这种情况,请使用您的语言或库提供的机制来带外传递变量。 [信用:查尔斯·达菲]

在 C# 中:

String.Format("//a/b/c[x={0}]", myParamForXAttribute);

在 Java 中:

String.format("//a/b/c[x=%s]", myParamForXAttribute);

在 Python 中:

 "//a/b/c[x={}]".format(myParamForXAttribute)
于 2015-05-20T14:56:22.547 回答