diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..4783fe1
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,284 @@
+2003-10-21 Ken MacLeod
+
+ * t/stream.t: fixed test 11 for Perl >= 5.6
+
+2001-07-23 Ken MacLeod
+
+ * lib/XML/SAX2Perl.pm (startElement): typo; reported by
+ mhershb@mcdermott.com (Mark A. Hershberger)
+
+2000-03-30 Ken MacLeod
+
+ * doc/index.html (Contributors): added Clark Cooper
+
+ * MANIFEST (doc/sax-2.0.html, doc/sax-2.0-adv.html): added
+
+2000-03-20 Ken MacLeod
+
+ * lib/Data/Grove/Visitor.pm (_children_accept_name): add return
+ @return; reported by Laurent CAPRANI
+
+2000-03-07 Ken MacLeod
+
+ * doc/sax-2.0.html, doc/sax-2.0-adv.html: added
+
+2000-03-02 Ken MacLeod
+
+ * lib/XML/ESISParser.pm: add -E0 to NSGMLS_FLAGS to not limit the
+ number of errors reported; suggested by Charles Thayer
+
+ (parse_fh): report line and line number on command character
+ errors; also suggested by Charles
+
+2000-02-22 Ken MacLeod
+
+ * doc/index.html (Contributors): added Michael Koehne, KangChan
+ Lee, and Colin Muller
+
+ * doc/mirror.sh, doc/index.html: added
+
+2000-02-17 Ken MacLeod
+
+ * doc/modules.xml: fixed several well-formedness errors; reported
+ by KangChan Lee
+
+1999-12-22 Ken MacLeod
+
+ * lib/Data/Grove.pm, lib/Data/Grove/Parent.pm,
+ lib/Data/Grove/Visitor.pm, lib/XML/Handler/XMLWriter.pm,
+ lib/XML/Handler/CanonXMLWriter.pm, lib/XML/Handler/Subs.pm,
+ lib/XML/SAX2Perl.pm, lib/XML/Perl2SAX.pm, lib/XML/ESISParser.pm,
+ lib/XML/Parser/PerlSAX.pm, lib/XML/PatAct/Amsterdam.pm,
+ lib/XML/PatAct/MatchName.pm, lib/XML/PatAct/ToObjects.pm: added
+ $VERSION
+
+ * lib/XML/Parser/PerlSAX.pm (_handle_start): support
+ UseAttributeOrder option
+ (_handle_attlist): Changed EntityName to ElementName (re 9/28
+ entry)
+
+1999-09-28 Ken MacLeod
+
+ * lib/XML/Parser/PerlSAX.pm (_handle_attlist): typo: was calling
+ entity_decl
+
+1999-09-09 Ken MacLeod
+
+ * lib/XML/Parser/PerlSAX.pm: add start_cdata, end_cdata, and
+ entity_reference events
+
+1999-08-28 Ken MacLeod
+
+ * lib/XML/PatAct/Amsterdam.pm: added Output and AsString options,
+ added support for attribute replacement
+
+ * t/amsterdam.t: added
+
+1999-08-18 Ken MacLeod
+
+ * lib/Data/Grove.pm: added Data::Grove::Characters
+
+ * lib/XML/ESISParser.pm (parse_fh): report newline as characters
+ if no record_end() handler
+
+ * lib/XML/PatAct/ToObjects.pm (_parse_action): removed debugging
+ statement
+
+1999-08-16 Ken MacLeod
+
+ * README: updated
+
+ * doc/modules.xml (libxml-perl): updated
+
+ * doc/PerlSAX.pod (Parameters): missing '>'
+
+ * release 0.05
+
+ * lib/XML/Parser/PerlSAX.pm (_handle_init): call set_document_locator
+
+ * lib/XML/PatAct/ActionTempl.pm, lib/XML/PatAct/Amsterdam.pm,
+ lib/XML/PatAct/MatchName.pm, lib/XML/PatAct/PatternTempl.pm (new):
+ Accept both key, value pairs and hash options
+
+ * lib/XML/PatAct/ToObjects.pm (new):
+
+ * lib/XML/Handler/Subs.pm: added
+
+ * t/subs.t: added
+
+ * t/stream.t: added
+
+1999-08-15 Ken MacLeod
+
+ * lib/XML/Handler/XMLWriter.pm: added
+
+ * lib/XML/Handler/Sample.pm: Placed in public domain
+
+1999-08-14 Ken MacLeod
+
+ * doc/PerlSAX.pod: added an introduction, a ``Deviations from the Java version'' section, added `set_document_locator()' handler method
+
+ * lib/XML/PatAct/ToObjects.pm: add CopyAttributes option, add
+ -grove-contents action
+
+1999-08-12 Ken MacLeod
+
+ * lib/XML/ESISParser.pm (parse_fh): dynamically test event handler
+ existance
+
+ * lib/XML/Parser/PerlSAX.pm (parse): wasn't capturing XML::Parser
+ Element events
+
+1999-08-10 Ken MacLeod
+
+ * README, doc/modules.xml: updated with PatAct modules
+
+ * lib/XML/PatAct/ActionTempl.pm, lib/XML/PatAct/Amsterdam.pm,
+ lib/XML/PatAct/MatchName.pm, lib/XML/PatAct/PatternTempl.pm,
+ lib/XML/PatAct/ToObjects.pm: added
+
+ * t/xp_sax.t, t/canon_xml_writer.t: added CVS ID
+
+ * t/schema.t: added
+
+ * examples/schema.xml, examples/schema.pl: added
+
+ * doc/UsingPatActModules.pod, doc/CreatingPatActModules.pod: added
+
+ * lib/XML/Parser/PerlSAX.pm (_handle_extern_ent): change "Perl
+ SAX" to "PerlSAX" in doc
+
+1999-08-09 Ken MacLeod
+
+ * lib/XML/ESISParser.pm (parse_fh): was not passing an empty hash
+
+ * lib/XML/Parser/PerlSAX.pm (_handle_init, _handle_final): was not
+ passing an empty hash
+
+1999-05-26 Ken MacLeod
+
+ * lib/XML/Handler/CanonXMLWriter.pm, t/canon_xml_writer.t: added
+
+1999-05-23 Ken MacLeod
+
+ * lib/Data/Grove/Tied.pm: renamed to Parent.pm
+
+ * README (DOCUMENTS): added
+ renamed libxml to libxml-perl
+
+ * libxml.spec: renamed libxml-perl.spec
+
+1999-05-17 Ken MacLeod
+
+ * libxml.spec: files in `doc/' go into top-dir of /usr/doc/$PKG
+
+ * PerlSAX.pod: moved to doc/PerlSAX.pod
+
+1999-05-09 Ken MacLeod
+
+ * doc/modules.xml: added
+
+1999-05-08 Ken MacLeod
+
+ * doc/UsingPerlSAX.pod, examples/MyHandler.pm,
+ examples/myhandler.pl, examples/myhandler.xml: added
+
+1999-05-07 Ken MacLeod
+
+ * lib/XML/ESISParser.pm, lib/Data/Grove.pm,
+ lib/XML/Handler/Sample.pm: added POD
+
+1999-05-06 Ken MacLeod
+
+ * lib/Data/Grove/Visitor.pm: remove XML::Grove extensions and make
+ generic
+
+ * lib/XML/Parser/SAXPerl.pm: renamed PerlSAX.pm
+
+ * lib/XML/Handler/Sample.pm: added
+
+ * examples/perlsax-test.pl: added
+
+ * examples/esis-test.pl: updated for new XML::ESISParser, moved
+ handler (Receiver) to XML::Handler::Sample, added command line
+ option for SGML
+
+1999-04-30 Ken MacLeod
+
+ * Makefile.PL: added PREREQ_PM for XML::Parser
+
+1999-04-15 Ken MacLeod
+
+ * lib/Data/Grove/Visitor.pm (accept): change XML:: to Data::
+
+ * lib/Data/Grove.pm (new): %{ shift } was being read as %shift
+
+1999-02-18 Ken MacLeod
+
+ * lib/Data/Grove/Visitor.pm: was XML::Grove::Visitor
+
+ * lib/Data/Grove/Tied.pm: was XML::Grove::Node
+
+ * lib/Data/Grove.pm: created from XML::Grove
+
+1999-02-15 Ken MacLeod
+
+ * lib/XML/Parser/SAXPerl.pm (parse): add comments
+
+ * lib/XML/ESISParser.pm: major changes for support of both XML and
+ SGML, and ongoing Perl SAX updates
+
+ * SAX.pod (end_document): noted that the return value of
+ end_document() is the return value of parse()
+
+ * README: added reference to FAQ, added module statuses, more
+ cleary described ESISParser, require Perl 5.005
+
+1999-02-13 Ken MacLeod
+
+ * lib/XML/ESISParser.pm: start move to Perl SAX
+
+1999-02-12 Ken MacLeod
+
+ * lib/XML/SAX2Perl.pm, lib/XML/Perl2SAX.pm, lib/XML/ESISParser.pm:
+ update to new Perl SAX
+
+ * lib/XML/Parser/SAXPerl.pm (new): allow hash or key/value pairs
+
+1999-02-12 Ken MacLeod
+
+ * interface-style.pod: note still undecided items
+
+ * lib/XML/Parser/SAXPerl.pm: fixes shown by xp_sax.t
+
+ * t/xp_sax.t: added
+
+ * lib/XML/Parser/SAXPerl.pm: added pod
+ many changes for Perl SAX and XML::Parser::Expat
+
+1999-02-11 Ken MacLeod
+
+ * SAX.pod: suggestions from Eric Prud'hommeaux and Enno Derksen
+
+ * interface-style.pod: suggestions from Larry Wall
+
+1999-02-01 Ken MacLeod
+
+ * MANIFEST: updated
+
+ * lib/XML/Parser/SAXPerl.pm: modified more towards Perl SAX
+
+ * SAX.pod: added
+
+1999-01-31 Ken MacLeod
+
+ * interface-style.pod: added
+
+1998-12-10 Ken MacLeod
+
+ * lib/XML/Parser/SAXPerl.pm: added
+
+1998-12-08 Ken MacLeod
+
+ * MANIFEST: added
+
diff --git a/Changes b/Changes
new file mode 100644
index 0000000..93e79d8
--- /dev/null
+++ b/Changes
@@ -0,0 +1,113 @@
+Revision history for Perl extension libxml
+
+Backwards incompatible changes are marked with a `*'.
+
+ToDo
+ - XML::ESISParser: include Robert Braddock's update for OpenSP,
+ in email 25Jul
+ - XML::Parser::PerlSAX doesn't pass ParseParamEnt to
+ XML::Parser, inspired by a request by Paul Mahoney
+
+ - switch Data::Grove::Visitor to use UNIVERSAL::can instead of
+ $self->{'has'}, suggested by Mike Richardson
+
+ - no modules are yet supporting SAX2
+ - XML::Parser::PerlSAX doesn't implement ErrorHandler, it
+ should at least call fatal_error() if XML::Parser dies;
+ reported by Craig N. Caroon
+
+0.08 Tue Oct 21 10:54:18 CDT 2003
+ - added Perl SAX 2.0 Binding
+ - XML::ESISParser: add -E0 to nsgmls options so that nsgmls
+ doesn't quit after 200 errors. Add more detail to command
+ character error message. Suggested by Charles Thayer
+ .
+ - fixes
+ - Data::Grove::Visitor: children_accept_name was not
+ returning any data in some cases; reported by Laurent
+ CAPRANI
+ - XML::SAX2Perl: typo in startElement; reported by Mark
+ A. Hershberger
+ - t/stream.t Test 11 fails due to 8-bit characters on Perl
+ 5.6, first reported by Ed Arnold
+
+0.07 Tue Feb 22 14:24:52 CST 2000
+ - doc/index.html: libxml-perl site index
+ - doc/mirror.sh: creates a libxml-perl mirror site
+ - fixes
+ - all modules: release script didn't insert version numbers
+ in Perl modules. Reported by Enno Derksen
+ - doc/modules.xml: well-formedness errors. Reported by
+ KangChan Lee
+
+0.06 Wed Dec 22 15:14:39 CST 1999
+ - all modules: add $VERSION. Suggested by Michael Koehne
+
+ - XML::Parser::PerlSAX: add UseAttributeOrder option and
+ AttributeOrder and Defaulted properties to start_element()
+ handler. Suggested by Enno Derksen
+ - XML::Parser::PerlSAX: add start_cdata, end_cdata, and
+ entity_reference events
+ - XML::PatAct::Amsterdam: added Output and AsString options,
+ added support for replacing attributes
+ - Data::Grove: add a Data::Grove::Characters class to act as a
+ default grove object for containing characters.
+ - fixes
+ - XML::PatAct::ToObjects: removed leftover debugging statement
+ - XML::ESISParser: report record end as characters if no
+ record_end() handler
+ - XML::Parser::PerlSAX: For attribute list declarations, now
+ correctly calls the attlist_decl() method and passes the
+ ElementName property, it used to call entity_decl()
+ passing EntityName. Reported by Enno Derksen
+ and Colin Muller
+
+0.05 Mon Aug 16 11:02:32 CDT 1999
+ - Major update to PerlSAX.pod
+ - added an introduction
+ - added a ``Deviations from the Java version'' section
+ * re-added the `set_document_locator()' handler method
+ - added arguments to method synopses
+ - attributed most of the content to the SAX 1.0 JavaDoc
+ - minor typos
+ - XML::Handler::XMLWriter: a new PerlSAX handler for writing
+ readable XML (in contrast to Canonical XML)
+ - XML::Handler::Subs: a new PerlSAX handler base class for
+ calling user-defined subs
+ - XML::Handler::Sample: this is a template for creating
+ PerlSAX handlers, it is now in the Public Domain
+ - XML::PatAct::ToObjects: add CopyAttributes option, add
+ -grove-contents option
+ - all PatAct modules can now take parameters as either a list
+ of key, value pairs or a hash
+ - fixes
+ - XML::ESISParser wasn't testing handlers for what methods
+ they support
+ - XML::Parser::PerlSAX wasn't capturing XML::Parser Element
+ events
+
+0.04 Wed Aug 11 10:03:00 CDT 1999
+ - README: updated with PatAct modules
+ - added Creating PatAct Modules and Using PatAct Modules docs
+ - added XML::PatAct::ActionTempl, XML::PatAct::Amsterdam,
+ XML::PatAct::MatchName, XML::PatAct::PatternTempl,
+ XML::PatAct::ToObjects
+ - added schema.pl and schema.xml examples
+ - added schema.t test
+ - fixes
+ - XML::Parser::PerlSAX and XML::ESISParser were not passing
+ a hash for start_document() or end_document() per spec
+ - t/canon_xml_writer.t, t/xp_sax.t: added CVS ID
+
+0.03 Wed May 26 19:49:46 CDT 1999
+ - added XML::Handler::CanonXMLWriter and test
+
+0.02 Mon May 24 18:02:00 CDT 1999
+ - renamed package from `libxml' to `libxml-perl'
+ - added doc/modules.xml
+ - added doc/UsingPerlSAX.pod and example files
+ - moved PerlSAX.pod and interface-style.pod to `doc/'
+ - renamed Data::Grove::Tied to Data::Grove::Parent
+
+0.01 Fri May 7 14:59:07 CDT 1999
+ - original version
diff --git a/MANIFEST b/MANIFEST
new file mode 100644
index 0000000..3cfe5b1
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,46 @@
+ChangeLog
+Changes
+MANIFEST
+Makefile.PL
+README
+libxml-perl.spec
+libxml-perl-0.08.spec
+doc/CreatingPatActModules.pod
+doc/PerlSAX.pod
+doc/UsingPatActModules.pod
+doc/UsingPerlSAX.pod
+doc/index.html
+doc/interface-style.pod
+doc/mirror.sh
+doc/modules.xml
+doc/sax-2.0.html
+doc/sax-2.0-adv.html
+lib/Data/Grove.pm
+lib/Data/Grove/Parent.pm
+lib/Data/Grove/Visitor.pm
+lib/XML/ESISParser.pm
+lib/XML/Perl2SAX.pm
+lib/XML/SAX2Perl.pm
+lib/XML/Handler/CanonXMLWriter.pm
+lib/XML/Handler/Sample.pm
+lib/XML/Handler/Subs.pm
+lib/XML/Handler/XMLWriter.pm
+lib/XML/Parser/PerlSAX.pm
+lib/XML/PatAct/ActionTempl.pm
+lib/XML/PatAct/Amsterdam.pm
+lib/XML/PatAct/MatchName.pm
+lib/XML/PatAct/PatternTempl.pm
+lib/XML/PatAct/ToObjects.pm
+examples/MyHandler.pm
+examples/esis-test.pl
+examples/myhandler.pl
+examples/myhandler.xml
+examples/perlsax-test.pl
+examples/schema.pl
+examples/schema.xml
+t/amsterdam.t
+t/canon_xml_writer.t
+t/schema.t
+t/stream.t
+t/subs.t
+t/xp_sax.t
diff --git a/Makefile.PL b/Makefile.PL
new file mode 100644
index 0000000..2bee5dd
--- /dev/null
+++ b/Makefile.PL
@@ -0,0 +1,20 @@
+#
+# Copyright (C) 1998 Ken MacLeod
+# This library is free software; you can redistribute it and/or modify
+# it under the same terms as Perl itself.
+#
+# $Id: Makefile.PL,v 1.3 1999/05/24 23:25:02 kmacleod Exp $
+#
+
+use ExtUtils::MakeMaker;
+
+$VERSION = '0.08';
+
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile(
+ 'NAME' => 'libxml-perl',
+ 'VERSION_FROM' => 'Makefile.PL',
+ 'PREREQ_PM' => { 'XML::Parser' => '2.19' },
+ dist => {'COMPRESS' => 'gzip', 'SUFFIX' => '.gz'},
+);
diff --git a/README b/README
new file mode 100644
index 0000000..5ba4fec
--- /dev/null
+++ b/README
@@ -0,0 +1,171 @@
+$Id: README,v 1.10 2003/10/21 16:01:54 kmacleod Exp $
+
+
+ libxml-perl
+
+ Collection of Perl modules for working with XML.
+
+
+INTRODUCTION
+
+ libxml-perl is a collection of smaller Perl modules, scripts, and
+ documents for working with XML in Perl. libxml-perl software
+ works in combination with XML::Parser, PerlSAX, XML::DOM,
+ XML::Grove and others.
+
+ See the file Changes for user-visible changes and ChangeLog for
+ detailed changes. See the `examples' directory for examples. POD
+ style documentation is included in all non-alpha modules and
+ scripts. You should also be able to use the 'perldoc' utility to
+ extract documentation from the module files directly. HTML
+ formatted docs are available at the libxml-perl home page
+ .
+
+ Newer versions of this module can be found on CPAN at
+ . To join the
+ Perl-XML mailing list, send an email message to
+ ListManager@ActiveState.com with the following text in the body:
+ Subscribe Perl-XML
+
+ View the Perl XML FAQ at
+ .
+
+ Copyright (C) 1998 Ken MacLeod and others
+ This library is free software; you can redistribute it and/or
+ modify it under the same terms as Perl itself.
+
+
+MODULES
+
+ The following modules are marked with their release status:
+
+ STABLE -- has been in use for a while with few or no outstanding
+ bugs
+ BETA -- interfaces are stable but there may still be bugs
+ ALPHA -- interfaces are changing, there may be lots of bugs, and
+ there may not be docs available yet
+
+ XML::Parser::PerlSAX STABLE
+ XML::Parser::PerlSAX is a PerlSAX parser using XML::Parser
+ (which uses James Clark's Expat XML Parser).
+
+ XML::Handler::Sample STABLE
+ XML::Handler::Sample is a PerlSAX handler that simply prints
+ out the event names as they are parsed by a PerlSAX parser.
+ It can be used for debugging or as a template for building new
+ handlers. XML::Handler::Sample contains handlers for all
+ known parser events.
+
+ XML::ESISParser STABLE
+ XML::ESISParser is a validating PerlSAX parser using James
+ Clark's `nsgmls' SGML/XML Parser. ESISParser supports both
+ XML and SGML document instances. Unless you need validation,
+ you should probably be using XML::Parser::PerlSAX or
+ XML::Parser.
+
+ XML::ESISParser with XML::Grove obsolete the
+ SGML::SPGroveBuilder and SGML::Grove modules.
+
+ XML::Handler::XMLWriter STABLE
+ A PerlSAX handler for writing readable XML (in contrast to
+ Canonical XML, for example). XMLWriter is also subclassable
+ and supports calling start and end methods by element-names
+ (subclassed from XML::Handler::Subs). XMLWriter is similar to
+ XML::Parser's Stream style.
+
+ XML::Handler::Subs STABLE
+ A PerlSAX handler base class that calls start and end methods
+ by element-names. Subs is similar to XML::Parser's Subs
+ style.
+
+ XML::Handler::CanonXMLWriter STABLE
+ A PerlSAX handler that outputs in Canonical XML
+ . This module is
+ generally only used for debugging.
+
+ Data::Grove STABLE
+ Data::Grove::Parent STABLE
+ Data::Grove::Visitor STABLE
+ Data::Grove and it's helpers provide a base class for deeply
+ nested or directed graph structures. Used by XML::Grove (and
+ others soon).
+
+ XML::SAX2Perl ALPHA
+ XML::Perl2SAX ALPHA
+ SAX2Perl and Perl2SAX are SAX Parser<->DocumentHandler
+ filters. These modules translate parse events between the
+ Java/CORBA style SAX methods and PerlSAX style methods.
+
+ XML::PatAct::MatchName ALPHA
+ MatchName is a pattern matching module that can be used with
+ PatAct action modules. MatchName uses simple element names or
+ element name lists to match names to actions.
+
+ XML::PatAct::ToObjects ALPHA
+ ToObjects is a PatAct action module. ToObjects can be used to
+ create application-ready Perl objects from XML instances.
+
+ XML::PatAct::Amsterdam ALPHA
+ Amsterdam is a PatAct action module. Amsterdam can be used to
+ apply a very simple form of style-sheet to an XML instance by
+ using ``before'' and ``after'' strings that are output before
+ and after the contents of elements.
+
+ XML::PatAct::PatternTempl BETA
+ XML::PatAct::ActionTempl BETA
+ PatternTempl and ActionTempl are template files that
+ pattern/action module writers can copy to create new modules.
+ See Creating PatAct Modules for more information.
+
+DOCUMENTS
+
+ sax-2.0.html, sax-2.0-adv.html
+ PerlSAX 2.0 bindings. Maintained by Robin Berjon and the
+ XML-Perl mailing list.
+
+ PerlSAX
+ This document defines a Perl binding to SAX 1.0. PerlSAX-
+ based parser modules implement and possibly extend the
+ interface described in PerlSAX.
+
+ UsingPerlSAX
+ A brief introduction to PerlSAX using the XML::Parser::PerlSAX
+ module.
+
+ UsingPatActModules
+ Describes how to use pattern/action modules to transform XML
+ instances.
+
+ CreatingPatActModules
+ A document for module writers who are writing new pattern/
+ action modules.
+
+ modules.xml
+ modules.xml contains a listing of all Perl XML packages and
+ their public modules categorized by several topics.
+
+
+INSTALLATION
+
+ In order to use this package you will need Perl version 5.005 or
+ better. Several other modules may also be required to use some
+ modules in libxml-perl, including XML::Parser, XML::DOM, and
+ XML::Grove. These are all available in the XML module directory
+ on CPAN.
+
+
+
+ You install libxml-perl, as you would install any perl module
+ library, by running these commands:
+
+ perl Makefile.PL
+ make
+ make test
+ make install
+
+ If you want to install a private copy of libxml-perl in your home
+ directory, then you should try to produce the initial Makefile
+ with something like this command:
+
+ perl Makefile.PL PREFIX=~/perl
+
diff --git a/doc/CreatingPatActModules.pod b/doc/CreatingPatActModules.pod
new file mode 100644
index 0000000..6eac7fc
--- /dev/null
+++ b/doc/CreatingPatActModules.pod
@@ -0,0 +1,76 @@
+=head1 Creating PatAct Modules
+
+This document is targeted towards the module writer creating a new
+pattern or action module or readers who want to understand what is
+going on inside a pattern or action module. If you are only
+interesting in using PatAct modules, please see ``Using PatAct
+Modules.''
+
+There are two types of modules involved in processing a pattern-action
+list the pattern module and the action module. Pattern modules are
+created by users and passed to the `new()' method of action modules,
+otherwise all pattern module methods are used only by the action
+module. Action modules are PerlSAX handlers (see PerlSAX.pod in
+libxml-perl). Action modules are responsible for initializing the
+pattern module, receiving PerlSAX events, calling the `match()' method
+in the pattern module for each element, and applying actions for
+matching elements.
+
+The interface the user uses to call the drivers is described in
+``Using PatAct Modules''.
+
+In general, the pattern-action modules perform their work on an
+element-by-element basis, but the action modules are called with
+PerlSAX events for all parse events (characters, processing
+instructions, etc.).
+
+=head1 Pattern Modules
+
+Pattern modules have this interface, where PATTERN is the pattern or
+query implementation:
+
+ use XML::PatAct::PATTERN;
+
+ $matcher = XML::PatAct::PATTERN->new(Patterns => $patterns [, OPTIONS]);
+ $matcher->initialize($actor);
+ $index = $matcher->match($element, $names, $nodes);
+ $matcher->finalize();
+
+A pattern module instance is created with the pattern list that will
+be used or processing as well as any additional options a pattern
+module may define. `$patterns' is the original array reference passed
+in by the user to the action module, so it is made up of pairs of
+PATTERN => ACTION. The pattern matcher should ignore the ACTION
+items.
+
+`initialize()' is called before any calls to `match()'. `$actor' is
+the action module that is calling the pattern module. `initialize()'
+is normally called from the `start_document()' PerlSAX event.
+
+`match()' performs a single matching against the pattern list and
+returns the index of the matching pattern or undef if no pattern
+matches. `$element' is the element to match. `$names' and `$nodes'
+are array references containing the names and nodes (hashes) of this
+element and all parent elements up to the element where processing
+started.
+
+`finalize()' is called at the end of processing and may be used to
+release state information. `finalize()' is normally called from the
+`end_document()' PerlSAX event.
+
+Here is a template for creating a pattern module:
+
+@include ../lib/XML/PatAct/PatternTempl.pm
+
+=head1 Action Modules
+
+Action modules are PerlSAX handlers (see PerlSAX.pod in libxml-perl).
+Action modules are responsible for initializing the pattern module,
+receiving PerlSAX events, calling the `match()' method in the pattern
+module for each element, and applying actions for matching elements.
+Action modules must also maintain arrays of element names and element
+nodes to be passed to the `match()' method.
+
+Here is a template for creating an action module:
+
+@include ../lib/XML/PatAct/ActionTempl.pm
diff --git a/doc/PerlSAX.pod b/doc/PerlSAX.pod
new file mode 100644
index 0000000..9e6170d
--- /dev/null
+++ b/doc/PerlSAX.pod
@@ -0,0 +1,643 @@
+=head1 SAX for Perl
+
+=head2 What is SAX?
+
+SAX (Simple API for XML) is a common parser interface for XML
+parsers. It allows application writers to write applications that use
+XML parsers, but are independent of which parser is actually used.
+
+This document describes a version of SAX used by Perl modules. The
+original version of SAX, for Java, is described at
+.
+
+There are two basic interfaces in the Perl version of SAX, the parser
+interface and the handler interface. The parser interface creates new
+parser instances, initiates parsing, and provides additional
+information to handlers on request. The handler interface is used to
+receive parse events from the parser.
+
+=head2 Deviations from the Java version
+
+=over 4
+
+=item *
+
+Takes parameters to `C' instead of using `set*' calls.
+
+=item *
+
+Allows a default Handler parameter to be used for all handlers.
+
+=item *
+
+No base classes are implemented. Instead, parsers dynamically check
+the handlers for what methods they support.
+
+=item *
+
+The AttributeList, InputSource, and SAXException classes have been
+replaced by anonymous hashes.
+
+=item *
+
+Handlers are passed a hash containing properties as an argument in
+place of positional arguments.
+
+=item *
+
+`C' returns the value returned by calling the
+`C' handler.
+
+=item *
+
+Method names have been converted to lower-case with underscores.
+Parameters are all mixed case with initial upper-case.
+
+=back
+
+=head1 Parser Interface
+
+SAX parsers are reusable but not re-entrant: the application may reuse
+a parser object (possibly with a different input source) once the
+first parse has completed successfully, but it may not invoke the
+`C' methods recursively within a parse.
+
+Parser objects contain the following options. A new or different
+handler option may provided in the middle of a parse, and the SAX
+parser must begin using the new handler immediately. The `C'
+option must not be changed in the middle of a parse. If an
+application does not provide a handler for a particular set of events,
+those events will be silently ignored unless otherwise stated. If an
+`C' is not provided, the parser will resolve system
+identifiers and open connections to entities itself.
+
+ Handler default handler to receive events
+ DocumentHandler handler to receive document events
+ DTDHandler handler to receive DTD events
+ ErrorHandler handler to receive error events
+ EntityResolver handler to resolve entities
+ Locale locale to provide localisation for errors
+
+If no handlers are provided then all events will be silently ignored,
+except for `C' which will cause a `C' to be
+called after calling `C'.
+
+All handler methods are called with a single hash argument containing
+the parameters for that method. `C' methods can be called with
+a hash or a list of key-value pairs containing the parameters.
+
+All SAX parsers must implement this basic interface: it allows
+applications to provide handlers for different types of events and to
+initiate a parse from a URI, a byte stream, or a character stream.
+
+=over 4
+
+=item new( I )
+
+Creates a Parser that will be used to parse XML sources. Any
+parameters passed to `C' will be used for subsequent parses.
+I may be a list of key, value pairs or a hash.
+
+=item parse( I )
+
+Parse an XML document.
+
+The application can use this method to instruct the SAX parser to
+begin parsing an XML document from any valid input source (a character
+stream, a byte stream, or a URI). I may be a list of key,
+value pairs or a hash. I passed to `C' override
+options given when the parser instance was created with `C'.
+
+Applications may not invoke this method while a parse is in progress
+(they should create a new Parser instead for each additional XML
+document). Once a parse is complete, an application may reuse the same
+Parser object, possibly with a different input source.
+
+`C' returns the result of calling the handler method
+`C'.
+
+A `C
+
+
+
+
+
+Source
+libxml-perl source is available on CPAN in the XML module
+directory. This link goes through the CPAN redirector so if the
+site gives you any problems, just click it again and you will be
+redirected to a different site.
+
+
+Modules
+
+The following modules are part of libxml-perl. Below they are marked with their release status:
+
+
+
STABLE
has been in use for a while with few or no outstanding bugs
+
BETA
interfaces are stable but there may still be bugs
+
ALPHA
interfaces are changing, there may be lots of bugs, and there may not be docs available yet
+
+
+XML::Parser::PerlSAX
+ BETA
+XML::Parser::PerlSAX is a PerlSAX parser using XML::Parser (which uses James Clark's Expat XML Parser).
+
+XML::Handler::XMLWriter
+ BETA
+A PerlSAX handler for writing readable XML (in contrast to Canonical
+XML, for example). XMLWriter is also subclassable and supports
+calling start and end methods by element-names (subclassed from
+XML::Handler::Subs). XMLWriter is similar to XML::Parser's Stream
+style.
+
+XML::Handler::Subs
+ BETA
+A PerlSAX handler base class that calls start and end methods by
+element-names. Subs is similar to XML::Parser's Subs style.
+
+XML::Handler::Sample
+ BETA
+XML::Handler::Sample is a PerlSAX handler that simply prints out the
+event names as they are parsed by a PerlSAX parser. It can be used for
+debugging or as a template for building new handlers.
+XML::Handler::Sample contains handlers for all known parser events.
+
+XML::ESISParser
+ BETA
+XML::ESISParser is a validating PerlSAX parser using James Clark's
+`nsgmls' SGML/XML Parser. ESISParser supports both XML and SGML
+document instances. Unless you need validation, you should probably
+be using XML::Parser::PerlSAX or XML::Parser.
+
+XML::ESISParser with XML::Grove obsolete the SGML::SPGroveBuilder and SGML::Grove modules.
+
+Data::Grove, Data::Grove::Parent, Data::Grove::Visitor
+ BETA
+Data::Grove and it's helpers provide a base class for deeply nested or
+directed graph structures. Used by XML::Grove (and others soon).
+
+XML::SAX2Perl, XML::Perl2SAX
+ ALPHA
+SAX2Perl and Perl2SAX are SAX Parser<->DocumentHandler filters. These
+modules translate parse events between the Java/CORBA style SAX
+methods and PerlSAX style methods.
+
+The following modules will very likely be renamed in the next release.
+
+XML::PatAct::MatchName
+ ALPHA
+MatchName is a pattern matching module that can be used with PatAct
+action modules. MatchName uses simple element names or element name
+lists to match names to actions.
+
+XML::PatAct::ToObjects
+ ALPHA
+ToObjects is a PatAct action module. ToObjects can be used to create
+application-ready Perl objects from XML instances.
+
+XML::PatAct::Amsterdam
+ ALPHA
+Amsterdam is a PatAct action module. Amsterdam can be used to apply a
+very simple form of style-sheet to an XML instance by using ``before''
+and ``after'' strings that are output before and after the contents of
+elements.
+
+XML::PatAct::PatternTempl, XML::PatAct::ActionTempl
+ BETA
+PatternTempl and ActionTempl are template files that pattern/action
+module writers can copy to create new modules. See Creating PatAct
+Modules for more information.
+
+
+Documents
+
+PerlSAX
+This document defines a Perl binding to SAX 1.0. PerlSAX-based parser
+modules implement and possibly extend the interface described in
+PerlSAX.
+
+Using PerlSAX
+UsingPerlSAX is a brief introduction to PerlSAX using the
+XML::Parser::PerlSAX module.
+
+Using PatAct Modules
+Describes how to use pattern/action modules to transform XML
+instances.
+
+Creating PatAct Modules
+A document for module writers who are writing new pattern/ action
+modules.
+
+modules.xml
+modules.xml contains a listing of all Perl XML packages and their
+public modules categorized by several topics.
XML::ESISParser: report record end as
+characters if no record_end() handler
+
-
XML::Parser::PerlSAX: For attribute
+list declarations, now correctly calls the attlist_decl() method and
+passes the ElementName property, it used to call entity_decl() passing
+EntityName. Reported by Enno
+Derksen and Colin
+Muller
Added pattern/action modules for name matching, converting to objects, and applying simple styles -- XML::PatAct::MatchName, XML::PatAct::ToObjects, and XML::PatAct::Amsterdam.
+
-
Added ``Using PatAct Modules'' and ``Creating PatActModules'' docs.
+
-
XML::Parser::PerlSAX and XML::ESISParser were not passing a hash for `start_document()' and `end_document()' per spec.
moved PerlSAX.pod and interface-style.pod to `doc/'
+
-
renamed Data::Grove::Tied to Data::Grove::Parent
+
+
+
+
+
+
+
+
+
+Contributors
+The following have shared their code, documents, comments, and/or suggestions for libxml-perl:
+
+Clark Cooper
+Eduard (Enno) Derksen
+Michael Koehne
+KangChan Lee
+Ken MacLeod
+Colin Muller
+Eric Prud'hommeaux
+Larry Wall
+
+
+
diff --git a/doc/interface-style.pod b/doc/interface-style.pod
new file mode 100644
index 0000000..aca1047
--- /dev/null
+++ b/doc/interface-style.pod
@@ -0,0 +1,79 @@
+=head1 Priorities
+
+Larry Wall suggests, ``In the absence of other considerations, I'd
+encourage you to provide the cleanest interface from the user's
+standpoint, and let the implementer worry about the details.''
+
+=head1 Naming
+
+B
+
+All method names use lower-case, `C<_>' seperated names.
+
+B
+
+All method names match their Java counterparts.
+
+All options, parameters, and property names use mixed case names, with
+an initial upper case character. This eliminates a certain amount of
+potential confusion with reserved words, which, for the most part, are
+lower case.
+
+The following words are abbreviated in method names and parameters:
+
+ Declaration decl Decl
+ Reference ref Ref
+ Identifier id Id
+
+=head1 Object Instantiation and Options
+
+For creating new parser or handler objects, the `new' methods accept a
+list of key-value pairs (C<=E>) or a hash containing the options.
+The key names are derived from the SAX positional parameter names
+(`C' and `C' in Parser's `C') or the name of
+option setting methods (`C', `C',
+`C', `C', and `C' in Parser).
+
+Callers may get and set options directly in the object, for example:
+
+ $parser = SAX::Parser->new( Source => { ByteStream => $fh },
+ DocumentHandler => $doc_handler );
+
+ $parser->{Locale} = 'el_GR.ISO-8859-7';
+
+There are no set/get methods in the Perl SAX API.
+
+=head1 Handler Calls
+
+Handler calls all take hashes instead of positional parameters. Key
+names are derived from SAX positional parameter names. This allows
+parsers and filters to provide additional parameters if they can or
+the user requests it.
+
+=head1 Extending Handler Interfaces
+
+Developers of event-generators can extend the handler interface as
+they need to. Event-generators that use an extended interface should
+accept generator options or use `C' to test whether a handler can
+support their extended interface.
+
+For example, a C that wants to receive internal
+entity events instead of having them resolved and passed in to the
+`C' method would define a `C' method
+and/or set a parser option to pass or not pass internal entity events.
+
+=head1 Helper Classes
+
+Perl SAX avoids helper classes (like SAXException and InputSource)
+where those classes only hold information and have no behavior. In
+those cases, simple hashes are used instead.
+
+B if these should be implemented anyway for
+easier portability.
+
+=head1 Contributors
+
+ Eduard (Enno) Derksen
+ Ken MacLeod
+ Eric Prud'hommeaux
+ Larry Wall
diff --git a/doc/mirror.sh b/doc/mirror.sh
new file mode 100644
index 0000000..124a489
--- /dev/null
+++ b/doc/mirror.sh
@@ -0,0 +1,69 @@
+#! /bin/sh
+#
+# NAME
+# mirror -- update web page with a libxml-perl release
+#
+# SYNOPSIS
+usage="mirror RELEASE DESTDIR"
+#
+# DESCRIPTION
+# `mirror' creates a web mirror using a libxml-perl release tar
+# file.
+#
+# `mirror' pulls files from the tar file to create the web page.
+# `mirror' searches HTML files for the string @VERSION@ and
+# replaces it with RELEASE. `mirror' searches for all *.pm and
+# *.pod files and converts them to HTML. It also copies a few
+# hardcoded files.
+#
+# `mirror' installs the web pages in DESTDIR.
+#
+# CAUTION: `mirror' removes the contents of DESTDIR before
+# copying files to it.
+#
+# AUTHOR
+# Ken MacLeod
+#
+# $Id: mirror.sh,v 1.2 2000/02/22 21:02:56 kmacleod Exp $
+#
+
+PWD_CMD="/bin/pwd"
+SED="sed"
+TR="/usr/bin/tr"
+
+if [ $# != 2 ]; then
+ echo "usage: $usage"
+ exit 1
+fi
+
+RELEASE="$1"
+DESTDIR="$2"
+
+set -e
+set -x
+
+rm -rf $DESTDIR
+mkdir -p $DESTDIR
+
+cp libxml-perl-${RELEASE}.tar.gz $DESTDIR
+
+cd $DESTDIR
+
+tar xzvf libxml-perl-${RELEASE}.tar.gz
+
+for ii in libxml-perl-${RELEASE}/doc/*.html; do
+ $SED <$ii >`basename $ii` \
+ -e "s/@VERSION@/$RELEASE/g"
+done
+for ii in `cd libxml-perl-${RELEASE}/doc; echo *.pod`; do
+ pod2html libxml-perl-${RELEASE}/doc/$ii >`basename $ii .pod`.html
+done
+for ii in `cd libxml-perl-${RELEASE}/lib; echo */*.pm */*/*.pm`; do
+ dstfile=`echo $ii | sed -e 's|/|::|g'`
+ pod2html libxml-perl-${RELEASE}/lib/$ii >`basename $dstfile .pm`.html
+done
+
+mv libxml-perl-${RELEASE}/README libxml-perl-${RELEASE}.readme
+mv libxml-perl-${RELEASE}/doc/modules.xml .
+
+rm -rf libxml-perl-${RELEASE} pod2html-dircache pod2html-itemcache
diff --git a/doc/modules.xml b/doc/modules.xml
new file mode 100644
index 0000000..d2e5026
--- /dev/null
+++ b/doc/modules.xml
@@ -0,0 +1,298 @@
+
+
+
+
+ Apache-MimeXML
+
+ Apache-MimeXML
+ XML
+
+
+
+
+ CGI-Formalware
+
+ CGI::Formalware
+ XML
+ XML::Parser
+
+
+
+
+ CGI-XML
+
+ CGI::XML
+ XML::Parser
+ XML Conversion
+
+
+
+
+ CGI-XMLForm
+
+ CGI::XMLForm
+ XML::Parser
+ XML Conversion
+
+
+
+
+ DBIx-XML_RDB
+
+ DBIx::XML_RDB
+ XML Conversion
+
+
+
+
+ libxml-perl
+
+ Data::Grove
+ XML
+
+
+ Data::Grove::Visitor
+ Data::Grove
+
+
+ XML::ESISParser
+ PerlSAX
+
+
+ XML::Handler::CanonXMLWriter
+ PerlSAX
+ XML Conversion
+
+
+ XML::Handler::Sample
+ PerlSAX
+ XML Conversion
+
+
+ XML::Handler::Subs
+ PerlSAX
+ XML Conversion
+
+
+ XML::Handler::XMLWriter
+ PerlSAX
+ XML Conversion
+
+
+ XML::Parser::PerlSAX
+ PerlSAX
+ XML::Parser
+
+
+ XML::PatAct::ActionTempl
+ PatAct
+ PatAct Action
+
+
+ XML::PatAct::Amsterdam
+ PerlSAX
+ XML Conversion
+ PatAct
+ PatAct Action
+
+
+ XML::PatAct::MatchName
+ PatAct
+ PatAct Pattern
+
+
+ XML::PatAct::PatternTempl
+ PatAct
+ PatAct Pattern
+
+
+ XML::PatAct::ToObjects
+ PatAct
+ PatAct Action
+ XML Conversion
+
+
+ XML::Perl2SAX
+ PerlSAX
+
+
+ XML::SAX2Perl
+ PerlSAX
+
+
+
+
+ Frontier-RPC
+
+ Frontier::RPC2
+ XML::Parser
+ XML Conversion
+
+
+ Frontier::Client
+
+
+ Frontier::Daemon
+
+
+
+
+ XML-DOM
+
+ XML::DOM
+ XML::Parser
+ XML Objects
+ XML Query
+ XML Conversion
+
+
+ XML::DOM::UTF8
+ XML::DOM
+
+
+
+
+ XML-Dumper
+
+ XML::Dumper
+ XML Conversion
+
+
+
+
+ XML-Edifact
+
+ XML::Edifact
+ XML Conversion
+
+
+
+
+ XML-Encoding
+
+ XML::Encoding
+ XML::Parser
+
+
+
+
+ XML-Generator
+
+ XML::Generator
+ XML Writer
+
+
+
+
+ XML-Grove
+
+ XML::Grove
+ XML Objects
+ Data::Grove
+
+
+ XML::Grove::AsCanonXML
+ XML::Grove
+ XML Writer
+
+
+ XML::Grove::AsString
+ XML::Grove
+ XML Conversion
+
+
+ XML::Grove::Builder
+ XML::Grove
+ PerlSAX
+
+
+ XML::Grove::IDs
+ XML::Grove
+ XML Query
+
+
+ XML::Grove::Path
+ XML::Grove
+ XML Query
+
+
+ XML::Grove::PerlSAX
+ XML::Grove
+ PerlSAX
+
+
+ XML::Grove::Sub
+ XML::Grove
+
+
+ XML::Grove::Subst
+ XML::Grove
+
+
+
+
+ XML-Parser
+
+ XML::Parser
+ XML
+
+
+ XML::ParserDebug
+ XML::Parser
+ XML Conversion
+
+
+ XML::Parser::Objects
+ XML::Parser
+ XML Objects
+
+
+ XML::Parser::Stream
+ XML::Parser
+ XML Conversion
+
+
+ XML::Parser::Subs
+ XML::Parser
+
+
+ XML::Parser::Tree
+ XML::Parser
+ XML Objects
+
+
+
+
+ XML-QL
+
+ XML::QL
+ XML::Parser
+ XML Query
+
+
+
+
+ XML-Registry
+
+ XML::Registry
+ XML
+
+
+
+
+ XML-Writer
+
+ XML::Writer
+ XML Writer
+
+
+
+
+ XML-XQL
+
+ XML::XQL
+ XML::DOM
+ XML Query
+
+
+
diff --git a/doc/sax-2.0-adv.html b/doc/sax-2.0-adv.html
new file mode 100644
index 0000000..b8fd491
--- /dev/null
+++ b/doc/sax-2.0-adv.html
@@ -0,0 +1,1005 @@
+
+
+
+ Advanced Features of the Perl SAX 2.0 Binding
+
+
+
+
+
Advanced SAX
+
+
The classes, methods, and features described below are
+not commonly used in most applications and can be ignored by most
+users. If however you find that you are not getting the granularity
+you expect from Basic SAX, this would be the place to look for more.
+Advanced SAX isn't advanced in the sense that it is harder, or requires
+better programming skills. It is simply more complete, and has been
+separated to keep Basic SAX simple in terms of the number of events
+one would have to deal with.
+
SAX supports several classes of event handlers: content handlers,
+declaration handlers, DTD handlers, error handlers, entity resolvers,
+and other extensions. For each class of events, a seperate handler
+can be used to handle those events. If a handler is not defined for a
+class of events, then the default handler, Handler, is used.
+Each of these handlers is described in the sections below.
+Applications may change an event handler in the middle of the parse
+and the SAX parser will begin using the new handler immediately.
+
+
SAX's basic interface defines methods for parsing system
+identifiers (URIs), open files, and strings. Behind the scenes,
+though, SAX uses a Source hash that contains that
+information, plus encoding, system and public identifiers if
+available. These are described below under the Source
+option.
+
+
SAX parsers accept all features as options to the parse()
+methods and on the parser's constructor. Features are described in
+the next section.
+
+
+
parse(options)
+
+Parses the XML instance identified by the Source option.
+options can be a list of option, value pairs or a hash.
+parse() returns the result of calling the
+end_document() handler.
+
+
+
ContentHandler
+
+Object to receive document content events. The
+ContentHandler, with additional events defined below, is the
+class of events described in Basic
+SAX Handler.If the application does not register a content handler
+or content event handlers on the default handler, content events
+reported by the SAX parser will be silently ignored.
+
+
+
DTDHandler
+
+Object to receive basic DTD events. If the application does not
+register a DTD handler or DTD event handlers on the default handler,
+DTD events reported by the SAX parser will be silently
+ignored.
+
+
+
EntityResolver
+
+Object to resolve external entities. If the application does not
+register an entity resolver or entity events on the default handler,
+the SAX parser will perform its own default resolution.
+
+
+
ErrorHandler
+
+Object to receive error-message events. If the application does not
+register an error handler or error event handlers on the default
+handler, all error events reported by the SAX parser will be silently
+ignored; however, normal processing may not continue. It is highly
+recommended that all SAX applications implement an error handler to
+avoid unexpected bugs.
+
+
+
Source
+
+A hash containing information about the XML instance to be parsed.
+See Input Sources below. Note that
+Source cannot be changed during the parse
+
+
+
+
Features
+
+ A hash containing Feature information, as described below.
+ Features can be set at runtime but not directly on the Features
+ hash (at least, not reliably. You can do it, but the results
+ might not be what you expect as it doesn't give the parser a
+ chance to look at what you've set so that it can't react properly
+ to errors, or Features that it doesn't support). You should use
+ the set_feature() method instead.
+
Features are as defined in SAX2: Features
+and Properties, but not of course limited to those. You may add
+your own Features. Also, Java has an artificial distinction between
+Features and Properties which is unnecessary. In Perl, both have been
+merged under the same name.
+
+
+
Features can be passed as options when creating a parser or calling
+a parse() method. They may also be set using the
+set_feature().
+
+ When performing namespace processing, Perl SAX parsers always provide
+ both the raw tag name in Name and the namespace names in
+ NamespaceURI, LocalName, and Prefix.
+ Therefore, the
+ "http://xml.org/sax/features/namespace-prefixes" Feature is
+ ignored.
+
+
+
+ Also, Features are things that are supposed to be turned
+ on, and thus should normally be off by default, especially if
+ the parser doesn't support turning them off. Due to backwards
+ compatibility problems, the one exception to this rule is the
+ "http://xml.org/sax/features/namespaces" Feature which is on by
+ default and which a number of parsers may not be able to turn off. Thus,
+ a parser claiming to support this Feature (and all SAX2 parsers must
+ support it) may in fact only support turning it on. This is only a minor
+ problem as turning it off basically amounts to returning to SAX1, which
+ can be accomplished by a filter (eg XML::Filter::SAX2toSAX1).
+
+
+
+ In addition to the Features described in the SAX spec
+ itself, a number of new ones may be defined for Perl. An example of
+ this would be http://xmlns.perl.org/sax/node-factory which
+ when supported by the parser would be settable to a NodeFactory object
+ that would be in charge of creating SAX nodes different from those that
+ are normally received by event handlers. See
+ http://xmlns.perl.org/ (currently
+ in alpha state) for details on how to register Features.
+
+
+
+ The following methods are used to get and set features:
+
+
+
+
get_feature(name)
+
+Look up the value of a feature.
+
+
The feature name is any fully-qualified URI. It is possible for an
+SAX parser to recognize a feature name but to be unable to return its
+value; this is especially true in the case of an adapter for a SAX1
+Parser, which has no way of knowing whether the underlying parser is
+validating, for example.
+
+
Some feature values may be available only in specific contexts,
+such as before, during, or after a parse.
+
+get_feature() returns the value of the feature, which is usually
+either a boolean or an object, and will throw
+XML::SAX::Exception::NotRecognized when the SAX parser does not
+recognize the feature name and XML::SAX::Exception::NotSupported
+when the SAX parser recognizes the feature name but cannot determine its
+value at this time.
+
+
+
set_feature(name,
+value)
+
+Set the state of a feature.
+
+
The feature name is any fully-qualified URI. It is possible for an
+SAX parser to recognize a feature name but to be unable to set its
+value; this is especially true in the case of an adapter for a SAX1
+Parser, which has no way of affecting whether the underlying parser is
+validating, for example.
+
+
Some feature values may be immutable or mutable only in specific
+contexts, such as before, during, or after a parse.
+
+set_feature() will throw XML::SAX::Exception::NotRecognized
+when the SAX parser does not recognize the feature name and
+XML::SAX::Exception::NotSupported when the SAX parser recognizes the
+feature name but cannot set the requested value.
+
+
+ This method is also the standard mechanism for setting extended handlers,
+ such as "http://xml.org/sax/handlers/DeclHandler".
+
+
+
+
+
+
+
get_features()
+
+ Look up all Features that this parser claims to support.
+
+ This method returns a hash of Features which the parser
+ claims to support. The value of the hash is currently
+ unspecified though it may be used later. This method is meant
+ to be inherited so that Features supported by the base parser
+ class (XML::SAX::Base) are declared to be supported by
+ subclasses.
+
+
+ Calling this method is probably only moderately useful to end
+ users. It is mostly meant for use by XML::SAX, so that it can
+ query parsers for Feature support and return an appropriate
+ parser depending on the Features that are required.
+
Input sources may be provided to parser objects or are returned by
+entity resolvers. An input source is a hash with these
+properties:
+
+
+
PublicId
+
The public identifier of this input source.
+
+
The public identifier is always optional: if the application writer
+includes one, it will be provided as part of the location
+information.
+
+
SystemId
+
The system identifier (URI) of this input source.
+
+
The system identifier is optional if there is a byte stream or a
+character stream, but it is still useful to provide one, since the
+application can use it to resolve relative URIs and can include it in
+error messages and warnings (the parser will attempt to open a
+connection to the URI only if there is no byte stream or character
+stream specified).
+
+If the application knows the character encoding of the object
+pointed to by the system identifier, it can register the encoding
+using the Encoding property.
+
+
ByteStream
+
The byte stream for this input source.
+
+
The SAX parser will ignore this if there is also a character stream
+specified, but it will use a byte stream in preference to opening a
+URI connection itself.
+
+If the application knows the character encoding of the byte stream, it
+should set the Encoding property.
+
+
CharacterStream
+
The character stream for this input source.
+
+
If there is a character stream specified, the SAX parser will
+ignore any byte stream and will not attempt to open a URI connection
+to the system identifier.
+
+
Note: A CharacterStream is a filehandle that does not need any encoding
+translation done on it. This is implemented as a regular filehandle
+and only works under Perl 5.7.2 or higher using PerlIO. To get a single
+character, or number of characters from it, use the perl core read()
+function. To get a single byte from it (or number of bytes), you can
+use sysread(). The encoding of the stream should be in the Encoding
+entry for the Source.
+
+
+
+
Encoding
+
The character encoding, if known.
+
+
The encoding must be a string acceptable for an XML encoding
+declaration (see section 4.3.3 of the XML 1.0 recommendation).
+
+This property has no effect when the application provides a character
+stream.
SAX supports several classes of event handlers: content handlers,
+declaration handlers, DTD handlers, error handlers, entity resolvers,
+and other extensions. This section defines each of these classes of
+events.
+
+
Content Events
+
+
This is the main interface that most SAX applications implement: if
+the application needs to be informed of basic parsing events, it
+implements this interface and registers an instance with the SAX
+parser using the ContentHandler property. The parser uses
+the instance to report basic document-related events like the start
+and end of elements and character data.
+
+
The order of events in this interface is very important, and
+mirrors the order of information in the document itself. For example,
+all of an element's content (character data, processing instructions,
+and/or subelements) will appear, in order, between the
+start_element event and the corresponding
+end_element event.
+
+
+
+
set_document_locator(locator)
+
+Receive an object for locating the origin of SAX document events.
+
+
SAX parsers are strongly encouraged (though not absolutely
+required) to supply a locator: if it does so, it must supply the
+locator to the application by invoking this method before invoking any
+of the other methods in the ContentHandler interface.
+
+
The locator allows the application to determine the end position of
+any document-related event, even if the parser is not reporting an
+error. Typically, the application will use this information for
+reporting its own errors (such as character content that does not
+match an application's business rules). The information provided by
+the locator is probably not sufficient for use with a search
+engine.
+
+
Note that the locator will provide correct information only during
+the invocation of the events in this interface. The application should
+not attempt to use it at any other time.
+
+
The locator is a hash with these properties:
+
+
+
+
ColumnNumber
+
The column number of the end of the text where the exception
+occurred.
+
LineNumber
+
The line number of the end of the text where the exception
+occurred.
+
PublicId
+
The public identifier of the entity where the exception
+occurred.
+
SystemId
+
The system identifier of the entity where the exception
+occurred.
+
+
+
+
+
+
start_prefix_mapping(mapping)
+
+Begin the scope of a prefix-URI Namespace mapping.
+
+
The information from this event is not necessary for normal
+Namespace processing: the SAX XML reader will automatically replace
+prefixes for element and attribute names when the
+"http://xml.org/sax/features/namespaces" feature is true (the
+default).
+
+
There are cases, however, when applications need to use prefixes in
+character data or in attribute values, where they cannot safely be
+expanded automatically; the start/end_prefix_mapping event supplies the
+information to the application to expand prefixes in those contexts
+itself, if necessary.
+
+
Note that start/end_prefix_mapping() events are
+not guaranteed to be properly nested relative to each-other: all
+start_prefix_apping() events will occur before the
+corresponding start_element() event, and all
+end_prefix_mapping events will occur after the corresponding
+end_element() event, but their order is not
+guaranteed.
+
+
+
mapping is a hash with these properties:
+
+
+
+
Prefix
+
The Namespace prefix being declared.
+
NamespaceURI
+
The Namespace URI the prefix is mapped to.
+
+
+
+
+
+
end_prefix_mapping(mapping)
+
+End the scope of a prefix-URI mapping.
+
+
See start_prefix_mapping() for details. This event will
+always occur after the corresponding end_element event, but
+the order of end_prefix_mapping events is not otherwise
+guaranteed.
+
+
mapping is a hash with this property:
+
+
+
+
Prefix
+
The Namespace prefix that was being mapped.
+
+
+
+
+
+
processing_instruction(pi)
+
+Receive notification of a processing instruction.
+
+
The Parser will invoke this method once for each processing
+instruction found: note that processing instructions may occur before
+or after the main document element.
+
+
A SAX parser should never report an XML declaration (XML 1.0,
+section 2.8) or a text declaration (XML 1.0, section 4.3.1) using this
+method.
+
+
pi is a hash with these properties:
+
+
+
+
Target
+
The processing instruction target.
+
Data
+
The processing instruction data, or null if none was
+supplied.
+
+
+
+
+
+
skipped_entity(entity)
+
+Receive notification of a skipped entity.
+
+
The Parser will invoke this method once for each entity skipped.
+Non-validating processors may skip entities if they have not seen the
+declarations (because, for example, the entity was declared in an
+external DTD subset). All processors may skip external entities,
+depending on the values of the
+"http://xml.org/sax/features/external-general-entities" and the
+"http://xml.org/sax/features/external-parameter-entities"
+Features.
+
+
entity is a hash with these properties:
+
+
+
+
Name
+
The name of the skipped entity. If it is a parameter
+entity, the name will begin with '%'.
+
+
+
+
+
Declaration Events
+
+
This is an optional extension handler for SAX2 to provide
+information about DTD declarations in an XML document. XML readers are
+not required to support this handler.
+
+
Note that data-related DTD declarations (unparsed entities and
+notations) are already reported through the DTDHandler interface.
+
+
If you are using the declaration handler together with a lexical
+handler, all of the events will occur between the start_dtd
+and the end_dtd events.
+
+
To set a seperate DeclHandler for an XML reader, set the
+"http://xml.org/sax/handlers/DeclHandler" Feature with the
+object to received declaration events. If the reader does not support
+declaration events, it will throw a XML::SAX::Exception::NotRecognized
+or a XML::SAX::Exception::NotSupported when you attempt to register
+the handler. Declaration event handlers on the default handler are
+automatically recognized and used.
+
+
+
+
element_decl(element)
+
+Report an element type declaration.
+
+
The content model will consist of the string "EMPTY", the string
+"ANY", or a parenthesised group, optionally followed by an occurrence
+indicator. The model will be normalized so that all whitespace is
+removed, and will include the enclosing parentheses.
+
+
element is a hash with these properties:
+
+
+
+
Name
+
The element type name.
+
Model
+
The content model as a normalized string.
+
+
+
+
+
+
attribute_decl(attribute)
+
+Report an attribute type declaration.
+
+
Only the effective (first) declaration for an attribute will be
+reported. The type will be one of the strings "CDATA",
+"ID", "IDREF", "IDREFS",
+"NMTOKEN", "NMTOKENS", "ENTITY",
+"ENTITIES", or "NOTATION", or a parenthesized token
+group with the separator "|" and all whitespace removed.
+
+
attribute is a hash with these properties:
+
+
+
+
eName
+
The name of the associated element.
+
aName
+
The name of the attribute.
+
Type
+
A string representing the attribute type.
+
ValueDefault
+
A string representing the attribute default ("#IMPLIED",
+"#REQUIRED", or "#FIXED") or undef if none of these
+applies.
+
Value
+
A string representing the attribute's default value, or null if
+there is none.
+
+
+
+
+
+
internal_entity_decl(entity)
+
+Report an internal entity declaration.
+
+
Only the effective (first) declaration for each entity will be
+reported.
+
+
entity is a hash with these properties:
+
+
+
+
Name
+
The name of the entity. If it is a parameter entity, the name will
+begin with '%'.
+
Value
+
The replacement text of the entity.
+
+
+
+
+
+
external_entity_decl(entity)
+
+Report a parsed external entity declaration.
+
+
Only the effective (first) declaration for each entity will be
+reported.
+
+
entity is a hash with these properties:
+
+
+
+
Name
+
The name of the entity. If it is a parameter entity, the name will
+begin with '%'.
+
PublicId
+
The public identifier of the entity, or undef if none was
+declared.
+
SystemId
+
The system identifier of the entity.
+
+
+
+
+
DTD Events
+
+
If a SAX application needs information about notations and unparsed
+entities, then the application implements this interface. The parser
+uses the instance to report notation and unparsed entity declarations
+to the application.
+
+
The SAX parser may report these events in any order, regardless of
+the order in which the notations and unparsed entities were declared;
+however, all DTD events must be reported after the document handler's
+start_document() event, and before the first
+start_element() event.
+
+
It is up to the application to store the information for future use
+(perhaps in a hash table or object tree). If the application
+encounters attributes of type "NOTATION", "ENTITY",
+or "ENTITIES", it can use the information that it obtained
+through this interface to find the entity and/or notation
+corresponding with the attribute value.
+
+
+
notation_decl(notation)
+
+Receive notification of a notation declaration event.
+
+
It is up to the application to record the notation for later
+reference, if necessary.
+
+
If a system identifier is present, and it is a URL, the SAX parser
+must resolve it fully before passing it to the application.
+
+
notation is a hash with these properties:
+
+
+
+
Name
+
The notation name.
+
PublicId
+
The public identifier of the entity, or undef if none was
+declared.
+
SystemId
+
The system identifier of the entity, or undef if none was
+declared.
+
+
+
+
+
+
unparsed_entity_decl(entity)
+
+Receive notification of an unparsed entity declaration event.
+
+
Note that the notation name corresponds to a notation reported by
+the notation_decl() event. It is up to the application to
+record the entity for later reference, if necessary.
+
+
If the system identifier is a URL, the parser must resolve it fully
+before passing it to the application.
+
+
entity is a hash with these properties:
+
+
+
+
Name
+
The unparsed entity's name.
+
PublicId
+
The public identifier of the entity, or undef if none was
+declared.
+
SystemId
+
The system identifier of the entity.
+
Notation
+
The name of the associated notation.
+
+
+
+
+
Entity Resolver
+
+
If a SAX application needs to implement customized handling for
+external entities, it must implement this interface.
+
+
The parser will then allow the application to intercept any
+external entities (including the external DTD subset and external
+parameter entities, if any) before including them.
+
+
+ Many SAX applications will not need to implement this interface,
+ but it will be especially useful for applications that build XML
+ documents from databases or other specialised input sources, or for
+ applications that use URI types that are either not URLs, or that
+ have schemes unknown to the parser.
+
+
+
+
resolve_entity(entity)
+
+Allow the application to resolve external entities.
+
+
The Parser will call this method before opening any external entity
+except the top-level document entity (including the external DTD
+subset, external entities referenced within the DTD, and external
+entities referenced within the document element): the application may
+request that the parser resolve the entity itself, that it use an
+alternative URI, or that it use an entirely different input
+source.
+
+
Application writers can use this method to redirect external system
+identifiers to secure and/or local URIs, to look up public identifiers
+in a catalogue, or to read an entity from a database or other input
+source (including, for example, a dialog box).
+
+
If the system identifier is a URL, the SAX parser must resolve it
+fully before reporting it to the application.
+
+
entity is a hash with these properties:
+
+
+
+
PublicId
+
The public identifier of the entity being referenced, or
+undef if none was declared.
+
SystemId
+
The system identifier of the entity being referenced.
+
+
+
+
+
Error Events
+
+
If a SAX application needs to implement customized error handling,
+it must implement this interface. The parser will then report all
+errors and warnings through this interface.
+
+
The parser shall use this interface to report errors instead or in
+addition to throwing an exception: for errors and warnings the recommended
+approach is to leave the application throw its own exceptions and to not
+throw them in the parser. For fatal errors however, it is not uncommon that
+the parser will throw an exception after having reported the error as it
+renders any continuation of parsing impossible.
+
+
+
All error handlers receive a hash, exception, with the
+properties defined in Exceptions.
+
+
+
warning(exception)
+
+Receive notification of a warning.
+
+
SAX parsers will use this method to report conditions that are not
+errors or fatal errors as defined by the XML 1.0 recommendation. The
+default behaviour is to take no action.
+
+The SAX parser must continue to provide normal parsing events after
+invoking this method: it should still be possible for the application
+to process the document through to the end.
+
+
+
error(exception)
+
+Receive notification of a recoverable error.
+
+
This corresponds to the definition of "error" in section 1.2 of the
+W3C XML 1.0 Recommendation. For example, a validating parser would use
+this callback to report the violation of a validity constraint. The
+default behaviour is to take no action.
+
+The SAX parser must continue to provide normal parsing events after
+invoking this method: it should still be possible for the application
+to process the document through to the end. If the application cannot
+do so, then the parser should report a fatal error even if the XML 1.0
+recommendation does not require it to do so.
+
+
+
fatal_error(exception)
+
+Receive notification of a non-recoverable error.
+
+
This corresponds to the definition of "fatal error" in section 1.2
+of the W3C XML 1.0 Recommendation. For example, a parser would use
+this callback to report the violation of a well-formedness
+constraint.
+
+The application must assume that the document is unusable after the
+parser has invoked this method, and should continue (if at all) only
+for the sake of collecting addition error messages: in fact, SAX
+parsers are free to stop reporting any other events once this method
+has been invoked.
+
+
Lexical Events
+
+
This is an optional extension handler for SAX2 to provide lexical
+information about an XML document, such as comments and CDATA section
+boundaries; XML readers are not required to support this handler.
+
+
The events in the lexical handler apply to the entire document, not
+just to the document element, and all lexical handler events must
+appear between the content handler's start_document() and
+end_document() events.
+
+
To set the LexicalHandler for an XML reader, set the Feature
+"http://xml.org/sax/handlers/LexicalHandler" on the parser to
+the object to receive lexical events. If the reader does not support
+lexical events, it will throw a XML::SAX::Exception::NotRecognized or
+a XML::SAX::Exception::NotSupported when you attempt to register the
+handler.
+
+
+
start_dtd(dtd)
+
+Report the start of DTD declarations, if any.
+
+
Any declarations are assumed to be in the internal subset unless
+otherwise indicated by a start_entity event.
+
+
Note that the start/end_dtd() events will appear
+within the start/end_document() events from Content
+Handler and before the first start_element() event.
+
+
dtd is a hash with these properties:
+
+
+
+
Name
+
The document type name.
+
PublicId
+
The declared public identifier for the external DTD subset, or
+undef if none was declared.
+
SystemId
+
The declared system identifier for the external DTD subset, or
+undef if none was declared.
+
+
+
+
+
+
end_dtd(dtd)
+
+Report the end of DTD declarations.
+
+
No properties are defined for this event (dtd is
+empty).
+
+
+
start_entity(entity)
+
+Report the beginning of an entity in content.
+
+
NOTE: entity references in attribute values -- and the start
+and end of the document entity -- are never reported.
+
+
The start and end of the external DTD subset are reported using the
+pseudo-name "[dtd]". All other events must be properly nested within
+start/end entity events.
+
+
Note that skipped entities will be reported through the
+skipped_entity() event, which is part of the ContentHandler
+interface.
+
+
entity is a hash with these properties:
+
+
+
+
Name
+
The name of the entity. If it is a parameter entity, the
+name will begin with '%'.
+
+
+
+
+
+
end_entity(entity)
+
+Report the end of an entity.
+
+
entity is a hash with these properties:
+
+
+
+
Name
+
The name of the entity that is ending.
+
+
+
+
+
+
start_cdata(cdata)
+
+Report the start of a CDATA section.
+
+
The contents of the CDATA section will be reported through the
+regular characters event.
+
+
No properties are defined for this event (cdata is
+empty).
+
+
+
end_cdata(cdata)
+
+Report the end of a CDATA section.
+
+
No properties are defined for this event (cdata is
+empty).
+
+
+
comment(comment)
+
+Report an XML comment anywhere in the document.
+
+
This callback will be used for comments inside or outside the
+document element, including comments in the external DTD subset (if
+read).
An XML filter is like an XML event generator, except that it
+obtains its events from another XML event generator rather than a
+primary source like an XML document or database. Filters can modify a
+stream of events as they pass on to the final application.
+
+
+
Parent
+
+The parent reader.
+
+
This Feature allows the application to link the filter to a parent
+event generator (which may be another filter).
+
+
+ See the XML::SAX::Base module for more on filters. It is meant to be
+ used as a base class for filters and drivers, and makes them much
+ easier to implement.
+
+
+The Perl SAX 2.0 binding differs from the Java binding in these ways:
+
+
+
+
Takes parameters to new(), to parse(), and to be
+set directly in the object, instead of requiring set/get calls (see
+below).
+
+
Allows a default Handler parameter to be used for all
+handlers.
+
+
+ No base classes are enforced. Instead, parsers dynamically
+ check the handlers for what methods they support. Note however that
+ using XML::SAX::Base as your base class for Drivers and Filters will
+ make your code a lot simpler, less error prone, and probably much more
+ correct with regard to this spec. Only reimplement that functionality
+ if you really need to.
+
+
+
The Attribute, InputSource, and SAXException (XML::SAX::Exception)
+classes are only described as hashes (see below).
+
+
Handlers are passed a hash (Node) containing properties as an
+argument instead of positional arguments.
+
+
parse() methods return the value returned by calling the
+end_document() handler.
+
+
+ Method names have been converted to lower-case with underscores.
+ Parameters are all mixed case with initial upper-case.
+
+
+
+
+ If compatibility is a problem for you consider writing a Filter that
+ converts from this style to the one you want. It is likely that such
+ a Filter will be available from CPAN in the not distant future.
+
SAX (Simple API for XML) is a common parser interface for XML
+parsers. It allows application writers to write applications that use
+XML parsers, but are independent of which parser is actually used.
+
+
This document describes the version of SAX used by Perl modules.
+The original version of SAX 2.0, for Java, is described at http://sax.sourceforge.net/.
+
+
There are two basic interfaces in the Perl version of SAX, the
+parser interface and the handler interface. The parser interface
+creates new parser instances, starts parsing, and provides additional
+information to handlers on request. The handler interface is used to
+receive parse events from the parser. This pattern is also commonly
+called "Producer and Consumer" or "Generator and Sink". Note that the
+parser doesn't have to be an XML parser, all it needs to do is provide
+a stream of events to the handler as if it were parsing XML. But the
+actual data from which the events are generated can be anything, a Perl
+object, a CSV file, a database table...
+
+
+
SAX is typically used like this:
+
+
+ my $handler = MyHandler->new();
+ my $parser = AnySAXParser->new( Handler => $handler );
+ $parser->parse($uri);
+
+
+
Handlers are typically written like this:
+
+
+ package MyHandler;
+
+ sub new {
+ my $type = shift;
+ return bless {}, $type;
+ }
+
+ sub start_element {
+ my ($self, $element) = @_;
+
+ print "Starting element $element->{Name}\n";
+ }
+
+ sub end_element {
+ my ($self, $element) = @_;
+
+ print "Ending element $element->{Name}\n";
+ }
+
+ sub characters {
+ my ($self, $characters) = @_;
+
+ print "characters: $characters->{Data}\n";
+ }
+
+ 1;
+
+
+
Basic SAX Parser
+
+
These methods and options are the most commonly used with SAX
+parsers and event generators.
+
+
Applications may not invoke a parse() method again while a
+parse is in progress (they should create a new SAX parser instead for
+each nested XML document). Once a parse is complete, an application
+may reuse the same parser object, possibly with a different input
+source.
+
+
During the parse, the parser will provide information about the XML
+document through the registered event handlers. Note that an event that
+hasn't been registered (ie that doesn't have its corresponding method in
+the handler's class) will not be called. This allows one to only
+get the events one is interested in.
+
+
+
+
parse(uri [, options])
+
+Parses the XML instance identified by uri (a system
+identifier). options can be a list of option, value pairs
+or a hash. Options include Handler, features and properties,
+and advanced SAX parser options. parse() returns the result
+of calling the end_document() handler. The options supported
+by parse() may vary slightly if what is being "parsed" isn't
+XML.
+
+
+
+
parse_file(stream [, options])
+
+Parses the XML instance in the already opened stream, an
+IO::Handler or similar. options are the same as for parse(). parse_file() returns the result
+of calling the end_document() handler.
+
+
+
parse_string(string [, options])
+
+Parses the XML instance in string. options are
+the same as for parse().
+parse_string() returns the result of calling the
+end_document() handler.
+
+
+
Handler
+
+The default handler object to receive all events from the parser.
+Applications may change Handler in the middle of the parse
+and the SAX parser will begin using the new handler
+immediately. The Advanced SAX document
+lists a number of more specialized handlers that can be used should you
+wish to dispatch different types of events to different objects.
+
These methods are the most commonly used by SAX handlers.
+
+
+
start_document(document)
+
+Receive notification of the beginning of a document.
+
+
The SAX parser will invoke this method only once, before any other
+methods (except for set_document_locator() in advanced SAX
+handlers).
+
+No properties are defined for this event (document is
+empty).
+
+
+
end_document(document)
+
+Receive notification of the end of a document.
+
+
The SAX parser will invoke this method only once, and it will be
+the last method invoked during the parse. The parser shall not invoke
+this method until it has either abandoned parsing (because of an
+unrecoverable error) or reached the end of input.
+
+
No properties are defined for this event (document is
+empty).
+
+The return value of end_document() is returned by the
+parser's parse() methods.
+
+
+
start_element(element)
+
+Receive notification of the start of an element.
+
+
The Parser will invoke this method at the beginning of every
+element in the XML document; there will be a corresponding
+end_element() event for every start_element() event (even when the
+element is empty). All of the element's content will be reported, in
+order, before the corresponding end_element() event.
+
+element is a hash with these properties:
+
+
+
+
Name
+
The element type name (including prefix).
+
Attributes
+
The attributes attached to the element, if any.
+
+
+
+If namespace processing is turned on (which is the default), these
+properties are also available:
+
+
+
+
NamespaceURI
+
The namespace of this element.
+
Prefix
+
The namespace prefix used on this element.
+
LocalName
+
The local name of this element.
+
+
+
+Attributes is a hash keyed by JClark namespace notation. That
+is, the keys are of the form "{NamespaceURI}LocalName". If the attribute
+has no NamespaceURI, then it is simply "{}LocalName". Each attribute is
+a hash with these properties:
+
+
+
+
Name
+
The attribute name (including prefix).
+
Value
+
The normalized value of the attribute.
+
NamespaceURI
+
The namespace of this attribute.
+
Prefix
+
The namespace prefix used on this attribute.
+
LocalName
+
The local name of this attribute.
+
+
+
+
+
+
+
+
end_element(element)
+
+Receive notification of the end of an element.
+
+
The SAX parser will invoke this method at the end of every element
+in the XML document; there will be a corresponding start_element() event for every end_element() event (even when the element is
+empty).
+
+element is a hash with these properties:
+
+
+
+
Name
+
The element type name (including prefix).
+
+
+
+If namespace processing is turned on (which is the default), these
+properties are also available:
+
+
+
+
NamespaceURI
+
The namespace of this element.
+
Prefix
+
The namespace prefix used on this element.
+
LocalName
+
The local name of this element.
+
+
+
+
+
+
characters(characters)
+
+Receive notification of character data.
+
+
The Parser will call this method to report each chunk of character
+data. SAX parsers may return all contiguous character data in a
+single chunk, or they may split it into several chunks (however, all
+of the characters in any single event must come from the same external
+entity so that the Locator provides useful information).
+
+
characters is a hash with this property:
+
+
+
+
Data
+
The characters from the XML document.
+
+
+
+
+
+
ignorable_whitespace(characters)
+
+Receive notification of ignorable whitespace in element content.
+
+
Validating Parsers must use this method to report each chunk of
+ignorable whitespace (see the W3C XML 1.0 recommendation, section
+2.10): non-validating parsers may also use this method if they are
+capable of parsing and using content models.
+
+
SAX parsers may return all contiguous whitespace in a single chunk,
+or they may split it into several chunks; however, all of the
+characters in any single event must come from the same external
+entity, so that the Locator provides useful information.
+ Conformant XML parsers are required to abort processing when
+ well-formedness or validation errors occur. In Perl, SAX parsers use
+ die() to signal these errors. To catch these errors and prevent
+ them from killing your program, use eval{}:
+
+
+
+
+
diff --git a/examples/MyHandler.pm b/examples/MyHandler.pm
new file mode 100644
index 0000000..56b9904
--- /dev/null
+++ b/examples/MyHandler.pm
@@ -0,0 +1,22 @@
+# This is the example module in doc/UsingPerlSAX.pod
+
+package MyHandler;
+
+sub new {
+ my ($type) = @_;
+ return bless {}, $type;
+}
+
+sub start_element {
+ my ($self, $element) = @_;
+
+ print "Start element: $element->{Name}\n";
+}
+
+sub end_element {
+ my ($self, $element) = @_;
+
+ print "End element: $element->{Name}\n";
+}
+
+1;
diff --git a/examples/esis-test.pl b/examples/esis-test.pl
new file mode 100644
index 0000000..6d09a31
--- /dev/null
+++ b/examples/esis-test.pl
@@ -0,0 +1,19 @@
+use XML::ESISParser;
+use XML::Handler::Sample;
+
+if ($ARGV[0] eq '--sgml') {
+ push (@additional_args, IsSGML => 1);
+ shift @ARGV;
+}
+
+if ($#ARGV != 0) {
+ die "usage: esis-test FILE\n";
+}
+$file = shift @ARGV;
+
+$my_handler = XML::Handler::Sample->new;
+
+XML::ESISParser->new->parse(Source => { SystemId => $file },
+ Handler => $my_handler,
+ @additional_args);
+
diff --git a/examples/myhandler.pl b/examples/myhandler.pl
new file mode 100644
index 0000000..6c9c3d1
--- /dev/null
+++ b/examples/myhandler.pl
@@ -0,0 +1,11 @@
+# This is the example script in doc/UsingPerlSAX.pod
+
+use XML::Parser::PerlSAX;
+use MyHandler;
+
+my $my_handler = MyHandler->new;
+my $parser = XML::Parser::PerlSAX->new( Handler => $my_handler );
+
+foreach my $instance (@ARGV) {
+ $parser->parse(Source => { SystemId => $instance });
+}
diff --git a/examples/myhandler.xml b/examples/myhandler.xml
new file mode 100644
index 0000000..7c0319a
--- /dev/null
+++ b/examples/myhandler.xml
@@ -0,0 +1,6 @@
+
+
+
+Using PerlSAX
+Working with PerlSAX ...
+
diff --git a/examples/perlsax-test.pl b/examples/perlsax-test.pl
new file mode 100644
index 0000000..d57068c
--- /dev/null
+++ b/examples/perlsax-test.pl
@@ -0,0 +1,13 @@
+use XML::Parser::PerlSAX;
+use XML::Handler::Sample;
+
+if ($#ARGV != 0) {
+ die "usage: esis-test FILE\n";
+}
+$file = shift @ARGV;
+
+$my_handler = XML::Handler::Sample->new;
+
+XML::Parser::PerlSAX->new->parse(Source => { SystemId => $file },
+ Handler => $my_handler);
+
diff --git a/examples/schema.pl b/examples/schema.pl
new file mode 100644
index 0000000..dbc5c8a
--- /dev/null
+++ b/examples/schema.pl
@@ -0,0 +1,36 @@
+# This template file is in the Public Domain.
+# You may do anything you want with this file.
+#
+# $Id: schema.pl,v 1.1 1999/08/10 21:43:50 kmacleod Exp $
+#
+
+# This is the example script in the XML::PatAct::ToObjects module doc,
+# it also uses XML::PatAct::MatchName and is an example of using PatAct
+# modules.
+
+use XML::Parser::PerlSAX;
+use XML::PatAct::MatchName;
+use XML::PatAct::ToObjects;
+
+my $patterns =
+ [
+ 'schema' => [ qw{ -holder } ],
+ 'table' => [ qw{ -make Schema::Table } ],
+ 'name' => [ qw{ -field Name -as-string } ],
+ 'summary' => [ qw{ -field Summary -as-string } ],
+ 'description' => [ qw{ -field Description -grove } ],
+ 'column' => [ qw{ -make Schema::Column -push-field Columns } ],
+ 'unique' => [ qw{ -field Unique -value 1 } ],
+ 'non-null' => [ qw{ -field NonNull -value 1 } ],
+ 'default' => [ qw{ -field Default -as-string } ],
+ ];
+
+my $matcher = XML::PatAct::MatchName->new( Patterns => $patterns );
+my $handler = XML::PatAct::ToObjects->new( Patterns => $patterns,
+ Matcher => $matcher);
+
+my $parser = XML::Parser::PerlSAX->new( Handler => $handler );
+$schema = $parser->parse(Source => { SystemId => $ARGV[0] } );
+
+require 'dumpvar.pl';
+dumpvar('main', 'schema');
diff --git a/examples/schema.xml b/examples/schema.xml
new file mode 100644
index 0000000..ffbbfaf
--- /dev/null
+++ b/examples/schema.xml
@@ -0,0 +1,16 @@
+
+
+ MyTable
+ A short summary
+ A long description that may
+ contain a subset of HTML
+
+ MyColumn1
+ A short summary
+ A long description
+
+
+ 42
+
+
+
diff --git a/lib/Data/Grove.pm b/lib/Data/Grove.pm
new file mode 100644
index 0000000..a198987
--- /dev/null
+++ b/lib/Data/Grove.pm
@@ -0,0 +1,120 @@
+#
+# Copyright (C) 1999 Ken MacLeod
+# Data::Grove is free software; you can redistribute it and/or
+# modify it under the same terms as Perl itself.
+#
+# $Id: Grove.pm,v 1.6 1999/12/22 21:15:00 kmacleod Exp $
+#
+
+###
+### For a similar package, see also:
+###
+### Graph::Element -- elements for a directed graph
+### Neil Bowers (NIELB)
+###
+
+package Data::Grove;
+
+use vars qw{ $VERSION };
+
+# will be substituted by make-rel script
+$VERSION = "0.08";
+
+sub new {
+ my $type = shift;
+ my $self = ($#_ == 0) ? { %{ (shift) } } : { @_ };
+
+ if (defined $self->{Raw}) {
+ # clone the raw object
+ $self = { %{ $self->{Raw} } };
+ }
+
+ return bless $self, $type;
+}
+
+package Data::Grove::Characters;
+use vars qw{ @ISA $type_name };
+@ISA = qw{Data::Grove};
+$type_name = 'characters';
+
+1;
+
+__END__
+
+=head1 NAME
+
+Data::Grove -- support for deeply nested structures
+
+=head1 SYNOPSIS
+
+ use Data::Grove;
+
+ $object = MyPackage->new;
+
+ package MyPackage;
+ @ISA = qw{Data::Grove};
+
+=head1 DESCRIPTION
+
+C provides support for deeply nested tree or graph
+structures. C is intended primarily for Perl module
+authors writing modules with many types or classes of objects that
+need to be manipulated and extended in a consistent and flexible way.
+
+C is best used by creating a core set of ``data'' classes
+and then incrementally adding functionality to the core data classes
+by using ``extension'' modules. One reason for this design is so that
+the data classes can be swapped out and the extension modules can work
+with new data sources. For example, these other data sources could be
+disk-based, network-based or built on top of a relational database.
+
+Two extension modules that come with C are
+C and C.
+C adds a `C' property to grove objects
+and implements a `C' method to grove objects to return the root
+node of the tree from anywhere in the tree and a `C' method
+to return a list of nodes between the root node and ``this'' node.
+C adds callback methods `C' and
+`C' that call your handler or receiver module back by
+object type name or the object's name.
+
+C objects do not contain parent references, Perl garbage
+collection will delete them when no longer referenced and
+sub-structures can be shared among several structures.
+C is used to create temporary objects with parent
+pointers.
+
+Properties of data classes are accessed directly using Perl's hash
+functions (i.e. `C<$object-E{Property}>'). Extension modules may
+also define properties that they support or use, for example
+Data::Grove::Parent adds `C' and `C' properties and
+Visitor depends on `C' and `C' properties.
+
+See the module C for an example implementation of
+C.
+
+=head1 METHODS
+
+=over 4
+
+=item new( PROPERTIES )
+
+Return a new object blessed into the SubClass, with the given
+properties. PROPERTIES may either be a list of key/value pairs, a
+single hash containing key/value pairs, or an existing C
+object. If an existing C is passed to `C', a
+shallow copy of that object will be returned. A shallow copy means
+that you are returned a new object, but all of the objects underneath
+still refer to the original objects.
+
+=back
+
+=head1 AUTHOR
+
+Ken MacLeod, ken@bitsko.slc.ut.us
+
+=head1 SEE ALSO
+
+perl(1)
+
+=cut
diff --git a/lib/Data/Grove/Parent.pm b/lib/Data/Grove/Parent.pm
new file mode 100644
index 0000000..a68c5ed
--- /dev/null
+++ b/lib/Data/Grove/Parent.pm
@@ -0,0 +1,384 @@
+#
+# Copyright (C) 1998,1999 Ken MacLeod
+# Data::Grove::Parent is free software; you can redistribute it and/or
+# modify it under the same terms as Perl itself.
+#
+# $Id: Parent.pm,v 1.2 1999/12/22 21:15:00 kmacleod Exp $
+#
+
+###
+### WARNING
+###
+###
+### This code has a bug in it that renders it useless. In the FETCH
+### routines, the new object created should have a reference to the
+### the tied object that has $self as the underlying value. As of
+### this version, I don't know of a way to get to the tied object.
+###
+
+# Search for places marked `VALIDATE' to see where validation hooks
+# may be added in the future.
+
+use strict;
+
+#--------------------------------------------------------------------------
+# Data::Grove::Parent
+#--------------------------------------------------------------------------
+
+package Data::Grove::Parent;
+
+use UNIVERSAL;
+use Carp;
+
+use vars qw{ $VERSION };
+
+# will be substituted by make-rel script
+$VERSION = "0.08";
+
+sub new {
+ my $type = shift;
+ my $raw = shift;
+ my $parent = shift;
+
+ if (UNIVERSAL::isa($raw, 'Data::Grove::Parent')) {
+ return $raw;
+ }
+
+ my @properties = ( Raw => $raw );
+
+ if (defined $parent) {
+ push @properties, Parent => $parent;
+ }
+
+ my $dummy = bless {}, ref($raw);
+ tie %$dummy, $type, @properties;
+ return $dummy;
+}
+
+sub TIEHASH {
+ my $type = shift;
+
+ return bless { @_ }, $type;
+}
+
+sub STORE {
+ my $self = shift;
+ my $key = shift;
+ my $value = shift;
+
+ if (exists $self->{$key}) {
+ $self->{$key} = $value;
+ } else {
+ # VALIDATE
+ if (UNIVERSAL::isa($value, 'Data::Grove::Parent')) {
+ $value = $value->{Raw};
+ } elsif (UNIVERSAL::isa($value, 'Data::Grove::ParentList')) {
+ $value = $value->[0];
+ }
+ $self->{Raw}{$key} = $value;
+ }
+}
+
+sub FETCH {
+ my $self = shift;
+ my $key = shift;
+
+ if (exists $self->{$key}) {
+ return $self->{$key};
+ } else {
+ my $value = $self->{Raw}{$key};
+ if (ref($value) eq 'ARRAY') {
+ $value = Data::Grove::ParentList->new($value, $self);
+ }
+ return $value;
+ }
+}
+
+sub FIRSTKEY {
+ my $self = shift;
+ my $raw = $self->{Raw};
+
+ $self->{'__each_in_raw'} = 1;
+ my $a = scalar keys %$raw;
+ each %$raw;
+}
+
+sub NEXTKEY {
+ my $self = shift;
+ my $raw = $self->{Raw};
+
+ my ($key, $value);
+ if ($self->{'__each_in_raw'}) {
+ if (($key, $value) = each %$raw) {
+ return $key;
+ }
+ delete $self->{'__each_in_raw'};
+ my $a = scalar keys %$self;
+ }
+
+ return each %$self;
+}
+
+sub EXISTS {
+ my $self = shift;
+ my $key = shift;
+
+ return (exists $self->{Raw}{$key})
+ || (exists $self->{$key});
+}
+
+
+sub DELETE {
+ my $self = shift;
+ my $key = shift;
+
+ if (exists $self->{$key}) {
+ croak "can't delete \`Parent' or \`Raw' properties\n"
+ if ($key eq 'Parent' || $key eq 'Raw');
+ delete $self->{$key};
+ } else {
+ delete $self->{'Raw'}{$key};
+ }
+}
+
+sub CLEAR {
+ my $self = shift;
+
+ %{ $self->{Raw} } = ();
+}
+
+#--------------------------------------------------------------------------
+# Data::Grove::ParentList
+#--------------------------------------------------------------------------
+
+package Data::Grove::ParentList;
+
+use UNIVERSAL;
+
+sub new {
+ my $type = shift;
+ my $raw = shift;
+ my $parent = shift;
+
+ if (UNIVERSAL::isa($raw, 'Data::Grove::ParentList')) {
+ return $raw;
+ }
+
+ my $dummy = [];
+ tie @$dummy, $type, $raw, $parent;
+ return $dummy;
+}
+
+sub TIEARRAY {
+ my $type = shift;
+
+ return bless [ @_ ], $type;
+}
+
+sub FETCHSIZE {
+ scalar @{$_[0][0]};
+}
+
+sub STORESIZE {
+ $#{$_[0][0]} = $_[1]-1;
+}
+
+sub STORE {
+ my $self = shift;
+ my $index = shift;
+ my $value = shift;
+
+ # VALIDATE
+ if (UNIVERSAL::isa($value, 'Data::Grove::Parent')) {
+ $value = $value->{Raw};
+ } elsif (UNIVERSAL::isa($value, 'Data::Grove::ParentList')) {
+ $value = $value->[0];
+ }
+ $self->[0][$index] = $value;
+}
+
+sub FETCH {
+ my $self = shift;
+ my $index = shift;
+
+ my $value = $self->[0][$index];
+ if (defined $value) {
+ if (ref($value)) {
+ return Data::Grove::Parent->new($value, $self->[1]);
+ } else {
+ return Data::Grove::Parent->new({ Data => $value }, $self->[1]);
+ }
+ }
+
+ return $value;
+}
+
+sub CLEAR {
+ @{$_[0][0]} = ();
+}
+
+sub POP {
+ pop(@{$_[0][0]});
+}
+
+sub PUSH {
+ my $o = shift;
+
+ foreach my $value (@_) {
+ # VALIDATE
+ if (UNIVERSAL::isa($value, 'Data::Grove::Parent')) {
+ $value = $value->{Raw};
+ } elsif (UNIVERSAL::isa($value, 'Data::Grove::ParentList')) {
+ $value = $value->[0];
+ }
+ }
+ push(@{$o->[0]},@_);
+}
+
+sub SHIFT {
+ shift(@{$_[0][0]});
+}
+
+sub UNSHIFT {
+ my $o = shift;
+
+ foreach my $value (@_) {
+ # VALIDATE
+ if (UNIVERSAL::isa($value, 'Data::Grove::Parent')) {
+ $value = $value->{Raw};
+ } elsif (UNIVERSAL::isa($value, 'Data::Grove::ParentList')) {
+ $value = $value->[0];
+ }
+ }
+ unshift(@{$o->[0]},@_);
+}
+
+sub SPLICE
+{
+ my $ob = shift;
+ my $sz = $ob->FETCHSIZE;
+ my $off = @_ ? shift : 0;
+ $off += $sz if $off < 0;
+ my $len = @_ ? shift : $sz-$off;
+
+ foreach my $value (@_) {
+ # VALIDATE
+ if (UNIVERSAL::isa($value, 'Data::Grove::Parent')) {
+ $value = $value->{Raw};
+ } elsif (UNIVERSAL::isa($value, 'Data::Grove::ParentList')) {
+ $value = $value->[0];
+ }
+ }
+ return splice(@{$ob->[0]},$off,$len,@_);
+}
+
+#--------------------------------------------------------------------------
+# Data::Grove
+#--------------------------------------------------------------------------
+
+package Data::Grove;
+
+sub root {
+ my $self = shift;
+
+ return $self
+ if !defined $self->{Parent};
+
+ return $self->{Parent}->root(@_);
+}
+
+sub rootpath {
+ my $self = shift;
+
+ if (defined $self->{Parent}) {
+ return ($self->{Parent}->rootpath, $self);
+ } else {
+ return ($self);
+ }
+}
+
+sub add_magic {
+ my $self = shift;
+ my $parent = shift;
+
+ return Data::Grove::Parent->new($self, $parent);
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Data::Grove::Parent - provide parent properties to Data::Grove objects
+
+=head1 SYNOPSIS
+
+ use Data::Grove::Parent;
+
+ $root = $object->root;
+ $rootpath = $object->rootpath;
+ $tied = $object->add_magic([ $parent ]);
+
+ $node = Data::Grove::Parent->new($hash [, $parent]);
+ $node_list = Data::Grove::ParentList->new($array [, $parent]);
+
+=head1 DESCRIPTION
+
+Data::Grove::Parent is an extension to Data::Grove that adds
+`C' and `C' properties to Data::Grove objects and methods
+for returning the root node of a grove, a list of nodes between and
+including the root node and the current node, and a method that
+creates parented nodes.
+
+Data::Grove::Parent works by creating a Perl ``tied'' object that
+contains a parent reference (`C') and a reference to the
+original Data::Grove object (`C'). Tying-magic is used so that
+every time you reference the Data::Grove::Parent object it actually
+references the underlying raw object.
+
+When you retrieve a list or a property of the Raw object,
+Data::Grove::Parent automatically adds magic to the returned list or
+node. This means you only call `add_magic()' once to create the first
+Data::Grove::Parent object and then use the grove objects like you
+normally would.
+
+The most obvious use of this is so you don't have to call a
+`C' method when you want to release a grove or part of a
+grove; since Data::Grove and Data::Grove::Parent objects have no
+cyclic references, Perl can garbage collect them normally.
+
+A secondary use is to allow you to reuse grove or property set
+fragments in multiple trees. WARNING: Data::Grove currently does not
+protect you from creating your B cyclic references! This could
+lead to infinite loops if you don't take care to avoid them.
+
+=head1 METHODS
+
+=over 4
+
+=item $object->root()
+
+=item $object->rootpath()
+
+`C' returns the root node if `C<$object>' is a
+`C' object. `C' returns an array of
+all the nodes between and including the root node and `C<$object>'.
+
+=item $tied = $object->add_magic([ $parent ])
+
+`C' returns a C object with
+`C<$object>' as it's `C' object. If `C<$parent>' is given, that
+becomes the tied object's parent object.
+
+=back
+
+=head1 AUTHOR
+
+Ken MacLeod, ken@bitsko.slc.ut.us
+
+=head1 SEE ALSO
+
+perl(1), Data::Grove(3)
+
+=cut
diff --git a/lib/Data/Grove/Visitor.pm b/lib/Data/Grove/Visitor.pm
new file mode 100644
index 0000000..6cf2e9f
--- /dev/null
+++ b/lib/Data/Grove/Visitor.pm
@@ -0,0 +1,212 @@
+#
+# Copyright (C) 1998,1999 Ken MacLeod
+# Data::Grove::Visitor is free software; you can redistribute it and/or
+# modify it under the same terms as Perl itself.
+#
+# $Id: Visitor.pm,v 1.6 2000/03/20 23:06:45 kmacleod Exp $
+#
+
+use strict;
+use 5.005;
+
+package Data::Grove::Visitor;
+
+use vars qw{ $VERSION };
+
+# will be substituted by make-rel script
+$VERSION = "0.08";
+
+# The following methods extend Data::Grove
+package Data::Grove;
+
+sub accept {
+ my $self = shift;
+ my $visitor = shift;
+
+ my $type_name;
+ my $package = ref($self);
+ eval "\$type_name = \$${package}::type_name";
+ if (!defined $type_name) {
+ return (); # no action
+ }
+
+ my $method_name = 'visit_' . $type_name;
+ if ($visitor->can($method_name)) {
+ return $visitor->$method_name ($self, @_);
+ } else {
+ return (); # no action
+ }
+}
+
+sub accept_name {
+ my $self = shift;
+
+ if (!defined $self->{Name}) {
+ return $self->accept (@_);
+ }
+
+ my $visitor = shift;
+
+ my $name = $self->{Name};
+ $name =~ s/\W/_/g;
+ my $name_method = "visit_name_$name";
+
+ if (!$self->{'has'}{$name_method}) {
+ return if (defined $self->{'has'}{$name_method});
+ $self->{'has'}{$name_method} = $visitor->can($name_method);
+ return $self->accept($visitor, @_) if (!$self->{'has'}{$name_method});
+ }
+
+ return $visitor->$name_method ($self, @_);
+}
+
+sub attr_accept {
+ my $self = shift; my $attr = shift; my $visitor = shift;
+
+ if (!defined $self->{Attributes}) {
+ return (); # no action
+ }
+
+ my $attrs = $self->{Attributes}{$attr};
+ if (ref($attrs) eq 'ARRAY') {
+ return $self->_children_accept ($attrs, $visitor, @_);
+ } else {
+
+ if (!$self->{has_visit_characters}) {
+ return if (defined $self->{has_visit_characters});
+ $self->{has_visit_characters} = $visitor->can('visit_characters');
+ return if (!$self->{has_visit_characters});
+ }
+ # FIXME should be some other generic than XML::Grove::Characters
+ return $visitor->visit_characters (XML::Grove::Characters->new(Data => $attrs), @_);
+ }
+}
+
+sub children_accept {
+ my $self = shift;
+
+ if (defined $self->{Contents}) {
+ return $self->_children_accept ($self->{Contents}, @_);
+ } else {
+ return (); # no action
+ }
+}
+
+sub children_accept_name {
+ my $self = shift;
+
+ if (defined $self->{Contents}) {
+ return $self->_children_accept_name ($self->{Contents}, @_);
+ } else {
+ return (); # no action
+ }
+}
+
+sub _children_accept {
+ my $self = shift; my $array = shift; my $visitor = shift;
+
+ my @return;
+ my $ii;
+ for ($ii = 0; $ii <= $#$array; $ii ++) {
+ push @return, $array->[$ii]->accept ($visitor, @_);
+ }
+
+ return @return;
+}
+
+sub _children_accept_name {
+ my $self = shift; my $array = shift; my $visitor = shift;
+
+ my @return;
+ my $ii;
+ for ($ii = 0; $ii <= $#$array; $ii ++) {
+ push @return, $array->[$ii]->accept_name ($visitor, @_);
+ }
+
+ return @return;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Data::Grove::Visitor - add visitor/callback methods to Data::Grove objects
+
+=head1 SYNOPSIS
+
+ use Data::Grove::Visitor;
+
+ @results = $object->accept ($visitor, ...);
+ @results = $object->accept_name ($visitor, ...);
+ @results = $object->children_accept ($visitor, ...);
+ @results = $object->children_accept_name ($visitor, ...);
+
+=head1 DESCRIPTION
+
+Data::Grove::Visitor adds visitor methods (callbacks) to Data::Grove
+objects. A ``visitor'' is a class (a package) you write that has
+methods (subs) corresponding to the objects in the classes being
+visited. You use the visitor methods by creating an instance of your
+visitor class, and then calling `C' on the
+top-most object you want to visit, that object will in turn call your
+visitor back with `C>', where I