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

XML I have:
<items> <item> <id>12345</id> <name>Name1</name> <desc>Description</desc> <img>/catalog/image1.jpg</img> <size>50.0 mm</size> </item> <item> <id>54321</id> <name>Name2</name> <desc>Description2</desc> <img>/catalog/image1.jpg</img> <size>50.0 mm</size> </item> </items>
I run this:
use XML::Twig; my $twig = new XML::Twig(twig_roots => {'item/id'=>1, 'item/name'=> 1} + ); $twig->parsefile('in.xml'); $twig->set_pretty_print('indented'); $twig->print_to_file('out.xml');
I get:
<items> <id>12345</id> <name>Name1</name> <id>54321</id> <name>Name2</name> </items>
What I need are <item>..</item> inbetween.

Replies are listed 'Best First'.
Re: How to filter XML elements, exclude some
by toolic (Bishop) on Sep 13, 2013 at 12:30 UTC
    Another way is to use XML::Twig delete:
    use warnings; use strict; use XML::Twig; my $twig = new XML::Twig( twig_handlers => { desc => sub { $_->delete() }, img => sub { $_->delete() }, size => sub { $_->delete() }, }, ); $twig->parsefile('in.xml'); $twig->set_pretty_print('indented'); $twig->print_to_file('out.xml'); __END__ <items> <item> <id>12345</id> <name>Name1</name> </item> <item> <id>54321</id> <name>Name2</name> </item> </items>
      Is it possible to avoid excluding name-specific elements? i.e. not to delete (and include others) but to include specific ones (and omit others)? The problem is that other elements than desc, img and size might occur
        #!perl use strict; use XML::Twig; my $twig = new XML::Twig( twig_handlers => { 'item' => \&item } ); $twig->parsefile('in.xml'); $twig->set_pretty_print('indented'); $twig->print_to_file('out.xml'); sub item { my ($t,$e) = @_; for ($e->children){ $_->delete unless ($_->name =~ /^id|name$/); } }
        poj
        Sure, if you spend a little more time researching:
        use warnings; use strict; use XML::Twig; my $twig = new XML::Twig( twig_handlers => { item => \&item, }, ); $twig->parsefile('in.xml'); $twig->set_pretty_print('indented'); $twig->print_to_file('out.xml'); sub item { my ( $twig, $item ) = @_; for my $c ($item->children()) { $c->cut($item) unless $c->tag() eq 'id' or $c->tag() eq 'name' ; } }