如果父标记的属性是

时间:2015-08-10 19:25:21

标签: xml perl xml-twig

我有一个XML文件:uml.model

<UML:Class name="2012">
  <type2>
    <type1>
        <def value="test string ABC" />
    </type1>
  </type2>
</UML:Class>

<UML:Class name="2013">
  <type2>
    <type1>
        <def value="test string ABC" />
    </type1>
  </type2>
</UML:Class>

我想用&#39; UML取代ABC:Class name =&#34; 2012&#34;&#39;进入DEF并将结果输出到新文件中:

<UML:Class name="2012">
  <type2>
    <type1>
        <def value="test string DEF" />
    </type1>
  </type2>
</UML:Class>

<UML:Class name="2013">
  <type2>
    <type1>
        <def value="test string ABC" />
    </type1>
  </type2>
</UML:Class>

我使用的perl脚本是:

#!/usr/bin/perl -w
use strict;
use warnings;

use XML::Twig;
my $twig = XML::Twig->new( twig_roots => { 'UML:Class' => \&uml_class } );
$twig->parsefile( 'uml.model' );
$twig->print_to_file( 'uml.model.new' );

sub uml_class {
    my ( $twig, $section ) = @_;
    my $subTwig;
    my $year = $section->{'att'}->{'name'};

    if ( $year eq '2012' ) {
        $subTwig = XML::Twig->new( twig_roots => { 'type1/def' => \&type_def } );
        $subTwig->parse( $section->sprint() };
    }
}

sub type_def {
    my ($twig, $elt) = @_;
    $elt->print ();
    print "\n";
}

它没有按预期工作。如何更改它以获得所需的结果?非常感谢,

1 个答案:

答案 0 :(得分:2)

您正在混合$array_for_my_switch = array(); foreach ($row["MySQL_Field"] as $field) { if (strpos($field, 'Option 1') !== false) $array_for_my_switch[] = 'Option 1'; if (strpos($field, 'Option 2') !== false) $array_for_my_switch[] = 'Option 2'; if (strpos($field, 'Option 3') !== false) $array_for_my_switch[] = 'Option 3'; } switch ($array_for_my_switch) { case "Option 1": $page->drawImage($checkmark, 20, 20, 30, 30); break; case "Option 2": $page->drawImage($checkmark, 40, 40, 50, 50); break; case "Option 3": $page->drawImage($checkmark, 60, 60, 70, 70); break; } printprint_to_file并不神奇,它并不会导致所有print_to_file转到该文件。您需要修改原始文档中的属性值,然后print将输出新值。

我会这样做:

print_to_file

打开(我的$ out,&#39;&gt;&#39;,&#39; uml.model.new&#39;)或死&#34;无法创建uml.model.new:$!& #34 ;;

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

几点说明:

  • 我使用了复杂的触发器(XML::Twig->new( twig_roots => { 'UML:Class[@name="2012"]' => sub { my $def= $_->next_elt( 'def'); $def->latt( 'value')=~ s{ABC}{DEF}; $_->flush; }, }, twig_print_outside_roots => $out, pretty_print => 'indented', ) ->parsefile( 'uml.model'); )而不是简单的'UML:Class[@name="2012"]',然后在处理程序中测试属性值。
  • UML:CLASS方法为您提供了latt属性,您可以根据需要进行更改,也可以使用lvalue ...但是使用$v= $def->att( 'value'); $v=~ s{ABC}{DEF}; $def->set_att( $v);可以使用latt简单
  • 我链接了方法调用(new / parse / print_to_file),我喜欢这种代码的样式,就像这个简单的YMMV