美好的一天,
我有很多需要解析的大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>
我正在尝试使用Nokogiri SAX(也尝试使用相同结果的libxml-ruby)解析器:
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 :(得分:0)
似乎问题是Libxml2不支持GB2312编码(请参阅here以获取支持的编码列表)。
我不确定您是否尝试过此操作,但我认为您可以通过从XML文件中删除编码声明来解决此问题(因此Libxml2不会尝试对数据进行转码)并设置文件的外部编码对象是GB2312,因为Ruby会在读取时将文件转码为UTF-8,从那时起,所有内容都将保留为UTF-8。
答案 1 :(得分:0)
所以,这是我的解决方法。
问题:
我最终得到了这个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