[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