【问题标题】:Perl dies on big XML file, using STDINPerl 死在大 XML 文件上,使用 STDIN
【发布时间】:2015-01-20 19:39:16
【问题描述】:

我在运行 perl 脚本时收到此错误:

unclosed token at line 1, column 0, byte 0 at /System/Library/Perl/Extras/5.18/darwin-thread-multi-2level/XML/Parser.pm line 187.

at mysscript.pl line 8.

这是第 8 行,mysscript.pl

$twig->parse( \*STDIN);

我尝试了其他一些变化,例如:

$twig->parse(\*STDIN);
$twig->parse(*STDIN);

但是他们没有工作,我知道它也说我的 perl 系统文件有问题,但我怀疑,我发现有人有同样的问题,他不得不修复他的代码。

【问题讨论】:

    标签: xml macos perl debugging unix


    【解决方案1】:

    这是一个 XML 错误,而不是 Perl 错误。它确实表明您有损坏的 XML。 您可以在解析中通过eval 捕获它。

    但实际上 - 考虑一下 - 问题可能是您只使用 parse 阅读 STDIN 的第一行。 尝试添加:

    { 
        local $/;
        $twig -> parse ( <STDIN> );
    }
    

    但是,对于大型 XML 文件,我非常喜欢 XML::Twig,因为它有一个 purge 方法,可以让您丢弃已经处理过的 XML。 XML 的缺点之一是它的内存占用大约是原始文件大小的 10 倍。因此,如果您的文件特别大,则可能内存不足。

    【讨论】:

    • 检查我的编辑 - 我认为这是因为您只阅读了 XML 的第一行。你的文件有多大?
    • 我认为这不是问题所在,STDIN 应该用这个语法正确解析
    • 您的修复是正确的,因为它将读取整个文件并将 XML 数据传递给parse。然而,问题不在于只读取第一行,因为在原始问题中读取的是 nothing 。当需要 XML 数据字符串时,正在传递文件句柄。让XML::Twig 解析文件的最佳方法是将文件名 传递给parsefile。没有接受文件句柄的方法。
    • @mirod:不,不应该。 OP 代码中的语法完全错误。但 Sobrique 的解决方案是正确的,尽管出于错误的原因不是最佳解决方案。
    • @mirod:我很抱歉并已更正:parse 方法可以使用(引用)文件句柄,所以$twig-&gt;parse(\*STDIN) 应该没问题。
    【解决方案2】:

    XML::Twig 模块只有两种读取要解析的 XML 的基本方式:

    • parse,它需要一个包含 XML 数据作为参数的 字符串

    • parsefile,需要一个字符串,指定要读取的 XML 文件的名称(和路径)

    没有传递打开文件句柄的选项,如果你写$twig-&gt;parse(\*STDIN)$twig-&gt;parse(*STDIN),那么你将分别传递(类似的)字符串GLOB(0x44b574)*main::STDIN,这显然是无效的XML。

    我想您可以从那里计算出您的通话应该是什么样子。如果您在命令行上将文件名作为参数传递,那么最简单的解决方案是编写

    $twig->parsefile(shift)
    

    但如果没有更多信息,我无法为您提供更多帮助。

    【讨论】:

    • 实际上,XML::Twig 确实 支持为parse 方法提供文件句柄。以下是 perldoc 的相关摘录:“$source 参数应该是包含整个 XML 文档的字符串,或者应该是打开的 IO::Handle(又名文件句柄)。”
    • @SamChoukri:谢谢你纠正我。我想我忽略了这一点,因为文档中没有传递文件句柄的示例
    【解决方案3】:

    $twig-&gt;parse( \*STDIN) 是正确的语法,所以这不是导致错误的原因。

    所以看起来您的 XML 有问题,或者某处存在错误。您是否尝试检查您的 XML(使用 xmlwfxmllint 或类似工具)?如果它解析,那么 XML 的编码是什么?如果是 UTF-16,那么这可能是问题所在,libexpat(XML::Twig 所基于的)似乎在使用这种编码时遇到了问题。

    【讨论】:

    • $twig-&gt;parse(*STDIN)错误parse 方法需要一个包含有效 XML 文档的字符串,而不是文件句柄。一般来说,文件句柄可以通过*STDIN\*STDIN作为参数传递,但有些情况下只能接受其中之一,后者是最多的常见的。
    • 糟糕! SO gremlins 吃了我的反斜杠(实际上,我输入了它,但它没有出现在帖子中)。我修好了。
    • 我很抱歉并已更正:parse 方法适用于(引用)文件句柄。
    猜你喜欢
    • 1970-01-01
    • 2017-01-21
    • 1970-01-01
    • 1970-01-01
    • 2017-10-28
    • 1970-01-01
    • 1970-01-01
    • 2022-12-05
    • 2021-11-11
    相关资源
    最近更新 更多