【问题标题】:In Perl, how can I parse an XML file that is too large to fit in available memory?在 Perl 中,如何解析一个太大而无法放入可用内存的 XML 文件?
【发布时间】:2010-07-08 23:27:37
【问题描述】:

我有一个非常大的 XML 文件(如果你介意的话,它是来自 EAD 的 AIXM 文件,但这并不重要)。为了弄清楚它是如何使用的,我想写一个简单的脚本,它遍历每个节点,记录它下面出现了哪些子节点以及出现了多少次,这样我就可以看到哪些节点包含<AptUid>以及是否大多数@ 987654323@ 节点是否有<GeoLat> 节点,诸如此类。

我尝试使用 XML::Simple 将整个内容加载到 hashref 中,但它太大而无法放入内存中。是否有一个 XML 解析器可以让我一次只查看一个文件?

【问题讨论】:

    标签: xml perl


    【解决方案1】:

    【讨论】:

      【解决方案2】:

      您想使用 SAX 解析器 XML::SAX 实现 start_element 和 end_element 方法来构建你的节点树

      【讨论】:

        【解决方案3】:

        试试XML::Parser 模块。应该是你需要的。

        another link

        【讨论】:

        • 一般不建议针对 XML::Parser API 编写新代码。 XML::SAX 是一个类似的 API,但允许使用对象来跟踪解析的状态(而不是全局),并且可以与许多不同的解析器库一起使用。 perl-xml.sourceforge.net/perl-sax
        【解决方案4】:

        您应该使用流式解析器,例如XML::Parser(它又是expat 之上的一层)。您必须为您感兴趣的标签注册处理程序,并自己记账。与 SAX 等其他流模型一样,您不会一次获得文件的完整视图(您在代码中明确使用的子集除外)。

        【讨论】:

        • 问题是我什至不知道存在哪些标签。这就是我要编写程序的原因。
        • 您可以使用 XML::Parser 中的 start 和 end 处理程序来查看哪些标签在哪里。
        【解决方案5】:

        这是一个使用 XML::Parser 的解决方案。欢迎评论。

        use XML::Parser;
        
        %elemMap = ();
        
        @context = ();
        
        sub on_start {
            my ($p, $elemName, @alist) = @_;
            my $parent = @context[-1];
            if ($parent) {
                $elemMap{$parent}{$elemName}++;
            }        
            push(@context, $elemName);
        }
        
        sub on_end {
            pop(@context);
        }
        
        $p = new XML::Parser(Handlers => {Start => \&on_start, End => \&on_end});
        $p->parse(STDIN);
        
        while (my ($elem, $childElems) = each(%elemMap)) {
            while (my ($childElem, $count) = each(%{$childElems})) {
                print "$elem > $childElem: $count\n";
            }
        }
        

        【讨论】:

        • 和我写的差不多。
        【解决方案6】:

        当您第一次尝试找出未知 XML 文件的结构时,请以更少或更多的方式打开它并开始翻阅它。不要使用试图将整个文件加载到内存中的编辑器,除非您非常喜欢等待您的机器。

        在您不知道数据的结构时构建解析器会非常令人沮丧,因此不要先开始编码,而是开始探索,直到您知道足以开始编码。

        【讨论】:

        • 真的吗?您可以“翻阅”一个 1300 万行的文件并记住您看到的所有节点,哪些节点具有 AptUid,以及您在 Rwy 标记下看到的 codeSurface 的哪些值,以及所有内容?是的,对。
        • 不,但我可以了解 XML 文件的布局,并就从哪里开始编码做出明智的决定,而不是跳进去。关于 XML 的好处是它通常是非常重复的,因为它所代表的数据通常一遍又一遍地重复。了解它是如何重复的,问题是如何减少的。
        • 问题似乎不在于理解布局,而是以编程方式处理文件。
        猜你喜欢
        • 2018-07-05
        • 1970-01-01
        • 2015-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-18
        • 2014-01-08
        相关资源
        最近更新 更多