2013-02-25 87 views
2

嘗試循環部分XML文件時出現問題。我正在使用Nokogiri和Rails3。在Rails 3中使用Nokogiri讀取XML文件

我讀這個XML飼料 - http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml

這裏是我的代碼:

def save_rates 

    # get the XML data form ECB URL 
    file_handle = open('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml') 

    # get document xml string and create Nokogiri object 
    doc = Nokogiri::XML(file_handle) 

    # foreach date... 
    doc.xpath("//Cube/Cube").each do |cube| 

     raise cube.inspect # isn't being executed 

     # foreach currency... 
     cube.xpath("./Cube").each do |curr| 
      # create DB entry 
      Exchange.create(:currency=>curr.currency, :rate=>curr.rate, :record_date => cube.time) 

     end 
    end 

end 

當我檢查doc我可以看到引入nokogiri對象。但是,當我嘗試在第一個.each循環內部提升cube.inspect時,它只是沒有開火。所以這讓我相信我的路線是錯誤的://Cube/Cube

從我在Nokogiri教程中看到的其他例子,路徑與此類似。我的路徑錯了還是有其他事情我在這裏做錯了?

我是紅寶石n00b所以請容易!

UPDATE

這裏是XML

<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"> 
    <gesmes:subject>Reference rates</gesmes:subject> 
    <gesmes:Sender> 
    <gesmes:name>European Central Bank</gesmes:name> 
    </gesmes:Sender> 
    <Cube> 
     <Cube time="2013-02-25"> 
      <Cube currency="USD" rate="1.3304"/> 
      <Cube currency="JPY" rate="125"/> 
      <Cube currency="BGN" rate="1.9558"/> 
      <Cube currency="CZK" rate="25.52"/> 
      <Cube currency="DKK" rate="7.4614"/> 
      <Cube currency="GBP" rate="0.8789"/> 
      ... 
     </Cube> 
     <Cube> 
     <Cube time="2013-02-24"> 
      <Cube currency="USD" rate="1.3304"/> 
      <Cube currency="JPY" rate="125"/> 
      <Cube currency="BGN" rate="1.9558"/> 
      <Cube currency="CZK" rate="25.52"/> 
      <Cube currency="DKK" rate="7.4614"/> 
      <Cube currency="GBP" rate="0.8789"/> 
      ... 
     </Cube> 
    </Cube> 
</gesmes:Envelope> 
+0

請包含您正在嘗試閱讀的XML片段。把URL放在你的代碼中是可以的,但是如果/當這個鏈接打破你的問題時,對於尋找同樣問題的其他人來說,沒有什麼意義,或者是有價值的。 – 2013-02-25 14:14:23

+0

我已經包含xml結構 – iamjonesy 2013-02-25 14:19:07

回答

4

的格式,這裏的問題是由於XML namespaces

在XML的根屬性中有xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"屬性,它指定了默認名稱空間。 Cube元素位於此命名空間中,如果您僅使用Cube而不指定命名空間,則不會獲得匹配。

指定的命名空間中引入nokogiri你可以做這樣的事情:

doc.xpath("//ecb:Cube/ecb:Cube", 'ecb' => "http://www.ecb.int/vocabulary/2002-08-01/eurofxref") 

這裏我們給出的命名空間前綴ecb,並在XPath表達式中使用的前綴。

在這種情況下,在命名空間是根節點上聲明默認的命名空間,引入nokogiri將宣佈它的xmlns前綴對我們,所以我們可以使用更簡單:

doc.xpath("//xmlns:Cube/xmlns:Cube") 

這將導致在與第一個相同的東西。

一個更簡單的可能性,如果你在命名空間不感興趣,是使用remove_namespaces! method

doc.remove_namespaces! 
doc.xpath("//Cube/Cube") 

這樣做的結果是不太一樣的,因爲命名空間中的前兩個例子信息已被刪除,但它會給你所期望的節點。

+0

非常感謝@matt。很好的解釋。我用了doc.remove_namespaces!這很好。 – iamjonesy 2013-02-25 15:26:05

+0

謝謝,remove_namespaces也幫助我,完全一樣的問題:]關心 – mArtinko5MB 2013-10-22 13:15:52