XML ontleden met Ruby

Ik ben helemaal nieuw in het werken met XML, maar er kwam een behoefte op mijn pad. Ik heb een gebruikelijk (voor mij) XML-formaat gekregen. Er staan dubbele punten in de tags.

<THING1:things type="Container">
  <PART1:Id type="Property">1234</PART1:Id>
  <PART1:Name type="Property">The Name</PART1:Name>
</THING1:things>

Het is een groot bestand en er is veel meer dan dit, maar ik hoop dat dit formaat iemand bekend zal zijn. Weet iemand een manier om een dergelijk XML-document te benaderen?

Ik schrijf liever niet alleen een brute-force manier om de tekst te ontleden, maar ik lijk geen vooruitgang te boeken met REXML of Hpricot en ik vermoed dat dit te wijten is aan deze ongebruikelijke tags.

mijn ruby-code:

   require 'hpricot'
    xml = File.open( "myfile.xml" )
    doc = Hpricot::XML( xml )
   (doc/:things).each do |thg|
     [ 'Id', 'Name' ].each do |el|
       puts "#{el}: #{thg.at(el).innerHTML}"
     end
   end

…die zojuist is verwijderd van: http://railstips .org/blog/archives/2006/12/09/parsing-xml-with-hpricot/

En ik dacht dat ik hier wat dingen uit zou kunnen halen, maar deze code levert niets op. Het geeft geen fout. Het komt gewoon terug.


Antwoord 1, autoriteit 100%

Zoals @pguardiario al zei, is Nokogiride feitelijke XML- en HTML-parseerbibliotheek. Als u de waarden voor Iden Namein uw voorbeeld wilt afdrukken, gaat u als volgt te werk:

require 'nokogiri'
xml_str = <<EOF
<THING1:things type="Container">
  <PART1:Id type="Property">1234</PART1:Id>
  <PART1:Name type="Property">The Name</PART1:Name>
</THING1:things>
EOF
doc = Nokogiri::XML(xml_str)
thing = doc.at_xpath('//things')
puts "ID   = " + thing.at_xpath('//Id').content
puts "Name = " + thing.at_xpath('//Name').content

Een paar opmerkingen:

  • at_xpathis voor het matchen van één ding. Als je weet dat je meerdere items hebt, wil je in plaats daarvan xpathgebruiken.
  • Afhankelijk van je document kunnen naamruimten problematisch zijn, dus het kan helpen om doc.remove_namespaces!te bellen (zie dit antwoordvoor een korte discussie).
  • Je kunt de css-methoden gebruiken in plaats van xpathals je daar meer vertrouwd mee bent.
  • Speel hier zeker mee in irbof pryom methoden te onderzoeken.

Bronnen

Bijwerken

Om meerdere items te verwerken, heb je een root-element nodig en moet je de //in de xpath-query verwijderen.

require 'nokogiri'
xml_str = <<EOF
<root>
  <THING1:things type="Container">
    <PART1:Id type="Property">1234</PART1:Id>
    <PART1:Name type="Property">The Name1</PART1:Name>
  </THING1:things>
  <THING2:things type="Container">
    <PART2:Id type="Property">2234</PART2:Id>
    <PART2:Name type="Property">The Name2</PART2:Name>
  </THING2:things>
</root>
EOF
doc = Nokogiri::XML(xml_str)
doc.xpath('//things').each do |thing|
  puts "ID   = " + thing.at_xpath('Id').content
  puts "Name = " + thing.at_xpath('Name').content
end

Dit geeft je:

Id   = 1234
Name = The Name1
ID   = 2234
Name = The Name2

Als u meer bekend bent met CSS-selectors, kunt u dit bijna identieke stukje code gebruiken:

doc.css('things').each do |thing|
  puts "ID   = " + thing.at_css('Id').content
  puts "Name = " + thing.at_css('Name').content
end

Antwoord 2, autoriteit 49%

In een Rails-omgeving wordt het Hash-object uitgebreid en kan men profiteren van de methode from_xml:

xml = File.open("myfile.xml")
data = Hash.from_xml(xml)

Other episodes