2009-09-21 2 views
3

Я пытаюсь вызвать подпрограмму для каждого тега, но end_tag_handlers никогда не вызывается.
Моей целью является этой последовательностью:Почему XML :: Twig не вызывает мой end_tag_handler?

--- последовательность ---
когда <auto> вызова \&loading.
когда <apps><title> звонок \&kicks.
когда <apps><logs> call \&bye.
когда <apps> звонок \&app.
когда <apps><title> звонок \&kicks.
когда <apps><logs> call \&bye.
когда <apps> звонок \&app.
когда </auto> call \&finish. → Это не было вызвано.

temp.pl:

#!/usr/local/bin/perl -w 

use XML::Twig; 
my $twig = XML::Twig->new(
      start_tag_handlers => 
       { 'auto' => \&loading 
       }, 
      twig_handlers => 
       { 'apps/title' => \&kicks, 
       'apps/logs' => \&bye 
       }, 
      twig_roots => 
       { 'apps' => \&app 
       }, 
      end_tag_handlers => 
       { 'auto' => \&finish 
       } 
      ); 
$twig -> parsefile("doc.xml"); 

    sub loading { 
    print "---loading--- \n"; 
    } 

    sub kicks { 
    my ($twig, $elt) = @_; 
    print "---kicks--- \n"; 
    print $elt -> text; 
    print " \n"; 
    } 

    sub app { 
    my ($twig, $apps) = @_; 
    print "---app--- \n"; 
    print $apps -> text; 
    print " \n"; 
    } 

    sub bye { 
    my ($twig, $elt) = @_; 
    print "---bye--- \n"; 
    print $elt->text; 
    print " \n"; 
    } 

    sub finish { 
    print "---fishish--- \n"; 
    } 

doc.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<auto> 
    <apps> 
    <title>watch</title> 
    <commands>set,start,00:00,alart,end</commands> 
    <logs>csv</logs> 
    </apps> 
    <apps> 
    <title>machine</title> 
    <commands>down,select,vol_100,check,line,end</commands> 
    <logs>dump</logs> 
    </apps> 
</auto> 

выход:

C:\>perl temp.pl 
---loading--- 
---kicks--- 
watch 
---bye--- 
csv 
---app--- 
watchset,start,00:00,alart,endcsv 
---kicks--- 
machine 
---bye--- 
dump 
---app--- 
machinedown,select,vol_100,check,line,enddump 

Я хотел бы больше здесь.

---finish--- 

ответ

6

Из документов для XML::Twig:

end_tag_handlers

Хэш {выражение => \ & обработчик}. Устанавливает обработчики элементов, вызываемые при закрытии элемента (в конце обработчика XML: Parser End). Обработчики вызываются с параметрами 2 : веточкой и тегом элемента.

twig_handlers вызывается, когда элемент полностью разбирается, поэтому почему этот избыточный вариант ? Существует только одно использование для end_tag_handlers: при использовании опции twig_roots, запускает обработчик для элемента вне корней.

Вы настраиваете обработчик для своего элемента auto, который является корнем. И вы используете только twig_roots для apps. Поэтому обработчик конца никогда не будет вызван.

Вместо этого вы должны установить свой обработчик, используя twig_handlers.

Так попробуйте это:

my $twig = XML::Twig->new(
     start_tag_handlers => 
      { 'auto' => \&loading 
      }, 
     twig_handlers => 
      { 'apps/title' => \&kicks, 
      'apps/logs' => \&bye, 
      'auto'  => \&finish 
      }, 
     twig_roots => 
      { 'apps' => \&app 
      }, 
     ); 
+0

Большое спасибо, это действительно работает. И у меня был вопрос о XML :: Twig раньше, и я снова прочитал документ. Увы, мои проблемы с английским языком также проблемы ... Теперь действительно ознакомьтесь с разделом start_tag_handlers в документе XML :: Twig по вашему ответу. – tknv

+0

кажется, что пользователи склонны слишком часто использовать twig_roots. Я на самом деле редко использую его сам. Я добавлю что-то об этом в документах. – mirod

Смежные вопросы