.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "XML::Checker::Parser 3pm" .TH XML::Checker::Parser 3pm "2021-01-03" "perl v5.32.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" XML::Checker::Parser \- an XML::Parser that validates at parse time .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use XML::Checker::Parser; \& \& my %expat_options = (KeepCDATA => 1, \& Handlers => [ Unparsed => \e&my_Unparsed_handler ]); \& my $parser = new XML::Checker::Parser (%expat_options); \& \& eval { \& local $XML::Checker::FAIL = \e&my_fail; \& $parser\->parsefile ("fail.xml"); \& }; \& if ($@) { \& # Either XML::Parser (expat) threw an exception or my_fail() died. \& ... your error handling code here ... \& } \& \& # Throws an exception (with die) when an error is encountered, this \& # will stop the parsing process. \& # Don\*(Aqt 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, @_); \& } .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" XML::Checker::Parser extends XML::Parser .PP I hope the example in the \s-1SYNOPSIS\s0 says it all, just use XML::Checker::Parser as if it were an XML::Parser. See XML::Parser for the supported (expat) options. .PP You can also derive your parser from XML::Checker::Parser instead of from XML::Parser. All you should have to do is replace: .PP .Vb 2 \& package MyParser; \& @ISA = qw( XML::Parser ); .Ve .PP with: .PP .Vb 2 \& package MyParser; \& @ISA = qw( XML::Checker::Parser ); .Ve .SH "XML::Checker::Parser constructor" .IX Header "XML::Checker::Parser constructor" .Vb 1 \& $parser = new XML::Checker::Parser (SkipExternalDTD => 1, SkipInsignifWS => 1); .Ve .PP The constructor takes the same parameters as XML::Parser with the following additions: .IP "SkipExternalDTD" 4 .IX Item "SkipExternalDTD" By default, it will try to load external DTDs using \s-1LWP.\s0 You can disable this by setting SkipExternalDTD to 1. See External DTDs for details. .IP "SkipInsignifWS" 4 .IX Item "SkipInsignifWS" By default, it will treat insignificant whitespace as regular Char data. By setting SkipInsignifWS to 1, the user Char handler will not be called if insignificant whitespace is encountered. See \*(L"\s-1INSIGNIFICANT_WHITESPACE\*(R"\s0 in XML::Checker for details. .IP "LWP_UserAgent" 4 .IX Item "LWP_UserAgent" When calling \fBparsefile()\fR with a \s-1URL\s0 (instead of a filename) or when loading external DTDs, we use \s-1LWP\s0 to download the remote file. By default it will use a LWP::UserAgent that is created as follows: .Sp .Vb 3 \& use LWP::UserAgent; \& $LWP_USER_AGENT = LWP::UserAgent\->new; \& $LWP_USER_AGENT\->env_proxy; .Ve .Sp Note that env_proxy reads proxy settings from your environment variables, which is what I need to do to get thru our firewall. If you want to use a different LWP::UserAgent, you can either set it globally with: .Sp .Vb 1 \& XML::Checker::Parser::set_LWP_UserAgent ($my_agent); .Ve .Sp or, you can specify it for a specific XML::Checker::Parser by passing it to the constructor: .Sp .Vb 1 \& my $parser = new XML::Checker::Parser (LWP_UserAgent => $my_agent); .Ve .Sp Currently, \s-1LWP\s0 is used when the filename (passed to parsefile) starts with one of the following \s-1URL\s0 schemes: http, https, ftp, wais, gopher, or file (followed by a colon.) If I missed one, please let me know. .Sp The \s-1LWP\s0 modules are part of libwww-perl which is available at \s-1CPAN.\s0 .SH "External DTDs" .IX Header "External DTDs" XML::Checker::Parser will try to load and parse external DTDs that are referenced in \s-1DOCTYPE\s0 definitions unless you set the \fBSkipExternalDTD\fR option to 1 (the default setting is 0.) See \s-1CAVEATS\s0 for details on what is not supported by XML::Checker::Parser. .PP XML::Parser (version 2.27 and up) does a much better job at reading external DTDs, because recently external \s-1DTD\s0 parsing was added to expat. Make sure you set the XML::Parser option \fBParseParamEnt\fR to 1 and the XML::Checker::Parser option \fBSkipExternalDTD\fR to 1. (They can both be set in the XML::Checker::Parser constructor.) .PP When external DTDs are parsed by XML::Checker::Parser, they are located in the following order: .IP "\(bu" 4 With the \f(CW%URI_MAP\fR, which can be set using \fBmap_uri\fR. This hash maps external resource ids (like system \s-1ID\s0's and public \s-1ID\s0's) to full path \s-1URI\s0's. It was meant to aid in resolving \s-1PUBLIC\s0 IDs found in \s-1DOCTYPE\s0 declarations after the \s-1PUBLIC\s0 keyword, e.g. .Sp .Vb 1 \& .Ve .Sp However, you can also use this to force XML::Checker to read DTDs from a different \s-1URL\s0 than was specified (e.g. from the local file system for performance reasons.) .IP "\(bu" 4 on the Internet, if their system identifier starts with a protocol (like http://...) .IP "\(bu" 4 on the local disk, if their system identifier starts with a slash (absolute path) .IP "\(bu" 4 in the \s-1SGML_SEARCH_PATH,\s0 if their system identifier is a relative file name. It will use \f(CW@SGML_SEARCH_PATH\fR if it was set with \&\fB\fBset_sgml_search_path()\fB\fR, or the colon-separated \f(CW$ENV\fR{\s-1SGML_SEARCH_PATH\s0}, or (if that isn't set) the list (\*(L".\*(R", \*(L"$ENV{'\s-1HOME\s0'}/.sgml\*(R", \*(L"/usr/lib/sgml\*(R", \&\*(L"/usr/share/sgml\*(R"), which includes the current directory, so it should do the right thing in most cases. .SS "Static methods related to External DTDs" .IX Subsection "Static methods related to External DTDs" .IP "set_sgml_search_path (dir1, dir2, ...)" 4 .IX Item "set_sgml_search_path (dir1, dir2, ...)" External DTDs with relative file paths are looked up using the \f(CW@SGML_SEARCH_PATH\fR, which can be set with this method. If \f(CW@SGML_SEARCH_PATH\fR is never set, it will use the colon-separated \f(CW$ENV\fR{\s-1SGML_SEARCH_PATH\s0} instead. If neither are set it uses the list: \*(L".\*(R", \*(L"$ENV{'\s-1HOME\s0'}/.sgml\*(R", \*(L"/usr/lib/sgml\*(R", \&\*(L"/usr/share/sgml\*(R". .Sp set_sgml_search_path is a static method. .IP "map_uri (pubid => uri, ...)" 4 .IX Item "map_uri (pubid => uri, ...)" To define the location of \s-1PUBLIC\s0 ids, as found in \s-1DOCTYPE\s0 declarations after the \s-1PUBLIC\s0 keyword, e.g. .Sp .Vb 1 \& .Ve .Sp call this method, e.g. .Sp .Vb 2 \& XML::Checker::Parser::map_uri ( \& "\-//W3C//DTD HTML 4.0//EN" => "file:/user/html.dtd"); .Ve .Sp See External DTDs for more info. .Sp XML::Checker::Parser::map_uri is a static method. .SH "Switching user handlers at parse time" .IX Header "Switching user handlers at parse time" You should be able to use \fBsetHandlers()\fR just as in XML::Parser. (Using setHandlers has not been tested yet.) .SH "Error handling" .IX Header "Error handling" XML::Checker::Parser routes the fail handler through \&\fBXML::Checker::Parser::fail_add_context()\fR before calling your fail handler (i.e. the global fail handler: \f(CW$XML::Checker::FAIL\fR. See \*(L"\s-1ERROR_HANDLING\*(R"\s0 in XML::Checker.) It adds the (line, column, byte) information from XML::Parser to the error context (unless it was the end of the \s-1XML\s0 document.) .SH "Supported XML::Parser handlers" .IX Header "Supported XML::Parser handlers" Only the following XML::Parser handlers are currently routed through XML::Checker: Init, Final, Char, Start, End, Element, Attlist, Doctype, Unparsed, Notation. .SH "CAVEATS" .IX Header "CAVEATS" When using XML::Checker::Parser to parse external DTDs (i.e. with SkipExternalDTD => 0), expect trouble when your external \s-1DTD\s0 contains parameter entities inside declarations or conditional sections. The external \s-1DTD\s0 should probably have the same encoding as the orignal \s-1XML\s0 document. .SH "AUTHOR" .IX Header "AUTHOR" Enno Derksen is the original author. .PP Send bug reports, hints, tips, suggestions to T.J. Mather at <\fItjmather@tjmather.com\fR>. .SH "SEE ALSO" .IX Header "SEE ALSO" XML::Checker (\*(L"\s-1SEE_ALSO\*(R"\s0 in XML::Checker), XML::Parser