Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl XML findnodes错误_Xml_Perl_Xpath - Fatal编程技术网

Perl XML findnodes错误

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

在我的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" 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;
}