是否可以参数化编译的Java XPath表达式ala PreparedStatement样式语义?

时间:2011-07-19 15:09:47

标签: java xpath parameterization

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

我想知道是否有一个API允许开发人员在编译的xpath中设置占位符并在运行时替换这些值。

对此是否有可能以及是否存在警告,陷阱或只是简单的“不做那种”类型建议的任何见解将不胜感激。

(注意我纠正了“穿越溪流”......正在与同事就xpath和正则表达进行对话......恰好是因为精神上的舌头被束缚了...抱歉混淆了)

3 个答案:

答案 0 :(得分:10)

这是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

答案 1 :(得分:4)

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

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

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

答案 2 :(得分:1)

AFAIK,没有。我前段时间研究过,最后使用String.format()

但是,这样你就无法将它编译为参数化的xpath expr,这就是我认为你想要的(以及我想要的)。