Как я могу получить выражение XPath, которое идентифицирует узел в Java?

1

У меня есть 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();
}
  • 0
    Для меня это не похоже на XML - предположительно, теги типа <root/> должны быть </root> . Пожалуйста, отредактируйте вопрос и исправьте XML, чтобы он был правильно сформирован.
Теги:
xpath
dom

2 ответа

0
Лучший ответ

Ваш код, похоже, работает, за исключением того, что он не добавляет индекс; Поэтому я предполагаю, что все, что вам нужно сделать, - это найти позицию текущего узла в родительском дочернем списке и добавить его в 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;
}
  • 0
    Но это также добавит индекс к тем узлам, которые не повторяются .... Мы должны добавить индекс только к тем узлам, которые повторяются. Спасибо за помощь, я пытаюсь изменить его, и, пожалуйста, держите меня в курсе, если вы получили его первым .. Еще раз спасибо
  • 0
    @ user3494200 сделано: D
Показать ещё 2 комментария
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] и так далее. Надеюсь, это поможет.

  • 0
    Я не могу получить индекс в xpath этим .. не работает в моем сценарии. выходные данные должны быть похожи на root / a [1] / bd [1] / aa [2] для каждого индекса узла, если он повторяется. Спасибо
  • 0
    @ user3494200 Смотрите мой обновленный ответ.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню