如何使用 nokogiri 正确解析和查看?
How to parse and view properly with nokogiri?
我无法正确查看我的 xml 数据。这是我在控制器和视图中的代码。
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 添加了一个"each do" 代码?谢谢。请帮忙!
<td> <%= @odds[0]['1'] %> </td>
<td> <%= @odds[0]['2'] %> </td>
<td> <%= @odds[0]['X'] %> </td>
显示第一个条目。或者在循环内迭代,随便什么。
你确定你明白你在做什么吗?
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
----------
在您的 rails 应用中,操作如下所示:
#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
我无法正确查看我的 xml 数据。这是我在控制器和视图中的代码。
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 添加了一个"each do" 代码?谢谢。请帮忙!
<td> <%= @odds[0]['1'] %> </td>
<td> <%= @odds[0]['2'] %> </td>
<td> <%= @odds[0]['X'] %> </td>
显示第一个条目。或者在循环内迭代,随便什么。
你确定你明白你在做什么吗?
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
----------
在您的 rails 应用中,操作如下所示:
#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