用Nokogiri解析简单的XML

Vin*_*ent 17 ruby xml xpath ruby-on-rails nokogiri

我有以下XML:

<links>

  <item>
    <title>Title 1</title>
    <url>http://www.example.com/url-1</url>
  </item>

  <item>
   <title>Title 2</title>
   <url>http://www.example.com/url-2</url>
  </item>

  <item>
    <title>Title 3</title>
    <url>http://www.example.com/url-3</url>
  </item>

</links>
Run Code Online (Sandbox Code Playgroud)

而且,我想将其转换为HTML列表:

<ul>
  <li><a href="http://www.example.com/url-1">Title 1</a></li>
  <li><a href="http://www.example.com/url-2">Title 2</a></li>
  <li><a href="http://www.example.com/url-3">Title 3</a></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

目前我有这个:

控制器:

require 'nokogiri'
doc = Nokogiri::XML(...)

@links = doc.xpath('//links/item').map do |i|
  {'title' => i.xpath('//title'), 'url' => i.xpath('//url')}
end
Run Code Online (Sandbox Code Playgroud)

模板:

<ul>
  <% @links.each do |l| %>
    <li><a href="<%= l['url'] %>"><%= l['title'] %></a></li>
  <% end %>
</ul> 
Run Code Online (Sandbox Code Playgroud)

产生的HTML:

<ul>
  <li><a href="http://www.example.com/url-1http://www.example.com/url-2http://www.example.com/url-3">Title 1Title 2Title 3</a></li>
  <li><a href="http://www.example.com/url-1http://www.example.com/url-2http://www.example.com/url-3">Title 1Title 2Title 3</a></li>
  <li><a href="http://www.example.com/url-1http://www.example.com/url-2http://www.example.com/url-3">Title 1Title 2Title 3</a></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?有更好的方法吗?

Dim*_*hev 28

替换这个:

@links = doc.xpath('//links/item').map do |i| 
  {'title' => i.xpath('//title'), 'url' => i.xpath('//url')} 
Run Code Online (Sandbox Code Playgroud)

:

@links = doc.xpath('//links/item').map do |i| 
  {'title' => i.xpath('title'), 'url' => i.xpath('url')} 
Run Code Online (Sandbox Code Playgroud)

说明:

//title 
Run Code Online (Sandbox Code Playgroud)

//url
Run Code Online (Sandbox Code Playgroud)

绝对的 XPath表达式,它们选择XML文档中的所有(分别)title和所有url元素.

与此对比:

title
Run Code Online (Sandbox Code Playgroud)

url
Run Code Online (Sandbox Code Playgroud)

这些是相对 XPath表达式,仅选择当前节点的所有(分别)titleurl子节点.


Mat*_*chu 6

这里的麻烦是Xpath //title从文档的根目录中搜索标题,因此返回所有title标签.使用Xpath title在给定节点的上下文中搜索,就像您想要的那样.同上url.

@links = doc.xpath('//links/item').map do |i|
  {'title' => i.xpath('title'), 'url' => i.xpath('url')}
end
Run Code Online (Sandbox Code Playgroud)