line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package XML::Validator::Schema::RootNode; |
2
|
5
|
|
|
5
|
|
29
|
use strict; |
|
5
|
|
|
|
|
7
|
|
|
5
|
|
|
|
|
153
|
|
3
|
5
|
|
|
5
|
|
60
|
use warnings; |
|
5
|
|
|
|
|
10
|
|
|
5
|
|
|
|
|
142
|
|
4
|
|
|
|
|
|
|
|
5
|
5
|
|
|
5
|
|
36
|
use base 'XML::Validator::Schema::ElementNode'; |
|
5
|
|
|
|
|
8
|
|
|
5
|
|
|
|
|
379
|
|
6
|
|
|
|
|
|
|
|
7
|
5
|
|
|
5
|
|
31
|
use XML::Validator::Schema::Util qw(_err); |
|
5
|
|
|
|
|
9
|
|
|
5
|
|
|
|
|
247
|
|
8
|
5
|
|
|
5
|
|
24
|
use Carp qw(croak); |
|
5
|
|
|
|
|
8
|
|
|
5
|
|
|
|
|
4634
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
=head1 NAME |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
XML::Validator::Schema::RootNode - the root node in a schema document |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
=head1 DESCRIPTION |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
This is an internal module used by XML::Validator::Schema to represent |
17
|
|
|
|
|
|
|
the root node in an XML Schema document. Holds references to the |
18
|
|
|
|
|
|
|
libraries for the schema document and is responsible for hooking up |
19
|
|
|
|
|
|
|
named types to their uses in the node tree at the end of parsing. |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
=cut |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
sub new { |
24
|
0
|
|
|
0
|
1
|
|
my $pkg = shift; |
25
|
0
|
|
|
|
|
|
my $self = $pkg->SUPER::new(@_); |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
# start up with empty libraries |
28
|
0
|
|
|
|
|
|
$self->{type_library} = XML::Validator::Schema::TypeLibrary->new; |
29
|
0
|
|
|
|
|
|
$self->{element_library} = XML::Validator::Schema::ElementLibrary->new; |
30
|
0
|
|
|
|
|
|
$self->{attribute_library} = XML::Validator::Schema::AttributeLibrary->new; |
31
|
|
|
|
|
|
|
|
32
|
0
|
|
|
|
|
|
return $self; |
33
|
|
|
|
|
|
|
} |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# finish typing and references |
36
|
|
|
|
|
|
|
sub compile { |
37
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
38
|
0
|
|
|
|
|
|
my $element_library = $self->{element_library}; |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
# put global elements into the library (could move this to ::ElementNode) |
41
|
0
|
|
|
|
|
|
foreach my $d ($self->daughters) { |
42
|
0
|
0
|
|
|
|
|
if (ref($d) eq 'XML::Validator::Schema::ElementNode') { |
43
|
0
|
|
|
|
|
|
$element_library->add(name => $d->{name}, |
44
|
|
|
|
|
|
|
obj => $d); |
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
} |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
# complete all element refs first, forming a complete tree |
50
|
0
|
|
|
|
|
|
foreach my $element ($self->descendants) { |
51
|
0
|
|
|
|
|
|
$self->complete_ref($element); |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
# completa all element types, including their attributes |
55
|
0
|
|
|
|
|
|
foreach my $element ($self->descendants) { |
56
|
0
|
|
|
|
|
|
$self->complete_type($element); |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
sub complete_ref { |
62
|
0
|
|
|
0
|
0
|
|
my ($self, $ref) = @_; |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
# handle any unresolved attribute types |
65
|
0
|
0
|
|
|
|
|
if ($ref->{attr}) { |
66
|
0
|
|
|
|
|
|
$self->complete_attr_ref($_) |
67
|
0
|
|
|
|
|
|
for (grep { $_->{unresolved_ref} } (@{$ref->{attr}})); |
|
0
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
# all done unless unresolved |
71
|
0
|
0
|
|
|
|
|
return unless $ref->{unresolved_ref}; |
72
|
|
|
|
|
|
|
|
73
|
0
|
|
|
|
|
|
my $name = $ref->{name}; |
74
|
0
|
|
|
|
|
|
my ($element) = $self->{element_library}->find(name => $ref->{name}); |
75
|
0
|
0
|
|
|
|
|
_err("Found unresolved reference to element '$name'") |
76
|
|
|
|
|
|
|
unless $element; |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
# replace the current element |
81
|
0
|
|
|
|
|
|
$ref->replace_with($element->copy_at_and_under); |
82
|
|
|
|
|
|
|
|
83
|
0
|
|
|
|
|
|
return; |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub complete_type { |
87
|
0
|
|
|
0
|
0
|
|
my ($self, $element) = @_; |
88
|
0
|
|
|
|
|
|
my $library = $self->{type_library}; |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
# handle any unresolved attribute types |
91
|
0
|
0
|
|
|
|
|
if ($element->{attr}) { |
92
|
0
|
|
|
|
|
|
$self->complete_attr_type($_) |
93
|
0
|
|
|
|
|
|
for (grep { $_->{unresolved_type} } (@{$element->{attr}})); |
|
0
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
# all done unless unresolved |
97
|
0
|
0
|
|
|
|
|
return unless $element->{unresolved_type}; |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
# get type data |
100
|
0
|
|
|
|
|
|
my $type_name = $element->{type_name}; |
101
|
0
|
|
|
|
|
|
my $type = $library->find(name => $type_name); |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
# isn't there? |
104
|
0
|
0
|
|
|
|
|
_err("Element '<$element->{name}>' has unrecognized type '$type_name'.") |
105
|
|
|
|
|
|
|
unless $type; |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
|
108
|
0
|
0
|
|
|
|
|
if ($type->isa('XML::Validator::Schema::ComplexTypeNode')) { |
|
|
0
|
|
|
|
|
|
109
|
|
|
|
|
|
|
# can't have daughters for this to work |
110
|
0
|
0
|
|
|
|
|
_err("Element '<$element->{name}>' is using a named complexType and has sub-elements of its own. That's not supported.") |
111
|
|
|
|
|
|
|
if $element->daughters; |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
# replace the current element with one based on the complex node |
114
|
0
|
|
|
|
|
|
my $new_node = $type->copy_at_and_under; |
115
|
0
|
|
|
|
|
|
$new_node->name($element->{name}); |
116
|
0
|
0
|
|
|
|
|
$new_node->{attr} = [ @{ $new_node->{attr} || [] }, |
|
0
|
0
|
|
|
|
|
|
117
|
0
|
|
|
|
|
|
@{ $element->{attr} || [] } ]; |
118
|
0
|
|
|
|
|
|
$element->replace_with($new_node); |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
} elsif ($type->isa('XML::Validator::Schema::SimpleType')) { |
122
|
0
|
|
|
|
|
|
$element->{type} = $type; |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
} else { |
125
|
0
|
|
|
|
|
|
croak("Library returned '$type'!"); |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
# fixed it |
129
|
0
|
|
|
|
|
|
delete $element->{unresolved_type}; |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
sub complete_attr_type { |
133
|
0
|
|
|
0
|
0
|
|
my ($self, $attr) = @_; |
134
|
|
|
|
|
|
|
|
135
|
0
|
|
|
|
|
|
my $type = $self->{type_library}->find(name => $attr->{type_name}); |
136
|
0
|
0
|
|
|
|
|
_err("Attribute '<$attr->{name}>' has unrecognized ". |
137
|
|
|
|
|
|
|
"type '$attr->{type_name}'.") |
138
|
|
|
|
|
|
|
unless $type; |
139
|
|
|
|
|
|
|
|
140
|
0
|
|
|
|
|
|
$attr->{type} = $type; |
141
|
0
|
|
|
|
|
|
delete $attr->{unresolved_type}; |
142
|
|
|
|
|
|
|
} |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
sub complete_attr_ref { |
145
|
0
|
|
|
0
|
0
|
|
my ($self, $ref) = @_; |
146
|
|
|
|
|
|
|
|
147
|
0
|
|
|
|
|
|
my $attr = $self->{attribute_library}->find(name => $ref->{name}); |
148
|
0
|
0
|
|
|
|
|
_err("Attribute reference '$ref->{name}' not found.") |
149
|
|
|
|
|
|
|
unless $attr; |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
# clone, keep use |
152
|
0
|
|
|
|
|
|
my $use = $ref->{required}; |
153
|
0
|
|
|
|
|
|
%$ref = %$attr; |
154
|
0
|
|
|
|
|
|
$ref->{required} = $use; |
155
|
|
|
|
|
|
|
|
156
|
0
|
|
|
|
|
|
return; |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
1; |