好吧,由于速度和_why的消失,从工作Hpricot切换到Libxml-ruby,看了Nokogiri一秒钟,但决定看看Libxml-ruby的速度和寿命。我必须遗漏一些基本的东西,但我想要做的是不工作,这是我的XML字符串:
<?xml version="1.0" encoding="utf-8" ?>
<feed>
<title type="xhtml"></title>
<entry xmlns="http://www.w3.org/2005/Atom">
<id>urn:publicid:xx.xxx:xxxxxx</id>
<title>US--xxx-xxxxx</title>
<updated>2009-08-19T15:49:51.103Z</updated>
<published>2009-08-19T15:44:48Z</published>
<author>
<name>XX</name>
</author>
<rights>blehh</rights>
<content type="text/xml">
<nitf>
<head>
<docdata>
<doc-id regsrc="XX" />
<date.issue norm="20090819T154448Z" />
<ed-msg info="Eds:" />
<doc.rights owner="xx" agent="hxx" type="none" />
<doc.copyright holder="xx" year="2009" />
</docdata>
</head>
<body>
<body.head>
<hedline>
<hl1 id="headline">headline</hl1>
<hl2 id="originalHeadline">blah blah</hl2>
</hedline>
<byline>john doe<byttl>staffer</byttl></byline>
<distributor>xyz</distributor>
<dateline>
<location>foo</location>
</dateline>
</body.head>
<body.content>
<block id="Main">
story content here
</block>
</body.content>
<body.end />
</body>
</nitf>
</content>
</entry>
</feed>
完整的Feed中有大约150个此类条目。
我只想循环浏览150个条目,然后获取内容和属性,但是我有一个很好的时间使用libxml-ruby让它与Hpricot一起运行。
这个小片段显示我甚至没有收到条目:
parser = XML::Parser.string(file)
doc = parser.parse
entries = doc.find('//entry')
puts entries.size
entries.each do |node|
puts node.inspect
end
有什么想法吗?我查看了文档,找不到一个简单的XML文件,下面是x,y,z的示例。这应该很简单。
答案 0 :(得分:1)
Nokogiri已经证明具有一定的速度和寿命,因此这里有一些如何处理示例XML中的命名空间的示例。我使用Nokogiri作为一个大的RDF / RSS / Atom聚合器,每天使用类似的东西处理成千上万的feed,以便在将它们推入后端数据库之前抓取我想要的字段。
require 'nokogiri'
doc = Nokogiri::XML(file)
namespace = {'xmlns' => 'http://www.w3.org/2005/Atom'}
entries = []
doc.search('//xmlns:entry', namespace).each do |_entry|
entry_hash = {}
%w[title updated published author].each do |_attr|
entry_hash[_attr.to_sym] = _entry.at('//xmlns:' << _attr, namespace).text.strip
end
entry_hash[:headlines] = _entry.search('xmlns|hedline > hl1, xmlns|hedline > hl2', namespace).map{ |n| n.text.strip }
entry_hash[:body] = _entry.at('//xmlns:body.content', namespace).text.strip
entry_hash[:title] = _entry.at('//xmlns:title', namespace).text
entries << entry_hash
end
require 'pp'
pp entries
# >> [{:title=>"US--xxx-xxxxx",
# >> :updated=>"2009-08-19T15:49:51.103Z",
# >> :published=>"2009-08-19T15:44:48Z",
# >> :author=>"XX",
# >> :headlines=>["headline", "blah blah"],
# >> :body=>"story content here"}]
Nokogiri中的CSS和XPath都可以处理名称空间。 Nokogiri将通过获取根节点中定义的所有名称空间来简化它们的使用,但是,在此XML示例中,名称空间在入口节点中定义,使我们可以手动执行。
我切换到头条新闻的CSS表示法,只是为了展示如何做到这一点。为方便起见,Nokogiri通常会允许CSS的通配名称空间,如果它能够找到名称空间声明,这会简化'|headline > hl1'
节点hl1
的访问者。
答案 1 :(得分:0)
我怀疑由于在您的查找中删除了命名空间而导致您遇到问题。如果你看一下xpath documentation for libxml-ruby,他们会有一些非常相关的例子。具体来说,您的查找可能应该是entries = doc.find('// atom:entry','atom:http://www.w3.org/2005/Atom'),因为格式正确。