2009-08-23 13 views
1

まあ、HpricotをLibxml-rubyに切り替えるのは速度が遅く、_whyが消えてしまったので、Nokogiriを一瞬見ていましたが、Libxml-rubyを見て速度と寿命を調べることにしました。私の基本的な何かが欠けているが、何イムがやろうとし機能していないされている必要があり、ここに私のXML列があります:libxml-ruby構文解析ヘルプ

<?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でうまく動作していました。

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を得るサンプルがあります。これはかなりシンプルなはずです。

答えて

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は通常、ネームスペース宣言を見つけることができたならば、アクセサーを'|headline > hl1'hl1ノードに簡略化していたなら、CSSにワイルドカードネームスペースを許可します。

+0

私はこのスレッドに戻るのを忘れましたが、はい、私は何か類似の錫をしました – initialized

0

あなたの検索の名前空間をスキップすることに問題があると思われます。 xpath documentation for libxml-rubyを見ると、かなり関連性の高い例がいくつかあります。具体的には、findはおそらくentries = doc.find( '// atom:entry'、 'atom:http://www.w3.org/2005/Atom')のように正しくフォーマットされている必要があります。