我的问题是:如何将一些参数传递给XML:Twig的处理程序,以及如何从处理程序返回结果.
这是我的代码,硬编码:
<counter name = "music", report type = "month", stringSet index = 4>
.
如何通过使用参数来实现这个$counter_name
,$type
,$id
?以及如何返回string_list的结果?谢谢(抱歉,我没有在这里发布xml文件,因为我有一些麻烦.<和>中的任何内容都被忽略).
use XML::Twig;
sub parse_a_counter {
my ($twig, $counter) = @_;
my @report = $counter->children('report[@type="month"]');
for my $report (@report){
my @stringSet = $report->children('stringSet[@index=”4”]');
for my $stringSet (@stringSet){
my @string_list = $stringSet->children_text('string');
print @string_list; # in fact I want to return this string_list,
# not just print it.
}
}
$counter->flush; # free the memory of $counter
}
my $roots = { 'counter[@name="music"]' => 1 };
my $handlers = { counter => \&parse_a_counter };
my $twig = new XML::Twig(TwigRoots => $roots,
TwigHandlers => $handlers);
$twig->parsefile('counter_test.xml');
Run Code Online (Sandbox Code Playgroud)
免责声明:我自己没有使用过 Twig,所以这个答案可能不是惯用的 - 它是一个通用的“如何在回调处理程序中保持状态”答案。
将信息传入和传出处理程序的三种方法是:
一。状态保持在静态位置
package TwigState;
my %state = ();
# Pass in a state attribute to get
sub getState { $state{$_[0]} }
# Pass in a state attribute to set and a value
sub setState { $state{$_[0]} = $_[1]; }
package main;
sub parse_a_counter { # Better yet, declare all handlers in TwigState
my ($twig, $element) = @_;
my $counter = TwigState::getState('counter');
$counter++;
TwigState::setState('counter', $counter);
}
Run Code Online (Sandbox Code Playgroud)
二。$t(XML::Twig 对象)本身在某个“状态”成员中保存的状态
# Ideally, XML::Twig or XML::Parser would have a "context" member
# to store context and methods to get/set that context.
# Barring that, simply make one, using a VERY VERY bad design decision
# of treating the object as a hash and just making a key in that hash.
# I'd STRONGLY not recommend doing that and choosing #1 or #3 instead,
# unless there's a ready made context data area in the class.
sub parse_a_counter {
my ($twig, $element) = @_;
my $counter = $twig->getContext('counter');
# BAD: my $counter = $twig->{'_my_context'}->{'counter'};
$counter++;
TwigState::setState('counter', $counter);
$twig->setContext('counter', $counter);
# BAD: $twig->{'_my_context'}->{'counter'} = $counter;
}
# for using DIY context, better pass it in with constructor:
my $twig = new XML::Twig(TwigRoots => $roots,
TwigHandlers => $handlers
_my_context => {});
Run Code Online (Sandbox Code Playgroud)
三。让处理程序成为一个闭包并让它保持这种状态