Подтвердить что ты не робот

Почему 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, он отлично работает.

Есть ли какая-то дополнительная вещь, которую мне нужно сделать, чтобы учесть объявление пространства имен? Это обходное решение кажется ужасным, как хак.

4b9b3361

Ответ 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-решении выше