有没有办法让 XML::Twig 理解 UTF-16 编码的 XML 文件?
Is there a way to get XML::Twig to understand a UTF-16-encoded XML file?
有没有办法让 XML::Twig
理解 UTF-16 编码的 XML 文件?
读取文件的代码就是教程里说的:
use warnings;
use strict;
use XML::Twig;
# ...
my $twig=XML::Twig->new(
twig_handlers => { ... },
prety_print => 'indented',
keep_encoding => 1,
};
# ...
$twig->parsefile('myXmlFile.xml'); # <= line 71
错误是:
error parsing tag '<RIBBON>' at /usr/lib/perl5/vendor_perl/5.14/x86_64-cygwin-threads/XML/Parser/Expat.pm line 470
at ../../cv32/res/convert-xml-string2.pl line 71
at ../../cv32/res/convert-xml-string2.pl line 71
XML 是这样开始的:
<?xml version="1.0" encoding="utf-16"?>
按照 Borodin 的建议更改我的打开代码,它仍然不起作用:
# parse the XML file
open(my $xmlIn, '<:encoding(UTF-16)', $xmlFile) or die "Couldn't open xml file '$xmlFile'. $!";
$twig->parse($xmlIn); # <= line 72
错误变为:
encoding specified in XML declaration is incorrect at line 1, column 30, byte 30 at /usr/lib/perl5/vendor_perl/5.14/x86_64-cygwin-threads/XML/Parser.pm line 187
at ../../cv32/res/convert-xml-string2.pl line 72
您的问题很不清楚,并且您没有显示 不 为您工作的 Perl 代码示例。所以我不得不做出很多猜测,而且真的是在黑暗中工作;但我希望这会有所帮助。
XML::Twig
subclasses XML::Parser
,提供了parse
方法。文档说这个
parse(SOURCE [, OPT => OPT_VALUE [...]])
The SOURCE parameter should either be a string containing the whole
XML document, or it should be an open IO::Handle.
这意味着您可以按自己的方式调用 open
,并将文件句柄传递给 XML::Twig->parse
方法。您的代码应如下所示
my $file_name = 'my_file.xml';
open my $xml_fh, '<:encoding(UTF-16)', $file_name
or die qq{Unable to open "$file_name" for input: $!};
my $twig = XML::Twig->new;
$twig->parse($xml_fh);
显然,XML::Twig (XML::Parser) 使用的 XML 解析器不支持
UTF-16。您需要先将 XML 文档转换为支持的编码(例如 UTF-8)。
例如,
use XML::LibXML qw( );
my $xml;
{
open(my $fh, '<:raw', $qfn)
or die $!;
local $/;
$xml = <$fh>;
}
{
my $doc = XML::LibXML->new()->parse_string($xml);
$doc->setEncoding('UTF-8');
$xml = $doc->toString();
}
$twig->parse($xml);
一个更简单的解决方案是 detect/expect UTF-16,解码文档(使用 Encode 的 decode
),使用正则表达式调整编码声明,然后编码文档(使用 Encodes encode
).
有没有办法让 XML::Twig
理解 UTF-16 编码的 XML 文件?
读取文件的代码就是教程里说的:
use warnings;
use strict;
use XML::Twig;
# ...
my $twig=XML::Twig->new(
twig_handlers => { ... },
prety_print => 'indented',
keep_encoding => 1,
};
# ...
$twig->parsefile('myXmlFile.xml'); # <= line 71
错误是:
error parsing tag '<RIBBON>' at /usr/lib/perl5/vendor_perl/5.14/x86_64-cygwin-threads/XML/Parser/Expat.pm line 470
at ../../cv32/res/convert-xml-string2.pl line 71
at ../../cv32/res/convert-xml-string2.pl line 71
XML 是这样开始的:
<?xml version="1.0" encoding="utf-16"?>
按照 Borodin 的建议更改我的打开代码,它仍然不起作用:
# parse the XML file
open(my $xmlIn, '<:encoding(UTF-16)', $xmlFile) or die "Couldn't open xml file '$xmlFile'. $!";
$twig->parse($xmlIn); # <= line 72
错误变为:
encoding specified in XML declaration is incorrect at line 1, column 30, byte 30 at /usr/lib/perl5/vendor_perl/5.14/x86_64-cygwin-threads/XML/Parser.pm line 187
at ../../cv32/res/convert-xml-string2.pl line 72
您的问题很不清楚,并且您没有显示 不 为您工作的 Perl 代码示例。所以我不得不做出很多猜测,而且真的是在黑暗中工作;但我希望这会有所帮助。
XML::Twig
subclasses XML::Parser
,提供了parse
方法。文档说这个
parse(SOURCE [, OPT => OPT_VALUE [...]])
The SOURCE parameter should either be a string containing the whole
XML document, or it should be an open IO::Handle.
这意味着您可以按自己的方式调用 open
,并将文件句柄传递给 XML::Twig->parse
方法。您的代码应如下所示
my $file_name = 'my_file.xml';
open my $xml_fh, '<:encoding(UTF-16)', $file_name
or die qq{Unable to open "$file_name" for input: $!};
my $twig = XML::Twig->new;
$twig->parse($xml_fh);
显然,XML::Twig (XML::Parser) 使用的 XML 解析器不支持 UTF-16。您需要先将 XML 文档转换为支持的编码(例如 UTF-8)。
例如,
use XML::LibXML qw( );
my $xml;
{
open(my $fh, '<:raw', $qfn)
or die $!;
local $/;
$xml = <$fh>;
}
{
my $doc = XML::LibXML->new()->parse_string($xml);
$doc->setEncoding('UTF-8');
$xml = $doc->toString();
}
$twig->parse($xml);
一个更简单的解决方案是 detect/expect UTF-16,解码文档(使用 Encode 的 decode
),使用正则表达式调整编码声明,然后编码文档(使用 Encodes encode
).