6

是否可以使用股票 JAX-P xpath 表达式引擎或其他兼容引擎来编译允许参数化的 xpath 表达式?

我正在寻找是否存在允许开发人员在已编译的 xpath 中设置占位符并在运行时替换这些值的 API。

任何关于这是否可能以及是否有警告、陷阱或只是简单的“不要那样做”类型的建议的见解将不胜感激。

(注意我更正了一个“跨越溪流”......正在与一位同事就 xpath 和正则表达式进行对话......只是碰巧在精神上被束缚了......对于混乱感到抱歉)

4

3 回答 3

11

这是一个非常简单的实现javax.xml.xpath.XPathVariableResolver

import java.util.HashMap;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.xpath.XPathVariableResolver;

public class SimpleVariableResolver implements XPathVariableResolver {

    private static final Map<QName, Object> vars = 
        new HashMap<QName, Object>();

    public void addVariable(QName name, Object value) {
        vars.put(name, value);
    }

    public Object resolveVariable(QName name) {
        return vars.get(name);
    }

}

像这样使用它:

public static void main(String[] args) throws ParserConfigurationException,
        SAXException, IOException, XPathExpressionException {

    DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = domFactory.newDocumentBuilder();
    Document doc = builder.parse("workbook.xml");

    XPath xpath = XPathFactory.newInstance().newXPath();
    SimpleVariableResolver resolver = new SimpleVariableResolver();
    resolver.addVariable(new QName(null, "id"), 2);
    xpath.setXPathVariableResolver(resolver);
    XPathExpression expr = xpath.compile("/root/element[@id=$id]");
    Object result = expr.evaluate(doc, XPathConstants.NODESET);

    NodeList nodes = (NodeList) result;
    for (int i = 0; i < nodes.getLength(); i++) {
        System.out.println(nodes.item(i).getTextContent());
    }
}

在这份文件上:

<root>
    <element id="1">one</element>
    <element id="2">two</element>
    <element id="3">three</element>
</root>

输出:

two
于 2011-07-19T17:59:51.953 回答
5

我不太确定“正则表达式”在哪里适合您的问题。

JAXP API 允许 XPath 表达式包含变量(例如//emp[ssn=$e]),并且变量的值是在运行时通过调用作为 API 的一部分提供的 VariableResolver 获得的。JAXP 规范对于可接受的值类型相当宽松,这可能因一种实现而异。

Saxon XPath API (s9api) 更进一步,允许您在编译表达式时显式声明变量及其类型,然后在执行表达式时为变量(任何 XPath 2.0 类型)提供值。

于 2011-07-19T16:47:50.840 回答
1

AFAIK,不。我前段时间研究过,最终使用String.format().

但是,这样一来,您将无法将其编译为参数化的 xpath expr,而这正是我认为您想要的(也是我想要的)。

于 2011-07-19T16:19:08.553 回答