我正在使用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);
时自动调用处理程序?
任何指针都会非常感激。
答案 0 :(得分:2)
是的,引擎会“自动”调用它们。
如果您查看源代码(链接到库的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:
具有预定义方法名称的自定义diff-handler类。从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 })
第二种方法更灵活,使用频率更高。