如何在Nokogiri中的XPath中使用xmlns声明

问题描述 投票:23回答:2

我正在使用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属性,则它可以正常工作。

我需要做一些额外的事情来说明名称空间声明吗?这种解决方法感觉就像骇客一样。

ruby xpath nokogiri xml-namespaces
2个回答
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/"})


20
投票
[我发现“ Namespaces in XML”确实有助于理解正在发生的事情。

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

因此,您可以做以下三件事之一:

  • 从根xmlns中删除SearchResponse属性。在这种情况下,您可以使用原始的无名称空间的XPath查询。
  • 在XPath查询中使用默认名称空间:

    doc/"//xmlns:Item/xmlns:Attribute[xmlns:Name='Foo']/xmlns:Value"

  • xpath方法的第二个参数中定义一个自定义名称空间,并在查询中使用它,如上述hrnt的解决方案所示。
  • © www.soinside.com 2019 - 2024. All rights reserved.