XPath - поиск элементов по пространству имен атрибута - PullRequest
20 голосов
/ 09 февраля 2009

Я пытаюсь использовать XPath, чтобы найти все элементы, у которых есть элемент в данном пространстве имен.

Например, в следующем документе я хочу найти элементы foo: bar и doodah

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:foo="http://foo.example.com">
  <foo:bar quux="value">Content</foo:bar>
  <widget>Content</widget>
  <doodah foo:quux="value">Content</doodah>
</root>

Я знаю, что могу использовать следующее выражение XPath для загрузки всех атрибутов из заданного пространства имен

"//@*[namespace-uri()='http://foo.example.com']"

Тем не менее:

  • Это не дает мне элементы, только атрибуты и
  • где элементы содержат несколько атрибутов из этого пространства имен, этот XPath будет возвращать результат для каждого атрибута, а не для каждого элемента

Можно ли получить то, что я хочу, или мне просто нужно собрать атрибуты и вычислить уникальный набор элементов, которым они соответствуют?

РЕДАКТИРОВАТЬ: Димитр Новатчев дал мне следующий ответ. Я не осознавал, что вы можете вкладывать предикаты внутри предикатов, например:

"//*[@*[namespace-uri()='http://foo.example.com']]"

В частности это говорит "Любой элемент, который имеет любой атрибут, который имеет namespace-uri = '...'"

Ответы [ 4 ]

25 голосов
/ 09 февраля 2009

Использование:

  //*[namespace-uri()='yourNamespaceURI-here'
     or
      @*[namespace-uri()='yourNamespaceURI-here']
     ]

предикат два условия определяются оператором XPath or.

Таким образом, выражение XPath выбирает любой элемент, который либо :

  • принадлежит указанному пространству имен

или

  • имеет атрибуты, которые принадлежат указанному пространству имен
4 голосов
/ 09 февраля 2009

Не уверен, что это именно то, что вы имеете в виду, но, удалив только 1 символ в вашем XPath, вы получите все элементы в определенном пространстве имен:

//*[namespace-uri()='http://foo.example.com']
0 голосов
/ 09 февраля 2009

Ваше выражение XPath почти идеально. Вместо запроса атрибутов "@ " запросите элементы "", и оно должно работать:

"//*[namespace-uri()='http://foo.example.com']"
0 голосов
/ 09 февраля 2009

Вы можете попробовать

//*[namespace-uri()='http://foo.example.com' or @*[namespace-uri()='http://foo.example.com']]

Это даст вам элемент foo: bar и element doodah (если вы измените tal:quux на foo:quux в ваших XML-данных):

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:foo="http://foo.example.com" xmlns:tal="xxx">
  <foo:bar quux="value">Content</foo:bar>
  <widget>Content</widget>
  <doodah foo:quux="value">Content</doodah>
</root>

это то, что вы хотите?

РЕДАКТИРОВАТЬ : Спасибо за обнаружение ошибки атрибута, исправленной сейчас.

...