nokogiri从xml到数组的多个元素



我有一个XML新闻提要,我想从中获取故事,以及每个故事中的一些元素。原始xml在这里,这是每个故事的一个例子。

<news:NewsResult>
        <news:Title>Essex Police/Fire</news:Title>
        <news:Url>http://www.gloucestertimes.com/local/x2118804357/Essex-Police-Fire</news:Url>
        <news:Source>Gloucester Daily Times</news:Source>
        <news:Snippet>ESSEX — An attempt to serve a summons to a Piper Lane resident was thwarted at 2:25 p.m. Monday when police discovered that the person no longer lives at that address. Alarms were set off in error on Belcher Street at 3:12 p.m. Monday, on Main Street at ...</news:Snippet>

到目前为止,我有这样的代码:

def xml2Var(xmlin)
  #Parse received XML with Nokogiri
  doc = Nokogiri::XML(xmlin)
  #Remove  namespaces  
  doc.remove_namespaces!
  #print dat ish?  
# p p doc
#extract values.
  title = doc.xpath("//Title")
  snippet = doc.xpath("//Snippet")
  url = doc.xpath("//Url")
  source = doc.xpath("//Source")

我想将这些值放入每个故事的数组中。然后,将每个故事添加到故事数组中,这样我就可以在Rails应用程序中显示它。我设法做到了这一点,但无法显示每个故事和每个故事的属性。我认为我对Xpath的使用是错误的?

要将故事放入数组,您需要执行以下操作:

doc.css("NewsResult").map{|nr| [nr.at('Title'),nr.at('Snippet'),nr.at('Url'),nr.at('Source')].map(&:text)}

给定四个值数组,您可以像这样交织它们:

titles   = %w[t1 t2 t3 t4]
snippets = %w[n1 n2 n3 n4]
urls     = %w[u1 u2 u3 u4]
sources  = %w[s1 s2 s3 s4]
pp titles.zip(snippets,urls,sources)
#=> [["t1", "n1", "u1", "s1"],
#=>  ["t2", "n2", "u2", "s2"],
#=>  ["t3", "n3", "u3", "s3"],
#=>  ["t4", "n4", "u4", "s4"]]

然而,这可能是危险的。如果每个数组中没有完全相同的数字——例如,如果一个数组缺少一个源——那么它们最终会被错误关联:

titles   = %w[t1 t2 t3 t4]
snippets = %w[n1 n2 n3 n4]
urls     = %w[u1 u2 u3 u4]
sources  = %w[s1    s3 s4]
pp titles.zip(snippets,urls,sources)
#=> [["t1", "n1", "u1", "s1"],
#=>  ["t2", "n2", "u2", "s3"],
#=>  ["t3", "n3", "u3", "s4"],
#=>  ["t4", "n4", "u4", nil]]

最好按照@pguardianio的建议:找到每个新闻结果,然后将其映射到其组成部分。写得更简洁:

parts = %w[Title Snippet Url Source]
all = doc.css("NewsResult").map{ |nr| parts.map{ |part| nr.at(part).text } }

这将为您提供一个由四值数组组成的数组,其中[0]是标题的文本,[1]是片段的文本,依此类推:

all.each do |title,snippet,url,source|
  puts "Title: #{title} @ #{url} came from #{source}"
end

如果你想要一个更可用的构造,我会亲自创建一个Hash,这样我就不会通过魔术索引访问值:

results = doc.css("NewsResult").map do |result|
  Hash[ parts.map{ |part| [part.downcase.to_sym, result.at(part).text] } ]
end
#…later…
results.each do |result|
  puts "Title: #{result[:title]} @ #{result[:url]} came from #{result[:source]}"
end

相关内容

  • 没有找到相关文章