为啥即使我禁用 XML::LibXML 仍会出现打印错误?

Posted

技术标签:

【中文标题】为啥即使我禁用 XML::LibXML 仍会出现打印错误?【英文标题】:Why does XML::LibXML keeps printing errors even when I disable them?为什么即使我禁用 XML::LibXML 仍会出现打印错误? 【发布时间】:2011-04-21 15:59:31 【问题描述】:

我正在使用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"
                                                                                ^

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

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");

抑制这些错误的唯一选择是使用2&gt;/dev/null 运行脚本,这是我不想要的。有人可以帮我摆脱这些错误吗?

【问题讨论】:

如果您认为您发现了 Lib::LibXML 的错误,请通过重现该问题的简单示例向作者报告。 【参考方案1】:

我不知道您是否正确地要求 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

还要注意,这一切都是假设这些警告来自 perl-space。 libxml2(在底层使用的 C 库 XML::LibXML)很可能会直接将警告写入 stderr 本身。 $SIG__WARN__ 将无法阻止它这样做。

【讨论】:

【参考方案2】:

一个可能的解决方案是安装一个$SIG__WARN__ 处理程序来过滤消息或只是使所有警告静音:

local $SIG__WARN__ = sub  /* $_[0] is the message */ ;

【讨论】:

据我所知,此用途不需要 BEGIN 块。不过,本地可能是个好主意。

以上是关于为啥即使我禁用 XML::LibXML 仍会出现打印错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥即使显示正确,在获取 nodeValue 时 null 仍会不断返回?

为啥即使回调参数与 XML 中的参数不匹配,GObject 方法仍会被调用?

带跨度的禁用按钮仍会触发点击功能!角

在 @INC 中找不到 XML/LibXML.pm

为啥分发配置文件过期后,iOS App Store 应用程序仍会启动?

为啥我的 WPF 应用程序禁用了拖放(即使 AllowDrop 为真)?