我正在使用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
属性,则效果非常好。
为了解释名称空间声明,我还需要做些什么吗?这种解决方法感觉非常像黑客。
答案 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查询将起作用。doc/"//xmlns:Item/xmlns:Attribute[xmlns:Name='Foo']/xmlns:Value"
xpath
方法调用的第二个参数中定义自定义命名空间,并在查询中使用该命名空间,如上面的hrnt解决方案所示