如何删除xml twig中的重复span标记?

时间:2015-05-08 09:09:20

标签: xml perl xml-twig

我需要在以下XML文档中使用相同的样式合并span标记:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<book>
<p><span style="font-size:10pt;">T</span><span style="font-size:10pt;">h</span><span style="font-size:10pt;">e</span></p>
<p><span style="font-style:italic;">o</span><span style="font-style:italic;">f</span><span style="font-size:10pt;">e</span></p>
</book>

我想要的输出是:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<book>
<p><span style="font-size:10pt;">The</span></p>
<p><span style="font-style:italic;">of</span><span style="font-size:10pt;">e</span></p>
</book>

这是我到目前为止所尝试的:

use strict;
use XML::Twig;
my $Document = XML::Twig->new(
        keep_encoding=>1,                                              
        twig_handlers =>{
        },
pretty_print => 'indented',
);
$Document->parsefile("book.xml");
$Document->print();

我很难理解这个模块的概念。我正在尝试做什么?

1 个答案:

答案 0 :(得分:0)

嗯,你并没有真正删除XML标签 - 就XML而言,每个span都是一个独立的实体。

但是,您可以使用XML::Twig::Elt方法prev_sibling - 因为它会查看同一级别的节点。如果前一个节点的类型正确,并且样式相同 - 将当前文本连接起来,并删除此节点。我不确定这是否适用于所有用例,但它会按照您的要求进行操作。

use strict;
use warnings;
use XML::Twig;

my $previous_span;
my $previous_style;

sub merge_span {
    my ( $twig, $span ) = @_;
    my $prev = $span->prev_sibling;
    if (    $prev
        and $prev->tag eq $span->tag
        and $prev->att('style') eq $span->att('style')
        and not $prev -> has_children
        and not $span -> has_children
        )
    {
        $prev->set_text( $prev->text . $span->text );
        $span->delete;
    }
}

my $xml = XML::Twig->new(
    'pretty_print'  => 'indented',
    'twig_handlers' => { 'span' => \&merge_span, },
);
$xml->parse( \*DATA );
$xml->print;


__DATA__
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<book>
<p><span style="font-size:10pt;">T</span><span style="font-size:10pt;">h</span><span style="font-size:10pt;">e</span></p>
<p><span style="font-style:italic;">o</span><span style="font-style:italic;">f</span><span style="font-size:10pt;">e</span></p>
</book>