我正在编写一个需要从XML文件中提取一些数据的Perl脚本。
XML文件本身使用UTF-8编码。但是,出于某种原因,我从文件中提取的内容最终被编码为ISO-8859-1。文档说明传递给我的处理程序的任何东西都应该是UTF-8,但它不是。
解析器基本上是这样的:
my $parser = XML::Parser->new( Handlers => {
# Some unrelated handlers here
Char => sub {
my ( $expat, $string ) = @_;
if ( exists $data->{$curId}{$curField} ) {
$data->{$curId}{$curField} .= $string;
} else {
$data->{$curId}{$curField} = $string;
}
} ,
} );
我尝试了以下变体进行实际解析:
$parser->parsefile
解析,没有选项; $parser->parsefile
使用ProtocolEncoding
选项解析; open( $handle , "<file.xml" )
打开文件,然后通过$parser->parse
; open( $handle , '<:utf8' , "file.xml" )
打开,然后通过$parser->parse
解析。此外,我已尝试在文件中包含和不包含<?xml encoding="utf-8"?>
标题的每个版本。
在所有情况下,使用ISO-8859-1对$data->{$curId}{$curField}
中的内容进行编码。
我做错了什么?
答案 0 :(得分:1)
我知道你已经在评论中找到了米歇尔的答案,但我会添加一些内容。使用任何编码,您必须严格要知道您正在接收什么以及您要发送什么。如果你需要什么,不要依赖环境;最终其他人将使用您的程序,并有一个搞砸的环境。
在阅读文件时,请勿使用':utf8'图层。如果八位字节实际上是UTF-8,则无关紧要:
open my $fh, '<:encoding(UTF-8)', $filename or ...;
无论您认为输出句柄是什么,请明确设置它。有多种方法可以做到这一点:
use open ':encoding(utf8)';
从命令行,您可以使用带有S标志的-C开关来使标准句柄UTF-8:
perl -CS input.xml
Tom Christiansen has a long list of things you need to pay attention to。
答案 1 :(得分:0)
$data->{$curId}{$curField}
是否有utf8标志?
如果使用utf8标志关闭的字符串连接带有utf8标志的字符串,Perl会将后者转换为Unicode。这是问题的常见原因。