我正在创建一个RubyonRails应用程序,并使用Nokogiri来解析XML文件。我正在尝试将XML文件解析为可变字符串,我可以对其进行操作以创建其他内容。
这是我使用的一个示例XML
<feed xmlns="http://www.w3.org/2005/Atom">
<entry>
<title type="html">
<![CDATA[ First Post! ]]>
</title>
<content type="html">
<![CDATA[
<p>I’m very excited to have finally got my site up and running along with this blog!</p>]]>
</content>
</entry>
</feed>
这是我迄今为止所做的与我的问题有关的事情
在我的控制器-
def index
@blog_title, @blog_post = parse_xml
end
private
def parse_xml
@xml_doc = Nokogiri::XML(open("atom.xml"))
titles = @xml_doc.css("entry title")
post = @xml_doc.css("content")
return titles, post
end
在我看来-
<% for i in 1..@blog_title.length %>
<li><%= @blog_title[i-1] %></li>
<li><%= @blog_post[i-1] %></li>
<% end %>
视图的样本输出(返回一个Nokogiri元素(-
<title type="html"><![CDATA[First Post!]]></title>
因此,理想情况下,我希望将Nokogiri::中的所有Nokogiri::元素都制作成字符串,或者将整个数组制作成字符串数组。
我尝试过迭代每个元素并调用.to_s,但似乎不起作用。
我还尝试过调用Ruby::String方法,比如slice,但这不起作用(原因很明显(。
我试图得到的最终结果(在我的视图中使用示例输出(是只返回以下内容,而不返回其余内容
First Post!
有人能帮我吗?如果我不够清楚,或者有人需要看更多的作品,请随时询问!
对于您的情况,您应该简单地使用.text
来提取标记的内容。像titles.text
这样的东西会起作用。
您正在处理的RSS/Atom提要可以包含多个title
标记。您需要对所有title
节点进行迭代,并分别提取它们的内容,这样您就可以跟踪它们的顺序以及它们所附的文章:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<feed xmlns="http://www.w3.org/2005/Atom">
<entry>
<title type="html">
<![CDATA[ First Post! ]]>
</title>
<content type="html">
<![CDATA[
<p>I’m very excited to have finally got my site up and running along with this blog!</p>]]>
</content>
</entry>
</feed>
EOT
doc.search('title').map(&:text)
# => ["n First Post! n "]
这将返回title
节点内的文本数组。从那里你可以很容易地清理每个字符串,操作它们,重用它们,等等。
doc.search('title').map{ |s| s.text.strip }
# => ["First Post!"]
search
返回一个NodeSet,它类似于文档中的title
节点数组。如果你不迭代它们,你会得到一个包含所有文本的串联字符串,通常是NOT你想要的:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<foo>
<title>this</title>
<title>is</title>
<title>what</title>
<title>you'd</title>
<title>get</title>
</foo>
EOT
doc.search('title').text
# => "thisiswhatyou'dget"
对比:
doc.search('title').map(&:text)
# => ["this", "is", "what", "you'd", "get"]
除非你事先知道文档的结构,否则试图分解第一个结果是不可能的,而这通常是不真实的。对返回的NodeSet进行迭代将产生非常有用的结果。
为了保持与提要中各种title
标记的一致性,您需要循环遍历条目,然后提取嵌入的标题,这与您的示例XML和代码显示的有点不同:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<feed xmlns="http://www.w3.org/2005/Atom">
<entry>
<title type="html">
<![CDATA[ First Post! ]]>
</title>
<content type="html">
<![CDATA[
<p>I’m very excited to have finally got my site up and running along with this blog!</p>]]>
</content>
</entry>
<entry>
<title type="html">
<![CDATA[ Second Post! ]]>
</title>
<content type="html">
<![CDATA[
<p>blah</p>]]>
</content>
</entry>
</feed>
EOT
titles = doc.search('entry').map { |entry|
entry.at('title').text.strip
}
titles # => ["First Post!", "Second Post!"]
或者可能更有用:
titles_and_content = doc.search('entry').map { |entry|
[
entry.at('title').text.strip,
entry.at('content').text.strip
]
}
titles_and_content
# => [["First Post!",
# "<p>I’m very excited to have finally got my site up and running along with this blog!</p>"],
# ["Second Post!", "<p>blah</p>"]]
其返回每个条目的标题和内容。从中,你可以很容易地构建代码,提取文章的链接、发布日期、刷新率、原始网站,以及你想了解的关于单个文章及其来源的一切,然后将其存储在数据库中,以备日后需要时查阅。
有一些宝石和脚本可用于处理RDF、RSS和Atom提要,然而,几年前,当我不得不为提要编写一个巨大的聚合器时,没有任何东西可以满足我的需求,我从头开始写了一个。我建议你试着找到一个,而不是重新发明轮子,否则就要仔细研究它们的来源,从它们的经验中学习。代码中有很多事情要做,才能成为一个好的网络公民,不会淹没服务器,让你被禁止。
另请参阅"如何避免在抓取时连接来自节点的所有文本"。