2009-08-23 13 views
1

Gut, Wechsel von der Arbeit Hpricot zu Libxml-Ruby wegen der Geschwindigkeit und gut das Verschwinden von _why, sah Nokogiri für eine Sekunde, aber entschied sich für Libxml-Ruby für Geschwindigkeit und Langlebigkeit. Ich muss etwas Grundsätzliches fehlt aber was im Versuch, nicht zu tun, arbeiten, hier ist meine XML-String:libxml-ruby parsing HILFE

<?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> 

gibt es etwa 150 solcher Einträge aus dem kompletten Feed.

Ich möchte nur die 150 Einträge durchlaufen und dann Inhalte und Attribute herausholen, aber ich habe eine Menge Zeit mit libxml-ruby hatte es funktioniert gut mit Hpricot.

Dieser kleine Ausschnitt zeigt, dass im nicht einmal die Einträge bekommen:

parser = XML::Parser.string(file) 
doc = parser.parse 
entries = doc.find('//entry') 
puts entries.size 
entries.each do |node| 
    puts node.inspect 
end 

Irgendwelche Ideen? Ich habe die Dokumente durchgesehen und konnte keine einfache XML-Datei finden, und hier sind Beispiele für den Auszug von x, y, z. Das sollte ziemlich einfach sein.

Antwort

1

Nokogiri hat sich als etwas schnell und langlebig erwiesen, daher hier einige Beispiele, wie Sie mit den Namespaces im XML-Beispiel umgehen. Ich habe Nokogiri für einen großen RDF/RSS/Atom-Aggregator verwendet, der täglich Tausende von Feeds verarbeitet, wobei ich etwas Ähnliches nutze, um die gewünschten Felder zu erfassen, bevor ich sie in eine Backend-Datenbank schiebe.

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"}] 

Sowohl CSS als auch XPath in Nokogiri können Namespaces verarbeiten. Nokogiri würde es vereinfachen, sie zu verwenden, indem alle Namespaces, die im Wurzelknoten definiert sind, erfasst werden. In diesem XML-Beispiel wird der Namespace jedoch im Eintragsknoten definiert, sodass wir ihn manuell ausführen können.

Ich wechselte für die Schlagzeilen in die CSS-Notation, nur um zu zeigen, wie man sie macht. Der Einfachheit halber würde Nokogiri normalerweise einen wildbehafteten Namespace für CSS zulassen, wenn er in der Lage gewesen wäre, die Namespacedeklaration zu finden, die den Accessor für den Knoten für den Knoten hl1 vereinfacht hätte.

+0

Ich habe vergessen, auf diesen Thread zurück, aber ja, ich habe etwas ähnliches Tin – initialized

0

Ich vermute, dass Sie Probleme haben, weil Sie die Namespaces in Ihrer Suche auslassen. Wenn Sie sich die xpath documentation for libxml-ruby ansehen, haben sie einige ziemlich relevante Beispiele. Genauer gesagt, sollte Ihr Fund wahrscheinlich wie entries = doc.find ('// atom: entry', 'atom: http://www.w3.org/2005/Atom') sein, da dies richtig formatiert ist.