我正在使用 Perl mod XML::SemanticDiff,它可以比较两个 XML 文档。我想编写自己的自定义处理程序,但作为 Perl 的新手,我不知道如何做到这一点。
我知道处理程序只不过是在某些事件发生时调用的子例程。但我不清楚这些事件如何调用我的代码中的方法的实现细节。
例如,这个模块的基本实现是这样开始的:
my $diff = XML::SemanticDiff->new(keepdata=> 1, keeplinenums => 1, diffhandler => 1);
my @changes = $diff->compare($file1, $file2);
我知道我的自定义处理程序看起来像这样:
sub element_value($self, $element, $to_element_properties, $fromdoc_element_properties) {
my ($self, @args) = @_;
}
但是是否需要中间代码来实际调用这个子程序?类似的东西,
foreach my $change (@changes) {
$change->element_value(some_arguements_here);
}
或者当 $diff->compare($file1, $file2);
执行时自动调用处理程序?
如有任何指点,我们将不胜感激。
最佳答案
是的,它们是由引擎“自动”调用的。
如果您查看源代码(链接到库的 CPAN 页面 XML::SemanticDiff
),您会发现它是如何轻松完成的:
sub compare {
# ... some code
# element value test
unless ($from_doc->{$element}->{TextChecksum}
eq $to_doc->{$element}->{TextChecksum}) {
push (@warnings, $handler->element_value($element,
$to_doc->{$element},
$from_doc->{$element}))
if $handler->can('element_value');
}
处理程序子程序分为三种(取决于使用它们的库的设计方式):
预定义名称。意思是,该库旨在在特定情况下始终调用名为“XYZ()”的固定名称的子。就“在哪个命名空间中搜索具有该名称的子项”而言,要做到这一点非常棘手?要解决该问题,更常见的方法是 #2:
具有预定义方法名称的自定义差异处理程序类。从
XML::SemanticDiff
可以看出文档,您的图书馆就是这种情况。该类通常继承自一些现有的具有默认处理程序的基处理程序类,这些处理程序应该被您的自定义子类覆盖。或者,它只需要实现一些/所有预定义的方法,而不必继承(这里是后者)。
在 XML::SemanticDiff 的情况下,您通过给它一个自定义处理程序类的对象来告诉模块您的自定义处理程序是什么:
use XML::SemanticDiff; use MyCustomHandlerModule; my $handlerObj = MyCustomHandlerModule->new(); my $diff = XML::SemanticDiff->new({ diffhandler => $handlerObj });
注册处理程序。大多数情况下,注册是通过传递子例程引用来处理的:
sub myHandler1 { ... }; sub myHandler2 { ... }; my $obj = My::Library->new({ Event1_handler => &myHandler1 , Event2_handler => &myHandler2 })
第二种方法更灵活,使用频率也高得多。
关于xml - 对 Perl Handlers 有很好的介绍吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7855225/