gpt4 book ai didi

perl - 在 Win32 Perl 中使用 XML::Twig 字符串损坏和不可打印字符

转载 作者:行者123 更新时间:2023-12-01 17:25:33 28 4
gpt4 key购买 nike

这是一个非常奇怪的问题。我几乎花了一整天的时间才将其缩减为一个完整演示问题的小型可执行脚本。

问题摘要:我正在使用 XML::Twig从 XML 文件中提取数据片段,然后将该数据片段粘贴到另一条数据的中间,我们将其称为父数据。当我开始时,父数据的开头有一个奇怪的不可打印字符。它是供应商提供的数据,所以我无法控制它。我的问题是,当我将数据片段粘贴到父数据的中间后,最终产品除了最初开始的字符之外,在其开头还有一个 new 不可打印字符。这个新的不可打印字符既不在父数据中,也不在子数据片段中。我不知道它从哪里来,也不知道它是如何进入我的数据的。

我怀疑这是一个 XML::Twig 错误,因为在 while 循环中从文件句柄读取一行时会发生字符串损坏,但当我删除 XML::时,我未能成功重现问题。 Twig 代码在我的脚本中,所以我不得不把它留在里面。

这是我第一次尝试处理字符串中的不可打印字符。我是否需要做一些特殊的事情,而不是将它们视为普通的字符串或其他东西?

我在 Windows XP 上使用 ActiveState Perl 5.10.1 和 XML::Twig 3.32(最新)以及 Eclipse 3.5.1 IDE。

这是一个演示该问题的脚本:

use strict; 
use warnings;
use XML::Twig;

my $FALSE = 0;
my $TRUE = 1;
my $name = 'KurtsProgram';
my $task = 'MainTask';
my $hidden_char = "\xBF";
my $data = $hidden_char .
'(*********************************************
Data-File-Header-Junk
**********************************************)

PROGRAM MainProgram ()
END_PROGRAM

TASK SecondaryTask ()
END_TASK

TASK MainTask ()
MainProgram;
END_TASK
';
my $new_data = insertProgram( $name, $task, $data );

# test to see if results start out as expected
if ( $new_data =~ m/^\Q$hidden_char\E/ ) {
print "SUCCESS\n";
}
else {
print STDERR "ERROR: What happened?\n";
print STDERR "ORIGINAL: \n$data\n";
print STDERR "MODIFIED: \n$new_data\n";
}

sub insertProgram {
my ( $local_name, $local_task, $local_data ) = @_;

# get program section from XML template
my $twig = new XML::Twig;
$twig->parse( '<?xml version="1.0"?>
<TemplateSet>
<PROGRAM>PROGRAM <Name>ProgramNameGoesHere</Name> ()
END_PROGRAM</PROGRAM>
<TASK>TASK <Name>TaskNameGoesHere</Name> ()
END_TASK</TASK>
</TemplateSet>
' );
my $program = $twig->root->first_child('PROGRAM');

# replace program name in XML template
$program->first_child('Name')->set_text($local_name);
my $insert = $program->text();

# stick modified program into data
if ( $local_data =~ s/(\s+PROGRAM\s+[^\s]+\s+\()/\n\n $insert $1/ ) {
# found it and inserted new program
}
else {
# not found
return;
}

# add program name to task list
my $added_program_to_task = $FALSE;
my $found_start = $FALSE;
my $found_end = $FALSE;
my $new_data = "";
# open string as a filehandle for line by line processing
my $filehandle;
open( $filehandle, '<', \$local_data )
or die("Can't open string as a filehandle: $!");
while (defined (my $line = <$filehandle>)) {
# look for start of our task
if (
( !$found_start ) &&
( $line =~ m/\s+TASK\s+\Q$local_task\E\s+\(/ )
) {
# found the task!
$found_start = $TRUE;
}

# look for end of our task
if (
( $found_start ) && ( !$found_end ) &&
( $line =~ m/\s+END_TASK/ )
)
{
# found the end tag for the task section!
$found_end = $TRUE;

# add the program name to the bottom of the list
$line = " " . $local_name . ";\n" . $line;
$added_program_to_task = $TRUE;
}

# compile new data from processed line or original line
$new_data = $new_data . $line;
}
close($filehandle);

if ($added_program_to_task) {
# success
}
else {
# unable to find task
return;
}

return $new_data;
}

当我运行此脚本时,我得到以下输出:

ERROR: What happened?
ORIGINAL:
¿(*********************************************
Data-File-Header-Junk
**********************************************)

PROGRAM MainProgram ()
END_PROGRAM

TASK SecondaryTask ()
END_TASK

TASK MainTask ()
MainProgram;
END_TASK

MODIFIED:
¿(*********************************************
Data-File-Header-Junk
**********************************************)

PROGRAM KurtsProgram ()
END_PROGRAM

PROGRAM MainProgram ()
END_PROGRAM

TASK SecondaryTask ()
END_TASK

TASK MainTask ()
MainProgram;
KurtsProgram;
END_TASK

您可以在 MODIFIED 中的 M 正下方看到添加到数据前面的额外字符。

最佳答案

它已对字符进行 ISO-8859-1 到 UTF-8 编码转换:\xBF -> \xC2\xBF

XML::Twig 将其所有输入转换为 UTF-8 ( see here )。

您可以使用 keep_encoding 告诉 Twig 保留输入编码选项(另请参阅 XML::Twig 常见问题解答: My XML documents/data are produced by tools that do not grok Unicode, will XML::Twig help me there? )。

但也许保留 UTF-8 更好,或者默默地删除该字符,具体取决于您要如何处理它。

关于perl - 在 Win32 Perl 中使用 XML::Twig 字符串损坏和不可打印字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1704163/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com