Update:Mirod points out that this trick will only work if your version of XML::Simple is using XML::Parser as it's underlying parser. If you have/are using SAX as the underlying Parser - ignore this:). Thanks for the heads-up Mirod++.
XML::Simple has a parseropts option which allows you to pass XML::Parser options through to the XML::Parser instantiated by XML::Simple. One of the XML::Parser options is Handlers=> [ Event=>\&handler, ...].
By using this to register your own handlers you can get your own code called--with salient information as to what is being processed--as XML::Parser processes your document.
The problem is that doing so overrides the XML::Parser::Tree style handlers used by XML::Simple. However, these handlers conform to a standard naming convention and it is easy to use perl's goto &func; form of goto, to invoke these standard handlers from your own once you have finished tracing the info.
The PoC code below produces this output while successful parsing the emebedded example XML.
c:\test>231115 Init: Start: config logdir /var/log/foo/ debugfile /tmp/foo.debug Char: Char: Start: server name sahara osname solaris osversion 2.6 Char: Char: Start: address Char: 10.0.0.101 End: address Char: Char: Start: address Char: 10.0.1.101 End: address Char: Char: End: server Char: Char: Start: server name gobi osname irix osversion 6.5 Char: Char: Start: address Char: 10.0.0.102 End: address Char: Char: End: server Char: Char: Start: server name kalahari osname linux osversion 2.0.34 Char: Char: Start: address Char: 10.0.0.103 End: address Char: Char: Start: address Char: 10.0.1.103 End: address Char: Char: End: server Char: End: config Final: c:\test>
The code: (Update:simplified option setting code)
#! perl -sw use strict; use XML::Simple; use Data::Dumper; my @handlers = qw[ Init Start Char Proc Comment CdataStart CdataEnd End Final ]; for my $handler ( @handlers ) { eval "sub $handler\t{ print qq[\$handler: \@_[1 .. \$#_]\\n]; goto + \&XML::Parser::Tree::$handler; }"; } my %handlers = map{ $_ => eval "\\&$_" } @handlers; my $xml = XML::Simple->new(); my $config = $xml->XMLin( \*DATA, parseropts => [ Handlers => \%handlers, ] ); #print Dumper $config; __DATA__ <config logdir="/var/log/foo/" debugfile="/tmp/foo.debug"> <server name="sahara" osname="solaris" osversion="2.6"> <address>10.0.0.101</address> <address>10.0.1.101</address> </server> <server name="gobi" osname="irix" osversion="6.5"> <address>10.0.0.102</address> </server> <server name="kalahari" osname="linux" osversion="2.0.34"> <address>10.0.0.103</address> <address>10.0.1.103</address> </server> </config>
For more information on what handlers you can override, and what information is passed to them see the XML::Parser pod. (or source).
I might make a package out of this idea if anyone is interested.
Examine what is said, not who speaks.
The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.
In reply to Re: XML::Simple noisy option?
by BrowserUk
in thread XML::Simple noisy option?
by Anonymous Monk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |