1

さて、動作中の Hpricot から Libxml-ruby に切り替えたのは、速度と _why の消失のためでした。しばらく 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 のエントリをループして、コンテンツと属性を取得したいだけですが、Hpricot で問題なく動作していた libxml-ruby で非常に苦労しています。

この小さなスニペットは、エントリを取得していないことを示しています。

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 を取得するサンプルを次に示します。これはかなり単純なはずです。

4

2 に答える 2

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のワイルドカード名前空間を許可します。これ'|headline > hl1'により、hl1ノードのアクセサーが簡略化されます。

于 2011-03-12T20:15:24.937 に答える
0

検索で名前空間をスキップしたために問題が発生していると思われます。libxml-rubyの xpath ドキュメントを見ると、かなり関連性のある例がいくつかあります。具体的には、適切にフォーマットされているため、検索はおそらく entry = doc.find('//atom:entry', 'atom: http://www.w3.org/2005/Atom ') のようになるはずです。

于 2009-08-23T16:35:09.703 に答える