The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

XML::Parser::Nodes - Extends XML::Parser

SYNOPSIS

  use XML::Parser::Nodes ;

Constructors

  $node = XML::Parser->new( Style => 'Nodes' )->parsefile( $xmlFileName ) ;
  $node = XML::Parser::Nodes->parsefile( $xmlFileName ) ;
  $node = new XML::Parser::Nodes $xmlFileName ;

  or

  $node = XML::Parser->new( Style => 'Nodes' )->parse( $xmlBufferedScalar ) ;
  $node = XML::Parser::Nodes->parse( $xmlBufferedScalar ) ;
  $node = new XML::Parser::Nodes $xmlBufferedScalar ;

  or

  $node = XML::Parser::Nodes->pl2xml( $ComplexPerlObject ) ;

Access Node Components

  @nodenames = $node->childlist() ;
  @elements = $node->childnodes() ;
  $nodevalue = $node->gettext() ;
  %nodeproperties = %{ $node->getattributes() } ;
  @values = @{ $node->cells( @keylist ) } ;

Survey the Document

  @nodekeys = $node->tree() ;

Retrieve a Node

  $childnode = $parentnode->childnode('nodename') ;
  @childnodes = $parentnode->childnode('nodename') ;
  $descendantnode = $parentnode->nodebykey( $nodekey ) ;

XML Output

  $xmldoc = $node->dump() ;
  $xmldoc = $node->nvpdump() ;

Create a Node Wrapper

  $parentnode = $node->wrapper( $parentname ) ;

DESCRIPTION

When XML::Parser::parse is used without callback functions, the returned object can get pretty hairy for complex objects. XML::Parser::Nodes provides methods to access that object's internals as a sequence of nodes.

XML::Parser::Nodes also has a constructor to create an object directly from a complex Perl object, similar to XML::Dumper->pl2xml(). The following two statements are equivalent:

  $xmlnode = XML::Parser::Nodes->pl2xml( $ComplexPerlObject ) ;

  $xmlnode = XML::Parser::Nodes->parse( 
                XML::Dumper->pl2xml( $ComplexPerlObject )
                ) ;

As a basic background, an XML document can be thought of as nested name-value- pairs. Basically, a node value is either a string or a set of child nodes. It's easy to imagine an XML object as a complex Perl object with a hierarchy of HASH references, whose bottom element is a scalar:

  print $company->{$division}->{$location}->{$department}->{Director}->{FirstName} ;

Might refer to a string "Jim".

In an XML document represented by an XML::Parser::Nodes object, that value would be accessed as:

  print $xmlnode->childnode( $company
                )->childnode( $division
                )->childnode( $location
                )->childnode( $department
                )->childnode('Director'
                )->childnode('FirstName')->gettext() ;

Alternatively,

  $nodekey = join '/', $division, $location, $department, 'Director', 'FirstName' ;
  print $xmlnode->nodebykey( $nodekey )->gettext ;

Some XML documents are more complex and contain sets of values.

  print $company->{$division}->{$location}->{$department}->{Staff}->[0]->{FirstName} ;

Represents a complex object where department staff consists of a set of individuals, one of whom has the first name, "Jim".

One of the features of XML::Parser::Nodes is the ability to survey the contents of a node. The most basic is childlist() which returns an ordered list of element names. If the node consists of 5 children with the same name, that name will be returned 5 times.

The tree() function is similar, except it recurses into each child. The returned values are similar to file pathnames where a slash represents a parent->child relationship.

There are analogous methods to retrieve a node: childnode() takes an element name as an argument; nodebykey() takes the path representation as its argument. When the key refers to a direct child, these two methods are interchangeable. These methods each return an array, but can be called in a scalar context, which returns the first matching node. In order to use the recursive methods and techniques, the caller should be confident that the target is a unique location.

cells() could be applied to each child of the division staff node in the example above and the results used in a spreadsheet application or database table.

This module is primarily designed to retrieve data from a complex XML document. The dump() method restores the XML document. This method is useful for converting a branch of an large XML object into a smaller document. The wrapper() method creates a wrapper node for this purpose.

childnodes() returns the child nodes as elements. An element is an array pair consisting of the element name and node value. Custom functions will most likely accept these elements as arguments. dump() is a wrapper for the method xmlout(), which takes this element pair as its arguments. With no arguments, childnode() functions identically.

XML::Parser::Nodes can be used to create custom XML output.

Example

dump() can be used as a template to override, or otherwise, alter the document output. The nvpdump() method is a useful example that generates output that may be specified as follows:

    <QBMSXML>
     <Signon>
      <Desktop>
       <DateTime>2012-02-29T12:40:09</DateTime>
       <Ticket>gas8p9ee-re2s9old-ref2i6t</Ticket>
       <Login>tqis.com</Login>
      </Desktop>
     </Signon>
     <MsgsRq>
      <CreditCard>
       <RequestID>546696356386</RequestID>
       <Number>4111111111111111</Number>
       <Year>2012</Year>
       <Amount>10.00</Amount>
       <Month>12</Month>
       <CardPresent>false</CardPresent>
      </CreditCard>
     </MsgsRq>
     <MsgsRq>
      <CreditCard>
       <RequestID>546696356387</RequestID>
       <Number>4123111111111111</Number>
       <Year>2014</Year>
       <Amount>20.00</Amount>
       <Month>8</Month>
       <CardPresent>false</CardPresent>
      </CreditCard>
     </MsgsRq>
    </QBMSXML>

Start by defining the data as a complex Perl object:

    $request = {
        'QBMSXML' => {
            'MsgsRq' => [ 
                {
                    'CreditCard' => {
                        'Amount' => '10.00',
                        'Year' => '2012',
                        'Number' => '4111111111111111',
                        'RequestID' => '546696356386',
                        'Month' => '12',
                        'CardPresent' => 'false'
                        }
                    },
                {
                    'CreditCard' => {
                        'Amount' => '20.00',
                        'Year' => '2014',
                        'Number' => '4123111111111111',
                        'RequestID' => '546696356387',
                        'Month' => '8',
                        'CardPresent' => 'false'
                        }
                    }
                ],
            'Signon' => {
                'Desktop' => {
                    'DateTime' => '2012-02-29T12:40:09',
                    'Ticket' => 'gas8p9ee-re2s9old-ref2i6t',
                    'Login' => 'tqis.com'
                    }
                }
            }
        } ;

The XML::Parser::Nodes module includes the nvpdump() method to perform this transformation:

  print XML::Parser::Nodes->pl2xml( $request )->nvpdump() ;

nvpdump() is called recursively on each node. The disposition of each node is determined by its name and constituent elements. If the node has no elements, display the string data (the NVP value). Otherwise, the method handles the key (the NVP name) based on the node name:

  Set the key if node name == "item"
  Reset the key if node name == "hashref"
  Preserve the key if node name == "arrayref"

EXPORT

None by default.

DEPENDENCIES

Requires XML::Parser.

The pl2xml function requires XML::Dumper.

SEE ALSO

Mention other useful documentation such as the documentation of related modules or operating system documentation (such as man pages in UNIX), or any relevant external documentation such as RFCs or standards.

AUTHOR

Jim Schueler, <jim@tqis.com>

COPYRIGHT AND LICENSE

Copyright (C) 2012 by Jim Schueler

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.9 or, at your option, any later version of Perl 5 you may have available.