Почему нет синтаксиса XPath для узлов, удовлетворяющих пространству имен? - PullRequest
15 голосов
/ 14 августа 2011

Некоторые узлы в документе XML имеют пространства имен, указанные с определенным префиксом.

Можно указать local-name () в XPath 1.0 и игнорировать пространства имен.

Однако я хочу разрешить автору XPath находить узлы, используя в качестве идентификатора их полное имя, определенное в пространстве имен.

Рекомендованным способом является добавление объявлений пространства имен в вызывающий код (в моем случае, Java). Но это означает, что человек, пишущий Xpath, не может работать с пространствами имен!

Как нам найти узлы по их полностью определенным именам, используя чистый XPath?

Ответы [ 4 ]

14 голосов
/ 14 августа 2011

Не уверен, что вы имели в виду под "идентификатором".

Как нам найти узлы по их полностью определенным именам, используя чистый XPath?

В XPath 1.0 с использованием local-name () и namespace-uri () , например,

"*[local-name() = 'foo' and namespace-uri() = 'http://my.org/ns/2.0']"

В XPath 2.0 имеется более богатый набор функций, связанных с пространствами имен, например, namespace-uri-from-QName(). Но я не уверен, что они улучшат вышесказанное для того, что вы хотите.

5 голосов
/ 15 августа 2011

XPath 3.0, который в настоящее время находится в рабочем состоянии черновика, будет включать буквенное выражение для QNames с квалификацией URI , позволяющее напрямую указывать пространство имен uri.

Вот несколько примеровEQNames:

  • pi - это лексическое QName без префикса пространства имен.
  • math: pi - это лексическое QName с префиксом пространства имен.
  • "http://www.w3.org/2005/xpath-functions/math":piопределяет URI пространства имен, используя URILiteral, это не лексическое QName.

Я думаю, что Saxon 9.3 включает в себя реализацию предварительного просмотра xpath 3.0, которую следует использовать черезJava API.

1 голос
/ 14 августа 2011

Вы можете использовать пространства имен во время запросов XPath. В Java вам нужно предоставить реализацию NamespaceContext , если вы также хотите использовать префиксы в этих запросах вместо полностью определенного пространства имен все время. Просто добавьте экземпляр NamespaceContext к вашему XPath - я предполагаю, что вы используете стандартную реализацию JDK - но концепция применима и к Jaxen или другим.

Затем вы можете выполнять такие запросы, как //customns:Element.

Если вы не можете или не можете использовать NamespaceContext (по какой-либо причине), тогда, похоже, единственным решением является использование функций local-name и namespace-uri:

Document doc = ...;
XPath xp = XPathFactory.newInstance().newXPath();
String name = "Element";
String ns = "http://www.custom.org/#";
String expr = "//*[local-name() = '"+name+" and namespace-uri() = '"+ns+"']";
Node node = ((NodeList)xp.evaluate(expr, doc, XPathConstants.NODESET)).item(0);
0 голосов
/ 27 октября 2015

В спецификации для XPath 3.0 написано:

Q{http://www.w3.org/2005/xpath-functions/math}pi

Это работает в данный момент (октябрь 2015 г.), например, в eXist-db.

...