首页 文章

如何将变量参数传递给XPath表达式?

提问于
浏览
2

我想将参数传递给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 但它没有用 .

2 回答

  • 4

    鉴于您正在使用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
    
  • 4

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

    In XSLT:

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

    请注意,与上述方法不同,下面的三个方法对XPath injection attacks开放,绝不应与不受控制或不受信任的输入一起使用;为避免这种情况,请使用您的语言或库提供的机制在带外传递变量 . [ Credit :Charles Duffy]

    In C#:

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

    In Java:

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

    In Python:

    "//a/b/c[x={}]".format(myParamForXAttribute)
    

相关问题