Xpath возвращает значение из неверного узла - PullRequest
0 голосов
/ 08 июня 2011

У меня проблемы с XPath. По какой-то неизвестной причине результат, который я получаю из своего выражения, - результат другого запуска функции.

Вот конструктор моего класса:

Wine(Node ndWine){
    try{
     xpath = XPathFactory.newInstance().newXPath();
    }
    catch(Exception e)
    {}

    Node ndName = null;

    try{
        ndName = (Node)xpath.evaluate("//name", ndWine, XPathConstants.NODE);
    }
    catch(Exception e)
    {}
    if (ndName != null)
        name = ndName.getTextContent();
}

А вот и XML:

<cellar>
  <wine>
    <name>Jasnières</name>
  </wine>
  <wine>
    <name>Ballet d'Octobre</name>
  </wine>
</cellar>

В вызывающем методе у меня есть другое выражение xpath, которое разбивает документ на список <wine> элементов. Приведенный выше код вызывается для каждого узла.
В отладчике я проверяю, что при втором запуске узел ndWine фактически содержит данные из второго узла документа, но оценка всегда возвращает значение Jasnieres вместо ballet d'octobre, которое я не могу понять.

Есть идеи о коренной причине?

Ответы [ 2 ]

3 голосов
/ 08 июня 2011

Запуск выражения XPath с // делает его абсолютным путем. Даже если вы передаете элемент <wine>, он игнорирует его и начинается с корня документа. Добавьте . впереди, чтобы сделать его относительным путем:

.//name

Или, что еще лучше, избегайте синтаксиса //, если можете. Лучше избегать полного поиска descendant-or-self, если вы точно знаете, где будут находиться элементы <name>. Если они всегда будут непосредственно внутри элемента <wine>, используйте этот XPath:

name
0 голосов
/ 08 июня 2011

Попробуйте этот кусок кода

try {                
     expr = xpath.compile("/cellar/wine/name");
     nodeList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
} catch (XPathExpressionException ignored) {}

for (int i = 0; i < nodeList.getLength(); i++) {
        Node node = nodeList.item(i);
        if (node != null) {
            NodeList childNodes = node.getChildNodes();
            for (int j = 0; j < childNodes.getLength(); j++) {
                Node childNode = childNodes.item(j);
                if (childNode.getNodeType() == Node.TEXT_NODE) {
                    System.out.println(childNode.getNodeValue());
                }
            }
        }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...