XML-Node-0.11/ 40777 0 0 0 7405307512 11113 5 ustar user group XML-Node-0.11/Changes 100666 0 0 1234 7405274210 12501 0 ustar user group Revision 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.xml 100666 0 0 63 7405266227 12463 0 ustar user group xa
y
XML-Node-0.11/Makefile.PL 100666 0 0 235 7005150400 13126 0 ustar user group use ExtUtils::MakeMaker;
WriteMakefile(
NAME => 'XML::Node',
# MAN3PODS => 'Node.pm',
VERSION_FROM => 'Node.pm',
);
XML-Node-0.11/MANIFEST 100666 0 0 233 7071305300 12307 0 ustar user group README
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.pm 100666 0 0 26430 7405307173 12463 0 ustar user group # 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.xml 100666 0 0 1076 7405262137 13237 0 ustar user group
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.pl 100666 0 0 1344 7405273577 13457 0 ustar user group #!/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.pl 100666 0 0 2000 7063142410 14135 0 ustar user group #!/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.pl 100666 0 0 2114 7063142410 14676 0 ustar user group #!/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/README 100666 0 0 10200 7405275234 12106 0 ustar user group 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.pl 100666 0 0 1706 7405307431 12530 0 ustar user group #!/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.xml 100666 0 0 4720 7011317744 12715 0 ustar user group
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!