在我的Perl脚本中,我尝试使用XML :: XPath解析XML文件。 我做了以下事情:
my $xml = XML::XPath->new(filename => "dat.xml");
foreach my $row ($xml->findnodes('/pack/data')) {
...
}
我在findnodes中收到错误,但我现在不知道如何找到它。脚本只打印出“Getötet”。我不使用perl die功能。
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大约10 MB。
谢谢!
答案 0 :(得分:0)
我注意到"Getötet" is German for "killed"。可能是您正在使用的特定设置不适合解析并在内存中保存10MB输入文件,这通常需要XPath查询才能运行。诊断&#34; Killed&#34;不是很有帮助,但有时表明Unix类型的操作系统(例如Linux)已经耗尽了相关进程的可用内存,并且只是简单地杀死了进程。
这就是我要做的事情:
<data>
块,保留文件格式相同,然后重新运行程序。如果是文件大小问题,处理它的一种方法是为程序提供更多内存 - 增加物理和/或虚拟内存大小,减少同时运行的其他进程。但是,如果您的数据可能会在此计划的整个生命周期内增长,那么这只是一个临时解决方案。
更长远的方法是重新考虑您如何访问数据。处理XML文件有不同的方法,不一次需要内存中的整个文件,例如Simple API for XML(SAX),尽管完全< / em>使用XML的不同方法,与简单地使用XPath相比,需要花费大量的工作。但它会继续在越来越大的输入文件上工作。
答案 1 :(得分:0)
我建议改为findnodes
- 原因有两个。如果你愿意的话,你仍然可以twig_handlers
使用它,并且非常整洁。
但是,它还允许您#!/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>
有效地处理更大的XML文件。 10MB不太可能成为问题,但请记住,XML内存占用量很容易成为源代码的10倍。
所以你可以:
New data node:
d0 = 88485488
d1 = 58915015
d2 = 56
d3 = 0
New data node:
d0 = 88485511
d1 = 16023676
d2 = 56
d3 = 0
打印:
#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;
}
但你仍然可以按照你想要的方式来寻找节点:
{{1}}