Using Perl with XML (part 1) - Random Walk (
Page 6 of 7 )
In
addition to elements and CDATA, Perl also allows you to set up handlers for
other types of XML structures, most notably PIs, entities and notations (if you
don't know what these are, you might want to skip this section and jump straight
into another, more complex example on the next page). As demonstrated in the
previous example, handlers for these structures are set up by specifying
appropriate callback functions via a call to the setHandlers() object
method.
Here's a quick list of the types of events that the parser can
handle, together with a list of their key names (as expected by the
setHandlers() method) and a list of the arguments that the corresponding
callback function will receive.
Key Arguments Event
to callback
------------------------------------------------------------------------
Final parser handle Document parsing completed
Start parser handle, Start tag found
element name,
attributes
End parser handle, End tag found
element name
Char parser handle, CDATA found
CDATA
Proc parser handle, PI found
PI target,
PI data
Comment parser handle, Comment found
comment
Unparsed parser handle, entity, Unparsed entity found
base, system ID, public
ID, notation
Notation parser handle, notation, Notation found
base, system ID, public
ID
XMLDecl parser handle, XML declaration found
version, encoding,
standalone
ExternEnt parser handle, base, External entity found
system ID, public ID
Default parser handle, data Default handler
As an example, consider the following example, which uses a
simple XML document,
<?xml version="1.0"?>
<random>
<?perl print rand(); ?>
</random>
in combination with this Perl script to demonstrate how to
handle processing instructions (PIs):
#!/usr/bin/perl
# include package
use XML::Parser;
# initialize parser
$xp = new XML::Parser();
# set PI handler
$xp->setHandlers(Proc => \&pih);
# output some HTML
print "Content-Type: text/html\n\n";
print "<html><head></head><body>And the winning number is: ";
$xp->parsefile("pi.xml");
print "</body></html>";
# this is called whenever a PI is encountered
sub pih()
{
# extract data
my ($parser, $target, $data) = @_;
# if Perl command
if (lc($target) == "perl")
{
# execute it
eval($data);
}
}
# end
In this case, the setHandlers() method knows that it has to
call the subroutine pih() when it encounters a processing instruction in the XML
data; this user-defined pih() function is automatically passed the PI target and
the actual command to be executed. Assuming the command is a Perl command - as
indicated by the target name - the function passes it on to eval() for
execution.