XML::Twig格式不正确(无效令牌)在执行就地编辑后解析文件
我正在处理一个需求,在这个需求中,我们的应用程序接收一个外部soapxml响应,该响应按原样写入一个文件。soap响应中的特定元素将具有嵌入的xml,该xml将html实体“”作为转义字符。目标是XML::Twig格式不正确(无效令牌)在执行就地编辑后解析文件,xml,perl,xml-twig,Xml,Perl,Xml Twig,我正在处理一个需求,在这个需求中,我们的应用程序接收一个外部soapxml响应,该响应按原样写入一个文件。soap响应中的特定元素将具有嵌入的xml,该xml将html实体“”作为转义字符。目标是 用“”替换所有溢出的字符 解析每个元素并解码嵌入的base64编码pdf,并将所有解码的页面数据合并到单个pdf文件中 soap响应如下所示: <?xml version="1.0" encoding="utf-8"?> <soap:Envel
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<RequestResponse>
<RequestResult><myAPI xmlns="http://integration.myapi.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://integration.myapi.com C:\MessageSet\DocumentInquiry.xsd"><myHeader Version="1.1">test Header</myHeader><Page Number="1" Format="PDF" ><Value>JVBERi0xLjYNJeLjz9MNCjI0IDAgb2Jq==</Value></Page><Page Number="2" Format="PDF" ><Value>JVBERi0xLjYNJeLjz9MNCjI0IDAgb2Jq==</Value></Page></myAPI>
</RequestResult>
</RequestResponse>
</soap:Body>
</soap:Envelope>
我怀疑在替换编码的html实体后,编辑的文件正在丢失原始编码,这就是为什么在我的细枝定义中包含KeepEncoding。但是仍然得到无效的令牌。
此外,如果我在浏览器中打开带有解码html实体的编辑文件,则该文件渲染良好,没有可见错误
你知道被编辑的文件有什么问题吗?感谢您的指点。我偏爱XML::LibXML。这就是我要用的:
使用XML::libxmlqw();
使用XML::LibXML::XPathContext qw();
my$doc=XML::LibXML->load_XML(location=>“in.XML”);
我的$xpc=XML::LibXML::XPathContext->new($doc);
$xpc->registerNs(soap=>)http://schemas.xmlsoap.org/soap/envelope/" );
我的($result\u节点)=
$xpc->findnodes('/soap:Envelope/soap:Body/RequestResponse/RequestResult');
if($result\u节点){
my$result_xml=$result_node->textContent();
utf8::encode($result\uXML);
$result\u node->childNodes()的$\u->unbindNode();
我的$result\u doc=XML::LibXML->load\u XML(字符串=>$result\u XML);
$result\u node->appendChild($result\u doc->documentElement);
}
$doc->toFile(“out.xml”);
说到字符编码,我假设内部文档不是双重编码的。如果是这种情况,$result\u xml
最初包含解码文本。但是解析器需要编码文本。如果没有
来说明其他情况,则应使用UTF-8。这解释了“在运行此脚本并传入接收到的soap响应文件后”对utf8::encode
Re的调用,那么您的脚本会生成什么不正确的XML?提示:die(…);退出代码>毫无意义die
抛出异常,因此永远不会到达以下exit
。删除对退出的调用。(无论如何,在出现错误时,您不应该以默认退出代码0
退出!)
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<RequestResponse>
<RequestResult>
<myAPI xmlns="http://integration.myapi.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://integration.myapi.com C:\MessageSet\DocumentInquiry.xsd">
<myHeader Version="1.1">test Header</myHeader>
<Page Number="1" Format="PDF" >
<Value>JVBERi0xLjYNJeLjz9MNCjI0IDAgb2Jq==</Value>
</Page>
<Page Number="2" Format="PDF">
<Value>JVBERi0xLjYNJeLjz9MNCjI0IDAgb2Jq==</Value>
</Page>
</myAPI>
</RequestResult>
</RequestResponse>
</soap:Body>
</soap:Envelope>
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
use MIME::Base64;
use Data::Dumper qw(Dumper);
my ($filename, $downloadLocation) = @ARGV;
if (not defined $filename) {
die "Need file name\n";
exit;
}
if (not defined $downloadLocation) {
die "Need download location\n";
exit;
}
# Take a back up of the file received
rename($filename, $filename.'.bak');
open(my $infh,'<:encoding(utf-8)', $filename.'.bak') or die "Error opening $filename: $!";
open(my $outfh,'>:encoding(utf-8)', $filename) or die "Error opening $filename: $!";
while(<$infh>)
{
# replace < with < and > with >
$_ =~ s/</</g;
$_ =~ s/>/>/g;
print $outfh $_;
}
close($infh);
close($outfh);
# create a twig for elements that hold pdf data
my $t= XML::Twig->new(
keep_spaces => 1,
keep_encoding => 1,
KeepEncoding => 1,
twig_roots => { 'Page[@Format]/Value' => \&decode_n_purge },
);
$t->parse($filename);
sub decode_n_purge {
my( $t, $elt)= @_;
my $epoc = time();
# Use the open() function to create the file where pdf data will be written.
unless(open DEST_FILE, '>'.$downloadLocation/$epoc.pdf) {
# Die with error message
# if we can't open it.
die "\nUnable to create $downloadLocation\n";
}
binmode DEST_FILE;
my $buf;
open(FILE, $filename) or die "$!";
# write decoded pdf data to the destination in chunks
while (read(FILE, $buf, 4000*57)) {
print DEST_FILE decode_base64($buf);
}
close FILE;
close DEST_FILE;
$t->purge; # frees the memory
}
$t->parse($filename);