我正在处理由perl生成的格式错误的XML,这是由我无法改变的上游进程生成的(这似乎是一个常见的问题).但是,据我所见,XML只有一种特殊的方式格式错误:它的属性值包含未转义的小于号,例如:
<tag v="< 2">
Run Code Online (Sandbox Code Playgroud)
我正在使用带有XML :: LibXML的 perl 进行解析,当然,这会生成解析错误.我已经尝试使用recover选项,它允许我解析,但它只是在遇到第一个解析错误时停止,所以我正在以这种方式丢失数据.
看起来我有两个一般的选择:
我倾向于选项1,因为我想捕获XML的任何其他错误.你会推荐什么?如果#1,有人可以引导我通过正则表达式方法吗?
我知道这不是你想要的答案 - 但XML规范非常明确和严格.
格式错误的XML是致命的.
如果它在验证器中不起作用,那么你的代码甚至不应该试图"修复"它,而不是你试图自动"修复"一些程序代码.
致命错误[定义:]符合XML处理器必须检测并向应用程序报告的错误.在遇到致命错误之后,处理器可以继续处理数据以搜索进一步的错误,并且可以将这样的错误报告给应用程序.为了支持纠正错误,处理器可以从文档中获得未处理的数据(具有混合的字符数据和标记),以供应用程序使用.但是,一旦检测到致命错误,处理器就不能继续正常处理(即,它不能继续以正常方式将字符数据和有关文档逻辑结构的信息传递给应用程序).
特别是关于原因的评论:"严厉"错误处理
我们希望XML能够让程序员编写可以通过Web传输并在大量桌面上执行的代码.但是,如果此代码必须包含针对各种草率最终用户实践的错误处理,则必须将其大小扩展到与Netscape Navigator或Microsoft Internet Explorer一样大小为数十兆字节的程度.打败目的.
如果你曾尝试为HTML编写一个解析器,你就会明白为什么它需要这样 - 你最终为边缘情况编写了很多处理程序,错误的标记嵌套,暗示标记关闭你的代码是一团糟从一开始.
而且因为它是Stack Overflow上我最喜欢的帖子 - 这是一个原因的例子:RegEx匹配开放标签,除了XHTML自包含标签
现在我明白这并不总是一个选择,如果要求你的上游'修复你的XML'是阻力最小的路径,你可能不会来这里.但是我仍然会敦促你在XML原始应用程序中将其报告为缺陷,并尽可能地抵制以编程方式"修复"的压力 - 因为正如你正确地想到的那样,当正确的答案是正确答案时,它正在为自己建立一个痛苦的世界.'在源头修复问题'.
如果你真的被困在这条路上,你可以 - 正如SinanÜnür所指出的那样 - 你唯一的选择就是陷阱解析器失败的地方,然后检查并尝试修复.但是你找不到一个能够为你做的XML解析器,因为根据定义,它会被破坏.
我建议你先说:
也可能有用作参考点:不应将哪个字符设置为XML文件中的值
一种选择是捕获异常,找出它们在输入中的位置,在那里修复输入,然后重试.
以下是一个快速,低效的概念验证脚本使用,XML::Twig
因为我还没有想出如何在Windows上从头开始构建和安装libxml2.
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $xml = q{ <tag v="< 2"/> };
while ( 1 ) {
eval {
my $twig = XML::Twig->new(
twig_handlers => { tag => \&tag_handler },
);
$twig->parse( $xml );
1;
} and last;
my $err = $@;
my ($i) = ($err =~ /byte ([0-9]+)/)
or die $err;
substr($xml, $i, 1) eq '<'
or die $err;
$xml = substr($xml, 0, $i) . '<' . substr($xml, $i + 1);
}
sub tag_handler {
my (undef, $elt) = @_;
print $elt->att('v'), "\n";
}
Run Code Online (Sandbox Code Playgroud)
我在博客上写了更多相关内容.
归档时间: |
|
查看次数: |
1471 次 |
最近记录: |