![](/img/trans.png)
[英]How to Include one xml file in another xml without root node of source xml file?
[英]Perl: How to handle a stream of XML Objects without a root node
我需要用Perl解析一个巨大的文件。 (所以我将使用流解析器..)该文件包含多个XML文档(对象),但没有根节点。 这会导致XML解析器在第一个Object之后中止,就像它应该的那样。 答案可能是修复假根节点之前/之后。
<FAKE_ROOT_TAG>Original Stream</FAKE_ROOT_TAG>
由于文件很大(> 1GByte),我不想复制/重写它,而是宁愿使用透明的类/模块(对于XML Parser)“合并”或“合并”多个流。
stream1 : <FAKE_ROOT_TAG> \
stream2 : Original Stream from file > merged stream
stream3 : </FAKE_ROOT_TAG> /
你能指点我这个问题的模块或示例代码吗?
这是一个简单的例子,说明如何通过将伪文件句柄传递给XML解析器来实现它。 此对象重载readline
操作符( <>
)以返回假根标记,其中包含文件中的行。
package FakeFile;
use strict;
use warnings;
use overload '<>' => \&my_readline;
sub new {
my $class = shift;
my $filename = shift;
open my $fh, '<', $filename or die "open $filename: $!";
return bless { fh => $fh }, $class;
}
sub my_readline {
my $self = shift;
return if $self->{done};
if ( not $self->{started} ) {
$self->{started} = 1;
return '<fake_root_tag>';
}
if ( eof $self->{fh} ) {
$self->{done} = 1;
return '</fake_root_tag>';
}
return readline $self->{fh};
}
1;
如果您的解析器需要一个真正的文件句柄(例如使用像sysread
这样的东西),这将无法工作,但也许您会发现它是鼓舞人心的。
用法示例:
echo "one
two
three" > myfile
perl -MFakeFile -E 'my $f = FakeFile->new( "myfile" ); print while <$f>'
这是PerlMonks提取的一个技巧:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Parser;
use XML::LibXML;
my $doc_file= shift @ARGV;
my $xml=qq{
<!DOCTYPE doc
[<!ENTITY real_doc SYSTEM "$doc_file">]
>
<doc>
&real_doc;
</doc>
};
{ print "XML::Parser:\n";
my $t= XML::Parser->new( Style => 'Stream')->parse( $xml);
}
{ print "XML::LibXML:\n";
my $parser = XML::LibXML->new();
my $doc = $parser->parse_string($xml);
print $doc->toString;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.