gpt4 book ai didi

XML::LibXML::Reader 需要警告模式错误而不是退出

转载 作者:行者123 更新时间:2023-12-02 20:18:01 24 4
gpt4 key购买 nike

基本上,我需要使用 perl 模块 XML::libXML::Reader 中的模式选项,以便在解析文件时验证大型 (>1GB) XML 文件。

以前,我使用 xmllint 命令根据给定架构 (xsd) 文件验证 XML 文件。但是现在我有一些大型 XML 文件需要验证,但尝试执行验证时内存不足 (8GB)。

我在 XML::libXML::Reader perl 模块页面上读到有一个模式选项。但是,当我使用它时(请参阅下面的代码),当找到 XML 文件的第一个无效元素时,代码就会退出。

use strict;
use warnings;
use XML::LibXML::Reader;

my $SchemaFile='schema.xsd';
my $FileToAnalyse='/tmp/file.xml';

my $reader = XML::LibXML::Reader->new(location => $FileToAnalyse,Schema=>$SchemaFile) or
die "cannot read file '$FileToAnalyse': $!\n";

while($reader->read) {

Process the file line by line here, even if not valid against schema (reduces memory usage for large files)
}

我需要收集无效条目并继续而不是退出。这可能吗?

最佳答案

$reader->read 无法从架构验证错误中恢复(即使可以恢复)的原因可以在 line #8815 中查看。 LibXML.xs。请注意,REPORT_ERROR() 是用零值调用的(该值指示 `LibXML_report_error_ctx() 是否能够从错误中恢复。零值意味着它不会尝试恢复,并且它会调用XML::LibXML::Error::_report_error来结束。

我尝试将 line #8815 处的值更改为 1并重新编译了 XS 模块,现在它将架构错误报告为警告(而不是死亡)并继续解析。

我想这个选项不提供给用户是有充分理由的,但我对 XML 解析不太熟悉,所以我可以举一个例子来说明这里可能会出现什么问题。

编辑:

看来正确的做法是捕获read()抛出的异常,然后尝试再次调用read(),如果下面的调用read() 返回 -1,解析器无法从错误中恢复,如果返回 0,则已到达文件结尾,如果返回 1,则可以从异常中恢复。我做了一些测试,它似乎能够从模式验证错误中恢复,但不能从解析错误中恢复。所以你可以尝试以下方法:

use feature qw(say);
use strict;
use warnings;

use Try::Tiny qw(try catch);
use XML::LibXML::Reader;

my $SchemaFile='schema.xsd';
my $FileToAnalyse='file.xml';
my $reader = XML::LibXML::Reader->new(
location => $FileToAnalyse, Schema => $SchemaFile
) or die "cannot read file '$FileToAnalyse': $!\n";
while (1) {
my $result;
try { $result = $reader->read } catch {
say '==> ' . $_;
$result = 1; # Try to continue after exception..
};
last if $result != 1;
if ( $reader->nodeType == XML_READER_ELEMENT ) {
say "Element node: ", $reader->name;
}
}
$reader->finish();
$reader->close();

关于XML::LibXML::Reader 需要警告模式错误而不是退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58448603/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com