/usr/share/perl5/XML/Validate/MSXML.pm is in libxml-validate-perl 1.025-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | # XML::Validate::MSXML
package XML::Validate::MSXML;
use strict;
use Win32::OLE;
use XML::Validate::Base;
use vars qw( $VERSION @ISA $MSXML_VERSION);
@ISA = qw( XML::Validate::Base );
$VERSION = sprintf'%d.%03d', q$Revision: 1.18 $ =~ /: (\d+)\.(\d+)/;
use constant XSI_NS => 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"';
my $VALID_OPTIONS = { strict_validation => 1 };
sub new {
my $class = shift;
my %options = @_;
my $self = {};
bless ($self, $class);
$self->clear_errors();
$self->set_options(\%options,$VALID_OPTIONS);
DUMP("Instantiating XML::Validate::MSXML", $self);
return $self;
}
sub version {
eval {create_doc_and_cache()};
return $MSXML_VERSION;
}
sub validate {
my ($self, $xml) = @_;
$self->clear_errors();
$self->{dom} = undef;
die "validate called with no data to validate\n" unless defined $xml and length $xml > 0;
DUMP("the xml to validate : $xml ", $self);
my ($msxml,$msxmlcache) = create_doc_and_cache();
$msxml->{async} = 0;
$msxml->{validateOnParse} = 0;
$msxml->{resolveExternals} = 1;
TRACE("Starting to parse");
$msxml->LoadXML($xml);
TRACE("Parsed the document");
my $xmlroot = $msxml->{documentElement};
if ($msxml->parseError()->{errorCode} != 0) {
TRACE("XML Parse Error (not syntactically valid)");
my $error = $msxml->parseError();
DUMP("Error", $error);
$self->add_error({
message => $error->{reason},
line => $error->{line},
column => $error->{linepos}
});
return;
}
if ($self->options->{strict_validation}) {
TRACE("XML Syntactically valid");
load_schemas($msxml, $msxmlcache);
TRACE("Validate against schema/DTD ");
if ($msxml->{doctype} || $msxml->{schemas}) {
#DUMP($msxml->{doctype}, $msxml->{schemas});
$msxml->{validateOnParse} = 1;
$msxml->LoadXML($xml);
my $error = $msxml->parseError();
if ($error->{errorCode} != 0) {
$self->add_error({
message => $error->{reason},
line => $error->{line},
column => $error->{linepos}
});
return;
}
$error = $msxml->validate();
if ($error->{errorCode} != 0) {
$self->add_error({
message => $error->{reason},
line => $error->{line},
column => $error->{linepos}
});
return;
}
} else {
# If there is nothing to validate against, treat it as valid.
TRACE("No doctype or schema");
}
}
#Valid
$self->{dom} = $msxml;
return 1;
}
sub last_dom {
my $self = shift;
return $self->{dom};
}
sub load_schemas {
my ($xml, $schema_cache) = @_;
my %schemas;
$xml->setProperty('SelectionNamespaces', XSI_NS);
my $no_ns_schema_xpath = q[//*/@xsi:noNamespaceSchemaLocation];
my $no_ns_schema_nodes = $xml->{documentElement}->selectNodes($no_ns_schema_xpath);
for (my $i=0; $i < $no_ns_schema_nodes->{length}; $i++){
my $schema_txt = $no_ns_schema_nodes->item($i)->{text};
my %add_schemas = ('', $schema_txt);
%schemas = (%schemas, %add_schemas);
}
my $schema_xpath = q[//*/@xsi:schemaLocation];
my $schema_location_nodes = $xml->{documentElement}->selectNodes($schema_xpath);
for (my $i=0; $i < $schema_location_nodes->{length}; $i++){
my $schema_txt = $schema_location_nodes->item($i)->{text};
my %add_schemas = split ' ', $schema_txt;
%schemas = (%schemas, %add_schemas);
}
while (my ($ns, $schema) = each %schemas) {
TRACE("Loading schema [$ns] -> $schema");
$schema_cache->add($ns, $schema);
if (my $schema_error = Win32::OLE::LastError()) {
$schema_error =~ s/OLE exception .*\n\n//m;
$schema_error =~ s/Win32::OLE.*//s;
die $schema_error;
}
}
$xml->{schemas} = $schema_cache if %schemas;
return;
}
sub dependencies_available {
create_doc_and_cache();
return 1;
}
sub create_doc_and_cache {
# Stop Win32::OLE from being noisy
my $warn_level = Win32::OLE->Option('Warn');
Win32::OLE->Option(Warn => 0);
foreach my $version ('5.0', '4.0') {
my $doc = Win32::OLE->new('MSXML2.DOMDocument.' . $version) or next;
my $cache = Win32::OLE->new('MSXML2.XMLSchemaCache.' . $version) or next;
$MSXML_VERSION = $version;
Win32::OLE->Option(Warn => $warn_level); # restore warn level
return ($doc,$cache);
}
die "Unable to instantiate MSXML DOMDocument and SchemaCache. (Do you have a compatible version of MSXML installed?)";
}
# Note: Our use of TRACE and DUMP here is a bit weird. We explicitly pass to
# the TRACE and DUMP in the superclass (XML::Validate::Base) because we expect
# to be dynamically loaded and we assume that the calling class will have dealt
# with Base but not this module. (Note that Log::Trace now has some support for
# dynamic loading. It doesn't play well with some modules in 5.6.1, but it seems
# fine in 5.8. So someday this won't be necessary.)
sub TRACE { XML::Validate::Base::TRACE(@_) }
sub DUMP { XML::Validate::Base::DUMP(@_) }
dependencies_available();
__END__
=head1 NAME
XML::Validate::MSXML - Interface to MSXML validator
=head1 SYNOPSIS
my $validator = new XML::Validate::MSXML(%options);
if ($doc = $validator->validate($xml)) {
... Do stuff with $doc ...
} else {
print "Document is invalid\n";
}
=head1 DESCRIPTION
XML::Validate::MSXML is an interface to Microsoft's MSXML parser (often
available in Windows environments) which can be used with the XML::Validate
module.
=head1 METHODS
=over
=item new(%options)
Returns a new XML::Validate::MSXML instance using the specified options. (See
OPTIONS below.)
=item validate($xml)
Returns true if $xml could be successfully parsed, undef otherwise.
=item last_dom()
Returns the MSXML DOM object of the document last validated.
=item last_error()
Returns the error from the last validate call. This is a hash ref with the
following fields:
=item create_doc_and_cache()
Internal method for instantiation of MSXML DOMDocument and SchemaCache objects
for use within the module.
=item dependencies_available()
Internal method to determine that the necessary dependencies are available for
instantiation of MSXML DOMDocument and SchemaCache objects.
=item load_schemas($msxml, $msxmlcache)
Internal method to perform loading of XML schema(s) into SchemaCache object.
=over
=item *
message
=item *
line
=item *
column
=back
Note that the error gets cleared at the beginning of each C<validate> call.
=item version()
Returns the version of the MSXML component that is installed
=back
=head1 OPTIONS
XML::Validate::MSXML takes the following options:
=over
=item strict_validation
If this boolean value is true, the document will be validated during parsing.
Otherwise it will only be checked for well-formedness. Defaults to true.
=back
=head1 ERROR REPORTING
When a call to validate fails to parse the document, the error may be retrieved
using last_error.
On errors not related to the XML parsing, these methods will throw exceptions.
Wrap calls with eval to catch them.
=head1 PACKAGE GLOBALS
$XML::Validate::MSXML::MSXML_VERSION contains the version number of MSXML.
=head1 DEPENDENCIES
Win32::OLE, MSXML 4.0 or 5.0
=head1 VERSION
$Revision: 1.18 $ on $Date: 2006/04/18 10:00:31 $ by $Author: mattheww $
=head1 AUTHOR
Nathan Carr, Colin Robertson
E<lt>cpan _at_ bbc _dot_ co _dot_ ukE<gt>
=head1 COPYRIGHT
(c) BBC 2005. This program is free software; you can redistribute it and/or modify it under the GNU GPL.
See the file COPYING in this distribution, or http://www.gnu.org/licenses/gpl.txt
=cut
|