为什么 XML::Twig 不调用我的 end_tag_handler?

发布于 2024-08-05 11:04:09 字数 2737 浏览 7 评论 0原文

我尝试为每个标签调用子例程,但从未调用 end_tag_handlers
我的目标是这个序列:

---sequence---
调用\&loading时。
</code> 调用 <code>\&kicks</code> 时。<br> 当 <code><apps><logs></code> 调用 <code>\&bye</code> 时。<br> 当 <code><apps></code> 调用 <code>\&app</code> 时。<br> 当 <code><apps><title></code> 调用 <code>\&kicks</code> 时。<br> 当 <code><apps><logs></code> 调用 <code>\&bye</code> 时。<br> 当 <code><apps></code> 调用 <code>\&app</code> 时。<br> 当 <code></auto></code> 调用 <code>\&finish</code> 时。 → <strong><em>未调用。</em></strong>

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---

I try to call subroutine for each tag, but the end_tag_handlers is never invoked.
My aim is a this sequence:

---sequence---
when <auto> call \&loading.
when <apps><title> call \&kicks.
when <apps><logs> call \&bye.
when <apps> call \&app.
when <apps><title> call \&kicks.
when <apps><logs> call \&bye.
when <apps> call \&app.
when </auto> call \&finish. → It was not called.

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>

output:

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  

I would like more here.

---finish---

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

以往的大感动 2024-08-12 11:04:09

XML::Twig 的文档中:

end_tag_handlers

哈希{表达式=>; \&处理程序}。设置当元素被调用时调用的元素处理程序
已关闭(在 XML::Parser End 处理程序的末尾)。处理程序被调用为 2
params:元素的树枝和标签。

twig_handlers 当一个元素被完全解析时被调用,那么为什么有这个多余的
选项? end_tag_handlers 只有一种用途:使用 twig_roots 选项时,
触发根外部元素的处理程序。

您正在为 auto 元素(即根元素)设置结束处理程序。而且您仅将 twig_roots 用于应用。所以最终处理程序永远不会被调用。

您应该使用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
          },
        );

From the docs for XML::Twig:

end_tag_handlers

A hash { expression => \&handler}. Sets element handlers that are called when the element
is closed (at the end of the XML::Parser End handler). The handlers are called with 2
params: the twig and the tag of the element.

twig_handlers are called when an element is completely parsed, so why have this redundant
option? There is only one use for end_tag_handlers: when using the twig_roots option, to
trigger a handler for an element outside the roots.

You're setting up an end handler for your auto element, which is the root. And you're only using twig_roots for apps. So the end handler will never be called.

You should install your handler using twig_handlers instead.

So try this:

my $twig = XML::Twig->new(
        start_tag_handlers => 
          { 'auto' => \&loading
          },
        twig_handlers =>
          { 'apps/title' => \&kicks,
            'apps/logs' => \&bye,
            'auto'      => \&finish
          },
        twig_roots =>
          { 'apps' => \&app
          },
        );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文