2013-08-06 106 views
0

我必須爲XML解析命名空間中的XML與紅寶石引入nokogiri

<Environment 
    Name="test" 
    xmlns="http://schemas.dmtf.org/ovf/environment/1" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:oe="http://schemas.dmtf.org/ovf/environment/1" 
    oe:id="123456789"> 
    <PropertySection> 
     <Property oe:key="mykey" oe:value="test"/> 
    </PropertySection> 
</Environment> 

我使用Ruby和引入nokogiri解析文檔的第二位。即

file = File.open('/tmp/myxml.xml') 
doc = Nokogiri::XML(file) 

env = doc.at('Environment') 
id = env['id'] 
printf("ID [%s]\n", id) 
properties = env.at('PropertySection') 

這個工程併成功地打印了xml中的id。 我現在想用'mykey'鍵訪問Property屬性。我嘗試了以下方法:

value = properties.at('Property[@key="mykey"]')['value'] 
printf("Value %s\n", value) 

不幸的是,properties.at方法返回一個零對象。我嘗試修改xml本身以從屬性'key'中刪除'oe'命名空間。重新運行我的腳本它的作品。

如何讓nokogiri在調用.at()時識別命名空間?

回答

1

您應該使用Nokogiri命名空間語法:http://nokogiri.org/tutorials/searching_a_xml_html_document.html#namespaces

首先,確保你有命名空間,你可以使用:

ns = { 
    'xmlns' => 'http://schemas.dmtf.org/ovf/environment/1', 
    'oe' => 'http://schemas.dmtf.org/ovf/environment/1' 
} 

(我定義這兩個,即使他們是在這個例子一樣)。您也可以考慮使用doc.collect_namespaces中已有的命名空間。

然後,你可以這樣做:

value = properties.at('./xmlns:Property[@oe:key="mykey"]/@oe:value', ns).content 

請注意,我用的./這裏,因爲,對於這個特定的搜索,引入nokogiri解釋的XPath因爲沒有它的CSS。您不妨使用.//

+0

謝謝,這工作。我曾嘗試'@oe:key =「mykey」,但它沒有起作用,但指定了otter標籤的名稱空間和其他屬性。 – Dave