2009-11-15 92 views
23

我正在使用Nokogiri :: XML來解析來自Amazon SimpleDB的響應。響應是一樣的東西:爲什麼Nokogiri xpath不像xmlns聲明

<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")返回一個空數組。但是,如果我從SelectResponse標記中刪除xmlns屬性,則它完美地起作用。

是否有一些額外的事情我需要做的帳戶名稱空間聲明?這種解決方法非常像黑客攻擊。

回答

32

XPath查詢查找不在任何名稱空間中的元素。你需要告訴你的XPath處理器,你正在尋找在命名空間中的元素做,與引入nokogiri是這個http://sdb.amazonaws.com/doc/2007-11-07/

方式一:

doc = Nokogiri::XML.parse(...) 
doc.xpath("//aws:Item/aws:Attribute[Name='Foo']/aws:Value", {"aws" => "http://sdb.amazonaws.com/doc/2007-11-07/"}) 
+0

這是固定的。謝謝。 – 2009-11-15 15:45:08

+8

只需提供像「doc.xpath('// xmlns:Item ...」這樣的「** xmlns:**」即可。 – user569825 2013-03-19 14:49:40

20

我發現這確實有助於理解這是怎麼回事: 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的解決方案上面
+4

有一個'remove_namespaces!'方法[http:// nokogiri .org/Nokogiri/XML/Document.html#method-i-remove_namespaces%21)。 – RobinGower 2011-10-04 22:17:45

+1

@RobinGower是的,它說'有關爲什麼這可能不是一件好事情的更多信息,請將瀏覽器指向' [tenderlovemaking.com/2009/04/23/namespaces-in-xml/](http://tenderlovemaking.com/2009/04/23/namespaces-in-xml) – nurettin 2012-07-16 12:14:54

+0

評論中的兩個鏈接都已過時。 [remove_namespaces!]的更新文檔鏈接(http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Document:remove_namespaces!) – Jason 2015-07-29 17:38:06