in reply to Re: XML::Simple: list all element attributes
in thread XML::Simple: list all element attributes

Thanks, it works now. A quick follow-up question. I've just noticed that a few "nodes" have child "nodes" with similar attributes:

<?xml version="1.0" encoding="Windows-1252"?> <App> <node name="1st node" text="Text of 1st node" /> <node name="2nd node" text="Text of 2nd node"> <node name="subnode A" text="Text of subnode A" /> <node name="subnode B" text="Text of subnode B" /> </node> <node name="3rd node" text="Text of 3rd node" /> ... </App>

I'd like to print this out as follows:

1st node: Text of 1st node 2nd node: Text of 2nd node subnode A: Text of subnode A subnode B: Text of subnode B 3rd node: Text of 3rd node

Without getting into any scary recursion, how would I modify the loop to print out the subnodes, too?

foreach my $node (@{$data->{node}}) { print $node->{name}.": ".$node->{text}."\n"; if ( ... ) { # detect the existence of a subnode here somehow foreach my $subnode (@{$data->{node}{subnode}}) { print "\t".$subnode->{name}.": ".$subnode->{text}."\n"; } } }

Replies are listed 'Best First'.
Re^3: XML::Simple: list all element attributes
by frozenwithjoy (Priest) on Apr 08, 2015 at 07:50 UTC

    What you are looking for is: if ( $node->{node} )

    However, is a little recursion OK?

    print_nodes($data); sub print_nodes { my $data = shift; foreach my $node ( @{ $data->{node} } ) { print $node->{name} . ": " . $node->{text} . "\n"; if ( $node->{node} ) { print_nodes($node); } } }

    This should work regardless of how deep the nodes go; however, it doesn't indent:

    1st node: Text of 1st node 2nd node: Text of 2nd node subnode A: Text of subnode A subnode B: Text of subnode B 3rd node: Text of 3rd node

    EDITED TO ADD INDENTATION:

    print_nodes( $data, 0 ); sub print_nodes { my ( $data, $depth ) = @_; my $tab_width = 4; foreach my $node ( @{ $data->{node} } ) { my $indent = " " x $depth x $tab_width; print $indent . $node->{name} . ": " . $node->{text} . "\n"; if ( $node->{node} ) { print_nodes( $node, $depth + 1 ); } } }
    1st node: Text of 1st node 2nd node: Text of 2nd node subnode A: Text of subnode A subnode B: Text of subnode B 3rd node: Text of 3rd node
      Everything's working now. Thank you very much for your help, especially adding the indents in recursion.