Perl XML findnodes错误
在我的Perl脚本中,我尝试用XML::XPath解析XML文件。 我做了以下工作:Perl XML findnodes错误,xml,perl,xpath,Xml,Perl,Xpath,在我的Perl脚本中,我尝试用XML::XPath解析XML文件。 我做了以下工作: my $xml = XML::XPath->new(filename => "dat.xml"); foreach my $row ($xml->findnodes('/pack/data')) { ... } 我在findnodes中得到一个错误,但我现在不知道如何找到它。脚本只是打印出Getötet。我不使用perl函数 xml看起来像: <?xml version="1.0" e
my $xml = XML::XPath->new(filename => "dat.xml");
foreach my $row ($xml->findnodes('/pack/data')) {
...
}
我在findnodes中得到一个错误,但我现在不知道如何找到它。脚本只是打印出Getötet。我不使用perl函数
xml看起来像:
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE pack SYSTEM "qy.dtd">
<pack>
<data>
<d0>88485488</d0>
<d1>58915015</d1>
<d2>56</d2>
<d3>0</d3>
</data>
<data>
<d0>88485511</d0>
<d1>16023676</d1>
<d2>56</d2>
<d3>0</d3>
</data>
</pack>
我怎样才能找到错误?XML大约有10MB大
谢谢大家! 我注意到了这一点。可能是您使用的特定设置不适合解析10MB的输入文件并将其保存在内存中,这通常是XPath查询正常运行所必需的。终止诊断没有多大帮助,但有时表明Unix类型的操作系统(例如Linux)已耗尽有关进程的可用内存,并已采取简单终止进程的方法
下面是我要做的:
去掉文件中的许多块,保持文件格式不变,然后重新运行程序。
如果成功,很可能是文件太大,但现在您有了一个较小的文件,可以在其上测试您的程序。
或者,如果它仍然不起作用,继续缩小文件直到它起作用,或者您有一个非常小的文件显示这种行为,然后再次询问。
如果是文件大小问题,一种解决方法是为程序提供更多内存—增加物理和/或虚拟内存大小,减少同时运行的其他进程。但是,如果您的数据可能在该程序的生命周期内增长,那么这将只是一个临时解决方案
一个更长远的方法是重新考虑如何访问数据。有不同的方法处理XML文件,这些文件不需要一次将整个文件存储在内存中,例如SAX,尽管这是处理XML的一种完全不同的方法,并且与简单使用XPath相比需要做大量的工作。但它将继续处理越来越大的输入文件。我建议改为使用XML::Twig,原因有二。如果你想的话,你仍然可以用它找到节点,这很好
但是,它还允许您使用细枝处理器来高效地处理较大的XML文件。10MB不太可能是个问题,但请记住,XML内存占用很容易是源的10倍
因此,您可以:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
use XML::Twig;
#set a callback.
sub handle_data {
#twig is the whole thing, data is this node.
my ( $twig, $data ) = @_;
print "New data node:\n";
#read child elements.
foreach my $node ( $data -> children ) {
#print it.
print $node -> tag, " = ", $node -> text, "\n";
}
#discard data thus far procesed.
$twig -> purge;
}
#instantiate the parser, configure the handler.
my $twig = XML::Twig -> new ( twig_handlers => { '/pack/data' => \&handle_data } )
#parse the data FH. Can use 'parsefile' here instead.
$twig -> parse ( \*DATA );
__DATA__
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE pack SYSTEM "qy.dtd">
<pack>
<data>
<d0>88485488</d0>
<d1>58915015</d1>
<d2>56</d2>
<d3>0</d3>
</data>
<data>
<d0>88485511</d0>
<d1>16023676</d1>
<d2>56</d2>
<d3>0</d3>
</data>
</pack>
但您仍然可以按预期的方式执行findnodes:
#instantiate the parser.
my $twig = XML::Twig -> new ( );
#parse the data FH. Can use 'parsefile' here instead.
$twig -> parse ( \*DATA );
foreach my $row ( $twig -> findnodes ( '/pack/data' ) ) {
$row -> print;
}
你是否有严格的使用习惯;使用警告;在脚本的顶部,您是否根据DTD验证了XML?请张贴您的DTD与问题,因为注释出DTD行让文件加载正常。是的,我使用严格;使用警告;一开始。当我从xml文件中删除dtd行时,同样的错误也会发生。两者都是有效的xml/dtd文件。由于版权限制,我不能在这里发布它们。值得注意的是,XML::XPath是一个旧的废弃模块。LibXML提供几乎完全相同的API,使用更少的内存,更快,更少的错误,并且具有更多的特性。
#instantiate the parser.
my $twig = XML::Twig -> new ( );
#parse the data FH. Can use 'parsefile' here instead.
$twig -> parse ( \*DATA );
foreach my $row ( $twig -> findnodes ( '/pack/data' ) ) {
$row -> print;
}