【问题标题】:Sending XPath a variable from Java从 Java 发送 XPath 变量
【发布时间】:2010-07-03 08:44:38
【问题描述】:

我有一个搜索静态值的 XPath 表达式。在这个例子中,“test”就是那个值:

XPathExpression expr = xpath.compile("//doc[contains(., 'test')]/*/text()");

如何传递变量而不是固定字符串?我在 Eclipse 中使用 Java。有没有办法使用 Java String 的值来声明 XPath 变量?

【问题讨论】:

    标签: java xml xpath


    【解决方案1】:

    您可以定义一个变量解析器并让表达式解析变量,例如$myvar,例如:

    XPathExpression expr = xpath.compile("//doc[contains(., $myVar)]/*/text()");

    here 有一个相当好的解释。我之前实际上并没有这样做过,所以我可能会尝试提供一个更完整的示例。


    更新:

    试一试,效果很好。对于一个非常简单的实现示例,您可以定义一个类,该类从映射中返回给定变量的值,如下所示:

    class MapVariableResolver implements XPathVariableResolver {
      // local store of variable name -> variable value mappings
      Map<String, String> variableMappings = new HashMap<String, String>();
    
      // a way of setting new variable mappings 
      public void setVariable(String key, String value)  {
        variableMappings.put(key, value);
      }
    
      // override this method in XPathVariableResolver to 
      // be used during evaluation of the XPath expression      
      @Override
      public Object resolveVariable(QName varName) {
        // if using namespaces, there's more to do here
        String key = varName.getLocalPart();
        return variableMappings.get(key);
      }
    }
    

    现在,在程序中声明并初始化这个解析器的一个实例,例如

    MapVariableResolver vr = new MapVariableResolver() ;
    vr.setVariable("myVar", "text");
    ...
    XPath xpath = factory.newXPath();
    xpath.setXPathVariableResolver(vr);
    

    然后,在计算 XPath 表达式 XPathExpression expr = xpath.compile("//doc[contains(., $myVar)]/*/text()"); 期间,变量 $myVar 将替换为字符串 text

    好问题,我自己学到了一些有用的东西!

    【讨论】:

      【解决方案2】:

      您不需要评估 Java(或 XPath 中的任何其他 PL 变量)。在 C# 中(不太了解 Java)我会使用:

          string XPathExpression = 
      "//doc[contains(., " + myVar.ToString() + ")]/*/text()";
      
          XmlNodelist result = xmlDoc.SelectNodes(XPathExpression);
      

      【讨论】:

      • 与使用真实变量的可能性相比,我发现简单的变量内联有点麻烦。此外,您还必须考虑句法完整性(例如,如果 myVar 包含引号怎么办?等)
      【解决方案3】:

      除了这个 answer here 很好地解释了如何使用标准 Java API 进行操作之外,您还可以使用像 jOOX 这样的第三方库,它可以以简单的方式处理变量:

      List<String> list = $(doc).xpath("//doc[contains(., $1)]/*", "test").texts();
      

      【讨论】:

        【解决方案4】:

        我使用类似于@brabster 的东西:

        // expression: "/message/PINConfiguration/pinValue[../keyReference=$keyReference]";
        
        Optional<Node> getNode(String xpathExpression, Map<String, String> variablesMap)
                throws XPathExpressionException {
            XPath xpath = XPathFactory.newInstance().newXPath();
            xpath.setXPathVariableResolver(qname -> variablesMap.get(qname.getLocalPart()));
            return Optional.ofNullable((Node) xpath.evaluate(xpathExpression, document, 
                    XPathConstants.NODE));
        }
        
        Optional<Node> getNode(String xpathExpression) throws XPathExpressionException {
            return getNode(xpathExpression, Collections.emptyMap());
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-16
          • 2011-09-21
          相关资源
          最近更新 更多