Perl XML findnodes错误

时间:2014-11-02 11:37:52

标签: 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 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。

谢谢!

2 个答案:

答案 0 :(得分:0)

我注意到"Getötet" is German for "killed"。可能是您正在使用的特定设置不适合解析并在内存中保存10MB输入文件,这通常需要XPath查询才能运行。诊断&#34; Killed&#34;不是很有帮助,但有时表明Unix类型的操作系统(例如Linux)已经耗尽了相关进程的可用内存,并且只是简单地杀死了进程。

这就是我要做的事情:

  1. 删除文件中的许多<data>块,保留文件格式相同,然后重新运行程序。
  2. 如果成功,可能是文件太大的情况,但现在你有一个较小的文件,可以测试你的程序。
  3. 或者,如果它仍然没有工作继续使文件更小,直到它,或者你有一个非常小文件,表现出这种行为,并且然后再问一遍。
  4. 如果是文件大小问题,处理它的一种方法是为程序提供更多内存 - 增加物理和/或虚拟内存大小,减少同时运行的其他进程。但是,如果您的数据可能会在此计划的整个生命周期内增长,那么这只是一个临时解决方案。

    更长远的方法是重新考虑您如何访问数据。处理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}}