如何获取标识Java中节点的XPath表达式?

时间:2014-05-29 13:37:48

标签: java xml dom xpath

我有一个XML文档,其结构如下:

<root>
    <a>
        <bd>
            <cd>
                <aa/>
                <bb/>
                <aa/>
            </cd>
        </bd>
    </a>
    <a>
        <bd>
            <cd>
                <aa/>
                <bb/>
                <aa/>
            </cd>
        </bd>
    </a>
    <tt>
        <at/>
        <bt/>
    </tt>
</root>

我正在使用递归函数,它将节点对象作为参数。我想在索引的XPath表达式中获取每个节点的xpath,如root/a[1]/bd[0]/aa[2]。我正在使用DOM解析器并从另一个递归函数调用此函数。

private static String getXPath(Node test_tempNode) {
    if (test_tempNode == null
            || test_tempNode.getNodeType() != Node.ELEMENT_NODE) {
        return "";
    }

    return getXPath(test_tempNode.getParentNode()) + "/"
            + test_tempNode.getNodeName();
}

2 个答案:

答案 0 :(得分:1)

您的代码似乎有效但除了它没有添加索引;所以我想你要做的就是在父子列表中搜索当前节点的位置并将其添加到xpath

private static String getXPath(Node test_tempNode) {
    if (test_tempNode == null
            || test_tempNode.getNodeType() != Node.ELEMENT_NODE) {
        return "";
    }

    //find index of the test_tempNode node in parent "list"
    Node parent = test_tempNode.getParentNode();
    NodeList childNodes = parent.getChildNodes();
    int index = 0;
    int found = 0;
    for (int i = 0; i < childNodes.getLength(); i++) {
        Node current = childNodes.item(i);
        if (current.getNodeName().equals(test_tempNode.getNodeName())) {
            if (current == test_tempNode) {
                found = index;
            }
            index++;
        }
    }

    String strIdx = "[" + found + "]";
    if(index == 1){
        strIdx = "";
    }
    return getXPath(test_tempNode.getParentNode()) + "/"
            + test_tempNode.getNodeName() + strIdx;
}

答案 1 :(得分:0)

这应该打印出每个节点的唯一路径,并根据需要添加索引。

private void printXPaths(Node node, OutputStream stream, String current, Map<String, int> occurences)
{
    if (node.getNodeType() != Node.ELEMENT_NODE) {
        return;
    }
    String nodePath = current + "/" + node.getNodeName();
    if(occurences.contains(nodePath)) {
        int occurrencesCount = occurences[nodePath];
        nodePath += "[" + occurrencesCount + "]";
        occurences[nodePath] = occurrencesCount + 1;
    } else {
        occurences[nodePath] = 1;
    }

    stream.println(nodePath);
    NodeList children = node.getChildNodes();
    for(int i=0; i<children.getLength(); i++) {
        printXPaths(children.item(i), stream, nodePath, occurences);
    }
}

public void printXPaths(Document doc, OutputStream stream) {
    printXPaths(doc.getDocumentElement(), stream, "", new HashMap<String, int>());
}

这样,第一个指示将显示/ root / tag,而第二个指示将显示/ root / tag [1],依此类推。 希望有所帮助。