|
1 # |
|
2 # Use XML::DOM::ValParser instead of XML::DOM::Parser and it will |
|
3 # use XML::Checker to validate XML at parse time. |
|
4 # |
|
5 |
|
6 package XML::DOM::ValParser; |
|
7 |
|
8 use strict; |
|
9 use XML::DOM; |
|
10 use XML::Checker::Parser; |
|
11 |
|
12 use vars qw( @ISA @SupportedHandlers ); |
|
13 |
|
14 @ISA = qw( XML::Checker::Parser ); |
|
15 |
|
16 # These XML::Parser handlers are currently supported by XML::DOM |
|
17 @SupportedHandlers = qw( Init Final Char Start End Default Doctype |
|
18 CdataStart CdataEnd XMLDecl Entity Notation Proc |
|
19 Default Comment Attlist Element Unparsed ); |
|
20 |
|
21 sub new |
|
22 { |
|
23 my ($class, %args) = @_; |
|
24 |
|
25 my %handlers = (); |
|
26 for (@SupportedHandlers) |
|
27 { |
|
28 my $domHandler = "XML::Parser::Dom::$_"; |
|
29 $handlers{$_} = \&$domHandler; |
|
30 } |
|
31 $args{Handlers} = \%handlers; |
|
32 $class->SUPER::new (%args); |
|
33 } |
|
34 |
|
35 sub parse |
|
36 { |
|
37 # Do what XML::DOM::Parser normally does. |
|
38 # Temporarily override his @ISA, so that he thinks he's a |
|
39 # XML::DOM::ValParser and calls the right SUPER::parse(), |
|
40 # (otherwise he thinks he's an XML::DOM::Parser and you see runtime |
|
41 # error: Can't call method "Init" on unblessed reference ...) |
|
42 local @XML::DOM::Parser::ISA = @ISA; |
|
43 local $XML::Checker::Parser::_skipInsignifWS = $_[0]->{SkipInsignifWS}; |
|
44 XML::DOM::Parser::parse (@_); |
|
45 } |
|
46 |
|
47 1; # package return code |
|
48 |
|
49 __END__ |
|
50 |
|
51 =head1 NAME |
|
52 |
|
53 XML::DOM::ValParser - an XML::DOM::Parser that validates at parse time |
|
54 |
|
55 =head1 SYNOPSIS |
|
56 |
|
57 use XML::DOM::ValParser; |
|
58 |
|
59 my %expat_options = (KeepCDATA => 1, |
|
60 Handlers => [ Unparsed => \&my_Unparsed_handler ]); |
|
61 my $parser = new XML::DOM::ValParser (%expat_options); |
|
62 |
|
63 eval { |
|
64 local $XML::Checker::FAIL = \&my_fail; |
|
65 my $doc = $parser->parsefile ("fail.xml"); |
|
66 ... XML::DOM::Document was created sucessfully ... |
|
67 }; |
|
68 if ($@) { |
|
69 # Either XML::Parser (expat) threw an exception or my_fail() died. |
|
70 ... your error handling code here ... |
|
71 # Note that the XML::DOM::Document is automatically disposed off and |
|
72 # will be garbage collected |
|
73 } |
|
74 |
|
75 # Throws an exception (with die) when an error is encountered, this |
|
76 # will stop the parsing process. |
|
77 # Don't die if a warning or info message is encountered, just print a message. |
|
78 sub my_fail { |
|
79 my $code = shift; |
|
80 die XML::Checker::error_string ($code, @_) if $code < 200; |
|
81 XML::Checker::print_error ($code, @_); |
|
82 } |
|
83 |
|
84 =head1 DESCRIPTION |
|
85 |
|
86 Use XML::DOM::ValParser wherever you would use L<XML::DOM::Parser> and |
|
87 your XML will be checked using L<XML::Checker> at parse time. |
|
88 |
|
89 See L<XML::DOM> for details on XML::DOM::Parser options. |
|
90 See L<XML::Checker> for details on setting the fail handler (my_fail.) |
|
91 |
|
92 The following handlers are currently supported, just like XML::DOM::Parser: |
|
93 Init, Final, Char, Start, End, Default, Doctype, CdataStart, CdataEnd, |
|
94 XMLDecl, Entity, Notation, Proc, Default, Comment, Attlist, Element, Unparsed. |
|
95 |
|
96 =head1 XML::DOM::ValParser |
|
97 |
|
98 XML::DOM::ValParser extends from L<XML::Checker::Parser>. It creates an |
|
99 L<XML::Checker> object and routes all event handlers through the checker, |
|
100 before processing the events to create the XML::DOM::Document. |
|
101 |
|
102 Just like L<XML::Checker::Parser>, the checker object can be retrieved with |
|
103 the getChecker() method and can be reused later on (provided that the DOCTYPE |
|
104 section of the XML::DOM::Document did not change in the mean time.) |
|
105 |
|
106 You can control which errors are fatal (and therefore should stop creation |
|
107 of the XML::DOM::Document) by filtering the appropriate error codes in |
|
108 the global $XML::Checker::FAIL handler |
|
109 (see L<XML::Checker/ERROR_HANDLING>) and |
|
110 calling I<die> or I<croak> appropriately. |
|
111 |
|
112 Just like XML::Checker::Parser, XML::DOM::ValParser supports the |
|
113 SkipExternalDTD and SkipInsignifWS options. See L<XML::Checker::Parser> |
|
114 for details. |
|
115 |
|
116 =head1 AUTHOR |
|
117 |
|
118 Send bug reports, hints, tips, suggestions to Enno Derksen at |
|
119 <F<enno@att.com>>. |
|
120 |
|
121 =head1 SEE ALSO |
|
122 |
|
123 L<XML::DOM>, L<XML::Checker> (L<XML::Checker/SEE_ALSO>) |