line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
7
|
|
|
7
|
|
3278
|
use 5.008001; use strict; use warnings; |
|
7
|
|
|
7
|
|
51
|
|
|
7
|
|
|
7
|
|
29
|
|
|
7
|
|
|
|
|
10
|
|
|
7
|
|
|
|
|
109
|
|
|
7
|
|
|
|
|
43
|
|
|
7
|
|
|
|
|
11
|
|
|
7
|
|
|
|
|
275
|
|
2
|
|
|
|
|
|
|
|
3
|
7
|
|
|
7
|
|
49
|
use Scalar::Util (); |
|
7
|
|
|
|
|
24
|
|
|
7
|
|
|
|
|
107
|
|
4
|
7
|
|
|
7
|
|
3573
|
use Encode (); |
|
7
|
|
|
|
|
66187
|
|
|
7
|
|
|
|
|
297
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
package XML::Builder; |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our $VERSION = '0.907'; |
9
|
|
|
|
|
|
|
|
10
|
7
|
|
|
7
|
|
2496
|
use Object::Tiny::Lvalue qw( nsmap default_ns encoding ); |
|
7
|
|
|
|
|
2120
|
|
|
7
|
|
|
|
|
29
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
# these aren't constants, they need to be overridable in subclasses |
13
|
|
|
|
|
|
|
my %class = ( |
14
|
|
|
|
|
|
|
ns => 'XML::Builder::NS', |
15
|
|
|
|
|
|
|
fragment => 'XML::Builder::Fragment', |
16
|
|
|
|
|
|
|
qname => 'XML::Builder::Fragment::QName', |
17
|
|
|
|
|
|
|
tag => 'XML::Builder::Fragment::Tag', |
18
|
|
|
|
|
|
|
unsafe => 'XML::Builder::Fragment::Unsafe', |
19
|
|
|
|
|
|
|
root => 'XML::Builder::Fragment::Root', |
20
|
|
|
|
|
|
|
document => 'XML::Builder::Fragment::Document', |
21
|
|
|
|
|
|
|
); |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
my ( $name, $class ); |
24
|
1
|
|
|
1
|
0
|
7
|
eval XML::Builder::Util::factory_method( $name, $class ) |
|
112
|
|
|
112
|
0
|
300
|
|
|
1
|
|
|
1
|
0
|
6
|
|
|
112
|
|
|
112
|
0
|
243
|
|
|
10
|
|
|
10
|
0
|
43
|
|
|
51
|
|
|
51
|
0
|
952
|
|
|
0
|
|
|
0
|
0
|
0
|
|
|
57
|
|
|
57
|
0
|
151
|
|
|
1
|
|
|
1
|
0
|
6
|
|
|
10
|
|
|
10
|
0
|
55
|
|
|
51
|
|
|
51
|
0
|
150
|
|
|
3
|
|
|
3
|
0
|
68
|
|
|
58
|
|
|
58
|
0
|
200
|
|
|
1
|
|
|
1
|
0
|
9
|
|
25
|
|
|
|
|
|
|
while ( $name, $class ) = each %class; |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
sub new { |
28
|
8
|
|
|
8
|
0
|
536
|
my $class = shift; |
29
|
8
|
|
|
|
|
26
|
my $self = bless { @_ }, $class; |
30
|
8
|
|
50
|
|
|
144
|
$self->encoding ||= 'us-ascii'; |
31
|
8
|
|
50
|
|
|
223
|
$self->nsmap ||= {}; |
32
|
8
|
|
|
|
|
72
|
return $self; |
33
|
|
|
|
|
|
|
} |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
sub register_ns { |
36
|
43
|
|
|
43
|
0
|
54
|
my $self = shift; |
37
|
43
|
|
|
|
|
65
|
my ( $uri, $pfx ) = @_; |
38
|
|
|
|
|
|
|
|
39
|
43
|
|
|
|
|
645
|
my $nsmap = $self->nsmap; |
40
|
|
|
|
|
|
|
|
41
|
43
|
|
|
|
|
179
|
$uri = $self->stringify( $uri ); |
42
|
|
|
|
|
|
|
|
43
|
43
|
100
|
|
|
|
97
|
if ( exists $nsmap->{ $uri } ) { |
44
|
32
|
|
|
|
|
45
|
my $ns = $nsmap->{ $uri }; |
45
|
32
|
|
|
|
|
478
|
my $registered_pfx = $ns->prefix; |
46
|
|
|
|
|
|
|
|
47
|
32
|
50
|
33
|
|
|
128
|
XML::Builder::Util::croak( "Namespace '$uri' being bound to '$pfx' is already bound to '$registered_pfx'" ) |
48
|
|
|
|
|
|
|
if defined $pfx and $pfx ne $registered_pfx; |
49
|
|
|
|
|
|
|
|
50
|
32
|
|
|
|
|
83
|
return $ns; |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
|
53
|
11
|
100
|
|
|
|
31
|
if ( not defined $pfx ) { |
54
|
4
|
|
|
|
|
13
|
my %pfxmap = map {; $_->prefix => $_ } values %$nsmap; |
|
3
|
|
|
|
|
45
|
|
55
|
|
|
|
|
|
|
|
56
|
4
|
100
|
66
|
|
|
51
|
if ( $uri eq '' and not exists $pfxmap{ '' } ) { |
57
|
1
|
|
|
|
|
7
|
return $self->register_ns( '', '' ); |
58
|
|
|
|
|
|
|
} |
59
|
|
|
|
|
|
|
|
60
|
3
|
|
|
|
|
11
|
my $counter; |
61
|
3
|
50
|
|
|
|
11
|
my $letter = ( $uri =~ m!([[:alpha:]])[^/]*/?\z! ) ? lc $1 : 'ns'; |
62
|
3
|
|
|
|
|
11
|
do { $pfx = $letter . ++$counter } while exists $pfxmap{ $pfx }; |
|
3
|
|
|
|
|
15
|
|
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
# FIXME needs proper validity check per XML TR |
66
|
10
|
50
|
66
|
|
|
44
|
XML::Builder::Util::croak( "Invalid namespace prefix '$pfx'" ) |
67
|
|
|
|
|
|
|
if length $pfx and $pfx !~ /[\w-]/; |
68
|
|
|
|
|
|
|
|
69
|
10
|
|
|
|
|
172
|
my $ns = $self->new_ns( |
70
|
|
|
|
|
|
|
uri => $uri, |
71
|
|
|
|
|
|
|
prefix => $pfx, |
72
|
|
|
|
|
|
|
); |
73
|
|
|
|
|
|
|
|
74
|
10
|
100
|
|
|
|
128
|
$self->default_ns = $uri if '' eq $pfx; |
75
|
10
|
|
|
|
|
103
|
return $nsmap->{ $uri } = $ns; |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub get_namespaces { |
79
|
3
|
|
|
3
|
0
|
48
|
my $self = shift; |
80
|
3
|
|
|
|
|
6
|
return values %{ $self->nsmap }; |
|
3
|
|
|
|
|
40
|
|
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
|
83
|
7
|
|
|
7
|
0
|
45
|
sub ns { shift->register_ns( @_ )->factory } |
84
|
3
|
|
|
3
|
0
|
674
|
sub null_ns { shift->ns( '', '' ) } |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub qname { |
87
|
35
|
|
|
35
|
0
|
44
|
my $self = shift; |
88
|
35
|
|
|
|
|
40
|
my $ns_uri = shift; |
89
|
35
|
|
|
|
|
66
|
return $self->register_ns( $ns_uri )->qname( @_ ); |
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
sub parse_qname { |
93
|
34
|
|
|
34
|
0
|
50
|
my $self = shift; |
94
|
34
|
|
|
|
|
57
|
my ( $name ) = @_; |
95
|
|
|
|
|
|
|
|
96
|
34
|
|
|
|
|
50
|
my $ns_uri = ''; |
97
|
34
|
50
|
|
|
|
74
|
$ns_uri = $1 if $name =~ s/\A\{([^}]+)\}//; |
98
|
|
|
|
|
|
|
|
99
|
34
|
|
|
|
|
63
|
return $self->qname( $ns_uri, $name ); |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
sub root { |
103
|
2
|
|
|
2
|
0
|
7
|
my $self = shift; |
104
|
2
|
|
|
|
|
5
|
my ( $tag ) = @_; |
105
|
2
|
|
|
|
|
6
|
return $tag->root; |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
sub document { |
109
|
1
|
|
|
1
|
0
|
5
|
my $self = shift; |
110
|
1
|
|
|
|
|
29
|
return $self->new_document( content => [ @_ ] ); |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
sub unsafe { |
114
|
1
|
|
|
1
|
0
|
3
|
my $self = shift; |
115
|
1
|
|
|
|
|
2
|
my ( $string ) = @_; |
116
|
1
|
|
|
|
|
25
|
return $self->new_unsafe( content => $string ); |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
sub comment { |
120
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
121
|
0
|
|
|
|
|
0
|
my ( $comment ) = $self->stringify( @_ ); |
122
|
0
|
0
|
|
|
|
0
|
XML::Builder::Util::croak( "Comment contains double dashes '$1...'" ) |
123
|
|
|
|
|
|
|
if $comment =~ /(.*?--)/; |
124
|
0
|
|
|
|
|
0
|
return $self->new_unsafe( "" ); |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
sub pi { |
128
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
129
|
0
|
|
|
|
|
0
|
my ( $name, $content ) = map $self->stringify( $_ ), @_; |
130
|
0
|
0
|
|
|
|
0
|
XML::Builder::Util::croak( "PI contains terminator '$1...'" ) |
131
|
|
|
|
|
|
|
if $content =~ /(.*\?>)/; |
132
|
0
|
|
|
|
|
0
|
return $self->new_unsafe( "$name $content?>" ); |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
sub render { |
136
|
106
|
|
|
106
|
0
|
174
|
my $self = shift; |
137
|
|
|
|
|
|
|
return 'SCALAR' eq ref $_[0] |
138
|
106
|
100
|
|
|
|
1594
|
? $self->qname( ${$_[0]}, @_[ 1 .. $#_ ] ) |
|
1
|
|
|
|
|
7
|
|
139
|
|
|
|
|
|
|
: $self->new_fragment( content => [ @_ ] ); |
140
|
|
|
|
|
|
|
} |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
sub test_fragment { |
143
|
157
|
|
|
157
|
0
|
180
|
my $self = shift; |
144
|
157
|
|
|
|
|
187
|
my ( $obj ) = @_; |
145
|
157
|
|
|
|
|
480
|
return $obj->isa( 'XML::Builder::Fragment::Role' ); |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
{ |
149
|
7
|
|
|
7
|
|
8593
|
no warnings 'qw'; |
|
7
|
|
|
|
|
15
|
|
|
7
|
|
|
|
|
2034
|
|
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
my %XML_NCR = map eval "qq[$_]", qw( |
152
|
|
|
|
|
|
|
\xA
\xD
|
153
|
|
|
|
|
|
|
& & < < > > |
154
|
|
|
|
|
|
|
" " ' ' |
155
|
|
|
|
|
|
|
); |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
my %type = ( |
158
|
|
|
|
|
|
|
encode => undef, |
159
|
|
|
|
|
|
|
escape_text => qr/([<>&'"])/, |
160
|
|
|
|
|
|
|
escape_attr => qr/([<>&'"\x0A\x0D])/, |
161
|
|
|
|
|
|
|
); |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
# using eval instead of closures to avoid __ANON__ |
164
|
|
|
|
|
|
|
while ( my ( $subname, $specials_rx ) = each %type ) { |
165
|
|
|
|
|
|
|
my $esc = ''; |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
$esc = sprintf '$str =~ s{ %s }{ $XML_NCR{$1} }gex', $specials_rx |
168
|
|
|
|
|
|
|
if defined $specials_rx; |
169
|
|
|
|
|
|
|
|
170
|
1
|
|
|
1
|
0
|
20
|
eval sprintf 'sub %s { |
|
1
|
|
|
35
|
0
|
4
|
|
|
1
|
|
|
65
|
0
|
16
|
|
|
35
|
|
|
|
|
1965
|
|
|
35
|
|
|
|
|
86
|
|
|
35
|
|
|
|
|
84
|
|
|
7
|
|
|
|
|
21
|
|
|
35
|
|
|
|
|
473
|
|
|
65
|
|
|
|
|
128
|
|
|
65
|
|
|
|
|
131
|
|
|
65
|
|
|
|
|
160
|
|
|
13
|
|
|
|
|
46
|
|
|
65
|
|
|
|
|
892
|
|
171
|
|
|
|
|
|
|
my $self = shift; |
172
|
|
|
|
|
|
|
my $str = $self->stringify( shift ); |
173
|
|
|
|
|
|
|
%s; |
174
|
|
|
|
|
|
|
return Encode::encode $self->encoding, $str, Encode::HTMLCREF; |
175
|
|
|
|
|
|
|
}', $subname, $esc; |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
sub stringify { |
180
|
149
|
|
|
149
|
0
|
1791
|
my $self = shift; |
181
|
149
|
|
|
|
|
226
|
my ( $thing ) = @_; |
182
|
|
|
|
|
|
|
|
183
|
149
|
50
|
|
|
|
249
|
return if not defined $thing; |
184
|
|
|
|
|
|
|
|
185
|
149
|
100
|
|
|
|
1578
|
return $thing if not Scalar::Util::blessed $thing; |
186
|
|
|
|
|
|
|
|
187
|
4
|
|
100
|
|
|
32
|
my $conv = $thing->can( 'as_string' ) || overload::Method( $thing, '""' ); |
188
|
4
|
100
|
|
|
|
91
|
return $conv->( $thing ) if $conv; |
189
|
|
|
|
|
|
|
|
190
|
1
|
|
|
|
|
3
|
XML::Builder::Util::croak( 'Unstringifiable object ', $thing ); |
191
|
|
|
|
|
|
|
} |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
####################################################################### |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
package XML::Builder::NS; |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
our $VERSION = '0.907'; |
198
|
|
|
|
|
|
|
|
199
|
7
|
|
|
7
|
|
65
|
use Object::Tiny::Lvalue qw( builder uri prefix qname_for_localname ); |
|
7
|
|
|
|
|
28
|
|
|
7
|
|
|
|
|
43
|
|
200
|
7
|
|
|
7
|
|
11199
|
use overload '""' => 'uri', fallback => 1; |
|
7
|
|
|
|
|
15212
|
|
|
7
|
|
|
|
|
45
|
|
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
sub new { |
203
|
10
|
|
|
10
|
|
54
|
my $class = shift; |
204
|
10
|
|
|
|
|
62
|
my $self = bless { @_ }, $class; |
205
|
10
|
|
50
|
|
|
166
|
$self->qname_for_localname ||= {}; |
206
|
10
|
|
|
|
|
374
|
Scalar::Util::weaken $self->builder; |
207
|
10
|
|
|
|
|
64
|
return $self; |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
sub qname { |
211
|
87
|
|
|
87
|
|
121
|
my $self = shift; |
212
|
87
|
|
|
|
|
103
|
my $name = shift; |
213
|
|
|
|
|
|
|
|
214
|
87
|
|
33
|
|
|
1259
|
my $builder = $self->builder |
215
|
|
|
|
|
|
|
|| XML::Builder::Util::croak( 'XML::Builder for this NS object has gone out of scope' ); |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
my $qname |
218
|
87
|
|
66
|
|
|
1392
|
= $self->qname_for_localname->{ $name } |
219
|
|
|
|
|
|
|
||= $builder->new_qname( name => $name, ns => $self ); |
220
|
|
|
|
|
|
|
|
221
|
87
|
100
|
|
|
|
1515
|
return @_ ? $qname->tag( @_ ) : $qname; |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
sub xmlns { |
225
|
3
|
|
|
3
|
|
20
|
my $self = shift; |
226
|
3
|
|
|
|
|
41
|
my $pfx = $self->prefix; |
227
|
3
|
50
|
|
|
|
79
|
return ( ( '' ne $pfx ? "xmlns:$pfx" : 'xmlns' ), $self->uri ); |
228
|
|
|
|
|
|
|
} |
229
|
|
|
|
|
|
|
|
230
|
7
|
|
|
7
|
|
37
|
sub factory { bless \shift, 'XML::Builder::NS::QNameFactory' } |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
####################################################################### |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
package XML::Builder::NS::QNameFactory; |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
our $VERSION = '0.907'; |
237
|
|
|
|
|
|
|
|
238
|
51
|
|
|
51
|
|
850
|
sub AUTOLOAD { my $self = shift; $$self->qname( ( our $AUTOLOAD =~ /.*::(.*)/ ), @_ ) } |
|
51
|
|
|
|
|
277
|
|
239
|
1
|
|
|
1
|
|
2
|
sub _qname { my $self = shift; $$self->qname( @_ ) } |
|
1
|
|
|
|
|
6
|
|
240
|
|
|
|
0
|
|
|
sub DESTROY {} |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
####################################################################### |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
package XML::Builder::Fragment::Role; |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
our $VERSION = '0.907'; |
247
|
|
|
|
|
|
|
|
248
|
0
|
|
|
0
|
|
0
|
sub depends_ns_scope { 1 } |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
####################################################################### |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
package XML::Builder::Fragment; |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
our $VERSION = '0.907'; |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
our @ISA = 'XML::Builder::Fragment::Role'; |
257
|
|
|
|
|
|
|
|
258
|
7
|
|
|
7
|
|
2849
|
use Object::Tiny::Lvalue qw( builder content ); |
|
7
|
|
|
|
|
14
|
|
|
7
|
|
|
|
|
50
|
|
259
|
|
|
|
|
|
|
|
260
|
0
|
|
|
0
|
|
0
|
sub depends_ns_scope { 0 } |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
sub new { |
263
|
170
|
|
|
170
|
|
222
|
my $class = shift; |
264
|
170
|
|
|
|
|
427
|
my $self = bless { @_ }, $class; |
265
|
170
|
|
|
|
|
2369
|
my $builder = $self->builder; |
266
|
170
|
|
|
|
|
2703
|
my $content = $self->content; |
267
|
|
|
|
|
|
|
|
268
|
170
|
|
|
|
|
482
|
my ( @gather, @take ); |
269
|
|
|
|
|
|
|
|
270
|
170
|
100
|
|
|
|
382
|
for my $r ( 'ARRAY' eq ref $content ? @$content : $content ) { |
271
|
223
|
|
|
|
|
331
|
@take = $r; |
272
|
|
|
|
|
|
|
|
273
|
223
|
100
|
|
|
|
490
|
if ( not Scalar::Util::blessed $r ) { |
274
|
66
|
100
|
|
|
|
158
|
@take = $builder->render( @$r ) if 'ARRAY' eq ref $r; |
275
|
66
|
|
|
|
|
88
|
next; |
276
|
|
|
|
|
|
|
} |
277
|
|
|
|
|
|
|
|
278
|
157
|
50
|
|
|
|
257
|
if ( not $builder->test_fragment( $r ) ) { |
279
|
0
|
|
|
|
|
0
|
@take = $builder->stringify( $r ); |
280
|
0
|
|
|
|
|
0
|
next; |
281
|
|
|
|
|
|
|
} |
282
|
|
|
|
|
|
|
|
283
|
157
|
100
|
|
|
|
2198
|
next if $builder == $r->builder; |
284
|
|
|
|
|
|
|
|
285
|
1
|
50
|
|
|
|
71
|
XML::Builder::Util::croak( 'Cannot merge XML::Builder fragments built with different namespace maps' ) |
286
|
|
|
|
|
|
|
if $r->depends_ns_scope; |
287
|
|
|
|
|
|
|
|
288
|
1
|
|
|
|
|
5
|
@take = $r->flatten; |
289
|
|
|
|
|
|
|
|
290
|
1
|
|
|
|
|
21
|
my ( $self_enc, $r_enc ) = map { lc $_->encoding } $builder, $r->builder; |
|
2
|
|
|
|
|
35
|
|
291
|
|
|
|
|
|
|
next |
292
|
|
|
|
|
|
|
if $self_enc eq $r_enc |
293
|
|
|
|
|
|
|
# be more permissive: ASCII is one-way compatible with UTF-8 and Latin-1 |
294
|
1
|
50
|
0
|
|
|
10
|
or 'us-ascii' eq $r_enc and grep { $_ eq $self_enc } 'utf-8', 'iso-8859-1'; |
|
0
|
|
33
|
|
|
0
|
|
295
|
|
|
|
|
|
|
|
296
|
0
|
|
|
|
|
0
|
XML::Builder::Util::croak( |
297
|
|
|
|
|
|
|
'Cannot merge XML::Builder fragments with incompatible encodings' |
298
|
|
|
|
|
|
|
. " (have $self_enc, fragment has $r_enc)" |
299
|
|
|
|
|
|
|
); |
300
|
|
|
|
|
|
|
} |
301
|
|
|
|
|
|
|
continue { |
302
|
223
|
|
|
|
|
814
|
push @gather, @take; |
303
|
|
|
|
|
|
|
} |
304
|
|
|
|
|
|
|
|
305
|
170
|
|
|
|
|
2394
|
$self->content = \@gather; |
306
|
|
|
|
|
|
|
|
307
|
170
|
|
|
|
|
1671
|
return $self; |
308
|
|
|
|
|
|
|
} |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
sub as_string { |
311
|
166
|
|
|
166
|
|
418
|
my $self = shift; |
312
|
166
|
|
|
|
|
2648
|
my $builder = $self->builder; |
313
|
166
|
100
|
|
|
|
486
|
return join '', map { ref $_ ? $_->as_string : $builder->escape_text( $_ ) } @{ $self->content }; |
|
223
|
|
|
|
|
2590
|
|
|
166
|
|
|
|
|
2099
|
|
314
|
|
|
|
|
|
|
} |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
sub flatten { |
317
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
318
|
0
|
|
|
|
|
0
|
return @{ $self->content }; |
|
0
|
|
|
|
|
0
|
|
319
|
|
|
|
|
|
|
} |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
####################################################################### |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
package XML::Builder::Fragment::Unsafe; |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
our $VERSION = '0.907'; |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
our @ISA = 'XML::Builder::Fragment'; |
328
|
|
|
|
|
|
|
|
329
|
0
|
|
|
0
|
|
0
|
sub depends_ns_scope { 0 } |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
sub new { |
332
|
1
|
|
|
1
|
|
2
|
my $class = shift; |
333
|
1
|
|
|
|
|
5
|
my $self = bless { @_ }, $class; |
334
|
1
|
|
|
|
|
19
|
$self->content = $self->builder->stringify( $self->content ); |
335
|
1
|
|
|
|
|
9
|
return $self; |
336
|
|
|
|
|
|
|
} |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
sub as_string { |
339
|
1
|
|
|
1
|
|
3
|
my $self = shift; |
340
|
1
|
|
|
|
|
14
|
return $self->builder->encode( $self->content ); |
341
|
|
|
|
|
|
|
} |
342
|
|
|
|
|
|
|
|
343
|
0
|
|
|
0
|
|
0
|
sub flatten { shift } |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
####################################################################### |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
package XML::Builder::Fragment::QName; |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
our $VERSION = '0.907'; |
350
|
|
|
|
|
|
|
|
351
|
7
|
|
|
7
|
|
4945
|
use Object::Tiny::Lvalue qw( builder ns name as_qname as_attr_qname as_clarkname as_string ); |
|
7
|
|
|
|
|
13
|
|
|
7
|
|
|
|
|
27
|
|
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
our @ISA = 'XML::Builder::Fragment'; |
354
|
7
|
|
|
7
|
|
2134
|
use overload '""' => 'as_clarkname', fallback => 1; |
|
7
|
|
|
|
|
21
|
|
|
7
|
|
|
|
|
45
|
|
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
sub new { |
357
|
51
|
|
|
51
|
|
72
|
my $class = shift; |
358
|
51
|
|
|
|
|
158
|
my $self = bless { @_ }, $class; |
359
|
|
|
|
|
|
|
|
360
|
51
|
|
|
|
|
724
|
my $uri = $self->ns->uri; |
361
|
51
|
|
|
|
|
1635
|
my $pfx = $self->ns->prefix; |
362
|
51
|
|
|
|
|
1413
|
Scalar::Util::weaken $self->ns; # really don't even need this any more |
363
|
51
|
|
|
|
|
790
|
Scalar::Util::weaken $self->builder; |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
# NB.: attributes without a prefix not in a namespace rather than in the |
366
|
|
|
|
|
|
|
# default namespace, so attributes without a namespace never need a prefix |
367
|
|
|
|
|
|
|
|
368
|
51
|
|
|
|
|
812
|
my $name = $self->name; |
369
|
51
|
100
|
|
|
|
862
|
$self->as_qname = ( '' eq $pfx ) ? $name : "$pfx:$name"; |
370
|
51
|
50
|
66
|
|
|
883
|
$self->as_attr_qname = ( '' eq $pfx or '' eq $uri ) ? $name : "$pfx:$name"; |
371
|
51
|
100
|
|
|
|
865
|
$self->as_clarkname = ( '' eq $uri ) ? $name : "{$uri}$name"; |
372
|
51
|
|
|
|
|
794
|
$self->as_string = '<' . $self->as_qname . '/>'; |
373
|
|
|
|
|
|
|
|
374
|
51
|
|
|
|
|
956
|
return $self; |
375
|
|
|
|
|
|
|
} |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
sub tag { |
378
|
40
|
|
|
40
|
|
56
|
my $self = shift; |
379
|
|
|
|
|
|
|
|
380
|
40
|
50
|
33
|
|
|
97
|
if ( 'SCALAR' eq ref $_[0] and 'foreach' eq ${$_[0]} ) { |
|
0
|
|
|
|
|
0
|
|
381
|
0
|
|
|
|
|
0
|
shift @_; # throw away |
382
|
0
|
|
|
|
|
0
|
return $self->foreach( @_ ); |
383
|
|
|
|
|
|
|
} |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
# has to be written this way so it'll drop undef attributes |
386
|
40
|
|
|
|
|
51
|
my $attr = {}; |
387
|
40
|
|
|
|
|
102
|
XML::Builder::Util::merge_param_hash( $attr, \@_ ); |
388
|
|
|
|
|
|
|
|
389
|
40
|
|
33
|
|
|
602
|
my $builder = $self->builder |
390
|
|
|
|
|
|
|
|| XML::Builder::Util::croak( 'XML::Builder for this QName object has gone out of scope' ); |
391
|
|
|
|
|
|
|
|
392
|
40
|
|
|
|
|
287
|
return $builder->new_tag( |
393
|
|
|
|
|
|
|
qname => $self, |
394
|
|
|
|
|
|
|
attr => $attr, |
395
|
|
|
|
|
|
|
content => [ map $builder->render( $_ ), @_ ], |
396
|
|
|
|
|
|
|
); |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
sub foreach { |
400
|
8
|
|
|
8
|
|
23
|
my $self = shift; |
401
|
|
|
|
|
|
|
|
402
|
8
|
|
|
|
|
14
|
my $attr = {}; |
403
|
8
|
|
|
|
|
12
|
my @out = (); |
404
|
|
|
|
|
|
|
|
405
|
8
|
|
33
|
|
|
118
|
my $builder = $self->builder |
406
|
|
|
|
|
|
|
|| XML::Builder::Util::croak( 'XML::Builder for this QName object has gone out of scope' ); |
407
|
|
|
|
|
|
|
|
408
|
8
|
|
|
|
|
39
|
do { |
409
|
17
|
|
|
|
|
47
|
XML::Builder::Util::merge_param_hash( $attr, \@_ ); |
410
|
17
|
50
|
|
|
|
42
|
my $content = 'HASH' eq ref $_[0] ? undef : shift; |
411
|
17
|
|
|
|
|
45
|
push @out, $builder->new_tag( |
412
|
|
|
|
|
|
|
qname => $self, |
413
|
|
|
|
|
|
|
attr => {%$attr}, |
414
|
|
|
|
|
|
|
content => $builder->render( $content ), |
415
|
|
|
|
|
|
|
); |
416
|
|
|
|
|
|
|
} while @_; |
417
|
|
|
|
|
|
|
|
418
|
8
|
100
|
66
|
|
|
116
|
return $builder->new_fragment( content => \@out ) |
419
|
|
|
|
|
|
|
if @out > 1 and not wantarray; |
420
|
|
|
|
|
|
|
|
421
|
3
|
|
|
|
|
30
|
return @out[ 0 .. $#out ]; |
422
|
|
|
|
|
|
|
} |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
####################################################################### |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
package XML::Builder::Fragment::Tag; |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
our $VERSION = '0.907'; |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
our @ISA = 'XML::Builder::Fragment'; |
431
|
7
|
|
|
7
|
|
3873
|
use Object::Tiny::Lvalue qw( qname attr ); |
|
7
|
|
|
|
|
14
|
|
|
7
|
|
|
|
|
22
|
|
432
|
|
|
|
|
|
|
|
433
|
0
|
|
|
0
|
|
0
|
sub depends_ns_scope { 1 } |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
sub as_string { |
436
|
57
|
|
|
57
|
|
89
|
my $self = shift; |
437
|
|
|
|
|
|
|
|
438
|
57
|
|
|
|
|
798
|
my $builder = $self->builder; |
439
|
57
|
|
|
|
|
859
|
my $qname = $self->qname->as_qname; |
440
|
57
|
|
50
|
|
|
1607
|
my $attr = $self->attr || {}; |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
my $tag = join ' ', $qname, |
443
|
57
|
|
|
|
|
338
|
map { sprintf '%s="%s"', $builder->parse_qname( $_ )->as_attr_qname, $builder->escape_attr( $attr->{ $_ } ) } |
|
34
|
|
|
|
|
590
|
|
444
|
|
|
|
|
|
|
sort keys %$attr; |
445
|
|
|
|
|
|
|
|
446
|
57
|
100
|
|
|
|
2456
|
my $content = @{ $self->content } ? $self->SUPER::as_string : undef; |
|
57
|
|
|
|
|
827
|
|
447
|
57
|
100
|
|
|
|
2921
|
return defined $content |
448
|
|
|
|
|
|
|
? "<$tag>$content$qname>" |
449
|
|
|
|
|
|
|
: "<$tag/>"; |
450
|
|
|
|
|
|
|
} |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
sub append { |
453
|
2
|
|
|
2
|
|
10
|
my $self = shift; |
454
|
2
|
|
|
|
|
40
|
return $self->builder->new_fragment( content => [ $self, $self->builder->render( @_ ) ] ); |
455
|
|
|
|
|
|
|
} |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
sub root { |
458
|
3
|
|
|
3
|
|
4
|
my $self = shift; |
459
|
3
|
|
|
|
|
71
|
bless $self, $self->builder->root_class; |
460
|
|
|
|
|
|
|
} |
461
|
|
|
|
|
|
|
|
462
|
1
|
|
|
1
|
|
3
|
sub flatten { shift } |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
####################################################################### |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
package XML::Builder::Fragment::Root; |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
our $VERSION = '0.907'; |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
our @ISA = 'XML::Builder::Fragment::Tag'; |
471
|
7
|
|
|
7
|
|
3418
|
use overload '""' => 'as_string', fallback => 1; |
|
7
|
|
|
|
|
13
|
|
|
7
|
|
|
|
|
36
|
|
472
|
|
|
|
|
|
|
|
473
|
1
|
|
|
1
|
|
3
|
sub depends_ns_scope { 0 } |
474
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
sub as_string { |
476
|
3
|
|
|
3
|
|
6
|
my $self = shift; |
477
|
|
|
|
|
|
|
|
478
|
3
|
|
|
|
|
59
|
my %decl = map $_->xmlns, $self->builder->get_namespaces; |
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
# make sure to always declare the default NS (if not bound to a URI, by |
481
|
|
|
|
|
|
|
# explicitly undefining it) to allow embedding the XML easily without |
482
|
|
|
|
|
|
|
# having to parse the fragment |
483
|
3
|
50
|
|
|
|
36
|
$decl{'xmlns'} = '' if not defined $decl{'xmlns'}; |
484
|
|
|
|
|
|
|
|
485
|
3
|
|
|
|
|
12
|
local @{ $self->attr }{ keys %decl } = values %decl; |
|
3
|
|
|
|
|
53
|
|
486
|
|
|
|
|
|
|
|
487
|
3
|
|
|
|
|
36
|
return $self->SUPER::as_string( @_ ); |
488
|
|
|
|
|
|
|
} |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
####################################################################### |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
package XML::Builder::Fragment::Document; |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
our $VERSION = '0.907'; |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
our @ISA = 'XML::Builder::Fragment'; |
497
|
7
|
|
|
7
|
|
1528
|
use overload '""' => 'as_string', fallback => 1; |
|
7
|
|
|
|
|
12
|
|
|
7
|
|
|
|
|
25
|
|
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
sub new { |
500
|
1
|
|
|
1
|
|
2
|
my $class = shift; |
501
|
1
|
|
|
|
|
13
|
my $self = $class->SUPER::new( @_ ); |
502
|
1
|
|
|
|
|
6
|
$self->validate; |
503
|
1
|
|
|
|
|
2
|
return $self; |
504
|
|
|
|
|
|
|
} |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
sub validate { |
507
|
1
|
|
|
1
|
|
2
|
my $self = shift; |
508
|
1
|
|
|
|
|
2
|
my @root; |
509
|
|
|
|
|
|
|
|
510
|
1
|
|
|
|
|
2
|
for ( @{ $self->content } ) { |
|
1
|
|
|
|
|
23
|
|
511
|
1
|
50
|
|
|
|
11
|
if ( Scalar::Util::blessed $_ ) { |
512
|
1
|
50
|
|
|
|
16
|
if ( $_->isa( $self->builder->tag_class ) ) { push @root, $_; next } |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
2
|
|
513
|
0
|
0
|
|
|
|
0
|
if ( $_->isa( $self->builder->unsafe_class ) ) { next } |
|
0
|
|
|
|
|
0
|
|
514
|
|
|
|
|
|
|
} |
515
|
0
|
|
|
|
|
0
|
XML::Builder::Util::croak( 'Junk at top level of document' ); |
516
|
|
|
|
|
|
|
} |
517
|
|
|
|
|
|
|
|
518
|
1
|
50
|
|
|
|
17
|
XML::Builder::Util::croak( 'Document must have exactly one document element, not ' . @root ) |
519
|
|
|
|
|
|
|
if @root != 1; |
520
|
|
|
|
|
|
|
|
521
|
1
|
|
|
|
|
5
|
$root[0]->root; |
522
|
|
|
|
|
|
|
|
523
|
1
|
|
|
|
|
3
|
return; |
524
|
|
|
|
|
|
|
} |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
sub as_string { |
527
|
1
|
|
|
1
|
|
305
|
my $self = shift; |
528
|
1
|
|
|
|
|
3
|
my $preamble = qq(builder->encoding}"?>\n); |
|
1
|
|
|
|
|
16
|
|
529
|
1
|
|
|
|
|
29
|
return $preamble . $self->SUPER::as_string( @_ ); |
530
|
|
|
|
|
|
|
} |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
####################################################################### |
533
|
|
|
|
|
|
|
|
534
|
0
|
|
|
|
|
0
|
BEGIN { |
535
|
|
|
|
|
|
|
package XML::Builder::Util; |
536
|
|
|
|
|
|
|
|
537
|
7
|
|
|
7
|
|
2039
|
our $VERSION = '0.907'; |
538
|
|
|
|
|
|
|
|
539
|
7
|
|
|
7
|
|
5942
|
use Carp::Clan '^XML::Builder(?:\z|::)'; |
|
7
|
|
|
|
|
10761
|
|
|
7
|
|
|
|
|
49
|
|
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
sub merge_param_hash { |
542
|
57
|
|
|
57
|
|
87
|
my ( $cur, $param ) = @_; |
543
|
|
|
|
|
|
|
|
544
|
57
|
100
|
66
|
|
|
214
|
return if not ( @$param and 'HASH' eq ref $param->[0] ); |
545
|
|
|
|
|
|
|
|
546
|
17
|
|
|
|
|
31
|
my $new = shift @$param; |
547
|
|
|
|
|
|
|
|
548
|
17
|
|
|
|
|
59
|
@{ $cur }{ keys %$new } = values %$new; |
|
17
|
|
|
|
|
39
|
|
549
|
17
|
|
|
|
|
61
|
while ( my ( $k, $v ) = each %$cur ) { |
550
|
33
|
100
|
|
|
|
106
|
delete $cur->{ $k } if not defined $v; |
551
|
|
|
|
|
|
|
} |
552
|
|
|
|
|
|
|
} |
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
sub factory_method { |
555
|
49
|
|
|
49
|
|
122
|
my ( $name, $class ) = @_; |
556
|
49
|
|
|
|
|
1451
|
my ( $class_method, $new_method ) = ( "$name\_class", "new_$name" ); |
557
|
49
|
|
|
|
|
2963
|
return <<";"; |
558
|
|
|
|
|
|
|
sub $class_method { "\Q$class\E" } |
559
|
|
|
|
|
|
|
sub $new_method { \$_[0]->$class_method->new( builder => \@_ ) } |
560
|
|
|
|
|
|
|
; |
561
|
|
|
|
|
|
|
} |
562
|
|
|
|
|
|
|
} |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
1; |
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
__END__ |