为什么XML :: LibXML即使在禁用它们时也会出现打印错误?

pol*_*mon 4 html perl libxml2 xml-parsing

我正在使用XML::LibXML解析文档.

它背后的HTML文件有一些小错误,解析器报告它们:

http://is.gd/create.php?longurl=http://google.com:15: validity error : ID smallink already defined
nal URL was <a href="http://google.com">http://google.com</a><span id="smallink"
                                                                                ^
http://is.gd/create.php?longurl=http://google.com:15: validity error : ID smallink already defined
and use <a href="http://is.gd/fNqtL-">http://is.gd/fNqtL-</a><span id="smallink"
                                                                                ^
Run Code Online (Sandbox Code Playgroud)

但是,我禁用了错误报告:

my $parser = XML::LibXML->new();
$parser->set_options({ recover           => 2,
                       validation        => 0,
                       suppress_errors   => 1,
                       suppress_warnings => 1,
                       pedantic_parser   => 0,
                       load_ext_dtd      => 0, });

my $doc = $parser->parse_html_file("http://is.gd/create.php?longurl=$url");
Run Code Online (Sandbox Code Playgroud)

我唯一的选择是抑制这些错误,就是运行脚本2>/dev/null,我不想要.有人可以帮助我摆脱那些错误吗?

raf*_*afl 6

我不知道你是否正在要求XML :: LibXML不打印它的警告.我假设你是,这是XML :: LibXML中的一个错误(你也应该向作者报告),并且只解决如何抑制警告.

每次打印警告时,perl都会查找值$SIG{__WARN__},如果包含代码引用,则调用它而不是打印警告本身.

您可以使用该停止打印要忽略的警告STDERR.但是,你应该小心这一点.确保只抑制误报,而不是所有警告.警告通常很有用.此外,请确保将您的使用本地化$SIG{__WARN__}到尽可能小的范围,以避免奇怪的副作用.

# warnings happen just as always
my $parser = ...;
$parser->set_options(...);

{ # in this scope we filter some warnings
    local $SIG{__WARN__} = sub {
        my ($warning) = @_;
        print STDERR $warning if $warning !~ /validity error/;
    };

    $parser->parse_html_file(...);
}

# more code, now the warnings are back to normal again
Run Code Online (Sandbox Code Playgroud)

另请注意,这些都是假设这些警告来自perl-space.libxml2(C库XML :: LibXML)很有可能直接将警告写入stderr本身.$SIG{__WARN__}将无法阻止它这样做.