#!/bin/perl -w use strict; use XML::Parser; # global, but could be attached to the parser or passed to the handlers my @results; # we need those to hold info about the parsing my( $elt_id, $child_seen, $in_child, $child_text); my $p= new XML::Parser( Handlers => { Start => \&start, # called when a start tag is found End => \&end, # called when an end tag is found Char => \&char, # called when characters are found }, ); $p->parse( \*DATA); # use parsefile to parse... a file print join "\n", @results; print "\n"; sub start { my( $p, $elt, %atts)= @_; # set by XML::Parser::Expat if( $elt eq 'elt') # we found an elt start tag { $child_seen= 0; # reset the flag, no child found yet $elt_id= $atts{id}; # store it in case we need it } elsif( $elt eq 'child') # found a child start tag { $child_seen= 1; # we've seen a child $in_child= 1; # we are in the child $child_text= ''; # reset the child text } } sub end { my( $p, $elt)= @_; if( $elt eq 'elt') # found and elt end tag { if( $child_seen) { push @results, $child_text; } else { push @results, "missing child for elt $elt_id"; } } elsif( $elt eq 'child') # found a child end tag { $in_child= 0; } # Toto, I guess we are not in the child any more } sub char # called for all non mark-up text { my( $p, $string)= @_; $child_text .= $string if( $in_child); # see the docs for why you can't } # just write $child_text = $string __DATA__ I am a child 1 child 2