2013-07-08 3 views
0

Я новичок в xml::Twig. Как добавить атрибут и значение из счета vmerge с указанием счета vmerge? Как я могу начать это? Какая логика используется в этом процессе?Как добавить атрибуты в xml twig

Мой сценарий до сих пор:

use XML::Twig; 
my $XMLHandler = XML::Twig->new(TwigHandlers => { 
    }, 
    pretty_print => 'indented', 
); 
$XMLHandler->parsefile("sample.xml"); 
$XMLHandler->print; 

Входной XML:

<xml> 
    <table> 
     <tr> 
      <column><vmerge value="start"/></column> 
      <column></column> 
      <column></column> 
      <column><vmerge value="start"/></column> 
     </tr> 
     <tr> 
      <column><vmerge/></column> 
      <column></column> 
      <column></column> 
      <column><vmerge/></column> 
     </tr> 
     <tr> 
      <column><vmerge value="start"/></column> 
      <column></column> 
      <column></column> 
      <column><vmerge/></column> 
     </tr> 
     <tr> 
      <column><vmerge/></column> 
      <column></column> 
      <column></column> 
      <column><vmerge/></column> 
     </tr> 
    </table> 
</xml> 

Мне нужен выход, чтобы быть следующим:

<xml> 
    <table> 
     <tr> 
      <column rowspan="2"></column> 
      <column></column> 
      <column></column> 
      <column rowspan="4"></column> 
     </tr> 
     <tr> 
      <column></column> 
      <column></column> 
      <column></column> 
      <column></column> 
     </tr> 
     <tr> 
      <column rowspan="2"></column> 
      <column></column> 
      <column></column> 
      <column></column> 
     </tr> 
     <tr> 
      <column></column> 
      <column></column> 
      <column></column> 
      <column></column> 
     </tr> 
    </table> 
</xml> 
+0

У меня нет идеи, как вы переходите от ввода к выходу. Могли бы вы объяснить? – mirod

+0

Я думаю, что его вопрос заключается в том, как это сделать. Кажется, что выход является желаемым выходом. – simbabque

+0

@simbabque Я просто не понял, каким должен быть алгоритм. Рассмотрев два документа, я думаю, что я понимаю. Я бы хотел, чтобы OP объяснил алгоритм, хотя вместо того, чтобы тратить время на его поиск. – mirod

ответ

3

Я думаю, что это то, что вы хотите:

#!/usr/bin/perl 

use strict; 
use warnings; 

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

sub table 
    { my($t, $table)= @_; 
    foreach my $vmerge ($table->descendants('vmerge[@value="start"]')) 
     { my $span=1; 
     my $start_column= $vmerge->parent; 
     $vmerge->delete; 
     my $column_index= scalar $start_column->prev_siblings('column'); 

     my $tr= $start_column->parent('tr')->next_sibling('tr'); 
     while($tr) 
      { my $cont_vmerge= $tr->child($column_index)->first_child('vmerge[@value!="start"]'); 
      if($cont_vmerge) { $span++; $cont_vmerge->delete; } 
      else    { last;       } 
      $tr= $tr->next_sibling('tr'); 
      } 
     $start_column->set_att(rowspan => $span); 
     } 
    } 

__DATA__ 
<xml> 
<table> 
<tr> 
<column><vmerge value="start"/></column> 
<column></column> 
<column></column> 
<column><vmerge value="start"/></column> 
</tr> 
<tr> 
<column><vmerge/></column> 
<column></column> 
<column></column> 
<column><vmerge/></column> 
</tr> 
<tr> 
<column><vmerge value="start"/></column> 
<column></column> 
<column></column> 
<column><vmerge/></column> 
</tr> 
<tr> 
<column><vmerge/></column> 
<column></column> 
<column></column> 
<column><vmerge/></column> 
</tr> 
</table> 
</xml> 
+0

большое спасибо .... ваш ответ очень фантастический ... – user1811486

+0

У меня есть небольшие сомнения? my $ cont_vmerge = $ tr-> child ($ column_index) -> first_child ('vmerge [@value! = "start"]'); Он работает так хорошо, но Хорошо, Как я могу получить точный тег vmerge оттуда? можешь мне помочь? – user1811486

+0

заменить 'first_child' на' first_descendant' – mirod