I wrote this little program:
require 'open-uri'
require 'nokogiri'
class Kapitel
attr_accessor :von, :bis, :bezeichnung
end
class SubKapitel
attr_accessor :von, :bis, :bezeichnung
end
def parse_file
doc = Nokogiri::XML(File.open("test.xml"))
parse_xml(doc)
end
def parse_xml(doc)
doc.root.elements.each do |node|
parse_kapitel(node)
end
end
def parse_kapitel(node)
if node.node_name.eql? 'nummer'
tmp_kapitel = Kapitel.new
end
if node.node_name.eql? 'gruppe'
tmp_kapitel = SubKapitel.new
end
tmp_kapitel.von = node['V'] if node.node_name.eql? 'von_icd_code'
tmp_kapitel.bis = node['V'] if node.node_name.eql? 'bis_icd_code'
end
puts parse_file
Using that, I parse this XML file:
<kapitel>
<nummer V="1"/>
<von_icd_code V="A00"/>
<bis_icd_code V="B99"/>
<bezeichnung V="Bestimmte infektiöse und parasitäre Krankheiten"/>
<gruppen_liste>
<gruppe>
<von_icd_code V="A00"/>
<bis_icd_code V="A09"/>
<bezeichnung V="Infektiöse Darmkrankheiten"/>
<diagnosen_liste>
<diagnose>
<icd_code V="A00.-"/>
<bezeichnung V="Cholera"/>
<abrechenbar V="n"/>
But somehow I get this error:
test.rb:32:in `parse_kapitel': undefined method `von=' for nil:NilClass(NoMethodError)
I think the problem is that von-icd-code
appears twice in the XML document.
Can somebody help me to solve this problem?
Which outputs:
If we look at what Nokogiri had to do to fix-up the XML:
We see that it added closing tags.
It was able to do so correctly for this XML, but in XML that is malformed, or has more complicated data it might not do as well. And, at that point, any subsequent work on the resulting DOM would be suspect.
Inside the method
The error undefined method 'von=' for nil:NilClass(NoMethodError) means at that time
node
name is'von_icd_code'
, not the'nummer'
. That's why theif node.node_name.eql? 'nummer'
evaluated asfalse
. But in Ruby local variables are created at parse time,whenever any such assignment statement encountered like,tmp_kapitel = Kapitel.new
.Now due toflase
evluation of theif node.node_name.eql? 'nummer'
,as I said earlier,tmp_kapitel
local variable holdsnil
,not the object ofKapitel.new
. AndNilClass
doesn't have any method called#von
,so the legitimate error thrown to you.