2009-02-09 4 views
20

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

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

<?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 будет возвращать результат в-атрибут, а не за элемент

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

EDIT: Мне дал следующий ответ Димитрия Новачева. Я не понимаю, что вы можете вложить предикаты внутри предикаты как это:

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

В частности, это говорит «Любой элемент, который имеет какой-либо атрибут, который имеет пространство имен URI =„...“»

+0

Вы забыли добавить пространство имен для doodah? Потому что я не вижу, как это можно выбрать через пространство имен. – potyl

+0

Если пояснения не были ясны, я использовал неправильное пространство имен в моем исходном примере. Виноват. – Gareth

+1

Спасибо за этот пост, это действительно помогло. Подводя итог: - Для того, чтобы получить элементы с атрибутами из заданного пространства имен: '// * [@ * [имен-URI() = 'HTTP: //foo.example.com']]' - Получить атрибуты из заданного пространства имен: '// @ * [namespace-uri() = 'http: //foo.example.com']' –

ответ

24

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

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

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

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

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

или

  • имеет атрибуты, которые принадлежат к указанной пространство имен
+0

Это была только вторая половина того, что мне было нужно :) Я не знал, что вы можете вложить предикаты в предикаты. Соответственно обновили мое сообщение – Gareth

+0

@Dimitre Novatchev вы могли бы посмотреть здесь, это проблема с пространством имен? tnx http://stackoverflow.com/questions/7007767/iphone-sdk-xml-mystery-after-adding-child-nodeforxpath-returns-nothing – Spring

4

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

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

не соответствует attrubutes в этом пространстве имен –

0

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

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

Это даст вам элемент Foo: бар и элемент штуковину (если вы измените 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> 

является то, что вы хотите?

EDIT: Благодарим за обнаружение ошибки атрибута.

+0

Не совсем так ... namespace-uri (./@*) = 'http: //foo.example.com'] возвращает true, только если первый атрибут (который зависит от реализации!) принадлежит этому пространству имен. Исходное сообщение хочет, чтобы элемент был выбран, если * любой * его атрибутов принадлежит пространству имен –

+0

Упс, хорошее место с талом, которое я там оставил по ошибке – Gareth

0

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

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

Вы не поняли вопрос. OP хочет, чтобы какой-либо элемент был выбран, который либо принадлежит пространству имен, либо имеет хотя бы один атрибут, принадлежащий пространству имен. Ваше выражение не выбирает элемент с атрибутами в пространстве имен, но элемент не принадлежит пространству имен. –

+0

Спасибо за разъяснение. Я знаю, что я не понял этого вопроса, поскольку добавил комментарий к вопросу о том, почему следует выбирать «doodah». – potyl

Смежные вопросы