XML :: Twig perl SVG过滤器可以进行最少的解析吗? start_tag_handler?

时间:2013-11-13 02:44:14

标签: perl parsing svg

下面的过滤器代码段非常简单。 如果顶级SVG组标记有匹配列表中包含的标签,则会强制执行其可见性(< g style =“display :)并且该组以及非分组代码将按原样复制 到标准输出(flush)。否则,该组将从流中删除(清除) 问题是: 据我所知,每个整个组(可能很大)被依次解析并存储在内存中,这是不必要的,因为只检查和修改了开始标记。什么是代码修改,以停止在开始标记后读取文件,然后飞到匹配的< / g取代;结束标记,是否复制遍历的代码,而不解析除标记嵌套之外的任何内容? 我读到start_tag_handler应该这样做,但我无法正确使用flush或purge。 作为奖励,如果$ g-> parent-> gi eq“g”则返回;由于不再处理内部组(在外部组之前),因此不再需要这可能是不正确的 任何错误的报告当然会受到赞赏:小事:$ indent似乎什么都不做;有什么不对吗? 完整的代码和示例与@ http://www.papou.byethost9.com/notes/svg-sieve/一起玩 svg-sieve -d all用debug来测试内联示例 svg-sieve -d ma -l Ixelles,language = ru,names = ru Brussels-municipalities.svg>位于布鲁塞尔的伊克塞尔 - ru.svg
-d mi发现层。

<谢谢时间= 1000 />

安德烈。

my $twig = new XML::Twig( twig_roots => { 'g' => \&g },
       twig_print_outside_roots => 1, pretty_print => "$indent",);

sub g { my ($t, $g) = @_; 
  return if $g->parent->gi eq "g";
  my $label=$g->att("inkscape:label");
  $label or $label=$g->att("id");
  if ( $label ~~ @matchlist | $label =~ /^BASE-/) {
    my $style=$g->att("style");
    $style =~ s/display:[^;]*(;?)/display:inline\1/;
    $g->set_att( style => "$style");
    $g-> flush;
  } else {
    $g-> purge;
  }
}

1 个答案:

答案 0 :(得分:0)

首先,如果作为Perl var,它没有设置为Twig所期望的属性值之一,那么$ indent就不会做任何事情('很好','缩进&#39等等。)

其次,我不太确定你的目标是什么。您的记忆问题似乎完全取决于您不想要的元素。如果是这样,您可能不需要使用tag_handlers。

您可以通过加入@matching" |"来明确匹配您想要的元素。在用户定义的处理程序的Xpath中。我也会在你的解析线之后刷新$ twig。

如果您对#return if $g->parent->gi eq "g";的XPath是绝对的,例如,您也不需要<g>'/root/parent/g'

my $twig_handlers = {
      'g[string(label) =~ /['.join('|',@matchlist).']/]' => sub { g_handler($_) },
   };

my $twig = new XML::Twig( 
      twig_roots => { 'g' => 1 },
      twig_handlers => $twig_handlers,
      twig_print_outside_roots => 1, pretty_print => $indent,);

sub g_handler { 
   my $g = shift;
   my $label=$g->att("label");
   $label or $label=$g->att("id");
   if ( $label ~~ @matchlist | $label =~ /^BASE-/) {
      my $style=$g->att("style");
      $style =~ s/display:[^;]*(;?)/display:inline$1/;
      $g->set_att( style => "$style");
      $g-> flush;
   }
}