将Nokogiri XML文档转换为字符串数组



我正在创建一个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&rsquo;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&rsquo;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&rsquo;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&rsquo;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提要,然而,几年前,当我不得不为提要编写一个巨大的聚合器时,没有任何东西可以满足我的需求,我从头开始写了一个。我建议你试着找到一个,而不是重新发明轮子,否则就要仔细研究它们的来源,从它们的经验中学习。代码中有很多事情要做,才能成为一个好的网络公民,不会淹没服务器,让你被禁止。

另请参阅"如何避免在抓取时连接来自节点的所有文本"。

相关内容

  • 没有找到相关文章

最新更新