代码之家  ›  专栏  ›  技术社区  ›  John Smith

为什么我得到“nil:NilClass的未定义方法`von='”?

  •  1
  • John Smith  · 技术社区  · 13 年前

    我写了这个小程序:

    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文档中出现两次。

    有人能帮我解决这个问题吗?

    2 回复  |  直到 13 年前
        1
  •  1
  •   Arup Rakshit    13 年前

    方法内部

    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
    

    错误 nil:NilClass的未定义方法“von=”(NoMethodError) 意味着当时 node 姓名为 'von_icd_code' ,而不是 'nummer' 。这就是为什么 if node.node_name.eql? 'nummer' 评估为 false 但是在Ruby中,每当遇到任何这样的赋值语句时,都会在解析时创建局部变量,比如, tmp_kapitel = Kapitel.new 。现在由于 flase 如果node.node_name.eql?'编号 ,正如我之前所说, tmp_kapitel 局部变量保持 nil ,而不是的对象 Kapitel.new NilClass 没有调用任何方法 #von ,所以向您抛出了合法的错误。

        2
  •  0
  •   the Tin Man    13 年前
    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的任何后续工作都是可疑的。