smattiuz has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, i need to remove a node from my xml document (called news.xml)
<listaNews> <new> blah blah blah </new> <new> blah blah blah </new> </listaNews>
this is the structure of my document. I need to remove one of the <new> nodes. I've tried with removeChild (XML::Simple) but doesn't work, since it doesn't find any xml simple library (even if it's configured). Also DOM doesn't work, since it doesn't provide anything good to remove a node from a document. Thanks

Replies are listed 'Best First'.
Re: Lib::XML removing Node
by Your Mother (Archbishop) on Jun 13, 2009 at 19:28 UTC
    I need to remove one of the <new> nodes.

    ...is a difficult thing to put into code. Either of two? Duplicate tags? Tags with duplicate values? Last one? All after first? Here's snippet that does the last one. Use the docs -- XML::LibXML -- to adjust as needed.

    use warnings; use strict; use XML::LibXML; my $doc = XML::LibXML->new->parse_fh(\*DATA); # or ->parse_file("news.xml") my $root = $doc->getDocumentElement; my @nodes = $root->findnodes("new"); $root->removeChild($nodes[-1]); # Remove the last. print $doc->serialize();# Or... print $root->serialize(); __DATA__ <listaNews> <new> blah blah blah </new> <new> blah blah blah </new> </listaNews>

      The following is a more general solution. It doesn't rely on knowing the parent.

      my $node = ...; # Node to delete $node->parentNode->removeChild( $node );

      It's the same in XML::DOM (which the OP mentioned).

      my $node = ...; # Node to delete $node->getParentNode->removeChild( $node );
      thanks mate, that worked :D i'll try to modify your solution to delete all elements and delete one specific one, then i'll post it to other users :D thanks!!!!!!!

        Sure thing. ikegami's suggestion is probably the most portable way to handle it too. It skips some of the node nonsense (naked text between elements are nodes|children too) and it is the way I usually do it in code. This would remove any after the first of a given TAGNAME.

        my @nodes = $doc->findnodes("//TAGNAME"); if ( @nodes > 1 ) { $_->getParentNode->removeChild($_) for @nodes[1..$#nodes]; }
        yes! everything went good! i modified the code to delete last inserted items and all items older than the current date. This all was for a university exam (HTML,CSS,XML,PERL,JAVASCRIPT), teacher gave me 28 out of 30 for my project (since it had a little issue with css in internet explorer! Really appreciated all your help!
Re: Lib::XML removing Node
by Anonymous Monk on Jun 13, 2009 at 16:19 UTC
    #!/usr/bin/perl -- use strict; use warnings; use XML::Simple; use Data::Dumper; my $xml = q~<?xml version='1.0'?><listaNews> <new>blah blah blah</new> <new>blah blah blah</new> </listaNews>~; print "$xml\n\n"; my $VAR1 = XMLin($xml, ForceContent=>0, ForceArray=>0); print Dumper( $VAR1), "\n\n"; pop @{$VAR1->{new}}; print XMLout($VAR1, NoAttr=>1,RootName=>'xml',XMLDecl => 1, keyattr => + []); __END__ <?xml version='1.0'?><listaNews> <new>blah blah blah</new> <new>blah blah blah</new> </listaNews> $VAR1 = { 'new' => [ 'blah blah blah', 'blah blah blah' ] }; <?xml version='1.0' standalone='yes'?> <xml> <new>blah blah blah</new> </xml>
      thanks, but actually XML:Simple doesn't work for me, even if it's actually configured!