2015-05-08 1 views
0

мне нужно объединить span тегов с одинаковым стилем в следующем документе XML:Как удалить повторяющийся тег span в xml twig?

<?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(); 

У меня возникли трудности с пониманием концепций этого модуля. Это то, что я пытаюсь сделать возможным?

ответ

0

Ну, вы действительно не удаляете теги XML там - насколько это касается XML, каждый span является независимым объектом.

Однако, вы можете использовать метод XML::Twig::Eltprev_sibling - потому что он смотрит на узлы на том же уровне. И если предыдущий узел имеет правильный тип и тот же стиль - concat текущий текст и удалить этот узел. Я не уверен, что это будет работать для всех случаев использования, но оно будет делать то, что вы просите.

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>