2015-03-07 3 views
1

У меня возникли проблемы с корректным просмотром данных xml. Вот мой код в контроллере и просмотр.Как правильно разобрать и просмотреть с помощью nokogiri?

def new 
    doc = Nokogiri::XML(open('sample3.xml')) 

    @link = doc.xpath('//match').map do |t| { 
     'home' => t.at('home').attr('name') 
    } 
    end 

    @odds = doc.xpath('//odds/type[@name="1x2"]/bookmaker[@id="781"]').map do |t| { 
     '1' => t.at('odd[@name="1"]').attr('value'), 
     '2' => t.at('odd[@name="2"]').attr('value'), 
     'X' => t.at('odd[@name="X"]').attr('value') 
    } 

    end 
    end 
    end 

Вид:

<table class="flat-table"> 
    <tbody> 

     <tr> 
      <% @link.each do |t| %> 
      <tr> 

      <td><%= t['home'] %></td> 

      <td> <%= t['1'] %> </td> 
      <td> <%= t['2'] %> </td> 
      <td> <%= t['X'] %> </td> 
     </tr> 
       <% end %> 

Моя проблема в том, как я могу показать ценность @odds, как я уже поставил «каждый сделать» код для @link? Благодарю. и, пожалуйста, помогите!

ответ

1

xml.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<data> 
    <match> 
    <home name="Wembley"></home> 
    </match> 

    <match> 
    <home name="Old Trafford"></home> 
    </match> 

    <odds> 
    <type name="1x2"> 
     <bookmaker id="781"> 
     <odd name="1" value="10"></odd> 
     <odd name="2" value="20"></odd> 
     <odd name="X" value="30"></odd> 
     </bookmaker> 
    </type> 
    </odds> 

    <odds> 
    <type name="1x2"> 
     <bookmaker id="781"> 
     <odd name="1" value="100"></odd> 
     <odd name="2" value="200"></odd> 
     <odd name="X" value="300"></odd> 
     </bookmaker> 
    </type> 
    </odds> 

</data> 

код:

require 'nokogiri' 

doc = Nokogiri::XML(
    File.read('xml.xml') 
) 

links = doc.xpath('//match').map do |match| 
    { 'home' => match.at('home').attr('name') } 
end 

my_xpath = '//odds/type[@name="1x2"]/bookmaker[@id="781"]' 

odds = doc.xpath(my_xpath).map do |bmaker| 
    { 
    '1' => bmaker.at('odd[@name="1"]').attr('value'), 
    '2' => bmaker.at('odd[@name="2"]').attr('value'), 
    'X' => bmaker.at('odd[@name="X"]').attr('value'), 
    } 
end 

Вы можете использовать цикл как это:

(0...links.size).each do |i| #Note the 3 dots, which excludes the last. 
    puts links[i]['home'] 

    puts odds[i]['1'] 
    puts odds[i]['2'] 
    puts odds[i]['X'] 

    puts '-' * 10 
end 

--output:-- 
Wembley 
10 
20 
30 
---------- 
Old Trafford 
100 
200 
300 
---------- 

Или, как это:

links.each_with_index do |link, i| 
    puts link['home'] 

    puts odds[i]['1'] 
    puts odds[i]['2'] 
    puts odds[i]['X'] 

    puts '-' * 10 
end 

Или, как это:

links.each do |link| 
    puts link['home'] 

    odd = odds.shift #Remove first item from odds array. The other items shuffle to the left one position. 
    puts odd['1'] 
    puts odd['2'] 
    puts odd['X'] 

    puts '-' * 10 
end 

Но я предпочитаю:

links_enum = links.each 
odds_enum = odds.each 

loop do 
    puts links_enum.next['home'] #The loop will end immediately if next() is called and there are no more items. 

    odd = odds_enum.next #The loop will end immediately if next() is called and there are no more items. 
    puts odd['1'] 
    puts odd['2'] 
    puts odd['X'] 

    puts '-' * 10 
end 

--output:-- 
Wembley 
10 
20 
30 
---------- 
Old Trafford 
100 
200 
300 
---------- 

В приложении рельсы, действие хотел бы это:

#Get the xml from somewhere: 
doc = Nokogiri::XML(
    File.read("#{Rails.root}/files/xml.xml") 
) 

links = doc.xpath('//match').map do |match| 
    { 'home' => match.at('home').attr('name') } 
end 

my_xpath = '//odds/type[@name="1x2"]/bookmaker[@id="781"]' 

odds = doc.xpath(my_xpath).map do |bmaker| 
    { 
    '1' => bmaker.at('odd[@name="1"]').attr('value'), 
    '2' => bmaker.at('odd[@name="2"]').attr('value'), 
    'X' => bmaker.at('odd[@name="X"]').attr('value'), 
    } 
end 

#Set the view variables: 
@links_enum = links.each 
@odds_enum = odds.each 

Тогда ваше мнение хотелось бы это:

<table class="flat-table"> 
<tbody> 

<% loop do %> 
    <tr> 
    <td><%= @links_enum.next['home'] %></td> 

    <% odd = @odds_enum.next %> 
    <td> <%= odd['1'] %> </td> 
    <td> <%= odd['2'] %> </td> 
    <td> <%= odd['X'] %> </td> 
    </tr> 
<% end %> 

</tbody> 
</table> 

Но используйте какой бы то ни было цикл для вас. :)

Ответ на комментарий:

require 'nokogiri' 
require 'open-uri' 

doc = Nokogiri::XML(
    open("http://www.tipgin.net/example-data/odds-worldcup-example.xml") 
) 

match_xpath = '/odds/league/matches/match[./odds/type]' 

doc.xpath(match_xpath).each do |match| 
    puts match.at_xpath("./home")['name'] 
    puts 'vs.' 
    puts match.at_xpath("./away")['name'] 

    match.xpath('./odds/type/bookmaker').each do |bmaker| 
    puts bmaker['name'] 

    bmaker.xpath('./odd').each do |odd| 
     puts "#{odd['name']} ... #{odd['value']}" 
    end 

    break 
    end 
    break 
end 

--output:-- 
Brazil 
vs. 
Croatia 
12Bet 
1 ... 1.27 
2 ... 9.56 
X ... 5.32 
+0

Здравствуйте, спасибо за ваш ответ :) Что делать, если моя структура xml выглядит так: – pyfl88

+0

@ pyfl88, What xml? – 7stud

+0

вы можете помочь мне взглянуть на этот http://www.tipgin.net/example-data/odds-worldcup-example.xml, где некоторые из матчей не имеют шансов, а некоторые имеют шансы, как мне фильтр, чтобы выбрать только те, у кого есть шансы? Благодарю. – pyfl88

0
 <td> <%= @odds[0]['1'] %> </td> 
     <td> <%= @odds[0]['2'] %> </td> 
     <td> <%= @odds[0]['X'] %> </td> 

Для отображения первой записи. Или итерации внутри цикла, что угодно.

Вы уверены, что понимаете, что вы делаете?

+0

Нет, я имею в виду, есть ли способ, что я могу добавить «каждый сделать» метод шансов вместе с ссылкой? – pyfl88

+0

Cos Я тоже хочу перебирать шансы. или я могу добавить коэффициенты и ссылки в 1 переменную в контроллере? – pyfl88

Смежные вопросы