【问题标题】:libxml-ruby parsing HELPlibxml-ruby 解析帮助
【发布时间】:2009-08-23 16:18:21
【问题描述】:

好吧,由于速度和 _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>

完整的提要中大约有 150 个这样的条目。

我只想遍历 150 个条目,然后提取内容和属性,但我用 libxml-ruby 玩得很开心,因为它与 Hpricot 一起工作得很好。

这个小sn-p表明我什至没有得到条目:

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 的示例。这应该很简单。

【问题讨论】:

    标签: ruby nokogiri hpricot libxml-ruby


    【解决方案1】:

    Nokogiri 已被证明具有一定的速度和寿命,因此这里有一些示例来说明如何处理示例 XML 中的命名空间。我将 Nokogiri 用于一个大型 RDF/RSS/Atom 聚合器,该聚合器每天处理数千个提要,使用类似的东西来获取我想要的字段,然后再将它们推送到后端数据库。

    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 使用通配符命名空间,前提是它能够找到命名空间声明,这将简化 hl1 节点的 '|headline &gt; hl1' 访问器。

    【讨论】:

    • 我忘了回到这个帖子,但是是的,我做了类似 Tin
    【解决方案2】:

    我怀疑您遇到问题是由于跳过了查找中的命名空间。如果您查看xpath documentation for libxml-ruby,他们有一些非常相关的示例。具体来说,您的 find 可能应该像 entries = doc.find('//atom:entry', 'atom:http://www.w3.org/2005/Atom') 那样格式正确。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-15
      • 2015-12-07
      • 2011-02-27
      • 1970-01-01
      相关资源
      最近更新 更多