Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PerlXML::细枝字符编码_Xml_Perl_Encoding_Utf 8 - Fatal编程技术网

PerlXML::细枝字符编码

PerlXML::细枝字符编码,xml,perl,encoding,utf-8,Xml,Perl,Encoding,Utf 8,我有一组XML文件,其中包含非简单ASCII字符和编码字符,例如: ... many 8-bit characters such as é, ⪚, and ñ. (第二个字符是的符号和分号版本。)⪚. 第一个和第三个是未转义的角色。) 这些文件是UTF-8格式的 当我使用XML::Twig运行Perl脚本时,实体(上面的第2个字符)会变成未知字符(当它写入文件时,我会收到“打印中的宽字符”消息) 这是我的密码。处理程序所做的只是读取XML,而不是进行任何更改: my $

我有一组XML文件,其中包含非简单ASCII字符和编码字符,例如:

... many 8-bit characters such as é, ⪚, and ñ.
(第二个字符是的符号和分号版本。)⪚. 第一个和第三个是未转义的角色。)

这些文件是UTF-8格式的

当我使用XML::Twig运行Perl脚本时,实体(上面的第2个字符)会变成未知字符(当它写入文件时,我会收到“打印中的宽字符”消息)

这是我的密码。处理程序所做的只是读取XML,而不是进行任何更改:

 my $twig= XML::Twig->new( 
   comments => 'keep',
   output_encoding => 'UTF-8',
#   keep_encoding => 1,
   twig_handlers => { topicref => \&topicref_processing,
            xref => \&topicref_processing,
            link => \&topicref_processing},
      pretty_print => 'indented',

 );

 $twig->parsefile($file);
 my($outfile) = $file;
 $outfile =~ s/([.]dita)/.out$1/i;

open(NEW,">$outfile");
$twig->flush( \*NEW);
close(NEW);
如果我添加keep_encoding=>1(上面已注释掉),实体将被保留,但第一个和第三个字符将被损坏:

...such as é, ⪚, and ñ.
如果我将UTF-8编码添加到刷新:

open(NEW,'>:encoding(UTF-8)', $outfile);
更奇怪的是:

...such as Ã?©, ⪚, and Ã?±. 
你知道如何毫发无损地穿过人物和实体吗? 非常感谢。
Scott

除了确保输入和输出IO通道设置为UTF-8编码之外,您无需做任何特殊的事情。打印中的
宽字符
警告表示您正试图将宽字符(大于255的代码点)打印到只有字节语义的通道

如果我使用这个数据

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <text>... many 8-bit characters such as é, &#10906;, and ñ.</text>
</root>
输出

... many 8-bit characters such as é, &#10906;, and ñ.

更新

这是为了解释你得到的输出

如果我添加keep_encoding=>1(上面已注释掉),实体将被保留,>但第一个和第三个字符将被损坏:

...such as é, &#10906;, and ñ.
…例如λλ,⪚, ñ

这些字符没有损坏,文本输出为UTF-8,但无论您使用什么方式查看它,都需要字节编码,类似于ISO-8859-1。当编码为UTF-8时,e-acute字符
U+00E9
是一个双字节字符
0xC3 0xA9
。当解释为ISO-8859-1时,0xC3是A-tilde,0xA9是版权标志,这正是您所看到的。如果您使用的是预期的UTF-8编码数据,那么您将看到单字符e-acute

如果我将UTF-8编码添加到刷新:

open(NEW,'>:encoding(UTF-8)', $outfile);
打开(新的,'>:编码(UTF-8)'$outfile)

更奇怪的是:

...such as �©, &#10906;, and �±. 
…如Ã?┱,⪚, 和ñ


这里发生的事情是,虽然来自
XML::Twig
的字符串已经编码为UTF-8,但数据没有标记为UTF-8。这意味着构成UTF-8编码字符的两个字节被视为单独的字符,它们被再次编码,总共四个字符

除了确保输入和输出IO通道设置为UTF-8编码之外,您无需做任何特殊的事情。打印中的
宽字符
警告表示您正试图将宽字符(大于255的代码点)打印到只有字节语义的通道

如果我使用这个数据

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <text>... many 8-bit characters such as é, &#10906;, and ñ.</text>
</root>
输出

... many 8-bit characters such as é, &#10906;, and ñ.

更新

这是为了解释你得到的输出

如果我添加keep_encoding=>1(上面已注释掉),实体将被保留,>但第一个和第三个字符将被损坏:

...such as é, &#10906;, and ñ.
…例如λλ,⪚, ñ

这些字符没有损坏,文本输出为UTF-8,但无论您使用什么方式查看它,都需要字节编码,类似于ISO-8859-1。当编码为UTF-8时,e-acute字符
U+00E9
是一个双字节字符
0xC3 0xA9
。当解释为ISO-8859-1时,0xC3是A-tilde,0xA9是版权标志,这正是您所看到的。如果您使用的是预期的UTF-8编码数据,那么您将看到单字符e-acute

如果我将UTF-8编码添加到刷新:

open(NEW,'>:encoding(UTF-8)', $outfile);
打开(新的,'>:编码(UTF-8)'$outfile)

更奇怪的是:

...such as �©, &#10906;, and �±. 
…如Ã?┱,⪚, 和ñ


这里发生的事情是,虽然来自
XML::Twig
的字符串已经编码为UTF-8,但数据没有标记为UTF-8。这意味着构成UTF-8编码字符的两个字节被视为单独的字符,它们被再次编码,总共四个字符。首先,在您的情况下,应该使用
保持编码
,而不是。这是一个古老的选项,可以追溯到远古时代,当时拉丁语1是一种常用的编码方式,而perl对unicode不太好。我在这里说的是5.8之前。该选项为生活在全拉丁世界的人们提供了一种处理XML的方法,而不必处理unicode。将其与utf-8数据一起使用会导致疯狂(以及您发现的编码问题)

如其他回答中所述,需要在
utf8
模式下打开输出文件,无论是在
open
还是通过
use utf8::all。这消除了
宽字符
警告,并避免了更糟糕的情况,即如果输出仅包含ascii和扩展ascii字符,则输出将转换为拉丁文1(perl这样做是为了保持向后兼容性,如果从输入中删除
⪚;
,则可以看到它)

完成此操作后,输出文件将以正确的utf-8格式显示,未进行扫描。如果显示不正确,可能是您的终端不支持utf-8

如果需要转义所有非ascii字符,可以使用
output\u filter=>“safe”
选项,如下代码所示

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;
use utf8::all; # either this or open the output file with '>:utf8'

my $file= 'test_enc.dita';

 my $twig= XML::Twig->new( 
   comments => 'keep',
   # escapes all non-ascii characters (including accented ones)
   output_filter => 'safe', 
   twig_handlers => { topicref => \&topicref_processing,
            xref => \&topicref_processing,
            link => \&topicref_processing},
      pretty_print => 'indented',

 );

 $twig->parsefile( $file);
 my($outfile) = $file;
 $outfile =~ s/([.]dita)/.out$1/i;

# current best practices recommend the  use the 3 args form of 
# open and lexical filehandles
open( my $out,'>', $outfile);
$twig->flush( $out);
close( $out);
除了keep_编码(这是一种黑客行为)之外,没有真正的方法来忠实地保存编码/非编码的字符形式。如果您确实需要将扩展ascii字符保留为字符,并将其他字符编码为数字字符实体,您将提供一个自定义函数来
output\u filter
,它应该接收字符串(所有utf-8字符),并将字符串返回到输出(一些字符编码为数字实体)

也就是说,我不确定你是否需要如此忠诚