下面的过滤器代码段非常简单。
如果顶级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;
}
}
答案 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;
}
}