Почему Nokogiri xpath не является объявлением xmlns
Я использую Nokogiri:: XML для анализа ответов от Amazon SimpleDB. Ответ такой:
<SelectResponse xmlns="http://sdb.amazonaws.com/doc/2007-11-07/">
<SelectResult>
<Item>
<Attribute><Name>Foo</Name><Value>42</Value></Attribute>
<Attribute><Name>Bar</Name><Value>XYZ</Value></Attribute>
</Item>
</SelectResult>
</SelectResponse>
Если я передам ответ прямо Nokogiri, все запросы XPath (например, doc/"//Item/Attribute[Name='Foo']/Value"
) возвращают пустой массив. Но если я удалю атрибут xmlns
из тега SelectResponse
, он отлично работает.
Есть ли какая-то дополнительная вещь, которую мне нужно сделать, чтобы учесть объявление пространства имен? Это обходное решение кажется ужасным, как хак.
Ответы
Ответ 1
Этот запрос XPath ищет элементы, которые не находятся в каком-либо пространстве имен. Вам нужно сообщить процессору XPath, что вы ищете элементы в пространстве имен http://sdb.amazonaws.com/doc/2007-11-07/
Один из способов сделать это с помощью nokogiri:
doc = Nokogiri::XML.parse(...)
doc.xpath("//aws:Item/aws:Attribute[Name='Foo']/aws:Value", {"aws" => "http://sdb.amazonaws.com/doc/2007-11-07/"})
Ответ 2
Я нашел это очень полезным в понимании того, что происходит:
http://tenderlovemaking.com/2009/04/23/namespaces-in-xml.html
В принципе, если у вас есть пространство имен, определенное вообще (через xmlns=
), вы должны использовать пространство имен в ваших поисках xpath.
Итак, в вашем случае вы можете сделать одну из трех вещей:
- Удалите атрибут xmlns из корня
SearchResponse
. В этом случае ваш исходный запрос xpath без пространства имен будет работать.
- Используйте пространство имен по умолчанию в запросе xpath
doc/"//xmlns:Item/xmlns:Attribute[xmlns:Name='Foo']/xmlns:Value"
- Определите собственное пространство имен во втором аргументе метода метода
xpath
и используйте его в своем запросе, как показано в hrnt-решении выше