如何使用XML :: Twig的处理程序传递参数并返回值?

use*_*955 5 perl xml-twig

我的问题是:如何将一些参数传递给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)

DVK*_*DVK 1

免责声明:我自己没有使用过 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)

三。让处理程序成为一个闭包并让它保持这种状态