如何将可变参数传递给 XPath 表达式?
How to pass variable parameter into XPath expression?
我想将参数传递给 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
但是没用。
这取决于您使用 XPath 的语言。
在 XSLT 中:
"//a/b/c[x=$myParamForXAttribute]"
请注意,与上述方法不同,以下三个方法对 XPath injection attacks 开放,并且永远不应与不受控制或不受信任的输入一起使用;为避免这种情况,请使用您的语言或库提供的机制来带外传递变量。 [Credit: Charles Duffy]
在 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)
鉴于您使用的是 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
我想将参数传递给 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
但是没用。
这取决于您使用 XPath 的语言。
在 XSLT 中:
"//a/b/c[x=$myParamForXAttribute]"
请注意,与上述方法不同,以下三个方法对 XPath injection attacks 开放,并且永远不应与不受控制或不受信任的输入一起使用;为避免这种情况,请使用您的语言或库提供的机制来带外传递变量。 [Credit: Charles Duffy]
在 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)
鉴于您使用的是 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