Подтвердить что ты не робот

Анализ XML с помощью Ruby

Я новичок в работе с XML, но мне просто нужно было упасть на колени. Мне был предоставлен обычный (мне) формат XML. В тегах есть двоеточия.

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

Это большой файл, и есть гораздо больше, чем это, но я надеюсь, что этот формат будет кому-то знаком. Кто-нибудь знает способ приблизиться к XML-документу такого рода?

Я бы предпочел не просто написать грубую синтаксическую разборку текста, но я не могу показаться, что это продвигается с REXML или Hpricot, и я подозреваю, что это связано с этими необычными тегами.

мой код ruby:

    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

... который просто снят с: http://railstips.org/blog/archives/2006/12/09/parsing-xml-with-hpricot/

И я подумал, что мне удастся вычислить некоторые вещи, но этот код ничего не возвращает. Это не ошибка. Он просто возвращается.

4b9b3361

Ответ 1

Как упоминалось в @pguardiario, Nokogiri является фактической библиотекой разбора XML и HTML. Если вы хотите распечатать значения Id и Name в вашем примере, вот как вы это сделаете:

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

Несколько примечаний:

  • at_xpath предназначен для соответствия одной вещи. Если вы знаете, что у вас несколько элементов, вы хотите использовать xpath.
  • В зависимости от вашего документа пространства имен могут быть проблематичными, поэтому вызов doc.remove_namespaces! может помочь (см. этот ответ для краткого обсуждения).
  • Вы можете использовать методы css вместо xpath, если вам более удобно с ними.
  • Определенно играйте с этим в irb или pry, чтобы исследовать методы.

Ресурсы

Update

Чтобы обрабатывать несколько элементов, вам нужен корневой элемент, и вам нужно удалить // в запросе xpath.

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

Это даст вам:

Id   = 1234
Name = The Name1

ID   = 2234
Name = The Name2

Если вы более знакомы с селекторами CSS, вы можете использовать этот почти идентичный бит кода:

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

Ответ 2

Если в среде Rails объект Hash расширен и можно воспользоваться методом from_xml:

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