我写了这个小程序:
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
使用它,我解析这个XML文件:
<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"/>
但不知怎的,我得到了这个错误:
test.rb:32:in `parse_kapitel': undefined method `von=' for nil:NilClass(NoMethodError)
我认为问题是von-icd-code
在XML文档中出现两次。
有人可以帮我解决这个问题吗?
答案 0 :(得分:1)
方法内部
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
错误未定义方法'von ='代表nil:NilClass(NoMethodError)表示当时node
名称为'von_icd_code'
,而不是'nummer'
。这就是if node.node_name.eql? 'nummer'
评估为false
的原因。但是在Ruby中,局部变量是在解析时创建的,只要遇到类似tmp_kapitel = Kapitel.new
的任何此类赋值语句。现在由于flase
的{{1}}已经如前所述if node.node_name.eql? 'nummer'
,{{1}局部变量保存tmp_kapitel
,而不是nil
的对象。并且Kapitel.new
没有任何名为NilClass
的方法,因此会向您抛出合法错误。
答案 1 :(得分:0)
require 'nokogiri'
doc = Nokogiri::XML(' <kapitel>
<nummer V="1"/>
<von_icd_code V="A00"/>
<bis_icd_code V="B99"/>
<bezeichnung V="Bestimmte infektise und parasitre Krankheiten"/>FFC3\U+FFA4re Krankheiten"/>
<gruppen_liste>
<gruppe>
<von_icd_code V="A00"/>
<bis_icd_code V="A09"/>
<bezeichnung V="Infektise Darmkrankheiten"/>krankheiten"/>
<diagnosen_liste>
<diagnose>
<icd_code V="A00.-"/>
<bezeichnung V="Cholera"/>
<abrechenbar V="n"/>')
doc.errors
哪个输出:
[
[0] #<Nokogiri::XML::SyntaxError: Premature end of data in tag diagnose line 12>,
[1] #<Nokogiri::XML::SyntaxError: Premature end of data in tag diagnosen_liste line 11>,
[2] #<Nokogiri::XML::SyntaxError: Premature end of data in tag gruppe line 7>,
[3] #<Nokogiri::XML::SyntaxError: Premature end of data in tag gruppen_liste line 6>,
[4] #<Nokogiri::XML::SyntaxError: Premature end of data in tag kapitel line 1>
]
如果我们看看Nokogiri必须做些什么来修复XML:
puts doc.to_xml
我们看到它添加了结束标记。
<?xml version="1.0"?>
<kapitel>
<nummer V="1"/>
<von_icd_code V="A00"/>
<bis_icd_code V="B99"/>
<bezeichnung V="Bestimmte infektise und parasitre Krankheiten"/>
<gruppen_liste>
<gruppe>
<von_icd_code V="A00"/>
<bis_icd_code V="A09"/>
<bezeichnung V="Infektise Darmkrankheiten"/>
<diagnosen_liste>
<diagnose>
<icd_code V="A00.-"/>
<bezeichnung V="Cholera"/>
<abrechenbar V="n"/></diagnose></diagnosen_liste></gruppe></gruppen_liste></kapitel>
它能够正确地为这个XML做到这一点,但是在格式错误的XML中,或者数据更复杂的情况下,它可能做得不好。而且,在那时,对结果DOM的任何后续工作都是可疑的。