【发布时间】:2011-01-31 11:32:43
【问题描述】:
我在处理 UTF-8、XML 和 Perl 时遇到了问题。以下是最小的 一段代码和数据,以便重现问题。
这是一个需要解析的 XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<test>
<words>בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת</words>
<words>בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת</words>
<words>בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת</words>
[<words> .... </words> 148 times repeated]
<words>בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת</words>
<words>בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת</words>
</test>
解析是用这个 perl 脚本完成的:
use warnings;
use strict;
use XML::Parser;
use Data::Dump;
my $in_words = 0;
my $xml_parser=new XML::Parser(Style=>'Stream');
$xml_parser->setHandlers (
Start => \&start_element,
End => \&end_element,
Char => \&character_data,
Default => \&default);
open OUT, '>out.txt'; binmode (OUT, ":utf8");
open XML, 'xml_test.xml' or die;
$xml_parser->parse(*XML);
close XML;
close OUT;
sub start_element {
my($parseinst, $element, %attributes) = @_;
if ($element eq 'words') {
$in_words = 1;
}
else {
$in_words = 0;
}
}
sub end_element {
my($parseinst, $element, %attributes) = @_;
if ($element eq 'words') {
$in_words = 0;
}
}
sub default {
# nothing to see here;
}
sub character_data {
my($parseinst, $data) = @_;
if ($in_words) {
if ($in_words) {
print OUT "$data\n";
}
}
}
当脚本运行时,它会生成out.txt 文件。问题出在这
第 147 行的文件。第 22 个字符(在 utf-8 中由 \xd6 \xb8 组成)被拆分
在 d6 和 b8 之间换行。这不应该发生。
现在,如果其他人有这个问题或可以重现它,我很感兴趣。 以及为什么我会遇到这个问题。 我在 Windows 上运行这个脚本:
C:\temp>perl -v
This is perl, v5.10.0 built for MSWin32-x86-multi-thread
(with 5 registered patches, see perl -V for more detail)
Copyright 1987-2007, Larry Wall
Binary build 1003 [285500] provided by ActiveState http://www.ActiveState.com
Built May 13 2008 16:52:49
【问题讨论】: