File Coverage

lib/XML/Validate.pm
Criterion Covered Total %
statement 24 56 42.8
branch 5 14 35.7
condition 0 3 0.0
subroutine 6 12 50.0
pod 5 7 71.4
total 40 92 43.4


line stmt bran cond sub pod time code
1             # Factory class providing a common interface to different XML validators
2              
3             package XML::Validate;
4              
5             # Using XML::Validate::Base here is cheating somewhat. We do this because we're
6             # dynamically loading the validation module, but we still want to be able to
7             # use Log::Trace's deep import feature. Any better ideas welcomed.
8              
9 1     1   768 use strict;
  1         2  
  1         49  
10 1     1   630 use XML::Validate::Base;
  1         2  
  1         27  
11 1     1   5 use vars qw($VERSION);
  1         2  
  1         622  
12              
13             $VERSION = sprintf"%d.%03d", q$Revision: 1.25 $ =~ /: (\d+)\.(\d+)/;
14              
15             # Xerces is preferred over MSXML as we've found in practice that MSXML4's schema validation occasionally
16             # lets through invalid documents which Xerces catches.
17             # At the time of writing, LibXML didn't have schema validation support.
18             my $DEFAULT_PRIORITISED_LIST = [ qw( Xerces MSXML LibXML ) ];
19              
20             sub new {
21 2     2 1 1551 my $class = shift;
22 2         6 my %args = @_;
23            
24 2         8 DUMP("Arguments", %args);
25            
26 2         5 my $self = {
27             backend => undef,
28             };
29            
30 2         4 bless($self,$class);
31            
32 2 50       8 if (!$args{Type}) {
33 0         0 die "Required argument Type missing\n";
34             }
35            
36 2 100       10 if ($args{Type} !~ /^\w+$/) {
37 1         7 die "Validator type name '$args{Type}' should only contain word characters.\n";
38             }
39            
40 1         2 my $backend_class;
41 1 50       4 if ($args{Type} eq 'BestAvailable') {
42 0   0     0 my $list = $args{PrioritisedList} || $DEFAULT_PRIORITISED_LIST;
43 0 0       0 my $type = $self->_best_available($list) or die sprintf("None of the listed backends (%s) are available\n",join(", ",@$list));
44 0         0 $backend_class = "XML::Validate::" . $type;
45             } else {
46 1         3 $backend_class = "XML::Validate::" . $args{Type};
47             }
48 1     1   456 eval "use $backend_class";
  0         0  
  0         0  
  1         57  
49 1 50       20 die "Validator $backend_class not loadable: $@" if $@;
50              
51 0         0 my $options = $args{Options};
52 0         0 $self->{backend} = new $backend_class(%{$options});
  0         0  
53            
54 0         0 return $self;
55             }
56              
57             sub validate {
58 0     0 1 0 my $self = shift;
59 0         0 $self->{backend}->validate(@_);
60             }
61              
62             sub last_error {
63 0     0 1 0 my $self = shift;
64 0         0 $self->{backend}->last_error(@_);
65             }
66              
67             sub type {
68 0     0 1 0 my $self = shift;
69 0         0 my $class = ref($self->{backend});
70 0         0 $class =~ m/XML::Validate::(.*)/;
71 0         0 return $1;
72             }
73              
74             sub version {
75 0     0 1 0 my $self = shift;
76 0 0       0 return unless $self->{backend}->can('version');
77 0         0 return $self->{backend}->version;
78             }
79              
80             sub _best_available {
81 0     0   0 my $self = shift;
82 0         0 my ($list) = @_;
83 0         0 foreach my $backend (@{$list}) {
  0         0  
84 0         0 TRACE("Attempting to load $backend");
85 0         0 eval "use XML::Validate::$backend";
86 0 0       0 next if $@;
87 0         0 TRACE("Loading succeeded. Returning $backend");
88 0         0 return $backend;
89             }
90 0         0 return;
91             }
92              
93 0     0 0 0 sub TRACE {}
94 2     2 0 2 sub DUMP {}
95              
96             1;
97              
98             __END__