2013-09-22 24 views
1

好日子,使用Ruby SAX解析器GB2312編碼的XML

我有很多的,我需要分析大的XML文件,但問題是他們有「GB2312」編碼。我會正常使用SAX解析器。

因此,這裏是示例XML的:

<?xml version="1.0" encoding="gb2312"?> 
<Root> 
<ValueList Count="112290" FieldCount="11"> 
    <Item1 Value1="23743" Value2="Дипломатия � Пустой кувшин" Value3="1" Value4="" Value5="6" Value6="0" Value7="0" Value8="0" Value9="0" Value10="0" Value11="0"/> 
    <Item2 Value1="6611" Value2="ДЛ � 018 омела � золотой кинжал" Value3="1" Value4="" Value5="6" Value6="0" Value7="0" Value8="0" Value9="0" Value10="0" Value11="0"/> 
    <Item3 Value1="6608" Value2="Наука (ДЛ)�круг фей 021�тяпка" Value3="1" Value4="" Value5="6" Value6="0" Value7="0" Value8="0" Value9="0" Value10="0" Value11="0"/> 
    <Item4 Value1="6612" Value2="Знаки ДЛ � 003руны � разрушение" Value3="1" Value4="" Value5="6" Value6="0" Value7="0" Value8="0" Value9="0" Value10="0" Value11="0"/> 
.... 
</Root> 

我試圖使用SAX引入nokogiri(也試過的libxml-紅寶石一樣的結果)解析器:

require 'nokogiri' 

class SchemaParser < Nokogiri::XML::SAX::Document 
    def initialize 
    @cnt = 0 
    end 
    def start_element name, attrs =[] 
    if name == "Item1" 
     @cnt+= 1 
     puts @cnt 
    end 
    end 
end 

parser = Nokogiri::XML::SAX::Parser.new(SchemaParser.new) 
parser.parse_io(File.open('2_4_EQUIPMENT_ESSENCE.xml'), 'gb2312') 

但是這給了錯誤「`check_encoding':'GB2312'不是有效的編碼(ArgumentError)」。如果我刪除編碼聲明,讓引入nokogiri檢測編碼自己,我會收到此錯誤:

encoding error : input conversion failed due to input error, bytes 0xA8 0x43 0x20 0xA7 
encoding error : input conversion failed due to input error, bytes 0xA8 0x43 0x20 0xA7 
I/O error : encoder error 

我還試圖打開與正確的編碼文件,但沒有幫助SAX解析器:

[3] pry(main)> f = File.open('2_4_EQUIPMENT_ESSENCE.xml', "r:gb2312") 
=> #<File:2_4_EQUIPMENT_ESSENCE.xml> 
[4] pry(main)> f.external_encoding.name 
=> "GB2312" 

有沒有人在ruby中使用'gb2312'編碼和SAX解析器?任何建議如何進行?

+0

這是一個已知的問題! https://github.com/sparklemotion/nokogiri/issues/918 –

+1

感謝您的通知。 現在很好找到解決方法。 – skatkov

+0

順便說一句,你的工作環境請張貼作爲答案,每當你將會! :) –

回答

0

所以,這是我的解決方法。

問題:

  1. 一些XML字符呈現的不是「GB2312」編碼,我發現「GB18030」將是全中國的文字是更好的選擇。
  2. 我將所有xml轉換爲utf8,所以我可以使用SAX解析器。

我結束了這個rake任務:

desc "convert chinese xml files to utf-8" 
task :convert do 
    rm_rf 'data/utf8' 
    mkdir 'data/utf8' 
    Dir.foreach('data') {|f| 
    if f.end_with?('.xml') 
     puts "converted:: data/utf8/#{f}" if system("iconv -f GB18030 -t UTF-8 data/#{f} > data/utf8/#{f}") 
    end 
    } 
    #replace encodings for xml files 
    system("bundle exec ruby -pi -e \"gsub(/gb2312/, 'UTF-8')\" data/utf8/*.xml") 
end 
0

看來問題在於Libxml2不支持GB2312編碼(有​​關支持的編碼列表,請參閱here)。

我不確定您是否嘗試過這種方式,但我認爲您可以通過從XML文件中移除編碼聲明(因此Libxml2不嘗試對數據進行轉碼)來解決此問題,並設置外部編碼將文件對象轉換爲GB2312,因爲Ruby會在讀取文件時將文件轉碼爲UTF-8,從此之後所有文件都將保持爲UTF-8。

+0

是的,我通過文檔檢查,而libxml2不支持這種編碼。 但是Nokogiri聲稱它與它一起工作就好了。實際上,只適用於DOM解析器,而不適用於SAX。 – skatkov