Java 从通用xpath获取精确的xpath

Java 从通用xpath获取精确的xpath,java,xml,xpath,Java,Xml,Xpath,我需要做两件事 验证XML文件中节点的值 如果值对应,我需要更改它 我已经有了一个复杂的对象层次结构来完成这项工作。现在我面临一个有问题的案子。让我们看一个例子: <staticTag> <randomTag> <anotherRandomTag> <staticTag property="id"> <staticTag> VALUE </staticTag>

我需要做两件事

  • 验证XML文件中节点的值

  • 如果值对应,我需要更改它

    我已经有了一个复杂的对象层次结构来完成这项工作。现在我面临一个有问题的案子。让我们看一个例子:

    <staticTag>
      <randomTag>
        <anotherRandomTag>  
          <staticTag property="id">
             <staticTag> VALUE </staticTag>
          </staticTag>  
        </anotherRandomTag>  
      </randomTag>  
    </staticTag>
    
    是的,它将返回我需要验证的所有值。问题是,如果值与我要查找的值相对应,我没有精确的xpath来更改该值

    如有必要,我可以发布代码示例。So tl;dr:有没有一种方法可以从通用的xpath生成精确的xpath?像往常一样,谢谢你抽出时间

    我还做了一些测试这里有一个虚拟xml

    <tag>
       <ZDSJG>
          <SJROT>X66P1</SJROT>
       </ZDSJG>
       <DNLVZ>
          <SJROT>VV1EZ</SJROT>
       </DNLVZ>
    </tag>
    
    另一个编辑:我修复了我的代码,我不得不使用
    NODESET
    而不是
    NODE

    不会尝试生成正确的Xpath,因为我没有找到任何可以从节点生成Xpath的内容。我自己做的。这是非常基本的,可以在很多方面进行改进。但目前它符合我的需要。如果有人有更好的解决办法,我会欣然接受。下面是我的java代码:请随意改进

        public List<String> generateAbsoluteXpath(File fileToRead, String expressionXPath) throws Exception {
        DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
        Document document = documentFactory.newDocumentBuilder().parse(fileToRead);
    
        XPathFactory xpathFactory = XPathFactory.newInstance();
        XPath xpath = xpathFactory.newXPath();
    
        XPathExpression expression = xpath.compile(expressionXPath);
        NodeList result = (NodeList) expression.evaluate(document, XPathConstants.NODESET);
    
        List<String> generatedXpath = Lists.newArrayList();
        for (int i = 0; i < result.getLength(); i++) {
            generatedXpath.add(getXPath(result.item(i)));
        }
        return generatedXpath;
    }
    
    
    
    public String getXPath(Node node)
    {
        Node parent = node.getParentNode();
        if (parent == null || parent.getNodeName().equals("#document")) {
            return "/" + node.getNodeName();
        }
        return getXPath(parent) + "/" + node.getNodeName();
    }
    
    public List generateabSolutionExpath(文件fileToRead,字符串表达式XPath)引发异常{
    DocumentBuilderFactory documentFactory=DocumentBuilderFactory.newInstance();
    Document Document=documentFactory.newDocumentBuilder().parse(fileToRead);
    XPathFactory XPathFactory=XPathFactory.newInstance();
    XPath=xpathFactory.newXPath();
    XPathExpression expression=xpath.compile(expressionXPath);
    NodeList result=(NodeList)expression.evaluate(文档,XPathConstants.NODESET);
    List generatedXpath=Lists.newArrayList();
    for(int i=0;i

    所以基本上,我输入一个XPath,它将生成多个节点。它返回引用使用常规路径找到的节点的绝对xpath列表。因为我有绝对xpath,所以我正在使用的另一个对象现在可以读取/替换该值。问题已解决。

    为什么不使用
    “staticTag[@property='id']”
    ,而不使用前导的
    /
    ?——您最上面的标记将不匹配,因为它没有该属性。我有此模式N次。在同一个XML文件中。我不需要改变所有这些N实例。只要该值与内存中的另一个值匹配即可。我想您需要使用属性捕捉中间的
    (我假设没有其他节点使用
    property=“id”
    属性)——您可以这样做吗?我们没有关于您的XML的信息。我已经用另一个示例和一些代码片段更新了这个问题。我希望我正在努力实现的目标现在看起来更加清晰。
        XPathExpression expression = xpath.compile(expressionXPath);
    
        NodeList result = (NodeList) expression.evaluate(document, XPathConstants.NODE);
    
        List<String> generatedXpath = Lists.newArrayList();
        for (int i = 0; i < result.getLength(); i++) {
            generatedXpath.add(getXPath(result.item(i)));
        }
        return generatedXpath;
    
        public List<String> generateAbsoluteXpath(File fileToRead, String expressionXPath) throws Exception {
        DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
        Document document = documentFactory.newDocumentBuilder().parse(fileToRead);
    
        XPathFactory xpathFactory = XPathFactory.newInstance();
        XPath xpath = xpathFactory.newXPath();
    
        XPathExpression expression = xpath.compile(expressionXPath);
        NodeList result = (NodeList) expression.evaluate(document, XPathConstants.NODESET);
    
        List<String> generatedXpath = Lists.newArrayList();
        for (int i = 0; i < result.getLength(); i++) {
            generatedXpath.add(getXPath(result.item(i)));
        }
        return generatedXpath;
    }
    
    
    
    public String getXPath(Node node)
    {
        Node parent = node.getParentNode();
        if (parent == null || parent.getNodeName().equals("#document")) {
            return "/" + node.getNodeName();
        }
        return getXPath(parent) + "/" + node.getNodeName();
    }