在Rails应用中导入XML文件,UTF-16编码问题

在Rails应用中导入XML文件,UTF-16编码问题

Importing XML file in Rails app, UTF-16 encoding problem

我正在尝试通过Ruby on Rails应用程序中的网页导入XML文件,代码ruby视图代码如下(我删除了HTML布局标签以使阅读代码更容易)

1
2
3
4
<% form_for( :fmfile, :url => '/fmfiles', :html => { :method => :post, :name => 'Form_Import_DDR', :enctype => 'multipart/form-data' } ) do |f| %>
<%= f.file_field :document, :accept => 'text/xml', :name => 'fmfile_document' %>
<%= submit_tag 'Import DDR' %>
<% end %>

以下HTML形式的结果

1
2
3
4
<form action="/fmfiles" enctype="multipart/form-data" method="post" name="Form_Import_DDR"><input name="authenticity_token" type="hidden" value="3da97372885564a4587774e7e31aaf77119aec62" />
<input accept="text/xml" id="fmfile_document" name="fmfile_document" size="30" type="file" />
<input name="commit" type="submit" value="Import DDR" />
</form>

" fmfiles_controller"中的Form_Import_DDR方法是使用REXML读取XML文档的艰苦工作的代码。代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@fmfile = Fmfile.new
@fmfile.user_id = current_user.id
@fmfile.file_group_id = 1
@fmfile.name = params[:fmfile_document].original_filename

respond_to do |format|
  if @fmfile.save
    require 'rexml/document'
    doc = REXML::Document.new(params[:fmfile_document].read)

    doc.root.elements['File'].elements['BaseTableCatalog'].each_element('BaseTable') do |n|
      @base_table = BaseTable.new
      @base_table.base_table_create(@fmfile.user_id, @fmfile.id, n)
    end

并且它继续读取所有不同的XML元素。

我在Mac OS X 10.5.4上的开发环境,同一台计算机上的站点数据库和浏览器中使用Rails 2.1.0和Mongrel 1.1.5。

我的问题是这个。读取字符编码为UTF-8的XML文档时,整个过程运行良好,但是当XML文件为UTF-16时,该过程失败,有人知道为什么会发生这种情况以及如何将其停止吗?

我在下面包括了调试器控制台的错误输出,大约需要5分钟才能得到此输出,并且浏览器在以下输出之前显示超时,并显示"无法打开页面"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Processing FmfilesController#create (for 127.0.0.1 at 2008-09-15 16:50:56) [POST]
Session ID: BAh7CDoMdXNlcl9pZGkGOgxjc3JmX2lkIiVmM2I3YWU2YWI4ODU2NjI0NDM2
NTFmMDE1OGY1OWQxNSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxh
c2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA==--dd9f588a68ed628ab398dd1a967eedcd09e505e0
Parameters: {"commit"=>"Import DDR","authenticity_token"=>"3da97372885564a4587774e7e31aaf77119aec62","action"=>"create","fmfile_document"=>#<File:/var/folders/LU/LU50A0vNHA07S4rxDAOk4E+++TI/-Tmp-/CGI.3001.1>,"controller"=>"fmfiles"}
[4;36;1mUser Load (0.000350)[0m   [0;1mSELECT * FROM"users" WHERE (id = 1) LIMIT 1[0m
[4;35;1mFmfile Create (0.000483)[0m   [0mINSERT INTO"fmfiles" ("name","file_group_id","updated_at","report_created_at","report_link","report_version","option_on_open_account_name","user_id","option_default_custom_menu_set","option_on_close_script","path","report_type","option_on_open_layout","option_on_open_script","created_at") VALUES('TheTest_fp7 2.xml', 1, '2008-09-15 15:50:56', NULL, NULL, NULL, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, '2008-09-15 15:50:56')[0m

REXML::ParseException (#<Iconv::InvalidCharacter:"??偒数 (followed by a few thousand similar looking chinese characters)
?偒数潲琾"
, ["\
"
]>
/Library/Ruby/Site/1.8/rexml/encodings/ICONV.rb:7:in `conv'
/Library/Ruby/Site/1.8/rexml/encodings/ICONV.rb:7:in `decode'

/Library/Ruby/Site/1.8/rexml/source.rb:50:in `encoding='
/Library/Ruby/Site/1.8/rexml/parsers/baseparser.rb:210:in `pull'

/Library/Ruby/Site/1.8/rexml/parsers/treeparser.rb:21:in `parse'
/Library/Ruby/Site/1.8/rexml/document.rb:190:in `build'

/Library/Ruby/Site/1.8/rexml/document.rb:45:in `initialize'

听起来可能不是您的XML文件或REXML处理它的方式问题,而不是Rails / mongrel问题。您可以通过编写一个短脚本来直接(而不是在请求中)读取XML文件并查看其是否仍然失败来进行检查。

假设确实如此,我将考虑几件事。首先,我将检查您是否正在运行最新版本的REXML。几年前,UTF-16处理中存在一个错误(http://www.germane-software.com/projects/rexml/ticket/63)。

我要检查的第二件事是您是否遇到的问题与此类似:http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/ba7b0585c7a6330d。如果是这样,您可以在该线程中尝试解决方法。

如果以上方法均无济于事,请回复并提供更多信息,例如尝试读取文件时遇到的异常。


实际上,我认为您的问题可能与我在本文中详述的问题有关。如果您是我,我将在BinPad模式下在TextPad中将其打开,并在XML开始之前查看是否有任何字节顺序标记。


您是否尝试过使用JRuby进行此操作?我听说JRuby更好地支持Unicode字符串。

您可以尝试的另一件事是使用另一个XML解析库,例如libxml ou Hpricot。

REXML是您可以使用且可能无法扩展的最慢的Ruby XML库之一。


由于要使其正常工作,我只需要将第一个XML元素的编码属性更改为具有值UTF-8而不是UTF-16,该XML文件实际上就是UTF-8,并且由生成该文件的应用程序错误地标记。

XML文件是FileMaker Pro Advanced 8.5在OS X 10.5.4上生成的FileMaker DDR导出。


推荐阅读

    linux文件常用命令?

    linux文件常用命令?,工作,地址,信息,系统,命令,目录,标准,情况,管理,常用命

    文件夹排序linux命令?

    文件夹排序linux命令?,系统,数字,信息,工作,时间,命令,管理,设备,单位,工具,

    linux命令拷贝文件?

    linux命令拷贝文件?,系统,文件,命令,目录,情况,源文件,目标,文件夹,选项,语

    压缩文件夹命令linux?

    压缩文件夹命令linux?,系统,软件,命令,工具,电脑,文件,文件名,格式,选项,目

    linux配置文件夹命令?

    linux配置文件夹命令?,地址,系统,工作,信息,命令,标准,服务,名称,位置,文件,l

    linux管理文件的命令?

    linux管理文件的命令?,系统,管理,工作,命令,信息,基础,目录,工具,文件,操作,l

    linux命令行关闭网页?

    linux命令行关闭网页?,服务,系统,状态,管理,命令,进程,文件,模式,指令,主机,l

    linux命令行文件夹?

    linux命令行文件夹?,系统,名称,文件夹,不了,命令,文件,名字,通用,数据,首次,l

    linux退出文件命令行?

    linux退出文件命令行?,状态,档案,命令,电脑,编辑,文件,模式,界面,指令,键盘,l

    linux文件io命令?

    linux文件io命令?,系统,设备,时间,地址,平均,信息,服务,工具,报告,网络,嵌入

    改文件linux命令行?

    改文件linux命令行?,地址,系统,工作,信息,数字,文件,命令,设备,密码,权限,lin

    拷贝文件夹linux命令?

    拷贝文件夹linux命令?,系统,地址,服务,信息,密码,情况,单位,项目,命令,文件,l

    进入文件夹linux命令?

    进入文件夹linux命令?,系统,密码,终端,目录,标的,一致,传播,图片,环境,工作,l

    d文件比较命令linux?

    d文件比较命令linux?,工作,系统,命令,地址,文件,信息,对比,数字,名称,一致,Li

    linux命令行文件夹?

    linux命令行文件夹?,系统,名称,文件夹,不了,命令,文件,名字,通用,数据,首次,l

    打包文件命令linux?

    打包文件命令linux?,系统,时间,工具,名称,命令,文件,目录,格式,表示,详细信

    linux删除命令文件夹?

    linux删除命令文件夹?,系统,数据,通用,文件夹,命令,文件,环境,百度,不了,名

    linux命令文件授权?

    linux命令文件授权?,系统,工具,权限,文件,档案,数字,软件,信息,时间,电脑,lin

    linux文件io命令?

    linux文件io命令?,系统,设备,时间,地址,平均,信息,服务,工具,报告,网络,嵌入

    linux中文件编辑命令?

    linux中文件编辑命令?,系统,工作,工具,信息,地址,发行,命令,第一,检测,基础,l