in reply to xml::twig delete element

You can't do that. '/document/header[2]' should trigger an error, [2] is not supported. You will need to call the handler on all headers, and manage the state yourself to see if you have deleted the second one.

This should work, by keeping track taht the second header has already been deleted in a hidden attribute in the parent:

#!/usr/bin/perl use strict; use warnings; use XML::Twig; my $twig_to_del=XML::Twig->new( twig_handlers=>{ #to_delete elements '/document/header'=>\&element_ +delete, }, ) ->parse(\*DATA) ->print; sub element_delete { my ($twig, $element)= @_; my $first_header= $element->prev_sibling( 'header'); if( $first_header && ! $first_header->att( '#header_deleted')) { $element->delete; $first_header->set_att( '#header_deleted' => 1); } } __DATA__ <document> <header>h1</header> <header>h2</header> <header>h3</header> </document>

Of course if you want to delete all headers after the first one, which is more likely, the code is much simpler, you just have to delete any header after the first one:

#!/usr/bin/perl use strict; use warnings; use XML::Twig; my $twig_to_del=XML::Twig->new( twig_handlers=>{ #to_delete elements '/document/header'=> sub { $_- +>delete if $_->prev_sibling( 'header'); }, }, ) ->parse(\*DATA) ->print; __DATA__ <document> <header>h1</header> <header>h2</header> <header>h3</header> </document>

Replies are listed 'Best First'.
Re^2: xml::twig delete element
by Selvakumar (Scribe) on Oct 13, 2009 at 07:22 UTC
    Thanks a lot. it's works fine. i have one more clarification. I am using the below code to find "$fcnvar" not equal to blank then i need to search '//color@self="ua5"' and i should get the attribute "pnam" of that "color" element. how can i do that. can you please suggest. i am struggling here. I am getting error where i have commented the code.
    sub content_handler { my ($twig, $content)= @_; if($content->{'att'}->{'type'} eq "text") { my $selfatt=$content->att_xml_string('Self'); my $expr='//box[@textflowid="'.$selfatt.'"][@type="text"]'; my @tagnames = $twig->get_xpath($expr); for my $temp (@tagnames) { $fcnvar=$temp->att_xml_string('frameColorID'); # print "#$fcnvar#"; # if (!($fcnvar eq "")){ # my $expr='//color[@self="ua5"]'; # print "$expr"; # my @colorvalarr = $twig->get_xpath($expr); # print @colorvalarr; # print $colorvalarr[0]; # $fcnvar=$colorvalarr[0]->att_xml_string('pnam'); # } } } }

      Please, when asking for help, send a minimum, self-contained, test case, including inputs, outputs and expected outputs. It will make it possible for me (and other monks) to run the code, fix it, check that it does what you want it to do and post it back. The code above makes no sense to me, it's missing way to much context. Thanks.

      BTW, the development version of XML::Twig now raises an error on handler triggers that use the position selector, thanks for spotting the bug.

        Hi mirod, please find my code below. I am using the below code in process of "content" element and find "$fcnvar" Which is from "box" element not equal to blank then i need to search '//color@self="ua5"' and i should get the attribute "pnam" of that "color" element. how can i do that. can you please suggest. i am struggling here.
        use strict; use warnings; use XML::Twig; my $twig=XML::Twig->new( twig_handlers=>{ content=> \&content_handler, }, ); $twig->parse(\*DATA); $twig->flush; sub content_handler { my ($twig, $content)= @_; if($content->{'att'}->{'type'} eq "text") { my $selfatt=$content->att_xml_string('Self'); my $expr='//box[@textflowid="'.$selfatt.'"][@type="text"]'; my @tagnames = $twig->get_xpath($expr); for my $temp (@tagnames) { my $fcnvar=$temp->att_xml_string('frameColorID'); # print "#$fcnvar#"; # if (!($fcnvar eq "")){ # my $expr='//color[@self="ua5"]'; # print "$expr"; # my @colorvalarr = $twig->get_xpath($expr); # print @colorvalarr; # print $colorvalarr[0]; # $fcnvar=$colorvalarr[0]->att_xml_string('pnam'); # } $content->set_tag('updated_tag'); $content->del_atts; $content->set_atts } } } __DATA__ <document> <root> <box type="text" cont="text" textflowid="rc_u5035" frameColorID="ua +5"/> </root> <content type="text" Self="rc_u5035" id="rc_u5035"/> <header>h3</header> <meta> <color type="colr" clmd="prss" clsp="CMYK" clvl="4_D_0_D_15_D_50_D_0 +" ovrd="norm" atcs="nasp" atvl="0" pnam="Color 04-15M/50Y" edbl="t" r +mbl="t" pvis="t" swID="1f01" Self="uce"/> <color type="colr" clmd="prss" clsp="CMYK" clvl="4_D_0_D_10_D_40_D_0 +" ovrd="norm" atcs="nasp" atvl="0" pnam="Color 05-10M/40Y" edbl="t" r +mbl="t" pvis="t" swID="1f01" Self="ua5"/> </meta> </document>
        OUTPUT REQUIRED:
        <document> <root> <box type="text" cont="text" textflowid="rc_u5035" frameColorID="ua +5"/> </root> <updated_tag color="Color 05-10M/40Y"/> <header>h3</header> <meta> <color type="colr" clmd="prss" clsp="CMYK" clvl="4_D_0_D_15_D_50_D_0 +" ovrd="norm" atcs="nasp" atvl="0" pnam="Color 04-15M/50Y" edbl="t" r +mbl="t" pvis="t" swID="1f01" Self="uce"/> <color type="colr" clmd="prss" clsp="CMYK" clvl="4_D_0_D_10_D_40_D_0 +" ovrd="norm" atcs="nasp" atvl="0" pnam="Color 05-10M/40Y" edbl="t" r +mbl="t" pvis="t" swID="1f01" Self="ua5"/> </meta> </document>