XML-Node-0.11/ 40777 0 0 0 7405307512 11113 5ustar usergroupXML-Node-0.11/Changes100666 0 0 1234 7405274210 12501 0ustar usergroupRevision history for Perl extension XML::Node 0.11 Dec 10 Mon 2:07:06 2001 - added support for relative paths - rename XML::Node.sgml to XML-Node.sgml so that Windows people can unzip the package. 0.10 Mar 13 Mon 2:07:06 - Bug fixs - Add suport for IO::Handle *** Note that old parse() is replaced by parsefile() *** 0.09 Mon Nov 15 11:29:53 PST 1999 - Add support for attributes 0.06 Thu Nov 4 17:26:25 PST 1999 - Change to object style. - Allow multiple instances running simultaneously 0.04 Thu Oct 20 09:00:00 1999 - Getting ready to upload to CPAN 0.01 Thu Oct 7 23:23:33 1999 - original version; XML-Node-0.11/foo.xml100666 0 0 63 7405266227 12463 0ustar usergroupx

a

y
XML-Node-0.11/Makefile.PL100666 0 0 235 7005150400 13126 0ustar usergroupuse ExtUtils::MakeMaker; WriteMakefile( NAME => 'XML::Node', # MAN3PODS => 'Node.pm', VERSION_FROM => 'Node.pm', ); XML-Node-0.11/MANIFEST100666 0 0 233 7071305300 12307 0ustar usergroupREADME Changes MANIFEST Makefile.PL Node.pm test.pl parse-orders.pl parse-testsuite.pl parse-foo.pl foo.xml orders.xml test.xml XML-Node.sgml XML-Node-0.11/Node.pm100666 0 0 26430 7405307173 12463 0ustar usergroup# Copyright (c) 1999 Chang Liu # All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the same terms as Perl itself. package XML::Node; #use strict; #use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION); =head1 NAME XML::Node - Node-based XML parsing: an simplified interface to XML::Parser =head1 SYNOPSIS use XML::Node; $xml_node = new XML::Node; $xml_node->register( $nodetype, $callback_type => \&callback_function ); $xml_node->register( $nodetype, $callback_type => \$variable ); open(FOO, 'xmlgenerator |'); $p3->parse(*FOO); close(FOO); $xml_node->parsefile( $xml_filename ); =head1 DESCRIPTION If you are only interested in processing certain nodes in an XML file, this module can help you simplify your Perl scripts significantly. The XML::Node module allows you to register callback functions or variables for any XML node. If you register a call back function, it will be called when the node of the type you specified are encountered. If you register a variable, the content of a XML node will be appended to that variable automatically. Subroutine register accepts both absolute and relative node registrations. Here is an example of absolute path registration: 1. register(">TestCase>Name", "start" => \&handle_TestCase_Name_start); Here are examples of single node name registration: 2. register( "Name", "start" => \&handle_Name_start); 3. register( "Name", "end" => \&handle_Name_end); 4. register( "Name", "char" => \&handle_Name_char); Here is an example of attribute registration: 5. register(">TestCase:Author", "attr" => \$testcase_author); Abosolute path trigger condition is recommended because a "Name" tage could appear in different places and stands for differe names. Example: 1 2 Something 3 4 Something 5 6 Statement 1 causes &handle_TestCase_Name_start to be called when parsing Line 2. Statements 2,3,4 cause the three handler subroutines to be called when parsing both Line 2 and Line 4. This module uses XML::Parser. =head1 EXAMPLE Examples "test.pl" and "parse_orders.pl" come with this perl module. =head1 SEE ALSO XML::Parser =head1 NOTE When you register a variable, XML::Node appends strings found to that variable. So please be sure to clear that variable before it is used again. =head1 AUTHORS Chang Liu =head1 LAST MODIFIED $Date: 2001/12/10 11:38:28 $ =cut use Exporter; $VERSION = "0.11"; @ISA = ('Exporter'); @EXPORT = qw (®ister &parse &parsefile); use XML::Parser; use Carp; if ($ENV{DEBUG}) { print "DEBUG:XML::Node.pm VERSION $VERSION\n"; } my $instance = 0; my @selves = (); my $myinstance; sub new{ my $class = shift; my $self = { INSTANCE => $instance, START_HANDLERS => {}, END_HANDLERS => {}, CHAR_HANDLERS => {}, ATTR_HANDLERS => {}, CURRENT_TAG => "", CURRENT_PATH => "", }; bless $self, $class; $selves[$instance++] = $self; return $self; } sub register { $self = shift or croak "XML::Node --self is expected as THE first parameter \®ister.\n"; my $node = shift or croak "XML::Node --a node path is expected as arg1 in \®ister.\n"; my $type = shift or croak "XML::Node --node type is expected as arg2 in \®ister.\n"; my $handler = shift or croak "XML::Node --a handler is expected as arg3 in \®ister.\n"; if ($type eq "start") { $self->{START_HANDLERS}->{$node} = $handler; } elsif ($type eq "end") { $self->{END_HANDLERS}->{$node} = $handler; } elsif ($type eq "char") { $self->{CHAR_HANDLERS}->{$node} = $handler; } elsif ($type eq "attr") { $self->{ATTR_HANDLERS}->{$node} = $handler; } else { croak "XML::Node --unknown handler type $type for node $node\n"; } } sub parsefile { $self = shift or croak "XML::Node --self is expected as THE first parameter \®ister.\n"; my $xml_file = shift or croak "XML::Node --an XML filename is expected in \&parse.\n"; $myinstance = $self->{INSTANCE}; carp "XML::Node - invoking parser [$myinstance]" if $ENV{DEBUG}; my $my_handlers = qq { sub handle_start_$myinstance { &handle_start($myinstance, \@_); } sub handle_end_$myinstance { &handle_end($myinstance, \@_); } sub handle_char_$myinstance { &handle_char($myinstance, \@_); } \$XML::Node::parser = new XML::Parser(Handlers => { Start => \\& handle_start_$myinstance, End => \\& handle_end_$myinstance, Char => \\& handle_char_$myinstance } ); }; #carp "[[[[[[[[[[[[[[[[$my_handlers]]]]]]]]]]]]]]"; eval ($my_handlers); $parser->parsefile("$xml_file"); } sub parse { $self = shift or croak "XML::Node --self is expected as THE first parameter \®ister.\n"; $myinstance = $self->{INSTANCE}; carp "XML::Node - invoking parser [$myinstance]" if $ENV{DEBUG}; my $my_handlers = qq { sub handle_start_$myinstance { &handle_start($myinstance, \@_); } sub handle_end_$myinstance { &handle_end($myinstance, \@_); } sub handle_char_$myinstance { &handle_char($myinstance, \@_); } \$XML::Node::parser = new XML::Parser(Handlers => { Start => \\& handle_start_$myinstance, End => \\& handle_end_$myinstance, Char => \\& handle_char_$myinstance } ); }; #carp "[[[[[[[[[[[[[[[[$my_handlers]]]]]]]]]]]]]]"; eval ($my_handlers); $parser->parse(shift); } sub handle_start { my $myinstance = shift; my $p = shift; my $element = shift; my $current_path = $selves[$myinstance]->{CURRENT_PATH} = $selves[$myinstance]->{CURRENT_PATH} . ">" . $element; my $current_tag = $selves[$myinstance]->{CURRENT_TAG} = $element; my $attr; my $value; # carp("handle_start called [$myinstance] [$element] [$current_path]\n"); while (defined ($attr = shift ) ) { if (! defined ($value = shift)) { croak ("value for attribute [$attr] of element [$element] is not returned by XML::Parser\n"); } # carp("Attribute [$attr] of element [$element] found with value [$value] attr_path:[$attr_path]\n"); my @array = split(/>/, $current_path); my $current_relative_path = "$current_tag:$attr"; my $i; if ($selves[$myinstance]->{ATTR_HANDLERS}->{$current_relative_path}) { handle($p, $value, $selves[$myinstance]->{ATTR_HANDLERS}->{$current_relative_path}); } for ($i=$#array-1;$i>=1;$i--) { # call all relative paths $current_relative_path = $array[$i] . ">" . $current_relative_path; if ($selves[$myinstance]->{ATTR_HANDLERS}->{$current_relative_path}) { handle($p, $value, $selves[$myinstance]->{ATTR_HANDLERS}->{$current_relative_path}); } } my $attr_path = "$current_path:$attr"; if ($selves[$myinstance]->{ATTR_HANDLERS}->{$attr_path}) { handle($p, $value, $selves[$myinstance]->{ATTR_HANDLERS}->{$attr_path}); } } my @array = split(/>/, $current_path); my $current_relative_path = $current_tag; my $i; if ($selves[$myinstance]->{START_HANDLERS}->{$current_tag}) { handle($p, $element, $selves[$myinstance]->{START_HANDLERS}->{$current_tag}); } #carp("--Begin loop\n"); for ($i=$#array-1;$i>=1;$i--) { # call all relative paths $current_relative_path = $array[$i] . ">" . $current_relative_path; #carp("Array size is $#array, \$i is $i, current_relative_path is $current_relative_path\n"); if ($selves[$myinstance]->{START_HANDLERS}->{$current_relative_path}) { handle($p, $element, $selves[$myinstance]->{START_HANDLERS}->{$current_relative_path}); } } #carp("--End loop\n"); if ($selves[$myinstance]->{START_HANDLERS}->{$current_path}) { handle($p, $element, $selves[$myinstance]->{START_HANDLERS}->{$current_path}); } } sub handle_end { my $myinstance = shift; my $p = shift; my $element = shift; my $current_path = $selves[$myinstance]->{CURRENT_PATH}; # carp("handle_end called [$myinstance] [$element]\n"); $selves[$myinstance]->{CURRENT_TAG} = $element; my @array = split(/>/, $current_path); my $current_relative_path = $element; my $i; if ($selves[$myinstance]->{END_HANDLERS}->{$selves[$myinstance]->{CURRENT_TAG}}) { handle($p, $element, $selves[$myinstance]->{END_HANDLERS}->{$selves[$myinstance]->{CURRENT_TAG}}); } for ($i=$#array-1;$i>=1;$i--) { # call all relative paths $current_relative_path = $array[$i] . ">" . $current_relative_path; #carp("Array size is $#array, \$i is $i, current_relative_path is $current_relative_path\n"); if ($selves[$myinstance]->{END_HANDLERS}->{$current_relative_path}) { handle($p, $element, $selves[$myinstance]->{END_HANDLERS}->{$current_relative_path}); } } if ($selves[$myinstance]->{END_HANDLERS}->{$selves[$myinstance]->{CURRENT_PATH}}) { handle($p, $element, $selves[$myinstance]->{END_HANDLERS}->{$selves[$myinstance]->{CURRENT_PATH}}); } $selves[$myinstance]->{CURRENT_PATH} =~ /(.*)>/; $selves[$myinstance]->{CURRENT_PATH} = $1; $selves[$myinstance]->{CURRENT_TAG} = $'; if ($element ne $selves[$myinstance]->{CURRENT_TAG}) { carp "start-tag <$selves[$myinstance]->{CURRENT_TAG}> doesn't match end-tag <$element>. Is this XML file well-formed?\n"; } $selves[$myinstance]->{CURRENT_PATH} =~ /(.*)>/; $selves[$myinstance]->{CURRENT_TAG} = $'; } sub handle_char { my $myinstance = shift; my $p = shift; my $element = shift; my $current_path = $selves[$myinstance]->{CURRENT_PATH}; # carp("handle_char called [$myinstance] [$element]\n"); my @array = split(/>/, $current_path); my $current_relative_path = $element; my $i; if ($selves[$myinstance]->{CHAR_HANDLERS}->{$selves[$myinstance]->{CURRENT_TAG}}) { handle($p, $element, $selves[$myinstance]->{CHAR_HANDLERS}->{$selves[$myinstance]->{CURRENT_TAG}}); } for ($i=$#array-1;$i>=1;$i--) { # call all relative paths $current_relative_path = $array[$i] . ">" . $current_relative_path; if ($selves[$myinstance]->{CHAR_HANDLERS}->{$current_relative_path}) { handle($p, $element, $selves[$myinstance]->{CHAR_HANDLERS}->{$current_relative_path}); } } if ($selves[$myinstance]->{CHAR_HANDLERS}->{$selves[$myinstance]->{CURRENT_PATH}}) { handle($p, $element, $selves[$myinstance]->{CHAR_HANDLERS}->{$selves[$myinstance]->{CURRENT_PATH}}); } } sub handle { my $p = shift; my $element = shift; my $handler = shift; my $handler_type = ref($handler); if ($handler_type eq "CODE") { &$handler($p,$element); # call the handler function } elsif ($handler_type eq "SCALAR") { # chomp($element); # $element =~ /^(\s*)/; # $element = $'; # $element =~ /(\s*)$/; # $element = $`; if (! defined $$handler) { $$handler = ""; #carp ("XML::Node - SCALAR handler undefined when processing [$element]"); } $$handler = $$handler . $element; #append the content to the handler variable } else { carp "XML::Node -unknown handler type [$handler_type]\n"; exit; } } 1; XML-Node-0.11/orders.xml100666 0 0 1076 7405262137 13237 0ustar usergroup These are the orders: A Book 1 Something Blah Blah A Pencil 2 Something A Pen 4 Something End of all orders. XML-Node-0.11/parse-foo.pl100666 0 0 1344 7405273577 13457 0ustar usergroup#!/usr/bin/perl -w use XML::Node; $xml_node = XML::Node->new(); $xml_node->register( "foo", 'char' => \$variable ); $xml_node->register( "foo>bar", "start" => sub { print "foo-bar[start](relative)\n" } ); $xml_node->register( "foo>bar", "end" => sub { print "foo-bar[end](relative)\n" } ); $xml_node->register( ">foo>bar", "end" => sub { print "foo-bar[end](absolute)\n" } ); $xml_node->register( ">foo:type", "attr" => sub { print "foo-type[attr](absolute)\n" } ); $xml_node->register( "foo:type", "attr" => sub { print "foo-type[attr](relative)\n" } ); my $file = "foo.xml"; print "Processing file [$file]...\n"; open(FOO, $file); $xml_node->parse(*FOO); close(FOO); print " has content: [$variable]\n"; XML-Node-0.11/parse-orders.pl100666 0 0 2000 7063142410 14135 0ustar usergroup#!/usr/bin/perl -w use XML::Node; my $item = ""; my $quantity = ""; my $id = ""; my $date = ""; my $orders = ""; $p = XML::Node->new(); $p->register(">Orders","start" => \&handle_orders_start); $p->register(">Orders","char" => \$orders); $p->register(">Orders>Order:ID","attr" => \$id); $p->register(">Orders>Order:Date","attr" => \$date); $p->register(">Orders>Order>Item","char" => \$item); $p->register(">Orders>Order>Quantity","char" => \$quantity); $p->register(">Orders>Order","end" => \&handle_order_end); $p->register(">Orders","end" => \&handle_orders_end); print "Processing file [orders.xml]...\n"; $p->parsefile("orders.xml"); sub handle_orders_start { print "Start of all orders\n-----\n$orders\n----\n"; } sub handle_order_end { print "Found order [$id] [$date] -- Item: [$item] Quantity: [$quantity]\n"; $date = ""; $id=""; $item = ""; $quantity = ""; } sub handle_orders_end { print "End of all orders\n-----\n$orders\n----\n"; } XML-Node-0.11/parse-testsuite.pl100666 0 0 2114 7063142410 14676 0ustar usergroup#!/usr/bin/perl -w # use XML::Node; # The following sample script calculates how many test cases there are in # a test suite XML file. # # The XML file name can be passed as a parameter. Example: # perl test.pl test.xml # my $suite_name = ""; my $testcase_name = ""; my $xml_filename = "test.xml"; my $testcase_no = 0; my $arg1 = shift; if ($arg1) { $xml_filename = $arg1; } $p = XML::Node->new(); $p->register(">TestTalk>TestSuite>Name","char" => \$ suite_name); $p->register(">TestTalk>TestSuite>TestCase>Name","char" => \$testcase_name); $p->register(">TestTalk>TestSuite>TestCase","end" => \& handle_testcase_end); $p->register(">TestTalk>TestSuite","end" => \& handle_testsuite_end); print "\nProcessing file [$xml_filename]...\n\n"; $p->parsefile($xml_filename); sub handle_testcase_end { print "Found test case [$testcase_name]\n"; $testcase_name = ""; $testcase_no ++; } sub handle_testsuite_end { print "\n--There are $testcase_no test cases in test suite [$suite_name]\n\n"; $testcase_name = ""; } XML-Node-0.11/README100666 0 0 10200 7405275234 12106 0ustar usergroup XML::Node Version 0.11 Here is a quick but complete example to show you how XML::Node promises to keep your XML processing scripts short and clear. ---------- orders.xml ---------------------------------------------- A Book 1 Something Blah Blah ---------- parse-orders.pl ------------------------------------------ use XML::Node; my $item = ""; my $quantity = ""; my $id = ""; $p = XML::Node->new(); $p->register(">Orders>Order:ID","char" => \$item); $p->register(">Orders>Order>Item","char" => \$item); $p->register(">Orders>Order>Quantity","char" => \$quantity); $p->register(">Orders>Order","end" => \&handle_order_end); print "Processing file [orders.xml]...\n"; $p->parsefile("orders.xml"); sub handle_order_end { print "Found order [$id] -- Item: [$item] Quantity: [$quantity]\n"; $id=""; $item = ""; $quantity = ""; } --------------------------------------------------------------------- Copyright (c) 1999,2000,2001 Chang Liu All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. This is a Perl extension interface to XML::Parser. It requires at least version 5.004 of perl. The documentation for this extension can be found in pod format in the file Node.pm. The 'perldoc' program, provided with the perl distribution, can be used to view this documentation. The purpose of this module is to simplify interface of XML parser. Instead of worrying about "start", "end", and "char" callbacks of every single XML node, you can simply say that you only want to be notified when a path, such as ">TestCase>Name", is found. Path ">TestCase>Name" corresponds to XML nodes: ... Something ... Using XML::Node, you can easily ignore the parts of XML files that you are not interested in. Another feature of XML::Node is that you can register a variable instead of a callback function. The corresponding string found in a XML file will be automatically appended to your variable. This way, you don't have to write a callback function for this type of simple handling. Here's an example: my $testcase_name = ""; register(">TestCase>Name","char" => \$testcase_name); --------------------------------------------------------------------- To install this module, cd to the directory that contains this README file and type the following: perl Makefile.PL Alternatively, if you plan to install XML::Node somewhere other than your system's perl library directory. You can type something like this: perl Makefile.PL PREFIX=/home/me/perl INSTALLDIRS=perl Then to build you run make. make You can then test the module by typing: make test There are some sample utilities in the samples directory along with an xml form of the XML specification to test them on. You may need to change the '#!' line at the top of these utilities to what is appropriate for your system. If you're going to play around with them prior to installing the module, you would need to add the blib paths to your perl search path, like this (assuming your current directory is samples): perl -I../blib/lib -I../blib/arch test.pl or set your PERLLIB environment variable. If you have write access to the installation directories, you may then install by typing: make install After this, you may use "man XML::Node" to view the man page of this module. --------------------------------------------------------------------- When testing the package, make sure "make install" is called every time after "Node.pm" is modified. --------------------------------------------------------------------- To rebuild the package: edit MANIFEST perl Makefile.PL make dist or nmake dist (make sure tar and gzip are on path.) --Chang Liu (liu@ics.uci.edu | changliu@acm.org) XML-Node-0.11/test.pl100666 0 0 1706 7405307431 12530 0ustar usergroup#!/usr/bin/perl -w # # Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl test.pl' ######################### We start with some black magic to print on failure. # Change 1..1 below to 1..last_test_to_print . # (It may become useful if the test is moved to ./t subdirectory.) BEGIN { $| = 1; print "1..4\n"; } END {print "not ok 1\n" unless $loaded;} use XML::Node; $loaded = 1; print "ok 1\n"; ######################### End of black magic. # Insert your test code below (better if it prints "ok 13" # (correspondingly "not ok 13") depending on the success of chunk 13 # of the test code): print "invoking parse-testsuite.pl...\n"; require "parse-testsuite.pl"; print "ok 2\n"; print "invoking parse-orders.pl...\n"; require "parse-orders.pl"; print "ok 3\n"; print "invoking parse-foo.pl...\n"; require "parse-foo.pl"; print "ok 4\n"; XML-Node-0.11/test.xml100666 0 0 4720 7011317744 12715 0ustar usergroup ClientTestSuite1 SimpleText SanityCheck http://localhost:8082 It Worked! ServerLog http://localhost access_log 127.0.0.1 - - \[22/Oct/1999:.*GET / HTTP/1\.0 OracleCombo SanityCheck http://localhost:8082 200 1:Test Page for Apache Installation on Web Site 51 1626 ChangeDocumentRoot RocumentRoot DocumentRoot22 http://localhost:8082 2:It Worked! DocumentRoot21 http://localhost:8082 1:It Worked! XML-Node-0.11/XML-Node.sgml100666 0 0 6162 7225400140 13413 0ustar usergroup
ChangLiu Nov 1999 Perl Module XML::Node 0.09 15 Nov 1999 --Add support to attributes 0.06 4 Nov 1999 --Change to an object class 0.04 20 Oct 1999 --The first version that's submitted to CPAN. XML::Node Overview XML::Node is for those who use Perl to process XML files. XML::Node is built on top of XML::Parser and provides a simplified programming interface. XML::Node users can register callback sub-routines or variables to specific type of XML nodes. The values of the specified XML nodes are automatically copied to the corresponding variables. When specified XML tags are found, registered callback sub-routines are called. XML::Node is a shortcut to XML::Parser if you don't care much about details of XML files. Here is an example. This XML file contains order information: orders.xml A Book 1 Something Blah Blah ]]> This simple Perl script can parse the XML file and print out all the orders. parse_orders.pl new(); $p->register(">Orders>Order>Item","char" => \$item); $p->register(">Orders>Order>Quantity","char" => \$quantity); $p->register(">Orders>Order","end" => \&handle_order_end); print "Processing file [orders.xml]...\n"; $p->parsefile("orders.xml"); sub handle_order_end { print "Found order -- Item: [$item] Quantity: [$quantity]\n"; $item = ""; $quantity = ""; } ]]> Download The XML::Node module can be found at http://belmont-shores.ics.uci.edu/pub, ftp://belmont-shores.ics.uci.edu/pub, or Perl CPAN. Bug Report Please submit any related bugs, issues, suggestions, or comments to http://belmont-shores.ics.uci.edu/bugzilla.