为什么Nokogiri xpath不像xmlns声明

时间:2009-11-15 13:50:33

标签: ruby xpath nokogiri xml-namespaces

我正在使用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属性,则效果非常好。

为了解释名称空间声明,我还需要做些什么吗?这种解决方法感觉非常像黑客。

2 个答案:

答案 0 :(得分:32)

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/"})

答案 1 :(得分:20)

我发现这对了解正在发生的事情非常有帮助: http://tenderlovemaking.com/2009/04/23/namespaces-in-xml.html

基本上,如果您完全定义了命名空间(通过xmlns=),则必须在xpath搜索中使用命名空间。

所以在你的情况下,你可以做以下三件事之一:

  • 从根SearchResponse中删除xmlns属性。在这种情况下,您的原始无名称空间的xpath查询将起作用。
  • 在xpath查询doc/"//xmlns:Item/xmlns:Attribute[xmlns:Name='Foo']/xmlns:Value"
  • 中使用默认命名空间
  • xpath方法调用的第二个参数中定义自定义命名空间,并在查询中使用该命名空间,如上面的hrnt解决方案所示