代码之家  ›  专栏  ›  技术社区  ›  DVK

如何使用PerlXML SAX解析器创建XML::Simple数据结构?

  •  3
  • DVK  · 技术社区  · 14 年前

    总结 :我正在寻找一个快速的XML解析器(很可能是一个围绕某个标准SAX解析器的包装器),它将生成与 XML::Simple .

    细节 :

    我们有一个大型的代码基础设施,它依赖于一个接一个地处理记录,并且期望记录是XML::Simple生成的格式的数据结构,因为从侏罗纪早期开始它就一直使用XML::Simple。

    一个简单的XML示例是:

    <root>
        <rec><f1>v1</f1><f2>v2</f2></rec>
        <rec><f1>v1b</f1><f2>v2b</f2></rec>
        <rec><f1>v1c</f1><f2>v2c</f2></rec>
    </root>
    

    例如,粗代码是:

    sub process_record { my ($obj, $record_hash) = @_; # do_stuff }
    my $records = XML::Simple->XMLin(@args)->{root};
    foreach my $record (@$records) { $obj->process_record($record) };
    

    众所周知,XML::Simple非常简单。更重要的是,由于它是一个DOM解析器,并且需要在内存中构建/存储100%的数据,所以速度非常慢并且占用内存。因此,它不是解析由大量小记录逐记录组成的XML文件的最佳工具。

    但是,重新编写整个代码(由大量“进程记录”类方法组成)以使用标准SAX解析器似乎是一项不值得使用资源的大任务,即使是以使用XML::Simple为代价。

    我正在寻找一个现有的模块,它可能基于一个SAX解析器(或者任何内存占用很小的快速模块),可以用来生成 $record hashrefs基于上面所示的可以传递给 $obj->process_record($record) 与xml::simple的hashrefs完全相同。

    我不太关心新模块的接口是什么,例如是否需要调用 next_record() 或者给它一个接受记录的回调coderef。

    3 回复  |  直到 14 年前
        1
  •  7
  •   draegtun    14 年前

    XML::Twig 有一个 简化 方法,您可以调用XML元素,根据文档,该元素表示:

    返回与xml::simple类似的可疑数据结构

    下面是一个例子:

    use XML::Twig;
    use Data::Dumper;
    
    my $twig = XML::Twig->new(
        twig_handlers => {
            rec => \&rec,
        }
    )->parsefile( 'data.xml' );
    
    
    sub rec {
        my ($twig, $rec) = @_;
        my $data = $rec->simplify;
        say Dumper $data;
        $rec->purge;
    }
    

    铌。这个 $RC &清除 立即从内存中清除记录。

    在XML示例中运行它会产生以下结果:

    $VAR1 = {
              'f1' => 'v1',
              'f2' => 'v2'
            };
    
    $VAR1 = {
              'f1' => 'v1b',
              'f2' => 'v2b'
            };
    
    $VAR1 = {
              'f1' => 'v1c',
              'f2' => 'v2c'
            };
    

    我希望是 可疑地 就像XML的结果一样:简单的:)

    /I3AZ/

        2
  •  6
  •   Grant McLean    14 年前

    作为XML::Simple的作者,我只想纠正您问题中的一些误解。

    Simple不是一个DOM解析器,实际上它根本不是一个解析器。它将所有解析任务委托给SAX解析器或XML::解析器。解析的速度将取决于系统中默认的解析程序模块。为xml::simple分发运行“make test”时,输出将列出默认的分析器。

    如果系统上的默认解析器是XML::SAX::purePerl,那么它将很慢,而且更重要的是,它也会出错。如果是这种情况,那么我建议安装xml::expat或xml::expatxs以立即加快速度。(最后安装的SAX解析器将是该点的默认值)。

    尽管如此,您的需求还是有点矛盾,您需要一些将整个文档作为散列返回的东西,但是您不需要一个将整个文档拖进内存的解析器。

    我理解您的短期目标,但是作为一个长期的解决方案,我建议您将代码迁移到XML::libxml。它是一个DOM解析器,但是速度非常快,因为所有的咕噜工作都是用C语言完成的。最好的是,内置的xpath支持使它比xml::simple更易于使用-请参见 this article .

        3
  •  0
  •   blah    14 年前
    推荐文章
    Praxder  ·  SAX XMLParser不工作
    12 年前