【发布时间】:2016-10-10 04:34:36
【问题描述】:
我编写了一个脚本,它将散列转换为 XML,并从 XML::LibXML::Document 返回 toString 函数的结果。如果不破坏 XML 文档中的 UTF-8 字符,我似乎不可能打印结果(字符串)。
我尝试将binmode 用于STDOUT,并使用/避免setEncoding 用于XML 文档。两者都没有达到我的预期。
对此的唯一“解决方案”是使用$XML::LibXML::skipXMLDeclaration = 1; 或decode 禁用XML 声明,然后再将其返回到要打印的脚本。
我只是没有得到这个声明行的部分。我什至可以将字符串(使用此声明行)返回到我的第二个脚本,将其写入没有任何残缺字符的文件,如果我直接打印到 STDOUT,则会得到残缺字符。如上所述,我什至尝试过使用binmode。
那么,toString 或一般将 XML 打印到 STDOUT 有什么问题?我错过了什么吗?如果需要,我当然可以提供一些代码。
在这种特定情况下,我刚刚从XML::Simple 切换到XML::LibXML,它与XML::Simple 配合得很好。我知道XML::Simple 不是很好;我只是很好奇为什么它工作得很好,XML::LibXML 让我忙了一整天。
这是我正在使用的代码示例。老实说,这个 sn-p 就像一个魅力,我仍在努力寻找与我的真实脚本的区别,我显然不能在这里发布。但是为了向你展示我在做什么,这可能没问题:
create_xml.pm
#!/usr/bin/perl
package create_xml;
use XML::LibXML;
use utf8;
sub convertHash
{
my ($hash) = @_;
my $xmlDoc = XML::LibXML::Document->new();
$xmlDoc->setEncoding('UTF-8');
my $xmlRoot = $xmlDoc->createElement('TestXML');
foreach my $key (keys %$hash)
{
my $wert = $hash->{$key};
my $element = $xmlDoc->createElement($key);
$element->appendTextNode($wert);
$xmlRoot->appendChild($element);
}
my $wsStatusElement = $xmlDoc->createElement('FixedElement');
$wsStatusElement->appendTextNode(123);
$xmlRoot->appendChild($wsStatusElement);
$xmlDoc->setDocumentElement($xmlRoot);
open(XML, '>', 'test1.xml');
print XML $xmlDoc->toString(1);
close(XML);
return $xmlDoc->toString(1);
}
1;
print_xml.pl
#!/usr/bin/perl
use lib '.';
use create_xml;
use utf8;
my %testhash;
$testhash->{'A'} = 15;
$testhash->{'B'} = 'abc';
$testhash->{'C'} = 'äöüä';
$testhash->{'D'} = '€';
my $xml = create_xml::convertHash($testhash);
open(XML, '>', 'test2.xml');
print XML $xml;
close(XML);
print $xml;
使用此脚本,两个编写的 xml 文件都很好,但最后一次打印的输出被破坏了。我的€ 看起来像这样<D>â�¬</D>。如前所述,这个 sn-p 工作。在发现差异后,我将稍后编辑我的问题。
我终于找到了问题所在。我使用了一个 perlmodule,上面写着use open ':std', ':encoding(UTF-8)';。那么为什么这会破坏我的打印字符,而不是写入文件呢?我仍然很困惑,觉得我错过了一些东西。这是已经 utf8 编码的字符被编码两次的部分吗?有没有重置的选项?
【问题讨论】:
-
我认为我们需要查看一个产生此问题的输入 XML 和 Perl 代码示例。对“致残”的更好描述也会有所帮助。您在哪个平台上工作,您如何检查程序的输出?
-
我附加了一个 sn-p,但现在这个 sn-p 正在工作。这让我很困惑,我会进一步调查。也许有人已经看到了,我的代码可能有什么问题;)