Android XPath.evaluate не распознает узлы, если я не удаляю 1 родительский узел - PullRequest
0 голосов
/ 29 декабря 2011

У меня есть XML-файл следующей структуры:

<?xml version="1.0" encoding="utf-8"?>
<root>
<ArrayOfLocationDTO xmlns:xsi="foo1" xmlns:xsd="foo2" xmlns="foo3">
<LocationDTO ~some data~>~child nodes etc~</LocationDTO>
<LocationDTO ~some data~>~child nodes etc~</LocationDTO>
... ... ...
<LocationDTO ~some data~>~child nodes etc~</LocationDTO>
<LocationDTO ~some data~>~child nodes etc~</LocationDTO>
</ArrayOfLocationDTO>
</root>

Я пытаюсь получить оттуда все «LocationDTO».Мой код выглядит так:

XPath xpath = XPathFactory.newInstance().newXPath();
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setNamespaceAware(true);
DocumentBuilder builder = builderFactory.newDocumentBuilder();
File XMLPath=new File(Environment.getExternalStorageDirectory(), "XMLSource.xml");
Document document = builder.parse(XMLPath);
NodeList nodes = (NodeList) xpath.evaluate("//LocationDTO", document, XPathConstants.NODESET);
int count=nodes.getLength();

Моя проблема в том, что код ничего не находит, если я не удаляю ArrayOfLocationDTO вручную из источника XML.Почему ArrayOfLocationDTO мешает моему коду работать должным образом и как я могу заставить его работать без программного удаления ArrayOfLocationDTO (я считаю последний своего рода «грязным решением»)?

1 Ответ

1 голос
/ 29 декабря 2011

ArrayOfLocationDTO имеет атрибут xmlns = "foo3". Этот атрибут является одним из очень немногих атрибутов XML, которые имеют особое значение: в частности, это означает, что ArrayOfLocationDTO и каждый тег внутри него имеют пространство имен «foo3» (каждый тег XML имеет локальное имя и - необязательно - пространство имен - которое является строка, представленная одним из синтаксисов xmlns).

Это означает, что в вашем документе НЕТ тега с именем «LocationDTO». «LocationDTO» является только локальной частью имени.

У вас есть два варианта:

  • найти теги по их локальным именам, используя функцию local-name: // * [local-name () = 'LocationDTO']; это, безусловно, самое быстрое решение в вашем случае (простой поиск, небольшой документ, единое пространство имен)

  • установить контекст пространства имен (используя, если я правильно помню, setNamespaceContext), который связывает «foo3» с произвольным префиксом (например, «f») и использовать запрос: // f: LocationDTO

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...