[RFC] XML::Simple::Tree

[RFC] XML::Simple::Tree

am 04.11.2005 08:37:50 von Aaron Dancygier

I've written a module called XML::Simple::Tree.
Its a tree object which is based on a XML::Simple tree data structure
returned from
XMLin($xmlfile, forcearray =>1). It provides facilities for
traversing, finding, cutting, pasting, copying, and moving nodes. If
you have any comments feel free to reply, and by all means feel free to
download it when its available.

Aaron Dancygier

NAME
XML::Simple::Tree - Tree object extension for XML::Simple data
structures


SYNOPSIS
## script 1
## create XML::Simple::Tree object and do a preorder traversal


## create XML::Simple::Tree object from an xml document
($xml_file)
my $xml_obj = XML::Simple::Tree->new(file => 'directory.xml',
node_key => 'dir',
target_key => 'name');


## sub set_do_node() method takes subroutine reference to be
executed at current node
$xml_obj->set_do_node(
sub {
my $self = $xml_obj;


my $cnode = $self->get_cnode();
my $level = $self->get_level();
my $padding = '* ' x ($level + 1);


print "$padding$cnode->{name}[0]\n";
}
);


## sub set_do_leaf() method takes subroutine reference to be
executed at leaf node
$xml_obj->set_do_leaf(
sub {
my $self = $xml_obj;


print "\n";
}
);


## Tree pre order traversal method that executes do_node() at
each node and do_leaf() at each leaf
$xml_obj->traverse();


## script 2
## find a node and retrieve a parameter.


my $xml_obj =
XML::Simple::Tree->new(
file => $xml_file,
node_key => 'directory',
target_key => 'name'
);


my $want_node = $xmlObj->find_node($target_directory);
my $mtime = $want_node->{mtime}[0];


## script 3
## find a node and cut (remove) it from tree.


my $cut_name = 'bin';


my $mainXml =
XML::Simple::Tree->new( file => $xml_file,
node_key => 'directory',
target_key => 'name');


$mainXml->cut_node($cut_name);


## script 4
## take XML::Simple::Tree object and paste it into a target node
of another
## convert it back to xml


my $target_dir = 'xxx';


my $cut_tree =
XML::Simple::Tree->new(file => $cut_xml_file,
node_key => 'directory',
target_key => 'name');


$config_tree->paste_node($target_dir,
$cut_tree->get_cnode()->{directory}[0]);


## convert to xml
my $xml = $config_tree->toXML();


## Additional examples can be found in the included tests.


DESCRIPTION
This module extends XML::Simple by taking the data structure
returned by
XML::Simple::XMLin($xml_file, forcearray => 1) and putting it in a
class
complete with tree manipulation and traversal methods. Important to
know
is that XMLin is called with the option ForceArray => 1. This
option
forces nested elements to be represented as arrays even when there
is
only one.


METHODS
new([file=>$xml_file | string => $xml_string], node_key=>$node_key,
target_key=>$target_key);
constructor returns an object of type XML::Simple::Tree with one of its
data members being a reference to a XML::Simple datastructure.
required parameters


Either 'file' or 'string' must be supplied with 'file' taking
precedence if both are provided.
* file - xml document filename
* string - xml document in string form
* node_key - xml element name which defines a node.
* target_key - name of xml element used as identifier field in
find()
operations.


find_node($name)
finds and returns node where $name matches 'target_node'


children( )
returns list of child node[s] of current node. Current node is
defined
in paramater 'cnode'


siblings( )
returns list of sibling nodes relative to current node ('cnode').
List
includes current node. Once again current node is stored in
'cnode'.
Simply iterates through children of 'pnode', parent node of cnode.!


cut_node($name)
finds and splices away specified node


move_node($name, $direction)
finds node specified by $name and swaps adjacent node (up -> -1,
down ->
+1) useful for reordering children


copy_node($name)
finds copies( dclone() ) and returns wanted node


paste_node($destination, $paste_node)
finds destination node and pastes (push()) paste_node in place


traverse( )
pre-order traversal which walks tree executing do_node() and
do_leaf
where appropriate


post_traversal( )
post-order traversal which walks tree executing do_node() and
do_leaf
where appropriate


set_do_node($sub_ref)
sets subroutine reference executed at each node


set_do_leaf($sub_ref)
sets subroutine reference executed at each leaf


is_leaf( )
returns true if current node has no children, and false otherwise.


toXML([$node_ref])
Returns XML representation of object instance tree. By default it
returns XML for the root node (rnode). The default behavior can be
overridden by supplying another node reference as an argument. This
method is implemented as a wrapper method for
XML::Simple::XMLout(), so
any options for that subroutine should carry over. See XML::Simple
documentation for more information.

Autoloaded accessors/mutators via Class::MethodMaker
Private methods
* _set_pnode($node_ref)
sets parent node field


* _set_wnode($node_ref)
sets wanted node field


* _set_cnode($node_ref)
sets current node field


* _set_level($level)
sets current level field


* _set_pos($pos)
sets position of node in pnode


Public methods
* get_cnode( )
gets current node field


* get_target_key
gets target_key field


* get_node_key( )
gets node_key field


* get_pnode( )
gets parent node field


* get_rnode( )
gets root node field


* get_level( )
returns level field


* get_pos( )
returns node position in pnode


* get_file( )
returns xml filename. Field 'file' is set only if passed to new
as
new(file => $xmlfile)


* get_string( )
returns xml in string form. Field 'string' is set only if
passed to
new as new(string => $xmlstr)


AUTHOR
Aaron Dancygier,


COPYRIGHT AND LICENSE
Copyright 2005 by Aaron Dancygier


This library is free software; you can redistribute it and/or
modify it
under the same terms as Perl itself.