reporting location of variably-nested XML data

robinjack14

New Member
I am attempting to parse an XML file trying to find a particular value. Here's the XML:\[code\]<?xml version="1.0"?><dump> <folder id="A0"> <folder id="A1"> <setting id="setting0"> <sequence id="sequence0"> <group name="info"> <variable name="foo" value="http://stackoverflow.com/questions/11362461/15"/> </group> </sequence> </setting> </folder> </folder></dump>\[/code\]Data::Dumper produces\[code\]$VAR1 = { 'folder' => { 'id' => 'A0', 'folder' => { 'setting' => { 'sequence' => { 'group' => { 'variable' => { 'value' => '15', 'name' => 'foo' }, 'name' => 'info' }, 'id' => 'sequence0' }, 'id' => 'setting0' }, 'id' => 'A1' } } };\[/code\]My goal is a report which says something like: "foo has a value of 15 at A0/A1/setting0/sequence0". Notice I want to use the \[code\]id\[/code\]s to refer to the "breadcrumb" trail to the location of \[code\]foo\[/code\].Currently I access the value "15" in this example XML with\[code\]use strict;use warnings;use XML::Simple;my $xml = new XML::Simple;my $data = http://stackoverflow.com/questions/11362461/$xml -> XMLin('test1.xml');print $data -> {folder}{folder}{setting}{sequence}{group}{variable}{value};\[/code\](However this doesn't work if there is more than one \[code\]<variable>\[/code\], and there will be...but that's not my main challenge...)The problem is the XML will contain an unpredictable nesting of \[code\]<folder>\[/code\]s, and I don't know how to find where a \[code\]<variable>\[/code\] exists with \[code\]name="foo"\[/code\], because I don't know how deep it will be.Multiple instances of \[code\]foo\[/code\] will occur, but just one for each \[code\]sequence\[/code\].A last little kicker is that I have access to XML::Simple and XML::Parser only! No SAX/Twig/LibXML etc. And the XML data file may be up to 100MB in size. All that now sounds quite complicated so I shall re-state my goal: traverse the XML for wherever \[code\]<variable>\[/code\] exists with \[code\]name="foo"\[/code\] and report its \[code\]value\[/code\] and location in the tree. Thanks for any help with this.Edit: using mirod's method below, here's what worked:\[code\]use strict;use warnings;use Twig;my $twig = new XML::Twig( twig_handlers => { 'variable[@name="foo"]' => \&variable, group => sub { $_->purge; } } );$twig->parsefile( "test.xml");sub variable { my( $t, $var)= @_; my $location= join '/', grep { $_ } map { $_->id } reverse $var->ancestors; print $var->att( 'name'), " has value ", $var->att( 'value'), " at $location\n"; }\[/code\]
 
Back
Top