使用Nokogiri解析简单的XML

17

我有以下的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>

同时,我想将它转换为 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>

目前我有这个:

控制器:

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

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

模板:

<ul>
  <% @links.each do |l| %>
    <li><a href="<%= l['url'] %>"><%= l['title'] %></a></li>
  <% end %>
</ul> 

生成的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>

我做错了什么?是否有更优化的方法可以做到这一点?


好问题,加一。请看我的答案,其中包括正确的解决方案和对问题的详细解释。 - Dimitre Novatchev
2个回答

29

替换此内容:

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

with:

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

解释:

//title 

并且。
//url

这是一个与之相对应的例子:

绝对 XPath 表达式会选择 XML 文档中所有的 title 元素和所有的 url 元素。

与此形成对比的是:

title

并且

url

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


回答撤销,+1,因为我认为你实际上知道你在说什么。我不懂Xpath,只是猜测xD。 - Matchu
@Matchu:是的,我知道XPath,并且在这个标签中排名第一。 :) 但是你的答案是正确的--你不需要删除它。恢复它,我会点赞的。 - Dimitre Novatchev
谢谢 :) 我通常对于在几秒钟内出现重复答案时只接受一个答案,因为我的强迫症胜过了我对声望的渴望。 不过还是谢谢你!你是位绅士和学者 :o - Matchu
@Matchu:请恢复你的回答,我想点赞它。 - Dimitre Novatchev

6
这里的问题在于Xpath //title 从文档根部搜索标题,因此返回所有title标签。使用Xpath title 可以在给定节点的上下文中搜索,就像你想要的那样。同样的,对于url也是如此。
@links = doc.xpath('//links/item').map do |i|
  {'title' => i.xpath('title'), 'url' => i.xpath('url')}
end

哇...我现在才看到你的undelete。当然,完全值得+1。我很钦佩你对决定数字表示是否为复合数的正则表达式的解释!!! - Dimitre Novatchev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接