Of course it is possible. I like using handlers because then you get rid of some of the tree before having to load it entirely in memory, plus I am used to it, and I find it often simpler than using XPath or navigation to get to the elements I want to process.
If size is not a problem you can certainly load the tree, and then write custom code to output the element and the tree "above it":
#!/usr/local/bin/perl -w
use strict;
use XML::Twig;
my $xml_twig = XML::Twig->new(
pretty_print => 'indented',
NoLWP => 1,
discard_spaces => 1,
EltClass => 'my_elt',
);
$xml_twig->parse ( \*DATA ) || die "\nError parsing data $@\n";
# here I split on the 'split' attribute, but any other
# way of getting the list of elements to split on is OK
foreach my $elt ($xml_twig->findnodes( '//*[@split]'))
{ print "Element: ", $elt->name, "\n\n", $elt->sub_doc, "\n\n";
$elt->delete;
}
package my_elt;
use base 'XML::Twig::Elt';
sub sub_doc { my $elt= shift; return $elt->start_tags . $elt->sprin
+t . $elt->end_tags; }
sub start_tags { my $elt= shift; return join '', map { $_->start_tag }
+ reverse $elt->ancestors; }
sub end_tags { my $elt= shift; return join '', map { $_->end_tag }
+ reverse $elt->ancestors; }
package main;
__DATA__
<myconfig_data foo="bar">
<level1 split="1">
<tag>hello1</tag>
</level1>
<level2>
<sub split="1">
<tag>hello2</tag>
</sub>
<sub split="1">
<tag>hello3</tag>
</sub>
</level2>
<level3 split="1">
<tag>hello4</tag>
</level3>
</myconfig_data>
|