我自己也试过一点,搜索了很多,但找不到一个如何在Perl中有效地做到这一点的解决方案(我猜这个解决方案有点类似于https://stackoverflow.com/a/22119220/6607497):
我有一些错误的XML输入文件(即它声称符合特定的XML内容模型,但元素名称的大小写不一致),如果有必要,我想修复。为此,我必须将每个元素名称与有效名称列表进行比较,如果错误的元素名称与有效的元素名称匹配,忽略名称的大小写,则应该将坏名称改变为相应的有效名称。
就像<Bad>...</Bad>
(错误的大小写)被转换成<bad>...</bad>
(正确的大小写)。当然,实际上它更复杂。而且,不好的标签使用混合大小写,而好的标签只使用小写并不总是正确的;它可以是任何组合。
我已经创建了一个所有有效元素名称的列表,但是我缺少(例如)如何使用XML::Twig
为“任何节点”设置处理程序(希望在处理程序中使用set_tag
来修复名称)。
创建一个标签的任意大小写排列的列表是可行的,但这似乎效率很低,因为所有这些可能的错误拼写中只有一小部分会在现实中发生。
Fancy Example
下面是一些有趣的例子:假设有效的元素名称是:
use constant GOOD_TAGS => qw(ABBA beard Elvis set ZZTop);
错误输入的示例如下所示:
<Set>
<Beard type="none">
<elvis />
</Beard>
<Beard type="long">
<ZZtop />
</Beard>
<Beard type="mixed">
<Abba />
</Beard>
</Set>
则固定输出应为:
<set>
<beard type="none">
<Elvis />
</beard>
<beard type="long">
<ZZTop />
</beard>
<beard type="mixed">
<ABBA />
</beard>
</set>
我不知道你可以使用编译后的正则表达式作为哈希键,但它似乎可以工作,所以你也可以假设这样的开始场景:
#!/usr/bin/perl
use strict;
use warnings;
use constant GOOD_TAGS => qw(ABBA beard Elvis set ZZTop);
my %fixes;
foreach (GOOD_TAGS) {
$fixes{qr/^${_}$/i} = $_;
}
my @matchers = keys %fixes;
因此,所有与@matchers
中的项匹配的元素都应该重命名为相应的哈希值。
3条答案
按热度按时间8cdiaqws1#
如何使用XML::Twig为“任何节点”设置处理程序
在创建
XML::Twig
对象时,将_all_
用作为twig_handlers
定义的处理程序中的键。创建一个任意标记的任意大小写排列的列表是可行的,但似乎效率很低
确实如此。相反,我建议规范化好的标签,并检查您在XML中看到的规范化的标签是否与任何规范化的好标签匹配。在这里,可以通过转换为小写来完成规范化。类似于:
把所有这些放在一起,这给了我们:
你也可以简化
到
我对这两种方式都没有强烈的感觉,所以选择一个你最喜欢的。短一点的有点贵(因为它有时会调用
$_->set_tag($_->tag)
),但这可能不重要。gorkyyrv2#
这里也使用XML::LibXML。它使用XML::LibXML::Node读取/设置节点名称。
遍历节点并根据好的列表检查它们的名称。在给定的示例中,可以将小写的node-name与小写(“规范化”)好的名称进行比较。由于
当然,实际上它更复杂。
实际比较标准符合实际。(Levenshtein距离?)
考虑到所有节点都必须被访问(以某种方式)才能被检查,这在原则上大致是有效的。
如果好的列表中有所有的节点名,那么它只需要进行上面的第二个测试
实际上,您可能需要更多和/或不同的测试。
aiqt4smr3#
测试了XML::SAX解析器。看起来下面应该可以工作: