23

我正在使用 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

我需要做一些额外的事情来解释命名空间声明吗?这种解决方法感觉非常像黑客。

4

2 回答 2

32

该 XPath 查询查找不在任何名称空间中的元素。http://sdb.amazonaws.com/doc/2007-11-07/您需要告诉 XPath 处理器您正在名称空间中寻找元素。

使用 Nokogiri 的一种方法是:

doc = Nokogiri::XML.parse(...)
doc.xpath("//aws:Item/aws:Attribute[Name='Foo']/aws:Value", {"aws" => "http://sdb.amazonaws.com/doc/2007-11-07/"})
于 2009-11-15T14:04:39.387 回答
20

我发现“ XML 中的命名空间”对于理解正在发生的事情非常有帮助。

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

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

  • xmlns从根中删除属性SearchResponse。在这种情况下,您原来的、无命名空间的 XPath 查询将起作用。

  • 在 XPath 查询中使用默认命名空间:

    doc/"//xmlns:Item/xmlns:Attribute[xmlns:Name='Foo']/xmlns:Value"
    
  • 在方法的第二个参数中定义自定义命名空间xpath并在查询中使用它,如上面 hrnt 的解决方案所示。

于 2010-05-10T17:36:27.677 回答