[Canberra-pm] Parsing an XML document using XML::Twig and using it on an Template [SEC=UNCLASSIFIED]
John.Hockaday at ga.gov.au
John.Hockaday at ga.gov.au
Mon Mar 22 16:03:45 PDT 2010
Many thanks to those who replied to me both on and off the list. I eventually came up with a solution.
The problem was, as suggested, that Twig uses objects and Template uses complex hash arrays and arrays for the data. I couldn't find a method that converts the Twig object into an array so I had to write a sub routine that did that and call it from the twig_roots method. Its not pretty but it does what I want.
Here is the relevant code:
...
my (%hash, @names);
my $twig = XML::Twig->new
(
twig_roots =>
{
'title' => \&pushOntoArray,
'identifier' => \&pushOntoArray,
'node-description' => \&pushOntoArray,
'hostname' => \&pushOntoArray,
'port' => \&pushOntoArray,
'repository-name' => \&pushOntoArray,
...
'contact/contact-fax' => \&pushOntoArray,
}
);
$twig->parsefile( $inputFile );
push @names, $rec;
my ($arrayRef) = \@names;
%hash = ('servers' => $arrayRef);
$hashRef = \%hash;
my $temp = Template->new({'INCLUDE_PATH' => "$templatePath",
'TAG_STYLE' => 'html',
'PRE_CHOMP' => '1',
'ABSOLUTE' => '1',})
|| die $Template::ERROR, "\n";
# process the template object
no strict "refs";
$temp->process($templateFile, $hashRef, $output)
|| die $temp->error();
################################
sub pushOntoArray
{
my ($t, $name) = @_;
my ($value) = $name->name;
$value =~ s{-}{}gxm;
my ($content) = $name->text;
$$rec{$value} = $content;
$t->purge;
print "$value, $content\n";
}
Thanks again for all your help.
John
> -----Original Message-----
> From: Mark Suter [mailto:suter at zwitterion.org]
> Sent: Thursday, 18 March 2010 6:58 PM
> To: Canberra Perl Mongers
> Subject: Re: Parsing an XML document using XML::Twig and
> using it on an Template
>
> John,
>
> > I am trying to read an XML document into a hash handler that can be
> > used on the Template package. I thought that XML::Twig
> would be good
> > for this but I have no idea how to create a hash/array "thingy" that
> > can be passed to the Template module. Can someone help with this? I
> > don't understand the hash/array structure created by the
> XML::Twig and
> > for the input to the Template.
>
> The code below works for me. I've run this email using perl -x
> and it produces this output:
>
> Dumper:
> $VAR1 = {'thing' => [{'name' => 'Perl','rating' =>
> 'Awesome'},{'name' => 'Python','rating' => 'Awesome'}]};
> Template:
> Perl is Awesome.
> Python is Awesome.
>
> I wouldn't recommend this coding style normally and it lacks a
> lot of the normal error checking; however, it looks cool ;)
>
> --
> Mark Suter http://zwitterion.org/ | I have often regretted my
> <mark.suter at member.sage-au.org.au> | speech, never my silence.
> mobile 0411 262 316 - gpg 2C71D63D | Xenocrates (396-314 B.C.)
>
> ----------------------------- perl -x -----------------------------
> #!/usr/bin/perl
> # [MJS 18 Mar 2010] XML::Twig -> Template demo
>
> use strict;
> use warnings;
> use XML::Twig;
> use Template;
> use Data::Dumper;
>
> ## Contrived sample XML ;)
> my $xml = <<'EOF' ;
> <?xml version="1.0" ?>
> <ratings>
> <thing><name>Perl</name><rating>Awesome</rating></thing>
> <thing><name>Python</name><rating>Awesome</rating></thing>
> </ratings>
> EOF
>
> ## Contrived sample template ;)
> my $template = <<'EOF' ;
> Dumper:
> [% dump %]
> Template:
> [% FOREACH thing IN thing -%]
> [% thing.name %] is [% thing.rating %].
> [% END -%]
> EOF
>
> ## Parse the XML into a simple data structure
> my $data = XML::Twig->parse($xml)->simplify();
>
> ## Add a text dump of that structure to itself
> $data->{dump} = Data::Dumper->new( [$data] )->Indent(0)->Dump();
>
> ## Template it
> Template->new()->process( \$template, $data );
>
> __END__
>
More information about the Canberra-pm
mailing list