# # Use XML::DOM::ValParser instead of XML::DOM::Parser and it will # use XML::Checker to validate XML at parse time. # package XML::DOM::ValParser; use strict; use XML::DOM; use XML::Checker::Parser; use vars qw( @ISA @SupportedHandlers ); @ISA = qw( XML::Checker::Parser ); # These XML::Parser handlers are currently supported by XML::DOM @SupportedHandlers = qw( Init Final Char Start End Default Doctype CdataStart CdataEnd XMLDecl Entity Notation Proc Default Comment Attlist Element Unparsed ); sub new { my ($class, %args) = @_; my %handlers = (); for (@SupportedHandlers) { my $domHandler = "XML::Parser::Dom::$_"; $handlers{$_} = \&$domHandler; } $args{Handlers} = \%handlers; $class->SUPER::new (%args); } sub parse { # Do what XML::DOM::Parser normally does. # Temporarily override his @ISA, so that he thinks he's a # XML::DOM::ValParser and calls the right SUPER::parse(), # (otherwise he thinks he's an XML::DOM::Parser and you see runtime # error: Can't call method "Init" on unblessed reference ...) local @XML::DOM::Parser::ISA = @ISA; local $XML::Checker::Parser::_skipInsignifWS = $_[0]->{SkipInsignifWS}; XML::DOM::Parser::parse (@_); } 1; # package return code __END__ =head1 NAME XML::DOM::ValParser - an XML::DOM::Parser that validates at parse time =head1 SYNOPSIS use XML::DOM::ValParser; my %expat_options = (KeepCDATA => 1, Handlers => [ Unparsed => \&my_Unparsed_handler ]); my $parser = new XML::DOM::ValParser (%expat_options); eval { local $XML::Checker::FAIL = \&my_fail; my $doc = $parser->parsefile ("fail.xml"); ... XML::DOM::Document was created sucessfully ... }; if ($@) { # Either XML::Parser (expat) threw an exception or my_fail() died. ... your error handling code here ... # Note that the XML::DOM::Document is automatically disposed off and # will be garbage collected } # Throws an exception (with die) when an error is encountered, this # will stop the parsing process. # Don't die if a warning or info message is encountered, just print a message. sub my_fail { my $code = shift; die XML::Checker::error_string ($code, @_) if $code < 200; XML::Checker::print_error ($code, @_); } =head1 DESCRIPTION Use XML::DOM::ValParser wherever you would use L and your XML will be checked using L at parse time. See L for details on XML::DOM::Parser options. See L for details on setting the fail handler (my_fail.) The following handlers are currently supported, just like XML::DOM::Parser: Init, Final, Char, Start, End, Default, Doctype, CdataStart, CdataEnd, XMLDecl, Entity, Notation, Proc, Default, Comment, Attlist, Element, Unparsed. =head1 XML::DOM::ValParser XML::DOM::ValParser extends from L. It creates an L object and routes all event handlers through the checker, before processing the events to create the XML::DOM::Document. Just like L, the checker object can be retrieved with the getChecker() method and can be reused later on (provided that the DOCTYPE section of the XML::DOM::Document did not change in the mean time.) You can control which errors are fatal (and therefore should stop creation of the XML::DOM::Document) by filtering the appropriate error codes in the global $XML::Checker::FAIL handler (see L) and calling I or I appropriately. Just like XML::Checker::Parser, XML::DOM::ValParser supports the SkipExternalDTD and SkipInsignifWS options. See L for details. =head1 AUTHOR Send bug reports, hints, tips, suggestions to Enno Derksen at >. =head1 SEE ALSO L, L (L)