line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# Copyrights 2006-2019 by [Mark Overmeer ]. |
2
|
|
|
|
|
|
|
# For other contributors see ChangeLog. |
3
|
|
|
|
|
|
|
# See the manual pages for details on the licensing terms. |
4
|
|
|
|
|
|
|
# Pod stripped from pm file by OODoc 2.02. |
5
|
|
|
|
|
|
|
# This code is part of distribution XML-Compile. Meta-POD processed with |
6
|
|
|
|
|
|
|
# OODoc into POD and HTML manual-pages. See README.md |
7
|
|
|
|
|
|
|
# Copyright Mark Overmeer. Licensed under the same terms as Perl itself. |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
package XML::Compile::Translate::Template; |
10
|
11
|
|
|
11
|
|
1945
|
use vars '$VERSION'; |
|
11
|
|
|
|
|
19
|
|
|
11
|
|
|
|
|
615
|
|
11
|
|
|
|
|
|
|
$VERSION = '1.63'; |
12
|
|
|
|
|
|
|
|
13
|
11
|
|
|
11
|
|
60
|
use base 'XML::Compile::Translate'; |
|
11
|
|
|
|
|
18
|
|
|
11
|
|
|
|
|
1434
|
|
14
|
|
|
|
|
|
|
|
15
|
11
|
|
|
11
|
|
78
|
use strict; |
|
11
|
|
|
|
|
18
|
|
|
11
|
|
|
|
|
221
|
|
16
|
11
|
|
|
11
|
|
44
|
use warnings; |
|
11
|
|
|
|
|
18
|
|
|
11
|
|
|
|
|
328
|
|
17
|
11
|
|
|
11
|
|
48
|
no warnings 'once', 'recursion'; |
|
11
|
|
|
|
|
14
|
|
|
11
|
|
|
|
|
471
|
|
18
|
|
|
|
|
|
|
|
19
|
11
|
|
|
11
|
|
60
|
use Log::Report 'xml-compile'; |
|
11
|
|
|
|
|
17
|
|
|
11
|
|
|
|
|
70
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
use XML::Compile::Util |
22
|
11
|
|
|
11
|
|
3132
|
qw/odd_elements even_elements SCHEMA2001i pack_type unpack_type/; |
|
11
|
|
|
|
|
18
|
|
|
11
|
|
|
|
|
848
|
|
23
|
11
|
|
|
11
|
|
69
|
use List::Util qw/max first/; |
|
11
|
|
|
|
|
27
|
|
|
11
|
|
|
|
|
698
|
|
24
|
|
|
|
|
|
|
|
25
|
11
|
|
|
11
|
|
56
|
use vars '$VERSION'; # OODoc adds $VERSION to the script |
|
11
|
|
|
|
|
21
|
|
|
11
|
|
|
|
|
76091
|
|
26
|
|
|
|
|
|
|
$VERSION ||= 'undef'; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
sub makeTagQualified |
30
|
31
|
|
|
31
|
0
|
81
|
{ my ($self, $path, $node, $local, $ns) = @_; |
31
|
31
|
|
|
|
|
147
|
my $prefix = $self->_registerNSprefix('', $ns, 1); |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
# it is certainly not correct to do a keyRewrite here, but it works :( |
34
|
31
|
100
|
|
|
|
170
|
$self->{_output} eq 'PERL' ? $self->keyRewrite($ns, $local) |
|
|
100
|
|
|
|
|
|
35
|
|
|
|
|
|
|
: length $prefix ? "$prefix:$local" |
36
|
|
|
|
|
|
|
: $local; |
37
|
|
|
|
|
|
|
} |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
sub makeTagUnqualified |
40
|
95
|
|
|
95
|
0
|
163
|
{ my ($self, $path, $node, $local, $ns) = @_; |
41
|
|
|
|
|
|
|
# $name =~ s/.*\://; |
42
|
|
|
|
|
|
|
return $self->keyRewrite($ns, $local) |
43
|
95
|
100
|
|
|
|
276
|
if $self->{_output} eq 'PERL'; |
44
|
|
|
|
|
|
|
|
45
|
35
|
|
|
|
|
66
|
my $prefix = $self->_registerNSprefix('', $ns, 1); |
46
|
35
|
100
|
|
|
|
91
|
length $prefix ? "$prefix:$local" : $local; |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
# Detect recursion. Based on type is best, but some schema's do not |
50
|
|
|
|
|
|
|
# have named types, so tags are indexed as well. |
51
|
|
|
|
|
|
|
my (%recurse_type, %reuse_type, %recurse_tag, %reuse_tag); |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
sub compile($@) |
54
|
19
|
|
|
19
|
1
|
118
|
{ my ($self, $type, %args) = @_; |
55
|
19
|
|
|
|
|
43
|
$self->{_output} = $args{output}; |
56
|
19
|
|
50
|
|
|
82
|
$self->{_style} = $args{output_style} || 1; |
57
|
19
|
|
|
|
|
45
|
(%recurse_type, %reuse_type, %recurse_tag, %reuse_tag) = (); |
58
|
19
|
|
|
|
|
147
|
$self->SUPER::compile($type, %args); |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
sub actsAs($) |
62
|
213
|
|
|
213
|
0
|
307
|
{ my ($self, $as) = @_; |
63
|
|
|
|
|
|
|
($as eq 'READER' && $self->{_output} eq 'PERL') |
64
|
213
|
100
|
100
|
|
|
1354
|
|| ($as eq 'WRITER' && $self->{_output} eq 'XML') |
|
|
|
100
|
|
|
|
|
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
sub makeWrapperNs($$$$$) |
68
|
4
|
|
|
4
|
0
|
11
|
{ my ($self, $path, $processor, $index, $filter) = @_; |
69
|
|
|
|
|
|
|
|
70
|
4
|
|
|
|
|
5
|
my @entries; |
71
|
4
|
50
|
|
8
|
|
19
|
$filter = sub {1} if ref $filter ne 'CODE'; |
|
8
|
|
|
|
|
12
|
|
72
|
|
|
|
|
|
|
|
73
|
4
|
|
|
|
|
20
|
foreach my $entry (sort {$a->{prefix} cmp $b->{prefix}} values %$index) |
|
17
|
|
|
|
|
28
|
|
74
|
16
|
100
|
|
|
|
31
|
{ $entry->{used} or next; |
75
|
8
|
|
|
|
|
7
|
my ($prefix, $uri) = @{$entry}{'prefix', 'uri'}; |
|
8
|
|
|
|
|
17
|
|
76
|
8
|
50
|
|
|
|
12
|
$filter->($uri, $prefix) or next; |
77
|
8
|
|
|
|
|
14
|
push @entries, [ $uri, $prefix ]; |
78
|
8
|
|
|
|
|
12
|
$entry->{used} = 0; |
79
|
|
|
|
|
|
|
} |
80
|
|
|
|
|
|
|
|
81
|
4
|
50
|
|
4
|
|
9
|
sub { my $data = $processor->(@_) or return (); |
82
|
4
|
50
|
|
|
|
9
|
if($self->{include_namespaces}) |
83
|
4
|
|
|
|
|
23
|
{ $data->{"xmlns:$_->[1]"} = $_->[0] for @entries; |
84
|
|
|
|
|
|
|
} |
85
|
4
|
|
|
|
|
18
|
$data; |
86
|
4
|
|
|
|
|
40
|
}; |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
sub typemapToHooks($$) |
90
|
19
|
|
|
19
|
0
|
39
|
{ my ($self, $hooks, $typemap) = @_; |
91
|
|
|
|
|
|
|
|
92
|
19
|
|
|
|
|
77
|
while(my($type, $action) = each %$typemap) |
93
|
3
|
50
|
|
|
|
6
|
{ defined $action or next; |
94
|
|
|
|
|
|
|
|
95
|
3
|
100
|
|
|
|
19
|
my ($struct, $example) |
|
|
100
|
|
|
|
|
|
96
|
|
|
|
|
|
|
= $action =~ s/^[\\]?\&/\$/ |
97
|
|
|
|
|
|
|
? ( "call on converter function with object" |
98
|
|
|
|
|
|
|
, "$action->('WRITER', \$object, '$type', \$doc)") |
99
|
|
|
|
|
|
|
: $action =~ m/^\$/ |
100
|
|
|
|
|
|
|
? ( "call on converter with object" |
101
|
|
|
|
|
|
|
, "$action->toXML(\$object, '$type', \$doc)") |
102
|
|
|
|
|
|
|
: ( [ "calls toXML() on $action objects", " with $type and doc" ] |
103
|
|
|
|
|
|
|
, "bless({}, '$action')" ); |
104
|
|
|
|
|
|
|
|
105
|
3
|
|
|
|
|
8
|
my $details = |
106
|
|
|
|
|
|
|
{ struct => $struct |
107
|
|
|
|
|
|
|
, example => $example |
108
|
|
|
|
|
|
|
}; |
109
|
|
|
|
|
|
|
|
110
|
3
|
|
|
3
|
|
19
|
push @$hooks, { type => $type, replace => sub { $details} }; |
|
3
|
|
|
|
|
4
|
|
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
|
113
|
19
|
|
|
|
|
38
|
$hooks; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
sub makeElementWrapper |
117
|
19
|
|
|
19
|
0
|
42
|
{ my ($self, $path, $processor) = @_; |
118
|
19
|
|
|
19
|
|
68
|
sub { $processor->() }; |
|
19
|
|
|
|
|
37
|
|
119
|
|
|
|
|
|
|
} |
120
|
|
|
|
|
|
|
*makeAttributeWrapper = \&makeElementWrapper; |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
sub _block($@) |
123
|
45
|
|
|
45
|
|
107
|
{ my ($self, $block, $path, @pairs) = @_; |
124
|
|
|
|
|
|
|
bless |
125
|
40
|
|
|
40
|
|
98
|
sub { my @elems = map { $_->() } odd_elements @pairs; |
|
85
|
|
|
|
|
112
|
|
126
|
40
|
|
|
|
|
64
|
my @tags = map { $_->{tag} } @elems; |
|
85
|
|
|
|
|
126
|
|
127
|
|
|
|
|
|
|
|
128
|
40
|
|
|
|
|
57
|
local $" = ', '; |
129
|
40
|
50
|
|
|
|
172
|
my $struct = @tags ? "$block of @tags" |
130
|
|
|
|
|
|
|
: "empty $block from ".join(" ", even_elements @pairs); |
131
|
|
|
|
|
|
|
|
132
|
40
|
|
|
|
|
57
|
my @lines; |
133
|
40
|
|
|
|
|
107
|
while(length $struct > 65) |
134
|
0
|
|
|
|
|
0
|
{ $struct =~ s/(.{1,60}|\S+)(?:\s+|$)//; |
135
|
0
|
|
|
|
|
0
|
push @lines, $1; |
136
|
|
|
|
|
|
|
} |
137
|
40
|
50
|
|
|
|
123
|
push @lines, $struct |
138
|
|
|
|
|
|
|
if length $struct; |
139
|
40
|
|
|
|
|
93
|
$lines[$_] =~ s/^/ / for 1..$#lines; |
140
|
|
|
|
|
|
|
|
141
|
40
|
|
|
|
|
185
|
{ tag => $block |
142
|
|
|
|
|
|
|
, elems => \@elems |
143
|
|
|
|
|
|
|
, struct => \@lines |
144
|
|
|
|
|
|
|
}; |
145
|
45
|
|
|
|
|
351
|
}, 'BLOCK'; |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
|
148
|
39
|
|
|
39
|
0
|
51
|
sub makeSequence { my $self = shift; $self->_block(sequence => @_) } |
|
39
|
|
|
|
|
81
|
|
149
|
6
|
|
|
6
|
0
|
11
|
sub makeChoice { my $self = shift; $self->_block(choice => @_) } |
|
6
|
|
|
|
|
22
|
|
150
|
0
|
|
|
0
|
0
|
0
|
sub makeAll { my $self = shift; $self->_block(all => @_) } |
|
0
|
|
|
|
|
0
|
|
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
sub makeBlockHandler |
153
|
45
|
|
|
45
|
0
|
105
|
{ my ($self, $path, $label, $min, $max, $proc, $kind, $multi) = @_; |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
my $code = |
156
|
40
|
|
|
40
|
|
71
|
sub { my $data = $proc->(); |
157
|
40
|
100
|
66
|
|
|
357
|
my $occur |
|
|
50
|
66
|
|
|
|
|
|
|
50
|
66
|
|
|
|
|
158
|
|
|
|
|
|
|
= $max eq 'unbounded' && $min==0 ? 'occurs any number of times' |
159
|
|
|
|
|
|
|
: $max ne 'unbounded' && $max==1 && $min==0 ? 'is optional' |
160
|
|
|
|
|
|
|
: $max ne 'unbounded' && $max==1 && $min==1 ? '' # the usual case |
161
|
|
|
|
|
|
|
: "occurs $min <= # <= $max times"; |
162
|
|
|
|
|
|
|
|
163
|
40
|
100
|
33
|
|
|
87
|
$data->{occur} ||= $occur if $occur; |
164
|
40
|
100
|
100
|
|
|
124
|
if($max ne 'unbounded' && $max==1) |
165
|
35
|
|
|
|
|
61
|
{ bless $data, 'BLOCK'; |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
else |
168
|
5
|
|
|
|
|
8
|
{ $data->{tag} = $multi; |
169
|
5
|
|
|
|
|
8
|
$data->{is_array} = 1; |
170
|
5
|
|
|
|
|
16
|
bless $data, 'REP-BLOCK'; |
171
|
|
|
|
|
|
|
} |
172
|
40
|
|
|
|
|
82
|
$data; |
173
|
45
|
|
|
|
|
146
|
}; |
174
|
45
|
|
|
|
|
168
|
($label => $code); |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
sub makeElementHandler |
178
|
85
|
|
|
85
|
0
|
173
|
{ my ($self, $path, $label, $min, $max, $req, $opt) = @_; |
179
|
80
|
50
|
|
80
|
|
146
|
sub { my $data = $opt->() or return; |
180
|
80
|
100
|
100
|
|
|
551
|
my $occur |
|
|
100
|
100
|
|
|
|
|
|
|
100
|
66
|
|
|
|
|
181
|
|
|
|
|
|
|
= $max eq 'unbounded' && $min==0 ? 'occurs any number of times' |
182
|
|
|
|
|
|
|
: $max ne 'unbounded' && $max==1 && $min==0 ? 'is optional' |
183
|
|
|
|
|
|
|
: $max ne 'unbounded' && $max==1 && $min==1 ? '' # the usual case |
184
|
|
|
|
|
|
|
: "occurs $min <= # <= $max times"; |
185
|
80
|
100
|
33
|
|
|
179
|
$data->{occur} ||= $occur if $occur; |
186
|
80
|
|
100
|
|
|
255
|
$data->{is_array} = $max eq 'unbounded' || $max > 1; |
187
|
80
|
|
|
|
|
162
|
$data; |
188
|
85
|
|
|
|
|
647
|
}; |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
sub makeRequired |
192
|
78
|
|
|
78
|
0
|
139
|
{ my ($self, $path, $label, $do) = @_; |
193
|
78
|
|
|
|
|
110
|
$do; |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
sub makeElementHref |
197
|
0
|
|
|
0
|
0
|
0
|
{ my ($self, $path, $ns, $childname, $do) = @_; |
198
|
0
|
|
|
|
|
0
|
$do; |
199
|
|
|
|
|
|
|
} |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
sub makeElement |
202
|
99
|
|
|
99
|
0
|
185
|
{ my ($self, $path, $ns, $childname, $do) = @_; |
203
|
97
|
|
|
97
|
|
137
|
sub { my $h = $do->(@_); |
204
|
97
|
|
|
|
|
148
|
$h->{_NAME} = $childname; |
205
|
97
|
|
|
|
|
174
|
$h; |
206
|
99
|
|
|
|
|
336
|
}; |
207
|
|
|
|
|
|
|
} |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
sub makeElementDefault |
210
|
0
|
|
|
0
|
0
|
0
|
{ my ($self, $path, $ns, $childname, $do, $default) = @_; |
211
|
0
|
|
|
0
|
|
0
|
sub { my $h = $do->(@_); |
212
|
0
|
|
|
|
|
0
|
$h->{occur} = "defaults to '$default'"; |
213
|
0
|
|
|
|
|
0
|
$h->{example} = $default; |
214
|
0
|
|
|
|
|
0
|
$h; |
215
|
0
|
|
|
|
|
0
|
}; |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
sub makeElementFixed |
219
|
0
|
|
|
0
|
0
|
0
|
{ my ($self, $path, $ns, $childname, $do, $fixed) = @_; |
220
|
0
|
|
|
0
|
|
0
|
sub { my $h = $do->(@_); |
221
|
0
|
|
|
|
|
0
|
$h->{occur} = "fixed to '$fixed'"; |
222
|
0
|
|
|
|
|
0
|
$h->{example} = $fixed; |
223
|
0
|
|
|
|
|
0
|
$h; |
224
|
0
|
|
|
|
|
0
|
}; |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
sub makeElementAbstract |
228
|
2
|
|
|
2
|
0
|
6
|
{ my ($self, $path, $ns, $childname, $do) = @_; |
229
|
|
|
|
|
|
|
# sub { () }; |
230
|
|
|
|
|
|
|
sub { |
231
|
2
|
|
|
2
|
|
4
|
my $h = $do->(@_); |
232
|
2
|
|
|
|
|
4
|
$h->{_NAME} = $childname; |
233
|
2
|
|
|
|
|
4
|
$h->{occur} = "ABSTRACT"; |
234
|
2
|
|
|
|
|
3
|
$h; |
235
|
2
|
|
|
|
|
6
|
}; |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
sub makeComplexElement |
239
|
35
|
|
|
35
|
0
|
89
|
{ my ($self, $path, $tag, $elems, $attrs, $any_attr, $type, $is_nillable)=@_; |
240
|
35
|
|
|
|
|
131
|
my @elem_parts = odd_elements @$elems; |
241
|
35
|
|
|
|
|
68
|
my @attr_parts = (odd_elements(@$attrs), @$any_attr); |
242
|
|
|
|
|
|
|
|
243
|
30
|
|
|
30
|
|
37
|
sub { my (@attrs, @elems); |
244
|
30
|
|
|
|
|
84
|
my $is_pseudo_type = $type !~ m/^{/; # like "unnamed complex" |
245
|
|
|
|
|
|
|
|
246
|
30
|
50
|
66
|
|
|
159
|
if((!$is_pseudo_type && $recurse_type{$type}) || $recurse_tag{$tag}) |
|
|
|
33
|
|
|
|
|
247
|
|
|
|
|
|
|
{ return |
248
|
0
|
|
|
|
|
0
|
+{ kind => 'complex' |
249
|
|
|
|
|
|
|
, struct => 'probably a recursive complex' |
250
|
|
|
|
|
|
|
, tag => $tag |
251
|
|
|
|
|
|
|
, _TYPE => $type |
252
|
|
|
|
|
|
|
}; |
253
|
|
|
|
|
|
|
} |
254
|
|
|
|
|
|
|
|
255
|
30
|
50
|
66
|
|
|
123
|
if((!$is_pseudo_type && $reuse_type{$type}) || $reuse_tag{$tag}) |
|
|
|
33
|
|
|
|
|
256
|
|
|
|
|
|
|
{ return |
257
|
0
|
|
|
|
|
0
|
+{ kind => 'complex' |
258
|
|
|
|
|
|
|
, struct => 'complex structure shown above' |
259
|
|
|
|
|
|
|
, tag => $tag |
260
|
|
|
|
|
|
|
, _TYPE => $type |
261
|
|
|
|
|
|
|
}; |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
|
264
|
30
|
|
|
|
|
60
|
$recurse_type{$type}++; $recurse_tag{$tag}++; |
|
30
|
|
|
|
|
46
|
|
265
|
30
|
|
|
|
|
39
|
$reuse_type{$type}++; $reuse_tag{$tag}++; |
|
30
|
|
|
|
|
38
|
|
266
|
30
|
|
|
|
|
65
|
push @elems, $_->() for @elem_parts; |
267
|
30
|
|
|
|
|
52
|
push @attrs, $_->() for @attr_parts; |
268
|
|
|
|
|
|
|
|
269
|
30
|
|
|
|
|
64
|
$recurse_type{$type}--; $recurse_tag{$tag}--; |
|
30
|
|
|
|
|
55
|
|
270
|
|
|
|
|
|
|
|
271
|
30
|
100
|
|
|
|
144
|
+{ kind => 'complex' |
272
|
|
|
|
|
|
|
, struct => ($is_nillable ? "is nillable, as: $tag => NIL" : undef) |
273
|
|
|
|
|
|
|
, tag => $tag |
274
|
|
|
|
|
|
|
, attrs => \@attrs |
275
|
|
|
|
|
|
|
, elems => \@elems |
276
|
|
|
|
|
|
|
, _TYPE => $type |
277
|
|
|
|
|
|
|
}; |
278
|
35
|
|
|
|
|
181
|
}; |
279
|
|
|
|
|
|
|
} |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
sub makeTaggedElement |
282
|
1
|
|
|
1
|
0
|
4
|
{ my ($self, $path, $tag, $st, $attrs, $attrs_any, $type, $is_nillable) = @_; |
283
|
1
|
|
|
|
|
4
|
my @parts = (odd_elements(@$attrs), @$attrs_any); |
284
|
|
|
|
|
|
|
|
285
|
1
|
|
|
1
|
|
3
|
sub { my @attrs = map $_->(), @parts; |
286
|
1
|
|
|
|
|
3
|
my %simple = $st->(); |
287
|
|
|
|
|
|
|
|
288
|
1
|
|
|
|
|
3
|
my @struct = 'string content of the container'; |
289
|
1
|
50
|
|
|
|
3
|
push @struct, $simple{struct} if $simple{struct}; |
290
|
1
|
50
|
|
|
|
4
|
push @struct, 'is nillable, hence value or NIL' if $is_nillable; |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
my %content = |
293
|
|
|
|
|
|
|
( tag => '_' |
294
|
|
|
|
|
|
|
, struct => \@struct |
295
|
1
|
|
50
|
|
|
5
|
, example => ($simple{example} || 'Hello, World!') |
296
|
|
|
|
|
|
|
); |
297
|
1
|
50
|
|
|
|
3
|
$content{_TYPE} = $simple{_TYPE} if $simple{_TYPE}; |
298
|
|
|
|
|
|
|
|
299
|
1
|
|
|
|
|
7
|
+{ kind => 'tagged' |
300
|
|
|
|
|
|
|
, struct => "$tag is simple value with attributes" |
301
|
|
|
|
|
|
|
, tag => $tag |
302
|
|
|
|
|
|
|
, attrs => \@attrs |
303
|
|
|
|
|
|
|
, elems => [ \%content ] |
304
|
|
|
|
|
|
|
, _TYPE => $type |
305
|
|
|
|
|
|
|
}; |
306
|
1
|
|
|
|
|
6
|
}; |
307
|
|
|
|
|
|
|
} |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
sub makeMixedElement |
310
|
1
|
|
|
1
|
0
|
4
|
{ my ($self, $path, $tag, $elems, $attrs, $attrs_any, $type, $is_nillable)=@_; |
311
|
1
|
|
|
|
|
5
|
my @parts = (odd_elements(@$attrs), @$attrs_any); |
312
|
|
|
|
|
|
|
|
313
|
1
|
|
|
|
|
3
|
my @struct = 'mixed content cannot be processed automatically'; |
314
|
1
|
50
|
|
|
|
4
|
push @struct, 'is nillable' if $is_nillable; |
315
|
|
|
|
|
|
|
|
316
|
1
|
|
|
|
|
5
|
my %mixed = |
317
|
|
|
|
|
|
|
( tag => '_' |
318
|
|
|
|
|
|
|
, struct => \@struct |
319
|
|
|
|
|
|
|
, example => "XML::LibXML::Element->new('$tag')" |
320
|
|
|
|
|
|
|
); |
321
|
|
|
|
|
|
|
|
322
|
1
|
50
|
|
|
|
3
|
unless(@parts) # show simpler alternative |
323
|
0
|
|
|
|
|
0
|
{ $mixed{tag} = $tag; |
324
|
0
|
|
|
|
|
0
|
$mixed{type} = $type; |
325
|
0
|
|
|
0
|
|
0
|
return sub { \%mixed }; |
|
0
|
|
|
|
|
0
|
|
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
|
328
|
1
|
|
|
1
|
|
2
|
sub { my @attrs = map $_->(), @parts; |
329
|
1
|
|
|
|
|
6
|
+{ kind => 'mixed' |
330
|
|
|
|
|
|
|
, struct => "$tag has a mixed content" |
331
|
|
|
|
|
|
|
, tag => $tag |
332
|
|
|
|
|
|
|
, elems => [ \%mixed ] |
333
|
|
|
|
|
|
|
, attrs => \@attrs |
334
|
|
|
|
|
|
|
, _TYPE => $type |
335
|
|
|
|
|
|
|
}; |
336
|
1
|
|
|
|
|
5
|
}; |
337
|
|
|
|
|
|
|
} |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
sub makeSimpleElement |
340
|
64
|
|
|
64
|
0
|
147
|
{ my ($self, $path, $tag, $st, undef, undef, $type, $is_nillable) = @_; |
341
|
67
|
|
|
67
|
|
61
|
sub { my @struct; |
342
|
67
|
100
|
|
|
|
97
|
push @struct, 'is nillable, hence value or NIL' if $is_nillable; |
343
|
67
|
|
|
|
|
96
|
+{ kind => 'simple' |
344
|
|
|
|
|
|
|
, struct => \@struct |
345
|
|
|
|
|
|
|
, tag => $tag |
346
|
|
|
|
|
|
|
, $st->() |
347
|
|
|
|
|
|
|
}; |
348
|
64
|
|
|
|
|
241
|
}; |
349
|
|
|
|
|
|
|
} |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
sub makeBuiltin |
352
|
90
|
|
|
90
|
0
|
231
|
{ my ($self, $path, $node, $type, $def, $check_values) = @_; |
353
|
90
|
|
|
87
|
|
337
|
sub { (_TYPE=> $type, example => $def->{example}) }; |
|
87
|
|
|
|
|
358
|
|
354
|
|
|
|
|
|
|
} |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
sub makeList |
357
|
0
|
|
|
0
|
0
|
0
|
{ my ($self, $path, $st) = @_; |
358
|
0
|
|
|
0
|
|
0
|
sub { my %d = $st->(); |
359
|
0
|
|
|
|
|
0
|
$d{struct} = 'a list of values, where each'; |
360
|
0
|
|
|
|
|
0
|
my $example = $d{example}; |
361
|
0
|
0
|
|
|
|
0
|
if($self->{_output} eq 'PERL') |
362
|
0
|
0
|
|
|
|
0
|
{ $example = qq("$example") if $example =~ m/[^0-9.]/; |
363
|
0
|
|
|
|
|
0
|
$d{example} = "[ $example , ... ]"; |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
else |
366
|
0
|
|
|
|
|
0
|
{ $d{example} = "$example $example ..."; |
367
|
|
|
|
|
|
|
} |
368
|
0
|
|
|
|
|
0
|
%d }; |
|
0
|
|
|
|
|
0
|
|
369
|
|
|
|
|
|
|
} |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
sub makeFacetsList |
372
|
0
|
|
|
0
|
0
|
0
|
{ my ($self, $path, $st, $info) = @_; |
373
|
0
|
|
|
|
|
0
|
$self->makeFacets($path, $st, $info); |
374
|
|
|
|
|
|
|
} |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
sub _ff($@) |
377
|
0
|
|
|
0
|
|
0
|
{ my ($self,$type) = (shift, shift); |
378
|
0
|
|
|
|
|
0
|
my @lines = $type.':'; |
379
|
0
|
|
|
|
|
0
|
while(@_) |
380
|
0
|
|
|
|
|
0
|
{ my $facet = shift; |
381
|
0
|
|
|
|
|
0
|
$facet =~ s/\t/\t/g; |
382
|
0
|
0
|
|
|
|
0
|
$facet = qq{"$facet"} if $facet =~ m/\s/; |
383
|
0
|
0
|
|
|
|
0
|
push @lines, ' ' if length($lines[-1]) + length($facet) > 55; |
384
|
0
|
|
|
|
|
0
|
$lines[-1] .= ' '.$facet; |
385
|
|
|
|
|
|
|
} |
386
|
0
|
|
|
|
|
0
|
@lines; |
387
|
|
|
|
|
|
|
} |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
sub makeFacets |
390
|
6
|
|
|
6
|
0
|
15
|
{ my ($self, $path, $st, $info) = @_; |
391
|
6
|
|
|
|
|
10
|
my @comment; |
392
|
6
|
|
|
|
|
36
|
foreach my $k (sort keys %$info) |
393
|
12
|
|
|
|
|
24
|
{ my $v = $info->{$k}; |
394
|
12
|
0
|
|
|
|
81
|
push @comment |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
395
|
|
|
|
|
|
|
, $k eq 'enumeration' ? $self->_ff('Enum', sort @$v) |
396
|
|
|
|
|
|
|
: $k eq 'pattern' ? $self->_ff('Pattern', @$v) |
397
|
|
|
|
|
|
|
: $k eq 'length' ? "fixed length of $v" |
398
|
|
|
|
|
|
|
: $k eq 'maxLength' ? "length <= $v" |
399
|
|
|
|
|
|
|
: $k eq 'minLength' ? "length >= $v" |
400
|
|
|
|
|
|
|
: $k eq 'totalDigits' ? "total digits is $v" |
401
|
|
|
|
|
|
|
: $k eq 'maxScale' ? "scale <= $v" |
402
|
|
|
|
|
|
|
: $k eq 'minScale' ? "scale >= $v" |
403
|
|
|
|
|
|
|
: $k eq 'maxInclusive' ? "value <= $v" |
404
|
|
|
|
|
|
|
: $k eq 'maxExclusive' ? "value < $v" |
405
|
|
|
|
|
|
|
: $k eq 'minInclusive' ? "value >= $v" |
406
|
|
|
|
|
|
|
: $k eq 'minExclusive' ? "value > $v" |
407
|
|
|
|
|
|
|
: $k eq 'fractionDigits' ? "faction digits is $v" |
408
|
|
|
|
|
|
|
: $k eq 'whiteSpace' ? "white-space $v" |
409
|
|
|
|
|
|
|
: "restriction? $k = $v"; |
410
|
|
|
|
|
|
|
} |
411
|
|
|
|
|
|
|
|
412
|
6
|
|
|
|
|
17
|
my %facet = (facets => \@comment, $st->()); |
413
|
|
|
|
|
|
|
|
414
|
6
|
50
|
|
|
|
23
|
if(my $enum = $info->{enumeration}) |
415
|
0
|
|
|
|
|
0
|
{ $facet{example} = $enum->[0]; |
416
|
|
|
|
|
|
|
} |
417
|
|
|
|
|
|
|
|
418
|
6
|
|
|
10
|
|
38
|
sub { %facet }; |
|
10
|
|
|
|
|
50
|
|
419
|
|
|
|
|
|
|
} |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
sub makeUnion |
422
|
0
|
|
|
0
|
0
|
0
|
{ my ($self, $path, @types) = @_; |
423
|
0
|
|
|
0
|
|
0
|
sub { my @choices = map { +{$_->()} } @types; |
|
0
|
|
|
|
|
0
|
|
424
|
|
|
|
|
|
|
+( kind => 'union' |
425
|
|
|
|
|
|
|
, struct => "one of the following (union)" |
426
|
|
|
|
|
|
|
, choice => \@choices |
427
|
|
|
|
|
|
|
, example => $choices[0]->{example} |
428
|
0
|
|
|
|
|
0
|
); |
429
|
0
|
|
|
|
|
0
|
}; |
430
|
|
|
|
|
|
|
} |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
sub makeAttributeRequired |
433
|
6
|
|
|
6
|
0
|
16
|
{ my ($self, $path, $ns, $tag, $label, $do) = @_; |
434
|
|
|
|
|
|
|
|
435
|
6
|
|
|
6
|
|
25
|
sub { +{ kind => 'attr' |
436
|
|
|
|
|
|
|
, tag => $label |
437
|
|
|
|
|
|
|
, occur => "attribute $tag is required" |
438
|
|
|
|
|
|
|
, $do->() |
439
|
|
|
|
|
|
|
}; |
440
|
6
|
|
|
|
|
26
|
}; |
441
|
|
|
|
|
|
|
} |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
sub makeAttributeProhibited |
444
|
0
|
|
|
0
|
0
|
0
|
{ my ($self, $path, $ns, $tag, $label, $do) = @_; |
445
|
0
|
|
|
|
|
0
|
(); |
446
|
|
|
|
|
|
|
} |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
sub makeAttribute |
449
|
19
|
|
|
19
|
0
|
38
|
{ my ($self, $path, $ns, $tag, $label, $do) = @_; |
450
|
17
|
|
|
17
|
|
27
|
sub { +{ kind => 'attr' |
451
|
|
|
|
|
|
|
, tag => $tag |
452
|
|
|
|
|
|
|
, occur => "becomes an attribute" |
453
|
|
|
|
|
|
|
, $do->() |
454
|
|
|
|
|
|
|
}; |
455
|
19
|
|
|
|
|
69
|
}; |
456
|
|
|
|
|
|
|
} |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
sub makeAttributeDefault |
459
|
0
|
|
|
0
|
0
|
0
|
{ my ($self, $path, $ns, $tag, $label, $do) = @_; |
460
|
|
|
|
|
|
|
sub { |
461
|
0
|
|
|
0
|
|
0
|
+{ kind => 'attr' |
462
|
|
|
|
|
|
|
, tag => $tag |
463
|
|
|
|
|
|
|
, occur => "attribute $tag has default" |
464
|
|
|
|
|
|
|
, $do->() |
465
|
|
|
|
|
|
|
}; |
466
|
0
|
|
|
|
|
0
|
}; |
467
|
|
|
|
|
|
|
} |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
sub makeAttributeFixed |
470
|
0
|
|
|
0
|
0
|
0
|
{ my ($self, $path, $ns, $tag, $label, $do, $fixed) = @_; |
471
|
0
|
|
|
|
|
0
|
my $value = $fixed->value; |
472
|
|
|
|
|
|
|
|
473
|
0
|
|
|
0
|
|
0
|
sub { +{ kind => 'attr' |
474
|
|
|
|
|
|
|
, tag => $tag |
475
|
|
|
|
|
|
|
, occur => "attribute $tag is fixed" |
476
|
|
|
|
|
|
|
, example => $value |
477
|
|
|
|
|
|
|
}; |
478
|
0
|
|
|
|
|
0
|
}; |
479
|
|
|
|
|
|
|
} |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
sub makeSubstgroup |
482
|
2
|
|
|
2
|
0
|
7
|
{ my ($self, $path, $type, @todo) = @_; |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
sub { |
485
|
2
|
|
|
2
|
|
4
|
my (@example_tags, $example_nest, %tags); |
486
|
2
|
|
|
|
|
4
|
my @do = @todo; |
487
|
2
|
|
|
|
|
4
|
my $group = $do[1][0]; |
488
|
|
|
|
|
|
|
|
489
|
2
|
|
|
|
|
6
|
while(@do) |
490
|
6
|
|
|
|
|
12
|
{ my ($type, $info) = (shift @do, shift @do); |
491
|
6
|
|
|
|
|
11
|
my ($label, $call) = @$info; |
492
|
6
|
|
|
|
|
10
|
my $processed = $call->(); |
493
|
6
|
|
|
|
|
7
|
my $show = ''; |
494
|
6
|
50
|
|
|
|
17
|
if($processed->{kind} eq 'substitution group') |
|
|
50
|
|
|
|
|
|
495
|
|
|
|
|
|
|
{ # substr extended by subst, which already is formatted. |
496
|
|
|
|
|
|
|
# need to extract only the indicated type info. |
497
|
0
|
|
0
|
|
|
0
|
my $s = $processed->{struct} || []; |
498
|
0
|
|
0
|
|
|
0
|
/^ $label (.*)/ and $show = $1 for @$s; |
499
|
|
|
|
|
|
|
} |
500
|
|
|
|
|
|
|
elsif(my $type = $processed->{_TYPE}) |
501
|
6
|
|
|
|
|
15
|
{ $show = $self->prefixed($type); |
502
|
|
|
|
|
|
|
} |
503
|
|
|
|
|
|
|
|
504
|
6
|
100
|
66
|
|
|
17
|
if($processed->{occur} && $processed->{occur} eq 'ABSTRACT') |
505
|
1
|
|
|
|
|
2
|
{ $show .= ' (abstract)'; |
506
|
|
|
|
|
|
|
} |
507
|
|
|
|
|
|
|
else |
508
|
|
|
|
|
|
|
{ # some complication to always produce the same tag for |
509
|
|
|
|
|
|
|
# regression tests... Instance uses a HASH... |
510
|
5
|
|
|
|
|
9
|
push @example_tags, $label; |
511
|
|
|
|
|
|
|
$example_nest ||= $processed->{kind} eq 'simple' |
512
|
5
|
100
|
50
|
|
|
30
|
? ($processed->{example} || '...') : '{...}'; |
|
|
|
66
|
|
|
|
|
513
|
|
|
|
|
|
|
} |
514
|
|
|
|
|
|
|
|
515
|
6
|
|
|
|
|
52
|
$tags{$label} = $show; |
516
|
|
|
|
|
|
|
} |
517
|
|
|
|
|
|
|
|
518
|
2
|
|
|
|
|
15
|
my $longest = max map length, keys %tags; |
519
|
2
|
|
|
|
|
32
|
my @lines = map sprintf(" %-${longest}s %s", $_, $tags{$_}), |
520
|
|
|
|
|
|
|
sort keys %tags; |
521
|
|
|
|
|
|
|
|
522
|
2
|
|
|
|
|
8
|
my $example_tag = (sort @example_tags)[0]; |
523
|
2
|
50
|
|
|
|
9
|
my $example = $example_tag ? "{ $example_tag => $example_nest }" |
524
|
|
|
|
|
|
|
: "undef # only abstract types known"; |
525
|
|
|
|
|
|
|
|
526
|
2
|
|
|
|
|
6
|
my $name = $self->prefixed($type); |
527
|
|
|
|
|
|
|
|
528
|
2
|
|
|
|
|
14
|
+{ kind => 'substitution group' |
529
|
|
|
|
|
|
|
, tag => $group |
530
|
|
|
|
|
|
|
, struct => [ "substitutionGroup $name", @lines ] |
531
|
|
|
|
|
|
|
, example => $example |
532
|
|
|
|
|
|
|
}; |
533
|
2
|
|
|
|
|
17
|
}; |
534
|
|
|
|
|
|
|
} |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
sub makeXsiTypeSwitch($$$$) |
537
|
1
|
|
|
1
|
0
|
4
|
{ my ($self, $where, $elem, $default_type, $types) = @_; |
538
|
1
|
|
|
|
|
8
|
my @types = map " ".$self->prefixed($_), sort keys %$types; |
539
|
1
|
|
|
|
|
3
|
my $deftype = $self->prefixed($default_type); |
540
|
|
|
|
|
|
|
|
541
|
1
|
|
|
1
|
|
7
|
sub { +{ kind => 'xsi:type switch' |
542
|
|
|
|
|
|
|
, tag => $elem |
543
|
|
|
|
|
|
|
, struct => [ 'xsi:type alternatives:', @types ] |
544
|
|
|
|
|
|
|
, example => "{ XSI_TYPE => '$deftype', %data }" |
545
|
|
|
|
|
|
|
} |
546
|
1
|
|
|
|
|
5
|
}; |
547
|
|
|
|
|
|
|
} |
548
|
|
|
|
|
|
|
|
549
|
|
|
|
|
|
|
sub makeAnyAttribute |
550
|
0
|
|
|
0
|
0
|
0
|
{ my ($self, $path, $handler, $yes, $no, $process) = @_; |
551
|
0
|
|
0
|
|
|
0
|
$yes ||= []; $no ||= []; |
|
0
|
|
0
|
|
|
0
|
|
552
|
0
|
0
|
|
|
|
0
|
$yes = [ map {$self->prefixed("{$_}") || $_} @$yes]; |
|
0
|
|
|
|
|
0
|
|
553
|
0
|
0
|
|
|
|
0
|
$no = [ map {$self->prefixed("{$_}") || $_} @$no]; |
|
0
|
|
|
|
|
0
|
|
554
|
0
|
0
|
|
|
|
0
|
my $occurs = @$yes ? "in @$yes" : @$no ? "not in @$no" : 'in any namespace'; |
|
|
0
|
|
|
|
|
|
555
|
0
|
|
|
0
|
|
0
|
bless sub { +{kind => 'attr' , struct => "any attribute $occurs" |
556
|
0
|
|
|
|
|
0
|
, tag => 'ANYATTR', example => 'AnySimple'} }, 'ANY'; |
557
|
|
|
|
|
|
|
} |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
sub makeAnyElement |
560
|
0
|
|
|
0
|
0
|
0
|
{ my ($self, $path, $handler, $yes, $no, $process, $min, $max) = @_; |
561
|
0
|
|
0
|
|
|
0
|
$yes ||= []; $no ||= []; |
|
0
|
|
0
|
|
|
0
|
|
562
|
0
|
0
|
|
|
|
0
|
$yes = [ map {$self->prefixed("{$_}") || $_} @$yes]; |
|
0
|
|
|
|
|
0
|
|
563
|
0
|
0
|
|
|
|
0
|
$no = [ map {$self->prefixed("{$_}") || $_} @$no]; |
|
0
|
|
|
|
|
0
|
|
564
|
0
|
0
|
|
|
|
0
|
my $where = @$yes ? "in @$yes" : @$no ? "not in @$no" : 'in any namespace'; |
|
|
0
|
|
|
|
|
|
565
|
|
|
|
|
|
|
|
566
|
0
|
|
|
|
|
0
|
my $data = +{ kind => 'element', struct => "any element $where" |
567
|
|
|
|
|
|
|
, tag => "ANY", example => 'Anything' }; |
568
|
0
|
0
|
0
|
|
|
0
|
my $occur |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
569
|
|
|
|
|
|
|
= $max eq 'unbounded' && $min==0 ? 'occurs any number of times' |
570
|
|
|
|
|
|
|
: $max ne 'unbounded' && $max==1 && $min==0 ? 'is optional' |
571
|
|
|
|
|
|
|
: $max ne 'unbounded' && $max==1 && $min==1 ? '' # the usual case |
572
|
|
|
|
|
|
|
: "occurs $min <= # <= $max times"; |
573
|
0
|
0
|
0
|
|
|
0
|
$data->{occur} ||= $occur if $occur; |
574
|
0
|
|
0
|
|
|
0
|
$data->{is_array} = $max eq 'unbounded' || $max > 1; |
575
|
|
|
|
|
|
|
|
576
|
0
|
|
|
0
|
|
0
|
bless sub { +$data }, 'ANY'; |
|
0
|
|
|
|
|
0
|
|
577
|
|
|
|
|
|
|
} |
578
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
sub makeHook($$$$$$$) |
580
|
3
|
|
|
3
|
0
|
9
|
{ my ($self, $path, $r, $tag, $before, $replace, $after, $fulltype) = @_; |
581
|
|
|
|
|
|
|
|
582
|
3
|
50
|
33
|
|
|
10
|
return $r unless $before || $replace || $after; |
|
|
|
33
|
|
|
|
|
583
|
|
|
|
|
|
|
|
584
|
3
|
50
|
33
|
|
|
12
|
error __x"template only supports one production (replace) hook" |
585
|
|
|
|
|
|
|
if $replace && @$replace > 1; |
586
|
|
|
|
|
|
|
|
587
|
3
|
50
|
33
|
0
|
|
7
|
return sub {()} if $replace && grep {$_ eq 'SKIP'} @$replace; |
|
0
|
|
|
|
|
0
|
|
|
3
|
|
|
|
|
12
|
|
588
|
|
|
|
|
|
|
|
589
|
3
|
50
|
|
|
|
9
|
my @replace = $replace ? map {$self->_decodeReplace($path,$_)} @$replace:(); |
|
3
|
|
|
|
|
7
|
|
590
|
3
|
50
|
|
|
|
6
|
my @before = $before ? map {$self->_decodeBefore($path,$_) } @$before :(); |
|
0
|
|
|
|
|
0
|
|
591
|
3
|
50
|
|
|
|
5
|
my @after = $after ? map {$self->_decodeAfter($path,$_) } @$after :(); |
|
0
|
|
|
|
|
0
|
|
592
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
sub |
594
|
3
|
|
|
3
|
|
15
|
{ my $doc = XML::LibXML::Document->new; |
595
|
3
|
0
|
|
|
|
6
|
for(@before) { $_->($doc, $path, undef) or return } |
|
0
|
|
|
|
|
0
|
|
596
|
|
|
|
|
|
|
|
597
|
3
|
50
|
|
|
|
10
|
my $xml = @replace ? $replace[0]->($doc, $path, $r) : $r->(); |
598
|
3
|
50
|
|
|
|
6
|
defined $xml or return (); |
599
|
|
|
|
|
|
|
|
600
|
3
|
0
|
|
|
|
5
|
for(@after) { $xml = $_->($doc, $path, $xml) or return } |
|
0
|
|
|
|
|
0
|
|
601
|
3
|
|
|
|
|
11
|
$xml; |
602
|
|
|
|
|
|
|
} |
603
|
3
|
|
|
|
|
13
|
} |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
sub _decodeBefore($$) |
606
|
0
|
|
|
0
|
|
0
|
{ my ($self, $path, $call) = @_; |
607
|
0
|
0
|
|
|
|
0
|
return $call if ref $call eq 'CODE'; |
608
|
0
|
|
|
|
|
0
|
error __x"labeled before hook `{name}' undefined", name => $call; |
609
|
|
|
|
|
|
|
} |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
sub _decodeReplace($$) |
612
|
3
|
|
|
3
|
|
5
|
{ my ($self, $path, $call) = @_; |
613
|
3
|
50
|
|
|
|
12
|
return $call if ref $call eq 'CODE'; |
614
|
|
|
|
|
|
|
|
615
|
0
|
0
|
|
|
|
0
|
if($call eq 'COLLAPSE') |
616
|
|
|
|
|
|
|
{ return sub |
617
|
0
|
|
|
0
|
|
0
|
{ my ($tag, $path, $do) = @_; |
618
|
0
|
|
|
|
|
0
|
my $h = $do->(); |
619
|
0
|
|
|
|
|
0
|
$h->{elems} = [ { struct => [ 'content collapsed' ] |
620
|
|
|
|
|
|
|
, kind => 'collapsed' } ]; |
621
|
0
|
|
|
|
|
0
|
delete $h->{attrs}; |
622
|
0
|
|
|
|
|
0
|
$h; |
623
|
0
|
|
|
|
|
0
|
}; |
624
|
|
|
|
|
|
|
} |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
# SKIP already handled |
627
|
0
|
|
|
|
|
0
|
error __x"labeled replace hook `{name}' undefined", name => $call; |
628
|
|
|
|
|
|
|
} |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
sub _decodeAfter($$) |
631
|
0
|
|
|
0
|
|
0
|
{ my ($self, $path, $call) = @_; |
632
|
0
|
0
|
|
|
|
0
|
return $call if ref $call eq 'CODE'; |
633
|
0
|
|
|
|
|
0
|
error __x"labeled after hook `{name}' undefined", name => $call; |
634
|
|
|
|
|
|
|
} |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
### |
638
|
|
|
|
|
|
|
### toPerl |
639
|
|
|
|
|
|
|
### |
640
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
sub toPerl($%) |
642
|
16
|
|
|
16
|
0
|
78
|
{ my ($self, $ast, %args) = @_; |
643
|
16
|
50
|
|
|
|
52
|
$ast or return undef; |
644
|
|
|
|
|
|
|
|
645
|
16
|
|
|
|
|
21
|
my @lines; |
646
|
16
|
100
|
|
|
|
42
|
if($ast->{kind}) |
647
|
13
|
|
33
|
|
|
32
|
{ my $name = $ast->{_NAME} || $ast->{tag}; |
648
|
13
|
|
|
|
|
47
|
my $pref = $self->prefixed($name); |
649
|
13
|
50
|
|
|
|
63
|
push @lines, defined $pref |
650
|
|
|
|
|
|
|
? ("# Describing $ast->{kind} $pref", "# $name") |
651
|
|
|
|
|
|
|
: "# Describing $ast->{kind} $name"; |
652
|
|
|
|
|
|
|
} |
653
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
push @lines |
655
|
|
|
|
|
|
|
, "#" |
656
|
|
|
|
|
|
|
, "# Produced by ".__PACKAGE__." version $VERSION" |
657
|
|
|
|
|
|
|
, "# on ".localtime() |
658
|
|
|
|
|
|
|
, "#" |
659
|
|
|
|
|
|
|
, "# BE WARNED: in most cases, the example below cannot be used without" |
660
|
|
|
|
|
|
|
, "# interpretation. The comments will guide you." |
661
|
|
|
|
|
|
|
, "#" |
662
|
16
|
50
|
|
|
|
54
|
unless $args{skip_header}; |
663
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
# add info about name-spaces |
665
|
16
|
|
|
|
|
118
|
foreach my $nsdecl (grep /^xmlns\:/, sort keys %$ast) |
666
|
1
|
|
50
|
|
|
8
|
{ push @lines, sprintf "# %-15s %s", $nsdecl, $ast->{$nsdecl} || '(none)'; |
667
|
|
|
|
|
|
|
} |
668
|
16
|
100
|
|
|
|
58
|
push @lines, '' if @lines; |
669
|
|
|
|
|
|
|
|
670
|
|
|
|
|
|
|
# produce data tree |
671
|
16
|
|
|
|
|
48
|
push @lines, $self->_perlAny($ast, \%args); |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
# remove leading 'type =>' |
674
|
16
|
|
|
|
|
70
|
for(my $linenr = 0; $linenr < @lines; $linenr++) |
675
|
73
|
100
|
|
|
|
227
|
{ next if $lines[$linenr] =~ m/^\s*\#/; |
676
|
29
|
100
|
|
|
|
113
|
next unless $lines[$linenr] =~ s/.*? \=\>\s*//; |
677
|
16
|
100
|
|
|
|
53
|
$lines[$linenr] =~ m/\S/ or splice @lines, $linenr, 1; |
678
|
16
|
|
|
|
|
27
|
last; |
679
|
|
|
|
|
|
|
} |
680
|
|
|
|
|
|
|
|
681
|
16
|
|
|
|
|
82
|
my $lines = join "\n", @lines; |
682
|
16
|
|
|
|
|
846
|
$lines =~ s/\,?\s*$/\n/; |
683
|
16
|
|
|
|
|
971
|
$lines; |
684
|
|
|
|
|
|
|
} |
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
my %seen; |
687
|
|
|
|
|
|
|
sub _perlAny($$); |
688
|
|
|
|
|
|
|
sub _perlAny($$) |
689
|
105
|
|
|
105
|
|
152
|
{ my ($self, $ast, $args) = @_; |
690
|
|
|
|
|
|
|
|
691
|
105
|
|
|
|
|
110
|
my ($pref, @lines); |
692
|
105
|
100
|
100
|
|
|
270
|
if($ast->{_TYPE} && $args->{show_type}) |
693
|
54
|
50
|
|
|
|
128
|
{ if($pref = $self->prefixed($ast->{_TYPE})) |
694
|
54
|
100
|
66
|
|
|
253
|
{ push @lines # not perfect, but a good attempt |
695
|
|
|
|
|
|
|
, $pref =~ m/^[aiou]/i && $pref !~ m/^(uni|eu)/i |
696
|
|
|
|
|
|
|
? "# is an $pref" : "# is a $pref"; |
697
|
|
|
|
|
|
|
} |
698
|
|
|
|
|
|
|
} |
699
|
|
|
|
|
|
|
|
700
|
105
|
100
|
100
|
|
|
264
|
if($ast->{struct} && $args->{show_struct}) |
701
|
56
|
|
|
|
|
67
|
{ my $struct = $ast->{struct}; |
702
|
56
|
100
|
|
|
|
145
|
my @struct = ref $struct ? @$struct : $struct; |
703
|
56
|
|
|
|
|
216
|
s/^/# /gm for @struct; |
704
|
56
|
|
|
|
|
91
|
push @lines, @struct; |
705
|
|
|
|
|
|
|
} |
706
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
push @lines, "# $ast->{occur}" |
708
|
105
|
100
|
100
|
|
|
234
|
if $ast->{occur} && $args->{show_occur}; |
709
|
|
|
|
|
|
|
|
710
|
105
|
100
|
100
|
|
|
172
|
if($ast->{facets} && $args->{show_facets}) |
711
|
3
|
|
|
|
|
4
|
{ my $facets = $ast->{facets}; |
712
|
3
|
50
|
|
|
|
9
|
my @facets = ref $facets ? @$facets : $facets; |
713
|
3
|
|
|
|
|
17
|
s/^/# /gm for @facets; |
714
|
3
|
|
|
|
|
5
|
push @lines, @facets; |
715
|
|
|
|
|
|
|
} |
716
|
|
|
|
|
|
|
|
717
|
105
|
|
|
|
|
102
|
my @childs; |
718
|
105
|
100
|
|
|
|
172
|
push @childs, @{$ast->{attrs}} if $ast->{attrs}; |
|
21
|
|
|
|
|
33
|
|
719
|
105
|
100
|
|
|
|
154
|
push @childs, @{$ast->{elems}} if $ast->{elems}; |
|
46
|
|
|
|
|
76
|
|
720
|
105
|
50
|
|
|
|
155
|
push @childs, $ast->{body} if $ast->{body}; |
721
|
|
|
|
|
|
|
|
722
|
105
|
|
|
|
|
100
|
my @subs; |
723
|
105
|
|
|
|
|
131
|
foreach my $child (@childs) |
724
|
89
|
|
|
|
|
398
|
{ my @sub = $self->_perlAny($child, $args); |
725
|
89
|
50
|
|
|
|
163
|
@sub or next; |
726
|
|
|
|
|
|
|
|
727
|
|
|
|
|
|
|
# last line is code and gets comma |
728
|
89
|
50
|
|
|
|
545
|
$sub[-1] =~ s/\,?\s*$/,/ |
729
|
|
|
|
|
|
|
if $sub[-1] !~ m/\#\s/; |
730
|
|
|
|
|
|
|
|
731
|
89
|
100
|
|
|
|
197
|
if(ref $ast ne 'BLOCK') |
732
|
46
|
|
|
|
|
637
|
{ s/^(.)/$args->{indent}$1/ for @sub; |
733
|
|
|
|
|
|
|
} |
734
|
|
|
|
|
|
|
|
735
|
|
|
|
|
|
|
# seperator blank, sometimes |
736
|
89
|
100
|
100
|
|
|
343
|
unshift @sub, '' |
|
|
|
100
|
|
|
|
|
737
|
|
|
|
|
|
|
if $sub[0] =~ m/^\s*[#{]/ # } |
738
|
|
|
|
|
|
|
|| (@subs && $subs[-1] =~ m/[}\]]\,\s*$/); |
739
|
|
|
|
|
|
|
|
740
|
89
|
|
|
|
|
296
|
push @subs, @sub; |
741
|
|
|
|
|
|
|
} |
742
|
|
|
|
|
|
|
|
743
|
105
|
100
|
|
|
|
206
|
if(ref $ast eq 'REP-BLOCK') |
744
|
|
|
|
|
|
|
{ # repeated block |
745
|
3
|
50
|
|
|
|
8
|
@subs or @subs = ''; |
746
|
3
|
100
|
|
|
|
13
|
$subs[0] =~ s/^ /{ / or $subs[0] =~ s/^\s*$/{/; |
747
|
3
|
50
|
|
|
|
12
|
if($subs[-1] =~ m/\#\s/) { push @subs, "}," } |
|
0
|
|
|
|
|
0
|
|
748
|
3
|
|
|
|
|
11
|
else { $subs[-1] =~ s/$/ },/ } |
749
|
|
|
|
|
|
|
} |
750
|
|
|
|
|
|
|
|
751
|
|
|
|
|
|
|
# XML does not permit difficult tags, but we still check. |
752
|
105
|
|
100
|
|
|
205
|
my $tag = $ast->{tag} || ''; |
753
|
105
|
100
|
66
|
|
|
477
|
if(defined $tag && $tag !~ m/^[\w_][\w\d_]*$/) |
754
|
3
|
|
|
|
|
4
|
{ $tag =~ s/\\/\\\\/g; |
755
|
3
|
|
|
|
|
5
|
$tag =~ s/'/\\'/g; |
756
|
3
|
|
|
|
|
3
|
$tag = qq{'$tag'}; |
757
|
|
|
|
|
|
|
} |
758
|
|
|
|
|
|
|
|
759
|
105
|
|
100
|
|
|
238
|
my $kind = $ast->{kind} || ''; |
760
|
105
|
100
|
33
|
|
|
522
|
if(ref $ast eq 'REP-BLOCK') |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
761
|
3
|
|
|
|
|
79
|
{ s/^(.)/ $1/ for @subs; |
762
|
3
|
|
|
|
|
11
|
$subs[0] =~ s/^ ?/[/; |
763
|
3
|
|
|
|
|
12
|
push @lines, "$tag => ", @subs , ']'; |
764
|
|
|
|
|
|
|
} |
765
|
|
|
|
|
|
|
elsif(ref $ast eq 'BLOCK') |
766
|
22
|
|
|
|
|
57
|
{ push @lines, @subs; |
767
|
|
|
|
|
|
|
} |
768
|
|
|
|
|
|
|
elsif(@subs) |
769
|
21
|
100
|
|
|
|
55
|
{ length $subs[0] or shift @subs; |
770
|
21
|
100
|
|
|
|
56
|
if($ast->{is_array}) |
771
|
3
|
|
|
|
|
58
|
{ s/^(.)/ $1/ for @subs; |
772
|
3
|
|
|
|
|
12
|
$subs[0] =~ s/^[ ]{0,3}/[ {/; |
773
|
3
|
50
|
33
|
|
|
18
|
if($subs[-1] =~ m/\#\s/ || $self->{_style}==2) |
774
|
0
|
|
|
|
|
0
|
{ push @subs, "}, ], " } |
775
|
3
|
|
|
|
|
8
|
else { $subs[-1] .= ' }, ], ' } |
776
|
3
|
|
|
|
|
13
|
push @lines, "$tag =>", @subs; |
777
|
|
|
|
|
|
|
} |
778
|
|
|
|
|
|
|
else |
779
|
18
|
|
|
|
|
77
|
{ $subs[0] =~ s/^ /{ /; |
780
|
18
|
50
|
|
|
|
79
|
if($self->{_style}==2) |
|
|
50
|
|
|
|
|
|
781
|
0
|
|
|
|
|
0
|
{ push @subs, "}, "; |
782
|
0
|
0
|
|
|
|
0
|
$subs[-1] .= "# $pref" if $pref; |
783
|
|
|
|
|
|
|
} |
784
|
0
|
|
|
|
|
0
|
elsif($subs[-1] =~ m/\#\s/) { push @subs, "}, " } |
785
|
18
|
|
|
|
|
48
|
else { $subs[-1] .= ' },' } |
786
|
18
|
|
|
|
|
117
|
push @lines, "$tag =>", @subs; |
787
|
|
|
|
|
|
|
} |
788
|
|
|
|
|
|
|
} |
789
|
|
|
|
|
|
|
elsif($kind eq 'complex' || $kind eq 'mixed') # empty complex-type |
790
|
|
|
|
|
|
|
{ # if there is an "occurs", then there can always be more than one |
791
|
0
|
0
|
|
|
|
0
|
push @lines, $tag.' => '.($ast->{occur} ? '[{},]' : '{}'); |
792
|
|
|
|
|
|
|
} |
793
|
|
|
|
|
|
|
elsif($kind eq 'collapsed') {;} |
794
|
|
|
|
|
|
|
elsif($kind eq 'union') # union type |
795
|
0
|
|
|
|
|
0
|
{ foreach my $union ( @{$ast->{choice}} ) |
|
0
|
|
|
|
|
0
|
|
796
|
|
|
|
|
|
|
{ # remove examples |
797
|
0
|
|
|
|
|
0
|
my @l = grep { m/^#/ } $self->_perlAny($union, $args); |
|
0
|
|
|
|
|
0
|
|
798
|
0
|
|
|
|
|
0
|
s/^\#/# -/ for $l[0]; |
799
|
0
|
|
|
|
|
0
|
s/^\#/# / for @l[1..$#l]; |
800
|
0
|
|
|
|
|
0
|
push @lines, @l; |
801
|
|
|
|
|
|
|
} |
802
|
|
|
|
|
|
|
} |
803
|
|
|
|
|
|
|
elsif(!exists $ast->{example}) |
804
|
0
|
|
|
|
|
0
|
{ push @lines, "$tag => 'TEMPLATE-ERROR $ast->{kind}'"; |
805
|
|
|
|
|
|
|
} |
806
|
|
|
|
|
|
|
|
807
|
105
|
|
|
|
|
162
|
my $example = $ast->{example}; |
808
|
105
|
100
|
|
|
|
159
|
if(defined $example) |
809
|
59
|
50
|
100
|
|
|
369
|
{ $example = qq{"$example"} # in quotes unless |
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
810
|
|
|
|
|
|
|
if $example !~ m/^[+-]?\d+(?:\.\d+)?$/ # numeric or |
811
|
|
|
|
|
|
|
&& $example !~ m/^\$/ # variable or |
812
|
|
|
|
|
|
|
&& $example !~ m/^bless\b/ # constructor or |
813
|
|
|
|
|
|
|
&& $example !~ m/^\$?[\w:]*\-\>/ # method call example |
814
|
|
|
|
|
|
|
&& $example !~ m/^\{.*\}$/ # anon HASH example |
815
|
|
|
|
|
|
|
&& $example !~ m/^\[.*\]$/; # anon ARRAY example |
816
|
|
|
|
|
|
|
|
817
|
|
|
|
|
|
|
push @lines, "$tag => " |
818
|
59
|
100
|
|
|
|
232
|
. ($ast->{is_array} ? "[ $example, ]" : $example); |
819
|
|
|
|
|
|
|
} |
820
|
105
|
|
|
|
|
516
|
@lines; |
821
|
|
|
|
|
|
|
} |
822
|
|
|
|
|
|
|
|
823
|
|
|
|
|
|
|
### |
824
|
|
|
|
|
|
|
### toXML |
825
|
|
|
|
|
|
|
### |
826
|
|
|
|
|
|
|
|
827
|
|
|
|
|
|
|
sub toXML($$%) |
828
|
2
|
|
|
2
|
0
|
11
|
{ my ($self, $doc, $ast, %args) = @_; |
829
|
2
|
|
|
|
|
12
|
my $xml = $self->_xmlAny($doc, $ast, "\n$args{indent}", \%args); |
830
|
|
|
|
|
|
|
|
831
|
2
|
50
|
|
|
|
100
|
UNIVERSAL::isa($xml, 'XML::LibXML::Element') |
832
|
|
|
|
|
|
|
or return $xml; |
833
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
# add comment |
835
|
2
|
|
|
|
|
3
|
my $pkg = __PACKAGE__; |
836
|
2
|
|
|
|
|
104
|
my $now = localtime(); |
837
|
|
|
|
|
|
|
|
838
|
2
|
|
|
|
|
22
|
my $header = $doc->createComment( <<_HEADER . ' ' ); |
839
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
BE WARNED: in most cases, the example below cannot be used without |
841
|
|
|
|
|
|
|
interpretation. The comments will guide you. |
842
|
|
|
|
|
|
|
Produced by $pkg version $VERSION |
843
|
|
|
|
|
|
|
on $now |
844
|
|
|
|
|
|
|
_HEADER |
845
|
|
|
|
|
|
|
|
846
|
2
|
50
|
|
|
|
15
|
unless($args{skip_header}) |
847
|
0
|
|
|
|
|
0
|
{ $xml->insertBefore($header, $xml->firstChild); |
848
|
0
|
|
|
|
|
0
|
$xml->insertBefore($doc->createTextNode("\n "), $header); |
849
|
|
|
|
|
|
|
} |
850
|
|
|
|
|
|
|
|
851
|
|
|
|
|
|
|
# I use xsi:type myself, too late for the usual "used" counter |
852
|
|
|
|
|
|
|
$ast->{'xmlns:xsi'} ||= SCHEMA2001i |
853
|
2
|
100
|
50
|
|
|
11
|
if $args{show_type}; |
854
|
|
|
|
|
|
|
|
855
|
|
|
|
|
|
|
# add info about name-spaces |
856
|
2
|
|
|
|
|
15
|
foreach (sort keys %$ast) |
857
|
20
|
100
|
|
|
|
83
|
{ if( m/^xmlns\:(.*)/ ) |
858
|
6
|
|
|
|
|
18
|
{ $xml->setNamespace($ast->{$_}, $1, 0); |
859
|
|
|
|
|
|
|
} |
860
|
|
|
|
|
|
|
} |
861
|
|
|
|
|
|
|
|
862
|
2
|
|
|
|
|
29
|
$xml; |
863
|
|
|
|
|
|
|
} |
864
|
|
|
|
|
|
|
|
865
|
|
|
|
|
|
|
sub _xmlAny($$$$); |
866
|
|
|
|
|
|
|
sub _xmlAny($$$$) |
867
|
42
|
|
|
42
|
|
68
|
{ my ($self, $doc, $ast, $indent, $args) = @_; |
868
|
42
|
|
|
|
|
41
|
my @res; |
869
|
|
|
|
|
|
|
my $xsi = $self->_registerNSprefix('xsi', SCHEMA2001i, 1) |
870
|
42
|
100
|
|
|
|
91
|
if $args->{show_type}; |
871
|
|
|
|
|
|
|
|
872
|
42
|
|
|
|
|
41
|
my @comment; |
873
|
42
|
100
|
100
|
|
|
96
|
if($ast->{struct} && $args->{show_struct}) |
874
|
17
|
|
|
|
|
20
|
{ my $struct = $ast->{struct}; |
875
|
17
|
50
|
|
|
|
34
|
push @comment, ref $struct ? @$struct : $struct; |
876
|
|
|
|
|
|
|
} |
877
|
|
|
|
|
|
|
|
878
|
|
|
|
|
|
|
push @comment, $ast->{occur} |
879
|
42
|
100
|
100
|
|
|
65
|
if $ast->{occur} && $args->{show_occur}; |
880
|
|
|
|
|
|
|
|
881
|
42
|
100
|
100
|
|
|
65
|
if($ast->{facets} && $args->{show_facets}) |
882
|
2
|
|
|
|
|
3
|
{ my $facets = $ast->{facets}; |
883
|
2
|
50
|
|
|
|
7
|
push @comment, ref $facets eq 'ARRAY' ? @$facets : $facets; |
884
|
|
|
|
|
|
|
} |
885
|
|
|
|
|
|
|
|
886
|
42
|
50
|
66
|
|
|
94
|
if(defined $ast->{kind} && $ast->{kind} eq 'union') |
887
|
0
|
|
|
|
|
0
|
{ push @comment, map " $_->{type}", @{$ast->{choice}}; |
|
0
|
|
|
|
|
0
|
|
888
|
|
|
|
|
|
|
} |
889
|
|
|
|
|
|
|
|
890
|
42
|
100
|
|
|
|
37
|
my @attrs = @{$ast->{attrs} || []}; |
|
42
|
|
|
|
|
92
|
|
891
|
42
|
|
|
|
|
63
|
foreach my $attr (@attrs) |
892
|
8
|
|
|
|
|
52
|
{ push @res, $doc->createAttribute($attr->{tag}, $attr->{example}); |
893
|
8
|
|
|
|
|
21
|
my ($ns, $local) = unpack_type $attr->{_TYPE}; |
894
|
8
|
|
|
|
|
18
|
my $prefix = $self->_registerNSprefix('', $ns, 1); |
895
|
|
|
|
|
|
|
push @comment, "attr $attr->{tag} has type $prefix:$local" |
896
|
8
|
100
|
|
|
|
25
|
if $args->{show_type}; |
897
|
|
|
|
|
|
|
} |
898
|
|
|
|
|
|
|
|
899
|
42
|
|
|
|
|
56
|
my $nest_indent = $indent.$args->{indent}; |
900
|
42
|
100
|
|
|
|
63
|
if(@comment) |
901
|
13
|
|
|
|
|
71
|
{ my $comment = ' '.join("$nest_indent ", @comment) .' '; |
902
|
13
|
|
|
|
|
88
|
push @res |
903
|
|
|
|
|
|
|
, $doc->createTextNode($indent) |
904
|
|
|
|
|
|
|
, $doc->createComment($comment); |
905
|
|
|
|
|
|
|
} |
906
|
|
|
|
|
|
|
|
907
|
42
|
100
|
|
|
|
45
|
my @elems = @{$ast->{elems} || []}; |
|
42
|
|
|
|
|
102
|
|
908
|
42
|
|
|
|
|
52
|
foreach my $elem (@elems) |
909
|
40
|
100
|
100
|
|
|
135
|
{ if(ref $elem eq 'BLOCK' || ref $elem eq 'REP-BLOCK') |
|
|
50
|
|
|
|
|
|
910
|
12
|
|
|
|
|
44
|
{ push @res, $self->_xmlAny($doc, $elem, $indent, $args); |
911
|
|
|
|
|
|
|
} |
912
|
|
|
|
|
|
|
elsif($elem->{tag} eq '_') |
913
|
0
|
|
|
|
|
0
|
{ push @res, $doc->createTextNode($indent.$elem->{example}); |
914
|
|
|
|
|
|
|
} |
915
|
|
|
|
|
|
|
else |
916
|
28
|
|
|
|
|
66
|
{ my $node = $self->_xmlAny($doc, $elem, $nest_indent, $args); |
917
|
28
|
50
|
|
|
|
210
|
push @res, $doc->createTextNode($indent) |
918
|
|
|
|
|
|
|
if $node->isa('XML::LibXML::Element'); |
919
|
28
|
|
|
|
|
48
|
push @res, $node; |
920
|
|
|
|
|
|
|
} |
921
|
|
|
|
|
|
|
} |
922
|
|
|
|
|
|
|
|
923
|
42
|
|
|
|
|
191
|
(my $outdent = $indent) =~ s/$args->{indent}$//; # sorry |
924
|
|
|
|
|
|
|
|
925
|
42
|
100
|
|
|
|
83
|
if(my $example = $ast->{example}) |
926
|
22
|
100
|
|
|
|
132
|
{ push @res, $doc->createTextNode |
927
|
|
|
|
|
|
|
(@comment ? "$indent$example$outdent" : $example) |
928
|
|
|
|
|
|
|
} |
929
|
|
|
|
|
|
|
|
930
|
42
|
100
|
100
|
|
|
93
|
if($ast->{_TYPE} && $args->{show_type}) |
931
|
15
|
|
|
|
|
38
|
{ my $pref = $self->prefixed($ast->{_TYPE}); |
932
|
15
|
|
|
|
|
153
|
push @res, $doc->createAttribute("$xsi:type" => $pref); |
933
|
|
|
|
|
|
|
} |
934
|
|
|
|
|
|
|
|
935
|
|
|
|
|
|
|
return @res |
936
|
42
|
100
|
|
|
|
99
|
if wantarray; |
937
|
|
|
|
|
|
|
|
938
|
30
|
|
|
|
|
99
|
my $node = $doc->createElement($ast->{tag}); |
939
|
30
|
|
|
|
|
243
|
$node->addChild($_) for @res; |
940
|
30
|
100
|
|
|
|
364
|
$node->appendText($outdent) if @elems; |
941
|
30
|
|
|
|
|
89
|
$node; |
942
|
|
|
|
|
|
|
} |
943
|
|
|
|
|
|
|
|
944
|
|
|
|
|
|
|
sub makeBlocked($$$) |
945
|
0
|
|
|
0
|
0
|
|
{ my ($self, $where, $class, $type) = @_; |
946
|
0
|
|
|
|
|
|
panic "namespace blocking not yet supported for Templates"; |
947
|
|
|
|
|
|
|
} |
948
|
|
|
|
|
|
|
|
949
|
|
|
|
|
|
|
|
950
|
|
|
|
|
|
|
1; |