Предположим, у меня есть документ XML с двумя объявлениями пространства имен с префиксом foo
, например:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:foo="http://www.foo.com">
<one>
<!-- children nodes here -->
</one>
<two>
<!-- children nodes here -->
</two>
<three xmlns:foo="http://www.foo.com">
<!-- children nodes here -->
</three>
</root>
Я хотел бы оценить выражение XPath (в Java), которое возвращало бы NodeList элементов, которые имеют это объявление пространства имен, а именно узлов root
и three
. Я не ищу все узлы, где это пространство имен находится в области видимости, только те узлы, у которых есть объявление пространства имен.
Вот Java, который я планирую использовать:
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
XPathExpression xPathExpression = null;
NodeList nodeList = null;
boolean theExpressionWasCompiled = true;
xPathExpression = xPath.compile(xPathStatement); // XPath goes here!
nodeList = (NodeList) xPathExpression.evaluate(document, XPathConstants.NODESET);
Какой XPath мне следует использовать (значение xPathStatement
для метода compile()
)?
Редактировать: XPath 1 или 2 ok.
Окончательное редактирование. Получается, что XPath не может делать именно то, что я хочу (см. Объяснение Димитра ниже, если вам нужны подробности). Лучшее, что я мог сделать, - это оценить XPath несколько раз (по одному разу на объявление пространства имен), чтобы найти каждый элемент с объявлением пространства имен. Я уже знал, сколько раз каждое пространство имен объявляется, поэтому знание того, сколько раз оценивать, не было для меня проблемой. Не супер эффективно, но это работает. Вот XPath, который я использовал, который очень похож на тот, который придумал Димитр (см. Ниже):
//*[namespace::*[local-name() = 'foo']]
[not
(parent::node()
[namespace::*
[local-name() = 'foo']
]
)
]
Благодарю моего друга, Роджера Костелло, за создание XPath, который я использовал.