XML::Grove::ToObjects: Simple Mapping from XML to Perl Objects


From      perl-xml-admin@lyris.activestate.com Tue Oct 13 13:24:04 1998
From:     Ken MacLeod <ken@bitsko.slc.ut.us>
Subject:  XML::Grove::ToObjects: simple mapping from XML to Perl objects
To:       "Perl-XML Mailing List" <perl-xml@lyris.activestate.com>
Date:     Tue, 13 Oct 1998 12:37:18 -0500 (CDT)

I've created a small package that helps create XML::Grove visitor functions for performing simple mappings from XML elements to Perl objects. According to the options you provide, ToObjects will create Perl objects from XML elements or store the value of an XML element in an already created Perl object.

This is the first cut of this package, it has not been folded into XML::Grove at this time. Most notably missing is support for XML element attributes. You can download the snapshot or view the HTML version of the POD at:

      http://bitsko.slc.ut.us/~ken/perl-xml/xml2objects/.

(Side note: this is not related to the recent XML objects and XML serialization threads. ToObjects is geared more toward document-based and mixed document/information-based XML applications rather than bi-directional marshaling of objects between Perl and XML.)

Here is the man page from the module, the example in the man page is included in the snapshot above.


-------- cut here --------

NAME
    XML::Grove::ToObjects -- simple mapping from XML to Perl objects

SYNOPSIS
    use XML::Grove::ToObjects;

    to_object (ELEMENT, OPTIONS);

DESCRIPTION
    XML::Grove::ToObjects is a code generator that creates
    XML::Grove::Visitor routines for performing simple mappings from
    XML elements to Perl objects.

    XML::Grove::ToObjects is intended to be used from within a Perl
    package.  The `to_object' function will create a new function in
    the package it is called from.  Generally, if `to_object' is given
    an element `title', it will create a subroutine called
    `visit_name_title' that can be called as a visitor.

    `to_object' takes the following options and parameters:

    ELEMENT
        The element name to convert (see `-query').

    -query ELEMENT
        The element name to convert.  Use this option if ELEMENT
        contains a leading `-' character.

    -holder
        Ignore this element, but continue processing it's children
        (compare to -ignore).

    -ignore
    -make PACKAGE
        Create an object blessed into PACKAGE, and continue processing
        this element and it's children.

    -field FIELD
        Store this element, object, or children of this element in the
        parent object's field named by FIELD.

    -push-field FIELD
        Similar to -field, except that FIELD is an array and the
        contents are pushed onto that array.

    -value VALUE
        Use VALUE as a literal value to store in FIELD, otherwise
        ignoring this element and it's children.  Only valid with
        -field or -push-field.

    -as-string
        Convert the contents of this element to a string (as in
        XML::Grove::AsString) and store in FIELD.  Only valid with
        -field or -push-field.

    -grove
        Copy this element to FIELD without further processing.  The
        element can then be processed later as the Perl objects are
        manipulated.  Only valid with -field or -push-field.

EXAMPLE
    The example Perl package `MyConverter' below will convert the
    following XML representing a Database schema:

        <schema>
          <table>
            <name>MyTable</name>
            <summary>A short summary</summary>
            <description>A long description that may
              contain a subset of HTML</description>
            <column>
              <name>MyColumn1</name>
              <summary>A short summary</summary>
              <description>A long description</description>
              <unique/>
              <non-null/>
              <default>42</default>
            </column>
          </table>
        </schema>
   into Perl objects looking like:

        [
          { name => "MyTable",
            summary => "A short summary",
            description => $grove_object,
            columns => [
              { name => "MyColumn1",
                summary => "A short summary",
                description => $grove_object,
                unique => 1,
                'non-null' => 1,
                default => 42
              }
            ]
          }
        ]

    Here's the Perl module that will perform the conversion, note the
    mixing of ordinary Visitor callbacks with ToObjects' created
    functions:

        # MyConverter is an XML converter that converts Schema
        # elements to Perl Schema objects.  $grove->accept($converter)
        # returns an anonymous array of Schema::Table objects.

        package MyConverter;
        use XML::Grove::ToObjects (to_object);

        sub new {
            return bless {}, $_[0];
        }

        sub visit_grove {
            my $self = shift; my $grove = shift;

            # provide a place for `table' to put it's values
            $self->{'tables'} = [];
            $grove->children_accept_name($self, $self);
            return $self->{'tables'};
        }

        to_object qw{ schema      -holder                                  };
        to_object qw{ table       -make Schema::Table -push-field tables   };
        to_object qw{ name        -field name -as-string                   };
        to_object qw{ summary     -field summary -as-string                };
        to_object qw{ description -field description -grove                };
        to_object qw{ column      -make Schema::Column -push-field columns };

        to_object qw{ unique      -field unique -value 1                   };
        to_object qw{ non-null    -field non-null -value 1                 };
        to_object qw{ default     -field default -as-string                };

        sub visit_scalar {
            my $self = shift; my $scalar = shift;
        }

        1;

    Here is a Perl script that would call the converter above to
    transform an XML::Grove into Schema objects, this script accepts a
    Schema XML file as an argument ($ARGV[0]) to the script:

        use Schema;
        use XML::Grove;
        use XML::Parser;
        use XML::Parser::Grove;

        use MyConverter;

        my $converter = MyConverter->new;

        my $parser = XML::Parser->new(Style => 'grove');
        my $grove = $parser->parsefile ($ARGV[0]);

        my $tables = $grove->accept($converter);

AUTHOR
    Ken MacLeod, ken@bitsko.slc.ut.us

SEE ALSO
    perl(1), XML::Parser(3), XML::Parser::Grove(3),
    XML::Grove::Visitor(3), XML::Grove::AsString(3).

    Extensible Markup Language (XML) <http://www.w3c.org/XML>