2014-05-11 88 views
0

下面是一個例子文件:如何使用nokogiri遍歷XML文件層次結構?

<?xml version="1.0" encoding="UTF-8"?> 
<response status="success"> 
    <campaigns> 
     <campaign> 
     <campaign_id>41381</campaign_id> 
     <campaign_name><![CDATA[campaign1]]></campaign_name> 
     <campaign_status>1</campaign_status> 
     <campaign_type>STANDARD</campaign_type> 
     <campaign_notes /> 
     <campaign_rate /> 
     <campaign_owner_id>33975</campaign_owner_id> 
     <campaign_start_date>11-05-2014</campaign_start_date> 
     <campaign_end_date>12-12-2020</campaign_end_date> 
     <creation_date>11-05-2014</creation_date> 
     <daily_budget>10.000</daily_budget> 
     <daily_budget_left>10.000000000000000000000000000000</daily_budget_left> 
     <total_budget>X</total_budget> 
     <total_budget_left>1000000.000000000000000000000000000000</total_budget_left> 
     <reporting> 
      <impressions /> 
      <clicks /> 
      <total_cost> 
       <currency>USD</currency> 
       <amount /> 
      </total_cost> 
      <average_cpc> 
       <currency>USD</currency> 
       <amount>0</amount> 
      </average_cpc> 
      <conversions /> 
      <cost_per_conversion> 
       <currency>USD</currency> 
       <amount>n/a</amount> 
      </cost_per_conversion> 
     </reporting> 
     </campaign> 
    </campaigns> 
</response> 

我想要做的就是通過每一個活動,並通過數據分析內存中的對象產生。例如,我想創建基於每個campaign的紅寶石對象。我希望能夠像campaigns.each {|campaign| puts impressions = campaign['reporting']['impressions']}

+0

xpath方法將是一個好的開始。 –

+0

rtfm? http://nokogiri.org/ – phoet

回答

1

下面是您的需求描述在您的文章中的一些代碼。它僅適用於Hash,如XML結構,例如示例數據中的campaign節點。如果您想要Array類似的行爲,您可能需要明確處理它們,就像我爲campaigns節點所做的那樣。

require 'nokogiri' 

def parse(element) 
    children = element.children.reject{|e| e.is_a?(Nokogiri::XML::Text) && e.text =~ /^\s*$/} 

    if children.count == 1 && children[0].is_a?(Nokogiri::XML::Text) 
    children[0].text 
    else 
    data = Hash.new 
    children.each do |child| 
     data[child.name] = parse(child) 
    end 
    data 
    end 
end 

doc = Nokogiri::XML(open('data.xml')) # suppose the xml is stored in data.xml 

campaigns = doc.xpath('/response/campaigns/campaign').map{|c| parse(c)} 
p campaigns