line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
############################################################################# |
2
|
|
|
|
|
|
|
## Name: Smart.pm |
3
|
|
|
|
|
|
|
## Purpose: XML::Smart |
4
|
|
|
|
|
|
|
## Author: Graciliano M. P. |
5
|
|
|
|
|
|
|
## Modified by: Harish Madabushi |
6
|
|
|
|
|
|
|
## Created: 10/05/2003 |
7
|
|
|
|
|
|
|
## RCS-ID: |
8
|
|
|
|
|
|
|
## Copyright: (c) 2003 Graciliano M. P. |
9
|
|
|
|
|
|
|
## Licence: This program is free software; you can redistribute it and/or |
10
|
|
|
|
|
|
|
## modify it under the same terms as Perl itself |
11
|
|
|
|
|
|
|
############################################################################# |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
package XML::Smart ; |
15
|
|
|
|
|
|
|
|
16
|
11
|
|
|
11
|
|
6710524
|
use 5.006 ; |
|
11
|
|
|
|
|
46
|
|
|
11
|
|
|
|
|
467
|
|
17
|
|
|
|
|
|
|
|
18
|
11
|
|
|
11
|
|
64
|
use strict ; |
|
11
|
|
|
|
|
18
|
|
|
11
|
|
|
|
|
364
|
|
19
|
11
|
|
|
11
|
|
57
|
use warnings ; |
|
11
|
|
|
|
|
25
|
|
|
11
|
|
|
|
|
409
|
|
20
|
|
|
|
|
|
|
|
21
|
11
|
|
|
11
|
|
60
|
use Carp ; |
|
11
|
|
|
|
|
19
|
|
|
11
|
|
|
|
|
881
|
|
22
|
|
|
|
|
|
|
|
23
|
11
|
|
|
11
|
|
18581
|
use Object::MultiType ; |
|
11
|
|
|
|
|
67217
|
|
|
11
|
|
|
|
|
402
|
|
24
|
|
|
|
|
|
|
|
25
|
11
|
|
|
11
|
|
7151
|
use XML::Smart::Shared qw( _unset_sig_warn _reset_sig_warn ) ; |
|
11
|
|
|
|
|
28
|
|
|
11
|
|
|
|
|
942
|
|
26
|
|
|
|
|
|
|
|
27
|
11
|
|
|
11
|
|
66
|
use vars qw(@ISA) ; |
|
11
|
|
|
|
|
14
|
|
|
11
|
|
|
|
|
623
|
|
28
|
|
|
|
|
|
|
@ISA = qw(Object::MultiType) ; |
29
|
|
|
|
|
|
|
|
30
|
11
|
|
|
11
|
|
7167
|
use XML::Smart::Tie ; |
|
11
|
|
|
|
|
35
|
|
|
11
|
|
|
|
|
503
|
|
31
|
11
|
|
|
11
|
|
8140
|
use XML::Smart::Tree ; |
|
11
|
|
|
|
|
33
|
|
|
11
|
|
|
|
|
101979
|
|
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
=head1 NAME |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
XML::Smart - A smart, easy and powerful way to access or create XML from fiels, data and URLs. |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
=head1 VERSION |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
Version 1.78 |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
=cut |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
our $VERSION = '1.78' ; |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
=head1 SYNOPSIS |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
This module provides an easy way to access/create XML data. It's based on a HASH |
49
|
|
|
|
|
|
|
tree created from the XML data, and enables dynamic access to it through the |
50
|
|
|
|
|
|
|
standard Perl syntax for Hash and Array, without necessarily caring about which |
51
|
|
|
|
|
|
|
you are working with. In other words, B
|
52
|
|
|
|
|
|
|
an Array at the same time>! |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
This module additionally provides special resources such as: search for nodes by |
55
|
|
|
|
|
|
|
attribute, select an attribute value in each multiple node, change the returned |
56
|
|
|
|
|
|
|
format, and so on. |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
The module also automatically handles binary data (encoding/decoding to/from base64), |
59
|
|
|
|
|
|
|
CDATA (like contents with ) and Unicode. It can be used to create XML files, |
60
|
|
|
|
|
|
|
load XML from the Web ( just by using an URL as the file path ) and has an easy |
61
|
|
|
|
|
|
|
way to send XML data through sockets - just adding the length of the data in |
62
|
|
|
|
|
|
|
the header. |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
You can use I with L, or with the 2 standard parsers of |
65
|
|
|
|
|
|
|
XML::Smart: |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=over 10 |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
=item I |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=item I. |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=back |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
I can be used to load/parse wild/bad XML data, or HTML tags. |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=head1 Tutorial and F.A.Q. |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
You can find some extra documents about I at: |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
=over 2 |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=item L - Tutorial and examples for XML::Smart. |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
=item L - Frequently Asked Questions about XML::Smart. |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
=back |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
=cut |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
=head1 USAGE |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
## Create the object and load the file: |
94
|
|
|
|
|
|
|
my $XML = XML::Smart->new('file.xml') ; |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
## Force the use of the parser 'XML::Smart::Parser'. |
97
|
|
|
|
|
|
|
my $XML = XML::Smart->new('file.xml' , 'XML::Smart::Parser') ; |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
## Get from the web: |
100
|
|
|
|
|
|
|
my $XML = XML::Smart->new('http://www.perlmonks.org/index.pl?node_id=16046') ; |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
## Cut the root: |
103
|
|
|
|
|
|
|
$XML = $XML->cut_root ; |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
## Or change the root: |
106
|
|
|
|
|
|
|
$XML = $XML->{hosts} ; |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
## Get the address [0] of server [0]: |
109
|
|
|
|
|
|
|
my $srv0_addr0 = $XML->{server}[0]{address}[0] ; |
110
|
|
|
|
|
|
|
## ...or... |
111
|
|
|
|
|
|
|
my $srv0_addr0 = $XML->{server}{address} ; |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
## Get the server where the attibute 'type' eq 'suse': |
114
|
|
|
|
|
|
|
my $server = $XML->{server}('type','eq','suse') ; |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
## Get the address again: |
117
|
|
|
|
|
|
|
my $addr1 = $server->{address}[1] ; |
118
|
|
|
|
|
|
|
## ...or... |
119
|
|
|
|
|
|
|
my $addr1 = $XML->{server}('type','eq','suse'){address}[1] ; |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
## Get all the addresses of a server: |
122
|
|
|
|
|
|
|
my @addrs = @{$XML->{server}{address}} ; |
123
|
|
|
|
|
|
|
## ...or... |
124
|
|
|
|
|
|
|
my @addrs = $XML->{server}{address}('@') ; |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
## Get a list of types of all the servers: |
127
|
|
|
|
|
|
|
my @types = $XML->{server}('[@]','type') ; |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
## Add a new server node: |
130
|
|
|
|
|
|
|
my $newsrv = { |
131
|
|
|
|
|
|
|
os => 'Linux' , |
132
|
|
|
|
|
|
|
type => 'Mandrake' , |
133
|
|
|
|
|
|
|
version => 8.9 , |
134
|
|
|
|
|
|
|
address => [qw(192.168.3.201 192.168.3.202)] |
135
|
|
|
|
|
|
|
} ; |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
push(@{$XML->{server}} , $newsrv) ; |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
## Get/rebuild the XML data: |
140
|
|
|
|
|
|
|
my $xmldata = $XML->data ; |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
## Save in some file: |
143
|
|
|
|
|
|
|
$XML->save('newfile.xml') ; |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
## Send through a socket: |
146
|
|
|
|
|
|
|
print $socket $XML->data(length => 1) ; ## show the 'length' in the XML header to the |
147
|
|
|
|
|
|
|
## socket know the amount of data to read. |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
__DATA__ |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
192.168.0.1 |
154
|
|
|
|
|
|
|
192.168.0.2 |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
192.168.1.10 |
158
|
|
|
|
|
|
|
192.168.1.20 |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
=cut |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
############### |
166
|
|
|
|
|
|
|
# AUTOLOADERS # |
167
|
|
|
|
|
|
|
############### |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
## Lead to mem leak? ## |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
sub data { |
172
|
7
|
|
|
7
|
1
|
6563
|
require XML::Smart::Data ; |
173
|
7
|
|
|
|
|
61
|
_unset_sig_warn() ; |
174
|
7
|
|
|
|
|
137
|
*data = \&XML::Smart::Data::data ; |
175
|
7
|
|
|
|
|
41
|
_reset_sig_warn() ; |
176
|
7
|
|
|
|
|
144
|
&XML::Smart::Data::data(@_) ; |
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
sub apply_dtd { |
180
|
3
|
|
|
3
|
1
|
26
|
require XML::Smart::DTD ; |
181
|
3
|
|
|
|
|
15
|
_unset_sig_warn() ; |
182
|
3
|
|
|
|
|
33
|
*apply_dtd = \&XML::Smart::DTD::apply_dtd ; |
183
|
3
|
|
|
|
|
14
|
_reset_sig_warn() ; |
184
|
3
|
|
|
|
|
22
|
&XML::Smart::DTD::apply_dtd(@_) ; |
185
|
|
|
|
|
|
|
} |
186
|
|
|
|
|
|
|
|
187
|
0
|
|
|
0
|
1
|
0
|
sub xpath { _load_xpath() ; &XML::Smart::XPath::xpath(@_) ;} |
|
0
|
|
|
|
|
0
|
|
188
|
0
|
|
|
0
|
1
|
0
|
sub XPath { _load_xpath() ; &XML::Smart::XPath::XPath(@_) ;} |
|
0
|
|
|
|
|
0
|
|
189
|
0
|
|
|
0
|
1
|
0
|
sub xpath_pointer { _load_xpath() ; &XML::Smart::XPath::xpath_pointer(@_) ;} |
|
0
|
|
|
|
|
0
|
|
190
|
0
|
|
|
0
|
1
|
0
|
sub XPath_pointer { _load_xpath() ; &XML::Smart::XPath::XPath_pointer(@_) ;} |
|
0
|
|
|
|
|
0
|
|
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
sub _load_xpath { |
193
|
|
|
|
|
|
|
|
194
|
0
|
|
|
0
|
|
0
|
require XML::Smart::XPath ; |
195
|
0
|
|
|
|
|
0
|
_unset_sig_warn() ; |
196
|
0
|
|
|
|
|
0
|
*xpath = \&XML::Smart::XPath::xpath ; |
197
|
0
|
|
|
|
|
0
|
*XPath = \&XML::Smart::XPath::XPath ; |
198
|
0
|
|
|
|
|
0
|
*xpath_pointer = \&XML::Smart::XPath::xpath_pointer ; |
199
|
0
|
|
|
|
|
0
|
*XPath_pointer = \&XML::Smart::XPath::XPath_pointer ; |
200
|
0
|
|
|
0
|
|
0
|
*_load_xpath = sub {} ; |
|
0
|
|
|
|
|
0
|
|
201
|
0
|
|
|
|
|
0
|
_reset_sig_warn() ; |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
################# |
206
|
|
|
|
|
|
|
# NO_XML_PARSER # |
207
|
|
|
|
|
|
|
################# |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
sub NO_XML_PARSER { |
210
|
0
|
0
|
|
0
|
0
|
0
|
$XML::Smart::Tree::NO_XML_PARSER = !@_ ? 1 : ( $_[0] ? 1 : undef ) ; |
|
|
0
|
|
|
|
|
|
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
####### |
214
|
|
|
|
|
|
|
# NEW # |
215
|
|
|
|
|
|
|
####### |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
sub new { |
218
|
|
|
|
|
|
|
|
219
|
273
|
|
|
273
|
1
|
249311
|
my $class = shift ; |
220
|
273
|
|
|
|
|
544
|
my $file = shift ; |
221
|
273
|
100
|
100
|
|
|
2769
|
my $parser = ($_[0] and $_[0] !~ /^(?:uper|low|arg|on|no|use)\w+$/i) ? shift(@_) : '' ; |
222
|
|
|
|
|
|
|
|
223
|
273
|
|
|
|
|
2358
|
my $this = Object::MultiType->new( |
224
|
|
|
|
|
|
|
boolsub => \&boolean , |
225
|
|
|
|
|
|
|
scalarsub => \&content , |
226
|
|
|
|
|
|
|
tiearray => 'XML::Smart::Tie::Array' , |
227
|
|
|
|
|
|
|
tiehash => 'XML::Smart::Tie::Hash' , |
228
|
|
|
|
|
|
|
tieonuse => 1 , |
229
|
|
|
|
|
|
|
code => \&find_arg , |
230
|
|
|
|
|
|
|
) ; |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
|
233
|
273
|
|
|
|
|
24263
|
$$this->{ parser } = $parser ; |
234
|
|
|
|
|
|
|
|
235
|
273
|
|
|
|
|
2141
|
$parser = &XML::Smart::Tree::load($parser) ; |
236
|
|
|
|
|
|
|
|
237
|
273
|
100
|
66
|
|
|
1696
|
if ( !($file) or $file eq '') { $$this->{tree} = {} ;} |
|
88
|
|
|
|
|
351
|
|
238
|
|
|
|
|
|
|
else { |
239
|
185
|
|
|
|
|
280
|
eval { |
240
|
185
|
|
|
|
|
774
|
$$this->{tree} = &XML::Smart::Tree::parse($file,$parser,@_) ; |
241
|
185
|
50
|
|
|
|
597
|
}; croak( $@ ) if( $@ ); |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
|
244
|
273
|
|
|
|
|
982
|
$$this->{point} = $$this->{tree} ; |
245
|
273
|
|
|
|
|
860
|
bless($this,$class) ; |
246
|
|
|
|
|
|
|
|
247
|
273
|
|
|
|
|
921
|
return $this ; |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
######### |
252
|
|
|
|
|
|
|
# CLONE # |
253
|
|
|
|
|
|
|
######### |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
sub clone { |
256
|
|
|
|
|
|
|
|
257
|
1502
|
|
|
1502
|
0
|
1759
|
my $saver = shift ; |
258
|
|
|
|
|
|
|
|
259
|
1502
|
|
|
|
|
1655
|
my ($pointer , $back , $array , $key , $i , $null_clone) ; |
260
|
|
|
|
|
|
|
|
261
|
1502
|
100
|
66
|
|
|
4390
|
if ($#_ == 0 && !ref $_[0]) { |
262
|
147
|
|
|
|
|
283
|
my $nullkey = shift ; |
263
|
147
|
|
|
|
|
270
|
$pointer = {} ; |
264
|
147
|
|
|
|
|
245
|
$back = {} ; |
265
|
147
|
|
|
|
|
217
|
$null_clone = 1 ; |
266
|
|
|
|
|
|
|
|
267
|
147
|
|
|
|
|
352
|
($i) = ( $nullkey =~ /(?:^|\/)\/\[(\d+)\]$/s ); |
268
|
147
|
|
|
|
|
1050
|
($key) = ( $nullkey =~ /(.*?)(?:\/\/\[\d+\])?$/s ); |
269
|
147
|
100
|
|
|
|
538
|
if ($key =~ /^\/\[\d+\]$/) { $key = undef ;} |
|
3
|
|
|
|
|
8
|
|
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
else { |
273
|
1355
|
|
|
|
|
1586
|
$pointer = shift ; |
274
|
1355
|
|
|
|
|
1362
|
$back = shift ; |
275
|
1355
|
|
|
|
|
1524
|
$array = shift ; |
276
|
1355
|
|
|
|
|
1685
|
$key = shift ; |
277
|
1355
|
|
|
|
|
1634
|
$i = shift ; |
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
|
280
|
1502
|
|
|
|
|
6496
|
my $clone = Object::MultiType->new( |
281
|
|
|
|
|
|
|
boolsub => \&boolean , |
282
|
|
|
|
|
|
|
scalarsub => \&content , |
283
|
|
|
|
|
|
|
tiearray => 'XML::Smart::Tie::Array' , |
284
|
|
|
|
|
|
|
tiehash => 'XML::Smart::Tie::Hash' , |
285
|
|
|
|
|
|
|
tieonuse => 1 , |
286
|
|
|
|
|
|
|
code => \&find_arg , |
287
|
|
|
|
|
|
|
) ; |
288
|
1502
|
|
|
|
|
84897
|
bless($clone,__PACKAGE__) ; |
289
|
|
|
|
|
|
|
|
290
|
1502
|
100
|
|
|
|
3777
|
if ( !$saver->is_saver ) { $saver = $$saver ;} |
|
90
|
|
|
|
|
391
|
|
291
|
|
|
|
|
|
|
|
292
|
1502
|
100
|
|
|
|
6368
|
if (!$back) { |
293
|
1265
|
50
|
|
|
|
2442
|
if (!$pointer) { $back = $saver->{back} ;} |
|
0
|
|
|
|
|
0
|
|
294
|
1265
|
|
|
|
|
2105
|
else { $back = $saver->{point} ;} |
295
|
|
|
|
|
|
|
} |
296
|
|
|
|
|
|
|
|
297
|
1502
|
50
|
66
|
|
|
9001
|
if (!$array && !$pointer) { $array = $saver->{array} ;} |
|
0
|
|
|
|
|
0
|
|
298
|
|
|
|
|
|
|
|
299
|
1502
|
|
|
|
|
1676
|
my @keyprev ; |
300
|
|
|
|
|
|
|
|
301
|
1502
|
100
|
|
|
|
2966
|
if (defined $key) { @keyprev = $key ;} |
|
1223
|
50
|
|
|
|
3826
|
|
302
|
279
|
|
|
|
|
763
|
elsif (defined $i) { @keyprev = "[$i]" ;} |
303
|
|
|
|
|
|
|
|
304
|
1502
|
100
|
|
|
|
2693
|
if (!defined $key) { $key = $saver->{key} ;} |
|
279
|
|
|
|
|
484
|
|
305
|
1502
|
100
|
|
|
|
2915
|
if (!defined $i) { $i = $saver->{i} ;} |
|
992
|
|
|
|
|
1561
|
|
306
|
|
|
|
|
|
|
|
307
|
1502
|
50
|
|
|
|
2968
|
if (!$pointer) { $pointer = $saver->{point} ;} |
|
0
|
|
|
|
|
0
|
|
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
# my @call = caller ; |
310
|
|
|
|
|
|
|
# print STDERR "CLONE>> $key , $i >> @{$saver->{keyprev}} >> @_\n" ; |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
|
313
|
1502
|
|
|
|
|
4525
|
$$clone->{tree} = $saver->{tree} ; |
314
|
1502
|
|
|
|
|
2567
|
$$clone->{point} = $pointer ; |
315
|
1502
|
|
|
|
|
2278
|
$$clone->{back} = $back ; |
316
|
1502
|
|
|
|
|
2319
|
$$clone->{array} = $array ; |
317
|
1502
|
|
|
|
|
2604
|
$$clone->{key} = $key ; |
318
|
1502
|
|
|
|
|
2549
|
$$clone->{i} = $i ; |
319
|
|
|
|
|
|
|
|
320
|
1502
|
50
|
|
|
|
3188
|
if ( @keyprev ) { |
321
|
1502
|
100
|
|
|
|
3285
|
$$clone->{keyprev} = ( $saver->{keyprev} ) ? [@{$saver->{keyprev}}] : [] ; |
|
1078
|
|
|
|
|
3639
|
|
322
|
1502
|
|
|
|
|
1907
|
push(@{$$clone->{keyprev}} , @keyprev) ; |
|
1502
|
|
|
|
|
3795
|
|
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
|
325
|
1502
|
100
|
|
|
|
3301
|
if (defined $_[0]) { $$clone->{content} = \$_[0] ;} |
|
309
|
|
|
|
|
862
|
|
326
|
|
|
|
|
|
|
|
327
|
1502
|
100
|
66
|
|
|
7497
|
if ( $null_clone || $saver->{null} ) { |
328
|
147
|
|
|
|
|
332
|
$$clone->{null} = 1 ; |
329
|
|
|
|
|
|
|
## $$clone->{self} = $clone ; |
330
|
|
|
|
|
|
|
} |
331
|
|
|
|
|
|
|
|
332
|
1502
|
50
|
|
|
|
2946
|
$$clone->{XPATH} = $saver->{XPATH} if $saver->{XPATH} ; |
333
|
|
|
|
|
|
|
|
334
|
1502
|
|
|
|
|
8222
|
return( $clone ) ; |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
} |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
########### |
339
|
|
|
|
|
|
|
# BOOLEAN # |
340
|
|
|
|
|
|
|
########### |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
sub boolean { |
343
|
|
|
|
|
|
|
|
344
|
3839
|
|
|
3839
|
0
|
37100
|
my $this = shift ; |
345
|
|
|
|
|
|
|
|
346
|
3839
|
100
|
|
|
|
12117
|
if ( $this->null ) { |
347
|
204
|
|
|
|
|
1085
|
return 0 ; |
348
|
|
|
|
|
|
|
} else { |
349
|
3635
|
|
|
|
|
18919
|
return 1 ; |
350
|
|
|
|
|
|
|
} |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
######## |
355
|
|
|
|
|
|
|
# NULL # |
356
|
|
|
|
|
|
|
######## |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
sub null { |
359
|
|
|
|
|
|
|
|
360
|
4222
|
|
|
4222
|
1
|
4527
|
my $this = shift ; |
361
|
|
|
|
|
|
|
|
362
|
4222
|
100
|
|
|
|
9529
|
if( $$this->{null} ) { |
363
|
164
|
|
|
|
|
402
|
return 1 ; |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
|
366
|
4058
|
100
|
|
|
|
4171
|
if( (keys %{$$this->{tree}}) < 1 ) { |
|
4058
|
|
|
|
|
11100
|
|
367
|
52
|
|
|
|
|
136
|
return 1 ; |
368
|
|
|
|
|
|
|
} |
369
|
|
|
|
|
|
|
|
370
|
4006
|
|
|
|
|
8377
|
return ; |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
} |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
######## |
375
|
|
|
|
|
|
|
# BASE # |
376
|
|
|
|
|
|
|
######## |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
sub base { |
379
|
|
|
|
|
|
|
|
380
|
98
|
|
|
98
|
1
|
194
|
my $this = shift ; |
381
|
|
|
|
|
|
|
|
382
|
98
|
|
|
|
|
513
|
my $base = Object::MultiType->new( |
383
|
|
|
|
|
|
|
boolsub => \&boolean , |
384
|
|
|
|
|
|
|
scalarsub => \&content , |
385
|
|
|
|
|
|
|
tiearray => 'XML::Smart::Tie::Array' , |
386
|
|
|
|
|
|
|
tiehash => 'XML::Smart::Tie::Hash' , |
387
|
|
|
|
|
|
|
tieonuse => 1 , |
388
|
|
|
|
|
|
|
code => \&find_arg , |
389
|
|
|
|
|
|
|
) ; |
390
|
|
|
|
|
|
|
|
391
|
98
|
|
|
|
|
6099
|
bless($base,__PACKAGE__) ; |
392
|
|
|
|
|
|
|
|
393
|
98
|
|
|
|
|
260
|
$$base->{tree} = $this->tree ; |
394
|
98
|
|
|
|
|
241
|
$$base->{point} = $$base->{tree} ; |
395
|
|
|
|
|
|
|
|
396
|
98
|
|
|
|
|
170
|
return( $base ) ; |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
} |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
######## |
401
|
|
|
|
|
|
|
# BACK # |
402
|
|
|
|
|
|
|
######## |
403
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
sub back { |
405
|
|
|
|
|
|
|
|
406
|
171
|
|
|
171
|
1
|
551
|
my $this = shift ; |
407
|
|
|
|
|
|
|
|
408
|
171
|
|
|
|
|
232
|
my @tree ; |
409
|
171
|
100
|
|
|
|
543
|
if( $$this->{keyprev} ) { |
410
|
98
|
|
|
|
|
140
|
@tree = @{$$this->{keyprev}} ; |
|
98
|
|
|
|
|
333
|
|
411
|
|
|
|
|
|
|
} |
412
|
|
|
|
|
|
|
|
413
|
171
|
100
|
|
|
|
475
|
if( !@tree ) { |
414
|
73
|
|
|
|
|
356
|
return $this ; |
415
|
|
|
|
|
|
|
} |
416
|
|
|
|
|
|
|
|
417
|
98
|
|
|
|
|
171
|
my $last = pop(@tree) ; |
418
|
98
|
|
|
|
|
264
|
my $i = 0 ; |
419
|
98
|
100
|
|
|
|
295
|
if( $last =~ /^\[(\d+)\]$/ ) { |
420
|
12
|
|
|
|
|
31
|
$i = $1 ; |
421
|
12
|
|
|
|
|
21
|
$last = pop(@tree) ; |
422
|
|
|
|
|
|
|
} |
423
|
|
|
|
|
|
|
|
424
|
98
|
|
|
|
|
246
|
my $back = $this->base ; |
425
|
|
|
|
|
|
|
|
426
|
98
|
|
|
|
|
450
|
foreach my $tree_i ( @tree ) { |
427
|
144
|
100
|
|
|
|
1859
|
if ($tree_i =~ /^\[(\d+)\]$/) { |
428
|
21
|
|
|
|
|
50
|
my $i = $1 ; |
429
|
21
|
|
|
|
|
58
|
$back = $back->[$i] ; |
430
|
|
|
|
|
|
|
} else { |
431
|
123
|
|
|
|
|
317
|
$back = $back->{$tree_i} ; |
432
|
|
|
|
|
|
|
} |
433
|
|
|
|
|
|
|
} |
434
|
|
|
|
|
|
|
|
435
|
98
|
100
|
|
|
|
3425
|
if ( wantarray ) { |
436
|
11
|
|
|
|
|
44
|
return( $back , $last , $i ) ; |
437
|
|
|
|
|
|
|
} |
438
|
|
|
|
|
|
|
|
439
|
87
|
|
|
|
|
259
|
return( $back ) ; |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
} |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
######## |
444
|
|
|
|
|
|
|
# PATH # |
445
|
|
|
|
|
|
|
######## |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
sub path { |
448
|
|
|
|
|
|
|
|
449
|
18
|
|
|
18
|
1
|
538
|
my $this = shift ; |
450
|
18
|
|
|
|
|
28
|
my @tree = @{$$this->{keyprev}} ; |
|
18
|
|
|
|
|
149
|
|
451
|
|
|
|
|
|
|
|
452
|
18
|
|
|
|
|
25
|
my $path ; |
453
|
|
|
|
|
|
|
|
454
|
18
|
|
|
|
|
39
|
foreach my $tree_i ( @tree ) { |
455
|
78
|
100
|
|
|
|
248
|
$path .= '/' if $tree_i !~ /^\[\d+\]$/ ; |
456
|
78
|
|
|
|
|
114
|
$path .= $tree_i ; |
457
|
|
|
|
|
|
|
} |
458
|
|
|
|
|
|
|
|
459
|
18
|
|
|
|
|
115
|
return $path ; |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
} |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
################# |
464
|
|
|
|
|
|
|
# PATH_AS_XPATH # |
465
|
|
|
|
|
|
|
################# |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
sub path_as_xpath { |
468
|
|
|
|
|
|
|
|
469
|
9
|
|
|
9
|
1
|
21
|
my $this = shift ; |
470
|
9
|
|
|
|
|
20
|
my @tree = @{$$this->{keyprev}} ; |
|
9
|
|
|
|
|
51
|
|
471
|
|
|
|
|
|
|
|
472
|
9
|
|
|
|
|
18
|
my $path ; |
473
|
|
|
|
|
|
|
|
474
|
9
|
|
|
|
|
15
|
foreach my $tree_i ( @tree ) { |
475
|
42
|
100
|
|
|
|
117
|
if ( $tree_i =~ /^\[(\d+)\]$/ ) { |
476
|
15
|
|
|
|
|
37
|
my $i = $1 + 1 ; |
477
|
15
|
|
|
|
|
41
|
$path .= "[$i]" ; |
478
|
|
|
|
|
|
|
} else { |
479
|
27
|
|
|
|
|
58
|
$path .= "/$tree_i" ; |
480
|
|
|
|
|
|
|
} |
481
|
|
|
|
|
|
|
} |
482
|
|
|
|
|
|
|
|
483
|
9
|
|
|
|
|
36
|
$path =~ s/\[1\]$// ; |
484
|
|
|
|
|
|
|
|
485
|
9
|
|
|
|
|
39
|
my $t = $this->is_node ; |
486
|
|
|
|
|
|
|
|
487
|
9
|
100
|
|
|
|
257
|
if ( !$this->is_node ) { |
488
|
6
|
|
|
|
|
272
|
$path =~ s/\/([^\/]+)$/\/\@$1/s ; |
489
|
|
|
|
|
|
|
} |
490
|
|
|
|
|
|
|
|
491
|
9
|
|
|
|
|
123
|
return $path ; |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
} |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
######## |
496
|
|
|
|
|
|
|
# ROOT # |
497
|
|
|
|
|
|
|
######## |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
sub root { |
500
|
|
|
|
|
|
|
|
501
|
0
|
|
|
0
|
1
|
0
|
my $this = shift ; |
502
|
|
|
|
|
|
|
|
503
|
0
|
|
|
|
|
0
|
my $root = ( $this->base->nodes_keys )[0] ; |
504
|
|
|
|
|
|
|
|
505
|
0
|
|
|
|
|
0
|
return $root ; |
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
} |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
####### |
510
|
|
|
|
|
|
|
# KEY # |
511
|
|
|
|
|
|
|
####### |
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
sub key { |
514
|
|
|
|
|
|
|
|
515
|
78
|
|
|
78
|
1
|
112
|
my $this = shift ; |
516
|
78
|
|
|
|
|
99
|
my $k = @{$$this->{keyprev}}[ $#{$$this->{keyprev}} ] ; |
|
78
|
|
|
|
|
185
|
|
|
78
|
|
|
|
|
169
|
|
517
|
78
|
100
|
|
|
|
273
|
if ($k =~ /^\[(\d+)\]$/) { |
518
|
12
|
|
|
|
|
20
|
$k = @{$$this->{keyprev}}[ $#{$$this->{keyprev}} -1 ] ; |
|
12
|
|
|
|
|
29
|
|
|
12
|
|
|
|
|
31
|
|
519
|
|
|
|
|
|
|
} |
520
|
|
|
|
|
|
|
|
521
|
78
|
|
|
|
|
204
|
return $k ; |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
} |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
##### |
526
|
|
|
|
|
|
|
# I # |
527
|
|
|
|
|
|
|
##### |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
sub i { |
530
|
|
|
|
|
|
|
|
531
|
0
|
|
|
0
|
1
|
0
|
my $this = shift ; |
532
|
0
|
|
|
|
|
0
|
my $i = $$this->{i} ; |
533
|
|
|
|
|
|
|
|
534
|
0
|
|
|
|
|
0
|
return $i ; |
535
|
|
|
|
|
|
|
} |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
######## |
538
|
|
|
|
|
|
|
# COPY # |
539
|
|
|
|
|
|
|
######## |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
sub copy { |
542
|
|
|
|
|
|
|
|
543
|
78
|
|
|
78
|
1
|
1378
|
my $this = shift ; |
544
|
|
|
|
|
|
|
|
545
|
78
|
|
|
|
|
404
|
my $data = $this->data( noheader => 1 ) ; |
546
|
78
|
|
|
|
|
468
|
my $copy = XML::Smart->new( $data, $$this->{ parser } ) ; |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
|
549
|
78
|
100
|
|
|
|
351
|
if( $$this->{keyprev} ) { |
550
|
5
|
|
|
|
|
13
|
my @old_array = @{ $$this->{keyprev} } ; |
|
5
|
|
|
|
|
20
|
|
551
|
5
|
|
|
|
|
15
|
my @new_array = @old_array ; |
552
|
5
|
|
|
|
|
18
|
$$copy->{keyprev} = \@new_array ; |
553
|
|
|
|
|
|
|
} |
554
|
|
|
|
|
|
|
|
555
|
78
|
|
|
|
|
357
|
my ( $back , $key , $i ) = $copy->back ; |
556
|
|
|
|
|
|
|
|
557
|
78
|
|
|
|
|
298
|
_unset_sig_warn() ; |
558
|
78
|
100
|
|
|
|
855
|
if( $key ne '' ) { |
559
|
5
|
|
|
|
|
23
|
$copy = $back->{$key} ; |
560
|
5
|
50
|
|
|
|
20
|
$copy = $back->[$i] if $i ; |
561
|
|
|
|
|
|
|
} |
562
|
78
|
|
|
|
|
489
|
_reset_sig_warn() ; |
563
|
|
|
|
|
|
|
|
564
|
78
|
|
|
|
|
419
|
return $copy ; |
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
} |
567
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
############## |
569
|
|
|
|
|
|
|
# _COPY_HASH # |
570
|
|
|
|
|
|
|
############## |
571
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
sub _copy_hash { |
573
|
|
|
|
|
|
|
|
574
|
0
|
|
|
0
|
|
0
|
my ( $ref ) = @_ ; |
575
|
0
|
|
|
|
|
0
|
my $copy ; |
576
|
|
|
|
|
|
|
|
577
|
0
|
0
|
|
|
|
0
|
if( ref $ref eq 'HASH' ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
578
|
0
|
|
|
|
|
0
|
$copy = {} ; |
579
|
0
|
|
|
|
|
0
|
foreach my $Key ( keys %$ref ) { |
580
|
0
|
0
|
|
|
|
0
|
if( ref $$ref{$Key} ) { |
581
|
0
|
|
|
|
|
0
|
$$copy{$Key} =&_copy_hash($$ref{$Key}) ; |
582
|
|
|
|
|
|
|
} else { |
583
|
0
|
|
|
|
|
0
|
$$copy{$Key} = $$ref{$Key} ; |
584
|
|
|
|
|
|
|
} |
585
|
|
|
|
|
|
|
} |
586
|
|
|
|
|
|
|
} elsif( ref $ref eq 'ARRAY' ) { |
587
|
0
|
|
|
|
|
0
|
$copy = [] ; |
588
|
0
|
|
|
|
|
0
|
foreach my $i ( @$ref ) { |
589
|
0
|
0
|
|
|
|
0
|
if( ref $i ) { |
590
|
0
|
|
|
|
|
0
|
push( @$copy, &_copy_hash($i) ) ; |
591
|
|
|
|
|
|
|
} else { |
592
|
0
|
|
|
|
|
0
|
push( @$copy, $i ) ; |
593
|
|
|
|
|
|
|
} |
594
|
|
|
|
|
|
|
} |
595
|
|
|
|
|
|
|
} elsif( ref $ref eq 'SCALAR' ) { |
596
|
0
|
|
|
|
|
0
|
my $copy = $$ref ; |
597
|
0
|
|
|
|
|
0
|
return( \$copy ) ; |
598
|
|
|
|
|
|
|
} else { |
599
|
0
|
|
|
|
|
0
|
return( {} ) ; |
600
|
|
|
|
|
|
|
} |
601
|
|
|
|
|
|
|
|
602
|
0
|
|
|
|
|
0
|
return( $copy ) ; |
603
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
} |
605
|
|
|
|
|
|
|
|
606
|
|
|
|
|
|
|
########### |
607
|
|
|
|
|
|
|
# TREE_OK # |
608
|
|
|
|
|
|
|
########### |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
sub tree_ok { |
611
|
0
|
|
|
0
|
1
|
0
|
return _tree_ok_parse( &tree ) ; |
612
|
|
|
|
|
|
|
} |
613
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
############## |
615
|
|
|
|
|
|
|
# POINTER_OK # |
616
|
|
|
|
|
|
|
############## |
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
sub pointer_ok { |
619
|
0
|
|
|
0
|
1
|
0
|
return _tree_ok_parse( &pointer ) ; |
620
|
|
|
|
|
|
|
} |
621
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
sub tree_pointer_ok { |
623
|
0
|
|
|
0
|
1
|
0
|
&pointer_ok ; |
624
|
|
|
|
|
|
|
} |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
################## |
627
|
|
|
|
|
|
|
# _TREE_OK_PARSE # |
628
|
|
|
|
|
|
|
################## |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
sub _tree_ok_parse { |
631
|
|
|
|
|
|
|
|
632
|
0
|
|
|
0
|
|
0
|
my ( $ref ) = @_ ; |
633
|
0
|
|
|
|
|
0
|
my $copy ; |
634
|
|
|
|
|
|
|
|
635
|
0
|
0
|
|
|
|
0
|
if( ref $ref eq 'HASH' ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
636
|
0
|
|
|
|
|
0
|
$copy = {} ; |
637
|
0
|
|
|
|
|
0
|
foreach my $Key ( keys %$ref ) { |
638
|
0
|
0
|
0
|
|
|
0
|
next if $Key eq '/order' || $Key eq '/nodes' || $Key =~ /\/\.CONTENT\// ; |
|
|
|
0
|
|
|
|
|
639
|
0
|
0
|
|
|
|
0
|
if( ref $$ref{$Key} ) { |
640
|
0
|
|
|
|
|
0
|
$$copy{$Key} =&_tree_ok_parse($$ref{$Key}) ; |
641
|
|
|
|
|
|
|
} else { |
642
|
0
|
|
|
|
|
0
|
$$copy{$Key} = $$ref{$Key} ; |
643
|
|
|
|
|
|
|
} |
644
|
|
|
|
|
|
|
} |
645
|
|
|
|
|
|
|
} elsif( ref $ref eq 'ARRAY' ) { |
646
|
0
|
|
|
|
|
0
|
$copy = [] ; |
647
|
0
|
|
|
|
|
0
|
foreach my $i ( @$ref ) { |
648
|
0
|
0
|
|
|
|
0
|
if( ref $i ) { |
649
|
0
|
|
|
|
|
0
|
push( @$copy, &_tree_ok_parse($i) ) ; |
650
|
|
|
|
|
|
|
} else { |
651
|
0
|
|
|
|
|
0
|
push( @$copy, $i ) ; |
652
|
|
|
|
|
|
|
} |
653
|
|
|
|
|
|
|
} |
654
|
|
|
|
|
|
|
} elsif( ref $ref eq 'SCALAR' ) { |
655
|
0
|
|
|
|
|
0
|
my $copy = $$ref ; |
656
|
0
|
|
|
|
|
0
|
return( \$copy ) ; |
657
|
|
|
|
|
|
|
} else { |
658
|
0
|
|
|
|
|
0
|
return( {} ) ; |
659
|
|
|
|
|
|
|
} |
660
|
|
|
|
|
|
|
|
661
|
0
|
|
|
|
|
0
|
return( $copy ) ; |
662
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
} |
664
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
######## |
666
|
|
|
|
|
|
|
# TREE # |
667
|
|
|
|
|
|
|
######## |
668
|
|
|
|
|
|
|
|
669
|
|
|
|
|
|
|
sub tree { |
670
|
|
|
|
|
|
|
|
671
|
440
|
|
|
440
|
1
|
2000
|
my $hash_to_return = ${$_[0]}->{tree} ; |
|
440
|
|
|
|
|
1887
|
|
672
|
|
|
|
|
|
|
|
673
|
440
|
|
|
|
|
6665
|
return ( $hash_to_return ) ; |
674
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
} |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
sub tree_pointer { |
678
|
0
|
|
|
0
|
1
|
0
|
&pointer ; |
679
|
|
|
|
|
|
|
} |
680
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
############# |
682
|
|
|
|
|
|
|
# DUMP_TREE # |
683
|
|
|
|
|
|
|
############# |
684
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
sub dump_tree { |
686
|
0
|
|
|
0
|
1
|
0
|
require Data::Dumper ; |
687
|
0
|
|
|
|
|
0
|
local $Data::Dumper::Sortkeys = 1 ; |
688
|
0
|
|
|
|
|
0
|
return Data::Dumper::Dumper( &tree ) ; |
689
|
|
|
|
|
|
|
} |
690
|
|
|
|
|
|
|
|
691
|
|
|
|
|
|
|
sub dump_tree_ok { |
692
|
0
|
|
|
0
|
0
|
0
|
require Data::Dumper ; |
693
|
0
|
|
|
|
|
0
|
local $Data::Dumper::Sortkeys = 1 ; |
694
|
0
|
|
|
|
|
0
|
return Data::Dumper::Dumper( &tree_ok ) ; |
695
|
|
|
|
|
|
|
} |
696
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
|
698
|
|
|
|
|
|
|
################ |
699
|
|
|
|
|
|
|
# DUMP_POINTER # |
700
|
|
|
|
|
|
|
################ |
701
|
|
|
|
|
|
|
|
702
|
|
|
|
|
|
|
sub dump_pointer { |
703
|
0
|
|
|
0
|
1
|
0
|
require Data::Dumper ; |
704
|
0
|
|
|
|
|
0
|
local $Data::Dumper::Sortkeys = 1 ; |
705
|
0
|
|
|
|
|
0
|
return Data::Dumper::Dumper( &pointer ) ; |
706
|
|
|
|
|
|
|
} |
707
|
|
|
|
|
|
|
|
708
|
|
|
|
|
|
|
sub dump_pointer_ok { |
709
|
0
|
|
|
0
|
0
|
0
|
require Data::Dumper ; |
710
|
0
|
|
|
|
|
0
|
local $Data::Dumper::Sortkeys = 1 ; |
711
|
0
|
|
|
|
|
0
|
return Data::Dumper::Dumper( &pointer_ok ) ; |
712
|
|
|
|
|
|
|
} |
713
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
sub dump_tree_pointer { |
716
|
0
|
|
|
0
|
1
|
0
|
&dump_pointer ; |
717
|
|
|
|
|
|
|
} |
718
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
sub dump_tree_pointer_ok { |
720
|
0
|
|
|
0
|
0
|
0
|
&dump_pointer_ok ; |
721
|
|
|
|
|
|
|
} |
722
|
|
|
|
|
|
|
|
723
|
|
|
|
|
|
|
########### |
724
|
|
|
|
|
|
|
# POINTER # |
725
|
|
|
|
|
|
|
########### |
726
|
|
|
|
|
|
|
|
727
|
|
|
|
|
|
|
sub pointer { |
728
|
|
|
|
|
|
|
|
729
|
115
|
|
|
115
|
1
|
171
|
my $hash_to_return ; |
730
|
|
|
|
|
|
|
|
731
|
115
|
100
|
|
|
|
162
|
if ( ${$_[0]}->{content} ) { |
|
115
|
|
|
|
|
380
|
|
732
|
9
|
|
|
|
|
15
|
$hash_to_return = ${${$_[0]}->{content}} ; |
|
9
|
|
|
|
|
14
|
|
|
9
|
|
|
|
|
24
|
|
733
|
|
|
|
|
|
|
} else { |
734
|
106
|
|
|
|
|
146
|
$hash_to_return = ${$_[0]}->{point} ; |
|
106
|
|
|
|
|
248
|
|
735
|
|
|
|
|
|
|
} |
736
|
|
|
|
|
|
|
|
737
|
115
|
|
|
|
|
303
|
return ( $hash_to_return ) ; |
738
|
|
|
|
|
|
|
} |
739
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
############ |
741
|
|
|
|
|
|
|
# CUT_ROOT # |
742
|
|
|
|
|
|
|
############ |
743
|
|
|
|
|
|
|
|
744
|
|
|
|
|
|
|
sub cut_root { |
745
|
|
|
|
|
|
|
|
746
|
6
|
|
|
6
|
1
|
214
|
my $this = shift ; |
747
|
|
|
|
|
|
|
|
748
|
6
|
|
|
|
|
31
|
my @nodes = $this->nodes_keys ; |
749
|
|
|
|
|
|
|
|
750
|
6
|
50
|
|
|
|
22
|
if( $#nodes > 0 ) { |
751
|
0
|
|
|
|
|
0
|
return $this ; |
752
|
|
|
|
|
|
|
} |
753
|
|
|
|
|
|
|
|
754
|
6
|
|
|
|
|
11
|
my $root = $nodes[0] ; |
755
|
6
|
|
|
|
|
16
|
return( $this->{$root} ) ; |
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
} |
758
|
|
|
|
|
|
|
|
759
|
|
|
|
|
|
|
########### |
760
|
|
|
|
|
|
|
# IS_NODE # |
761
|
|
|
|
|
|
|
########### |
762
|
|
|
|
|
|
|
|
763
|
|
|
|
|
|
|
sub is_node { |
764
|
|
|
|
|
|
|
|
765
|
21
|
|
|
21
|
1
|
158
|
my $this = shift ; |
766
|
|
|
|
|
|
|
|
767
|
21
|
50
|
|
|
|
49
|
return if $this->null ; |
768
|
|
|
|
|
|
|
|
769
|
21
|
|
|
|
|
64
|
my $key = $this->key ; |
770
|
21
|
|
|
|
|
62
|
my $back = $this->back ; |
771
|
|
|
|
|
|
|
|
772
|
21
|
100
|
66
|
|
|
73
|
return 1 if( $back->{'/nodes'}{$key} || $back->{$key}->nodes_keys ) ; |
773
|
12
|
|
|
|
|
44
|
return undef ; |
774
|
|
|
|
|
|
|
|
775
|
|
|
|
|
|
|
} |
776
|
|
|
|
|
|
|
|
777
|
|
|
|
|
|
|
######## |
778
|
|
|
|
|
|
|
# ARGS # |
779
|
|
|
|
|
|
|
######## |
780
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
sub args { |
782
|
|
|
|
|
|
|
|
783
|
0
|
|
|
0
|
1
|
0
|
my $this = shift ; |
784
|
|
|
|
|
|
|
|
785
|
0
|
0
|
|
|
|
0
|
return () if $this->null ; |
786
|
|
|
|
|
|
|
|
787
|
0
|
|
|
|
|
0
|
my @args ; |
788
|
|
|
|
|
|
|
|
789
|
0
|
|
|
|
|
0
|
my $nodes = $this->back->{'/nodes'} ; |
790
|
0
|
|
|
|
|
0
|
my $pointer = $$this->{point} ; |
791
|
|
|
|
|
|
|
|
792
|
0
|
|
|
|
|
0
|
foreach my $Key ( keys %$this ) { |
793
|
|
|
|
|
|
|
|
794
|
0
|
0
|
|
|
|
0
|
next if( $$nodes{$Key} ) ; |
795
|
|
|
|
|
|
|
|
796
|
0
|
0
|
0
|
|
|
0
|
if( |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
797
|
0
|
|
|
|
|
0
|
( !ref $$pointer{ $Key} ) || |
798
|
|
|
|
|
|
|
( ref( $$pointer{ $Key} ) eq 'HASH') || |
799
|
|
|
|
|
|
|
( ref( $$pointer{ $Key} ) eq 'ARRAY' && $#{$$pointer{$Key}} == 0 ) |
800
|
|
|
|
|
|
|
) { |
801
|
|
|
|
|
|
|
|
802
|
0
|
|
|
|
|
0
|
push(@args , $Key) ; |
803
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
} |
805
|
|
|
|
|
|
|
} |
806
|
|
|
|
|
|
|
|
807
|
0
|
|
|
|
|
0
|
return @args ; |
808
|
|
|
|
|
|
|
} |
809
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
############### |
811
|
|
|
|
|
|
|
# ARGS_VALUES # |
812
|
|
|
|
|
|
|
############### |
813
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
sub args_values { |
815
|
|
|
|
|
|
|
|
816
|
0
|
|
|
0
|
1
|
0
|
my $this = shift ; |
817
|
|
|
|
|
|
|
|
818
|
0
|
0
|
|
|
|
0
|
return () if $this->null ; |
819
|
|
|
|
|
|
|
|
820
|
0
|
|
|
|
|
0
|
my @args = $this->args ; |
821
|
|
|
|
|
|
|
|
822
|
0
|
|
|
|
|
0
|
my @values ; |
823
|
|
|
|
|
|
|
|
824
|
0
|
|
|
|
|
0
|
foreach my $args_i ( @args ) { |
825
|
0
|
|
|
|
|
0
|
push( @values, $this->{$args_i} ) ; |
826
|
|
|
|
|
|
|
} |
827
|
|
|
|
|
|
|
|
828
|
0
|
|
|
|
|
0
|
return @values ; |
829
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
} |
831
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
######### |
833
|
|
|
|
|
|
|
# NODES # |
834
|
|
|
|
|
|
|
######### |
835
|
|
|
|
|
|
|
|
836
|
|
|
|
|
|
|
sub nodes { |
837
|
|
|
|
|
|
|
|
838
|
3
|
|
|
3
|
1
|
8
|
my $this = shift ; |
839
|
|
|
|
|
|
|
|
840
|
3
|
50
|
|
|
|
12
|
return () if $this->null ; |
841
|
|
|
|
|
|
|
|
842
|
3
|
|
|
|
|
10
|
my $nodes = $this->{'/nodes'}->pointer ; |
843
|
3
|
|
|
|
|
14
|
my $pointer = $$this->{point} ; |
844
|
|
|
|
|
|
|
|
845
|
3
|
|
|
|
|
152
|
my @nodes ; |
846
|
|
|
|
|
|
|
|
847
|
3
|
|
|
|
|
8
|
foreach my $Key ( keys %$this ) { |
848
|
|
|
|
|
|
|
|
849
|
9
|
50
|
66
|
|
|
72
|
if( |
|
|
|
33
|
|
|
|
|
|
|
|
66
|
|
|
|
|
850
|
0
|
|
|
|
|
0
|
$$nodes{$Key} || |
851
|
|
|
|
|
|
|
(ref($$pointer{$Key}) eq 'HASH') || |
852
|
|
|
|
|
|
|
(ref($$pointer{$Key}) eq 'ARRAY' && $#{$$pointer{$Key}} > 0) |
853
|
|
|
|
|
|
|
) { |
854
|
|
|
|
|
|
|
|
855
|
3
|
50
|
|
|
|
15
|
if( ref($$pointer{$Key}) eq 'ARRAY' ) { |
856
|
0
|
|
|
|
|
0
|
my $n = $#{$$pointer{$Key}} ; |
|
0
|
|
|
|
|
0
|
|
857
|
0
|
|
|
|
|
0
|
for my $i (0..$n) { |
858
|
0
|
|
|
|
|
0
|
push( @nodes, $this->{$Key}[$i] ) ; |
859
|
|
|
|
|
|
|
} |
860
|
|
|
|
|
|
|
} else { |
861
|
3
|
|
|
|
|
10
|
push( @nodes, $this->{$Key}[0] ) ; |
862
|
|
|
|
|
|
|
} |
863
|
|
|
|
|
|
|
} |
864
|
|
|
|
|
|
|
} |
865
|
|
|
|
|
|
|
|
866
|
3
|
|
|
|
|
102
|
return @nodes ; |
867
|
|
|
|
|
|
|
|
868
|
|
|
|
|
|
|
} |
869
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
############## |
871
|
|
|
|
|
|
|
# NODES_KEYS # |
872
|
|
|
|
|
|
|
############## |
873
|
|
|
|
|
|
|
|
874
|
|
|
|
|
|
|
sub nodes_keys { |
875
|
|
|
|
|
|
|
|
876
|
25
|
|
|
25
|
1
|
126
|
my $this = shift ; |
877
|
|
|
|
|
|
|
|
878
|
25
|
50
|
|
|
|
72
|
return () if $this->null ; |
879
|
|
|
|
|
|
|
|
880
|
|
|
|
|
|
|
|
881
|
25
|
|
|
|
|
87
|
my $nodes = $this->{'/nodes'}->pointer ; |
882
|
25
|
|
|
|
|
86
|
my $pointer = $$this->{point} ; |
883
|
|
|
|
|
|
|
|
884
|
25
|
|
|
|
|
676
|
my @nodes ; |
885
|
25
|
|
|
|
|
73
|
foreach my $Key ( keys %$this ) { |
886
|
19
|
50
|
66
|
|
|
109
|
if( |
|
|
|
33
|
|
|
|
|
|
|
|
66
|
|
|
|
|
887
|
0
|
|
|
|
|
0
|
$$nodes{$Key} || |
888
|
|
|
|
|
|
|
(ref($$pointer{$Key}) eq 'HASH') || |
889
|
|
|
|
|
|
|
(ref($$pointer{$Key}) eq 'ARRAY' && $#{$$pointer{$Key}} > 0) |
890
|
|
|
|
|
|
|
) { |
891
|
13
|
|
|
|
|
33
|
push(@nodes , $Key) ; |
892
|
|
|
|
|
|
|
} |
893
|
|
|
|
|
|
|
} |
894
|
|
|
|
|
|
|
|
895
|
25
|
|
|
|
|
148
|
return @nodes ; |
896
|
|
|
|
|
|
|
} |
897
|
|
|
|
|
|
|
|
898
|
|
|
|
|
|
|
############ |
899
|
|
|
|
|
|
|
# SET_NODE # |
900
|
|
|
|
|
|
|
############ |
901
|
|
|
|
|
|
|
|
902
|
|
|
|
|
|
|
sub set_node { |
903
|
|
|
|
|
|
|
|
904
|
18
|
|
|
18
|
1
|
41
|
my $this = shift ; |
905
|
18
|
|
|
|
|
44
|
my ( $bool ) = @_ ; |
906
|
|
|
|
|
|
|
|
907
|
18
|
100
|
|
|
|
54
|
if( !@_ ) { |
908
|
3
|
|
|
|
|
6
|
$bool = 1 ; |
909
|
|
|
|
|
|
|
} |
910
|
|
|
|
|
|
|
|
911
|
18
|
|
|
|
|
250
|
my $key = $this->key ; |
912
|
18
|
|
|
|
|
57
|
my $back = $this->back ; |
913
|
|
|
|
|
|
|
|
914
|
18
|
100
|
|
|
|
60
|
$back->{'/nodes'} = {} if( $back->{'/nodes'}->null ) ; |
915
|
18
|
|
|
|
|
61
|
my $nodes = $back->{'/nodes'}->pointer ; |
916
|
|
|
|
|
|
|
|
917
|
18
|
100
|
|
|
|
54
|
if( $bool ) { |
918
|
|
|
|
|
|
|
|
919
|
12
|
100
|
66
|
|
|
620
|
if( $$nodes{$key} && $$nodes{$key} =~ /^(\w+,\d+),(\d*)/ ) { |
920
|
3
|
|
|
|
|
16
|
$$nodes{$key} = "$1,1" ; |
921
|
|
|
|
|
|
|
} else { |
922
|
9
|
|
|
|
|
25
|
$$nodes{$key} = 1 ; |
923
|
|
|
|
|
|
|
} |
924
|
|
|
|
|
|
|
|
925
|
12
|
100
|
|
|
|
32
|
if ( !$this->{CONTENT} ) { |
926
|
9
|
|
|
|
|
48
|
my $content = $this->content ; |
927
|
9
|
50
|
|
|
|
45
|
$this->{CONTENT} = $content if $content ne '' ; |
928
|
|
|
|
|
|
|
} |
929
|
|
|
|
|
|
|
|
930
|
|
|
|
|
|
|
} else { |
931
|
|
|
|
|
|
|
|
932
|
6
|
|
|
|
|
179
|
delete $$nodes{$key} ; |
933
|
6
|
|
|
|
|
17
|
my @keys = keys %$this ; |
934
|
6
|
50
|
33
|
|
|
46
|
if( $#keys == 0 && $keys[0] eq 'CONTENT' ) { |
935
|
6
|
50
|
|
|
|
19
|
my $content = ( !$this->{CONTENT}->null ) ? $this->{CONTENT}('.') : $this->content ; |
936
|
6
|
|
|
|
|
46
|
$this->back->pointer->{$key} = $content ; |
937
|
|
|
|
|
|
|
} |
938
|
|
|
|
|
|
|
} |
939
|
|
|
|
|
|
|
|
940
|
|
|
|
|
|
|
} |
941
|
|
|
|
|
|
|
|
942
|
|
|
|
|
|
|
########### |
943
|
|
|
|
|
|
|
# SET_TAG # |
944
|
|
|
|
|
|
|
########### |
945
|
|
|
|
|
|
|
|
946
|
|
|
|
|
|
|
sub set_tag { |
947
|
0
|
|
|
0
|
1
|
0
|
&set_node ; |
948
|
|
|
|
|
|
|
} |
949
|
|
|
|
|
|
|
|
950
|
|
|
|
|
|
|
############# |
951
|
|
|
|
|
|
|
# SET_ORDER # |
952
|
|
|
|
|
|
|
############# |
953
|
|
|
|
|
|
|
|
954
|
|
|
|
|
|
|
sub set_order { |
955
|
6
|
|
|
6
|
1
|
12
|
my $this = shift ; |
956
|
6
|
|
|
|
|
15
|
my $pointer = $$this->{point} ; |
957
|
6
|
|
|
|
|
12
|
@{$$pointer{'/order'}} = @_ ; |
|
6
|
|
|
|
|
112
|
|
958
|
|
|
|
|
|
|
} |
959
|
|
|
|
|
|
|
|
960
|
|
|
|
|
|
|
sub order { |
961
|
6
|
|
|
6
|
1
|
10
|
my $this = shift ; |
962
|
6
|
|
|
|
|
14
|
my $pointer = $$this->{point} ; |
963
|
6
|
50
|
33
|
|
|
40
|
return @{$$pointer{'/order'}} if defined $$pointer{'/order'} && ref($$pointer{'/order'}) eq 'ARRAY' ; |
|
6
|
|
|
|
|
33
|
|
964
|
0
|
|
|
|
|
0
|
return() ; |
965
|
|
|
|
|
|
|
} |
966
|
|
|
|
|
|
|
|
967
|
|
|
|
|
|
|
############# |
968
|
|
|
|
|
|
|
# SET_CDATA # |
969
|
|
|
|
|
|
|
############# |
970
|
|
|
|
|
|
|
|
971
|
|
|
|
|
|
|
sub set_node_type { |
972
|
|
|
|
|
|
|
|
973
|
33
|
|
|
33
|
0
|
55
|
my $this = shift ; |
974
|
|
|
|
|
|
|
|
975
|
33
|
|
|
|
|
56
|
my ( $type, $bool ) = @_ ; |
976
|
33
|
50
|
|
|
|
86
|
if( $#_ < 1 ) { |
977
|
0
|
|
|
|
|
0
|
$bool = 1 ; |
978
|
|
|
|
|
|
|
} |
979
|
|
|
|
|
|
|
|
980
|
33
|
|
|
|
|
103
|
my $key = $this->key ; |
981
|
33
|
|
|
|
|
93
|
my $back = $this->back ; |
982
|
|
|
|
|
|
|
|
983
|
33
|
50
|
|
|
|
94
|
$back->{'/nodes'} = {} if( $back->{'/nodes'}->null ); |
984
|
33
|
|
|
|
|
90
|
my $nodes = $back->{'/nodes'}->pointer ; |
985
|
|
|
|
|
|
|
|
986
|
33
|
100
|
|
|
|
108
|
if( $bool ) { |
987
|
|
|
|
|
|
|
|
988
|
15
|
100
|
66
|
|
|
528
|
if( $$nodes{$key} && $$nodes{$key} =~ /^\w+,\d+,(\d*)/ ) { |
989
|
9
|
|
|
|
|
21
|
my $val = $1 ; |
990
|
9
|
|
|
|
|
31
|
$$nodes{$key} = "$type,1,$val" ; |
991
|
|
|
|
|
|
|
} else { |
992
|
6
|
50
|
|
|
|
22
|
my $existing_node_data = ( $$nodes{$key} ) ? $$nodes{$key} : "" ; |
993
|
6
|
|
|
|
|
32
|
$$nodes{$key} = "$type,1," . $existing_node_data ; |
994
|
|
|
|
|
|
|
} |
995
|
|
|
|
|
|
|
|
996
|
15
|
100
|
|
|
|
39
|
if( !$this->{CONTENT} ) { |
997
|
11
|
|
|
|
|
37
|
my $content = $this->content ; |
998
|
11
|
50
|
|
|
|
51
|
$this->{CONTENT} = $content if $content ne '' ; |
999
|
|
|
|
|
|
|
} |
1000
|
|
|
|
|
|
|
|
1001
|
|
|
|
|
|
|
} else { |
1002
|
|
|
|
|
|
|
|
1003
|
18
|
100
|
|
|
|
762
|
if( !$$nodes{$key} ) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1004
|
7
|
|
|
|
|
25
|
my $tp = _data_type( $back->{$key} ) ; |
1005
|
7
|
50
|
|
|
|
26
|
if ( $tp > 2 ) { $$nodes{$key} = "$type,0," ;} |
|
7
|
|
|
|
|
226
|
|
1006
|
|
|
|
|
|
|
} elsif( $$nodes{$key} eq '1' ) { |
1007
|
5
|
|
|
|
|
24
|
$$nodes{$key} = "$type,0,1" ; |
1008
|
|
|
|
|
|
|
} elsif( $$nodes{$key} =~ /^\w+,\d+,1/ ) { |
1009
|
6
|
|
|
|
|
32
|
$$nodes{$key} = "$type,0,1" ; |
1010
|
|
|
|
|
|
|
} elsif( $$nodes{$key} =~ /^\w+,\d+,0?$/ ) { |
1011
|
|
|
|
|
|
|
|
1012
|
0
|
|
|
|
|
0
|
delete $$nodes{$key} ; |
1013
|
0
|
|
|
|
|
0
|
my @keys = keys %$this ; |
1014
|
|
|
|
|
|
|
|
1015
|
0
|
0
|
0
|
|
|
0
|
if( $#keys == 0 && $keys[0] eq 'CONTENT') { |
1016
|
0
|
|
|
|
|
0
|
my $content = $this->{CONTENT}('.') ; |
1017
|
0
|
|
|
|
|
0
|
$this->back->pointer->{$key} = $content ; |
1018
|
|
|
|
|
|
|
} |
1019
|
|
|
|
|
|
|
|
1020
|
|
|
|
|
|
|
} |
1021
|
|
|
|
|
|
|
} |
1022
|
|
|
|
|
|
|
|
1023
|
|
|
|
|
|
|
} |
1024
|
|
|
|
|
|
|
|
1025
|
|
|
|
|
|
|
############# |
1026
|
|
|
|
|
|
|
# SET_CDATA # |
1027
|
|
|
|
|
|
|
############# |
1028
|
|
|
|
|
|
|
|
1029
|
|
|
|
|
|
|
sub set_cdata { |
1030
|
15
|
|
|
15
|
1
|
37
|
my $this = shift ; |
1031
|
15
|
|
|
|
|
61
|
$this->set_node_type('cdata',@_) ; |
1032
|
|
|
|
|
|
|
} |
1033
|
|
|
|
|
|
|
|
1034
|
|
|
|
|
|
|
############## |
1035
|
|
|
|
|
|
|
# SET_BINARY # |
1036
|
|
|
|
|
|
|
############## |
1037
|
|
|
|
|
|
|
|
1038
|
|
|
|
|
|
|
sub set_binary { |
1039
|
18
|
|
|
18
|
1
|
32
|
my $this = shift ; |
1040
|
18
|
|
|
|
|
59
|
$this->set_node_type('binary',@_) ; |
1041
|
|
|
|
|
|
|
} |
1042
|
|
|
|
|
|
|
|
1043
|
|
|
|
|
|
|
################# |
1044
|
|
|
|
|
|
|
# SET_AUTO_NODE # |
1045
|
|
|
|
|
|
|
################# |
1046
|
|
|
|
|
|
|
|
1047
|
|
|
|
|
|
|
sub set_auto_node { |
1048
|
|
|
|
|
|
|
|
1049
|
3
|
|
|
3
|
1
|
9
|
my $this = shift ; |
1050
|
|
|
|
|
|
|
|
1051
|
3
|
|
|
|
|
12
|
my $key = $this->key ; |
1052
|
3
|
|
|
|
|
13
|
my $back = $this->back ; |
1053
|
|
|
|
|
|
|
|
1054
|
3
|
50
|
|
|
|
12
|
$back->{'/nodes'} = {} if( $back->{'/nodes'}->null ); |
1055
|
3
|
|
|
|
|
12
|
my $nodes = $back->{'/nodes'}->pointer ; |
1056
|
|
|
|
|
|
|
|
1057
|
3
|
50
|
33
|
|
|
11
|
if( !$$nodes{$key} || $$nodes{$key} eq '1' ) { |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1058
|
|
|
|
|
|
|
# Do nothing. ; |
1059
|
|
|
|
|
|
|
} elsif( $$nodes{$key} =~ /^\w+,\d+,1/ ) { |
1060
|
3
|
|
|
|
|
128
|
$$nodes{$key} = 1 ; |
1061
|
|
|
|
|
|
|
} elsif( $$nodes{$key} =~ /^\w+,\d+,0?$/ ) { |
1062
|
|
|
|
|
|
|
|
1063
|
0
|
|
|
|
|
0
|
delete $$nodes{$key} ; |
1064
|
0
|
|
|
|
|
0
|
my @keys = keys %$this ; |
1065
|
|
|
|
|
|
|
|
1066
|
0
|
0
|
0
|
|
|
0
|
if( $#keys == 0 && $keys[0] eq 'CONTENT') { |
1067
|
0
|
|
|
|
|
0
|
my $content = $this->{CONTENT}('.') ; |
1068
|
0
|
|
|
|
|
0
|
$this->back->pointer->{$key} = $content ; |
1069
|
|
|
|
|
|
|
} |
1070
|
|
|
|
|
|
|
|
1071
|
|
|
|
|
|
|
} |
1072
|
|
|
|
|
|
|
|
1073
|
|
|
|
|
|
|
} |
1074
|
|
|
|
|
|
|
|
1075
|
|
|
|
|
|
|
############ |
1076
|
|
|
|
|
|
|
# SET_AUTO # |
1077
|
|
|
|
|
|
|
############ |
1078
|
|
|
|
|
|
|
|
1079
|
|
|
|
|
|
|
sub set_auto { |
1080
|
|
|
|
|
|
|
|
1081
|
3
|
|
|
3
|
1
|
9
|
my $this = shift ; |
1082
|
|
|
|
|
|
|
|
1083
|
3
|
|
|
|
|
13
|
my $key = $this->key ; |
1084
|
3
|
|
|
|
|
15
|
my $back = $this->back ; |
1085
|
|
|
|
|
|
|
|
1086
|
3
|
50
|
|
|
|
13
|
$back->{'/nodes'} = {} if $back->{'/nodes'}->null ; |
1087
|
3
|
|
|
|
|
12
|
my $nodes = $back->{'/nodes'}->pointer ; |
1088
|
|
|
|
|
|
|
|
1089
|
3
|
|
|
|
|
12
|
delete $$nodes{$key} ; |
1090
|
3
|
|
|
|
|
100
|
my @keys = keys %$this ; |
1091
|
3
|
50
|
33
|
|
|
30
|
if( $#keys == 0 && $keys[0] eq 'CONTENT') { |
1092
|
3
|
|
|
|
|
12
|
my $content = $this->{CONTENT}('.') ; |
1093
|
3
|
|
|
|
|
23
|
$this->back->pointer->{$key} = $content ; |
1094
|
|
|
|
|
|
|
} |
1095
|
|
|
|
|
|
|
|
1096
|
|
|
|
|
|
|
} |
1097
|
|
|
|
|
|
|
|
1098
|
|
|
|
|
|
|
############## |
1099
|
|
|
|
|
|
|
# _DATA_TYPE # |
1100
|
|
|
|
|
|
|
############## |
1101
|
|
|
|
|
|
|
|
1102
|
|
|
|
|
|
|
## 4 binary |
1103
|
|
|
|
|
|
|
## 3 CDATA |
1104
|
|
|
|
|
|
|
## 2 content |
1105
|
|
|
|
|
|
|
## 1 value |
1106
|
|
|
|
|
|
|
|
1107
|
|
|
|
|
|
|
sub _data_type { |
1108
|
|
|
|
|
|
|
|
1109
|
|
|
|
|
|
|
|
1110
|
1231
|
|
|
1231
|
|
78163
|
my $data = shift ; |
1111
|
|
|
|
|
|
|
|
1112
|
|
|
|
|
|
|
# TODO: 0x80, 0x81, 0x8d, 0x8f, 0x90, 0xa0 |
1113
|
1231
|
|
|
|
|
12553
|
my @bin_data = ( |
1114
|
|
|
|
|
|
|
0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8e, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, |
1115
|
|
|
|
|
|
|
0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9e, 0x9f, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, |
1116
|
|
|
|
|
|
|
0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, |
1117
|
|
|
|
|
|
|
0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, |
1118
|
|
|
|
|
|
|
0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, |
1119
|
|
|
|
|
|
|
0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, |
1120
|
|
|
|
|
|
|
0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x20, |
1121
|
|
|
|
|
|
|
); |
1122
|
|
|
|
|
|
|
|
1123
|
|
|
|
|
|
|
|
1124
|
1231
|
|
|
|
|
108006
|
my $bin_string = join( '', ( map( pack("H*", $_), @bin_data ) ) ) ; |
1125
|
|
|
|
|
|
|
|
1126
|
1231
|
100
|
100
|
|
|
25959
|
return 4 if( $data && ( |
|
|
|
66
|
|
|
|
|
1127
|
|
|
|
|
|
|
$data =~ /[^\w\d\s!"#\$\%&'\(\)\*\+,\-\.\/:;<=>\?\@\[\\\]\^\`\{\|}~~$bin_string]/s |
1128
|
|
|
|
|
|
|
or |
1129
|
|
|
|
|
|
|
$data =~ /(\240|\351|\361|\363|\341|\374|\340|\350|\366|\343|\355|\366|\344|\372|\364|\324|\301|\342)/s |
1130
|
|
|
|
|
|
|
) |
1131
|
|
|
|
|
|
|
) ; |
1132
|
1070
|
100
|
100
|
|
|
4947
|
return 3 if( $data && $data =~ /<.*?>/s ) ; |
1133
|
1048
|
100
|
100
|
|
|
4674
|
return 2 if( $data && $data =~ /[\r\n\t]/s ) ; |
1134
|
1019
|
|
|
|
|
11866
|
return 1 ; |
1135
|
|
|
|
|
|
|
} |
1136
|
|
|
|
|
|
|
|
1137
|
|
|
|
|
|
|
####### |
1138
|
|
|
|
|
|
|
# RET # |
1139
|
|
|
|
|
|
|
####### |
1140
|
|
|
|
|
|
|
|
1141
|
|
|
|
|
|
|
sub ret { |
1142
|
|
|
|
|
|
|
|
1143
|
27
|
|
|
27
|
0
|
38
|
my $this = shift ; |
1144
|
27
|
|
|
|
|
47
|
my $type = shift ; |
1145
|
|
|
|
|
|
|
|
1146
|
27
|
50
|
|
|
|
80
|
if ($type =~ /^\s*\s*$/si ) { |
1147
|
0
|
|
|
|
|
0
|
return $this->data_pointer( noheader => 1 ) ; |
1148
|
|
|
|
|
|
|
} |
1149
|
|
|
|
|
|
|
|
1150
|
27
|
|
|
|
|
42
|
my @ret ; |
1151
|
27
|
|
|
|
|
89
|
$type =~ s/[^<\$\@\%\.k]//gs ; |
1152
|
|
|
|
|
|
|
|
1153
|
27
|
100
|
|
|
|
96
|
if ($type =~ /^) { |
1154
|
6
|
|
|
|
|
22
|
$type =~ s/^<+// ; |
1155
|
|
|
|
|
|
|
|
1156
|
6
|
|
|
|
|
22
|
my ($back , $key , $i) = $this->back ; |
1157
|
|
|
|
|
|
|
|
1158
|
6
|
50
|
|
|
|
41
|
if( $type =~ /\$$/ ) { |
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1159
|
0
|
|
|
|
|
0
|
@ret = $back->{$key}[$i]->content ; |
1160
|
|
|
|
|
|
|
} elsif( $type =~ /\@$/ ) { |
1161
|
|
|
|
|
|
|
|
1162
|
6
|
|
|
|
|
9
|
@ret = @{$back} ; |
|
6
|
|
|
|
|
21
|
|
1163
|
|
|
|
|
|
|
|
1164
|
6
|
|
|
|
|
25
|
foreach my $ret_i ( @ret ) { |
1165
|
24
|
|
|
|
|
787
|
$ret_i = $ret_i->{$key}[$i] ; |
1166
|
|
|
|
|
|
|
} |
1167
|
|
|
|
|
|
|
|
1168
|
|
|
|
|
|
|
} elsif( $type =~ /\%$/ ) { |
1169
|
0
|
|
|
|
|
0
|
@ret = %{$back->{$key}[$i]} ; |
|
0
|
|
|
|
|
0
|
|
1170
|
|
|
|
|
|
|
} |
1171
|
|
|
|
|
|
|
} else { |
1172
|
|
|
|
|
|
|
|
1173
|
21
|
100
|
|
|
|
67
|
if( $this->null ) { |
1174
|
3
|
|
|
|
|
13
|
return ; |
1175
|
|
|
|
|
|
|
} |
1176
|
|
|
|
|
|
|
|
1177
|
18
|
50
|
|
|
|
181
|
if ($type =~ /\$$/) { @ret = $this->content ; } |
|
0
|
100
|
|
|
|
0
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
1178
|
6
|
|
|
|
|
10
|
elsif ($type =~ /\@$/) { @ret = @{$this} ; } |
|
6
|
|
|
|
|
25
|
|
1179
|
0
|
|
|
|
|
0
|
elsif ($type =~ /\%$/) { @ret = %{$this} ; } |
|
0
|
|
|
|
|
0
|
|
1180
|
9
|
|
|
|
|
29
|
elsif ($type =~ /\.$/) { @ret = $this->pointer ; } |
1181
|
|
|
|
|
|
|
elsif ($type =~ /[\@\%]k$/) { |
1182
|
|
|
|
|
|
|
|
1183
|
3
|
|
|
|
|
6
|
my @keys = keys %{$this} ; |
|
3
|
|
|
|
|
10
|
|
1184
|
|
|
|
|
|
|
|
1185
|
3
|
|
|
|
|
16
|
foreach my $key ( @keys ) { |
1186
|
9
|
|
|
|
|
15
|
my $n = $#{ $this->{$key} } ; |
|
9
|
|
|
|
|
24
|
|
1187
|
9
|
50
|
|
|
|
30
|
if ($n > 0) { |
1188
|
0
|
|
|
|
|
0
|
my @multi = ($key) x ($n+1) ; |
1189
|
0
|
|
|
|
|
0
|
push(@ret , @multi) ; |
1190
|
|
|
|
|
|
|
} else { |
1191
|
9
|
|
|
|
|
341
|
push(@ret , $key) ; |
1192
|
|
|
|
|
|
|
} |
1193
|
|
|
|
|
|
|
} |
1194
|
|
|
|
|
|
|
|
1195
|
|
|
|
|
|
|
} |
1196
|
|
|
|
|
|
|
} |
1197
|
|
|
|
|
|
|
|
1198
|
24
|
50
|
|
|
|
239
|
if( $type =~ /^\$./ ) { |
1199
|
0
|
|
|
|
|
0
|
foreach my $ret_i ( @ret ) { |
1200
|
0
|
0
|
|
|
|
0
|
if(ref($ret_i) eq 'XML::Smart') { |
1201
|
0
|
|
|
|
|
0
|
$ret_i = $ret_i->content ; |
1202
|
|
|
|
|
|
|
} |
1203
|
|
|
|
|
|
|
} |
1204
|
|
|
|
|
|
|
} |
1205
|
|
|
|
|
|
|
|
1206
|
|
|
|
|
|
|
|
1207
|
24
|
100
|
|
|
|
58
|
if( wantarray ) { |
1208
|
15
|
|
|
|
|
67
|
return( @ret ) ; |
1209
|
|
|
|
|
|
|
} |
1210
|
9
|
|
|
|
|
35
|
return $ret[0] ; |
1211
|
|
|
|
|
|
|
|
1212
|
|
|
|
|
|
|
} |
1213
|
|
|
|
|
|
|
|
1214
|
|
|
|
|
|
|
######## |
1215
|
|
|
|
|
|
|
# FIND # |
1216
|
|
|
|
|
|
|
######## |
1217
|
|
|
|
|
|
|
|
1218
|
|
|
|
|
|
|
sub find { |
1219
|
0
|
|
|
0
|
0
|
0
|
&find_arg |
1220
|
|
|
|
|
|
|
} |
1221
|
|
|
|
|
|
|
|
1222
|
|
|
|
|
|
|
############ |
1223
|
|
|
|
|
|
|
# FIND_ARG # |
1224
|
|
|
|
|
|
|
############ |
1225
|
|
|
|
|
|
|
|
1226
|
|
|
|
|
|
|
sub find_arg { |
1227
|
|
|
|
|
|
|
|
1228
|
102
|
|
|
102
|
0
|
2507
|
my $this = shift ; |
1229
|
102
|
100
|
66
|
|
|
483
|
if( $#_ == 0 && ref($_[0]) ne 'ARRAY' ) { |
1230
|
27
|
|
|
|
|
111
|
return $this->ret(@_) ; |
1231
|
|
|
|
|
|
|
} |
1232
|
|
|
|
|
|
|
|
1233
|
75
|
100
|
100
|
|
|
258
|
if( $#_ == 1 && $_[0] eq '[@]' ) { |
1234
|
3
|
|
|
|
|
8
|
my $arg = $_[1] ; |
1235
|
3
|
|
|
|
|
14
|
return $this->{$arg}('<@') ; |
1236
|
|
|
|
|
|
|
} |
1237
|
|
|
|
|
|
|
|
1238
|
72
|
|
|
|
|
101
|
my @search ; |
1239
|
|
|
|
|
|
|
|
1240
|
72
|
|
|
|
|
208
|
for( my $i = 0; $i <= $#_ ; ++$i ) { |
1241
|
75
|
100
|
33
|
|
|
678
|
if( ref($_[$i]) eq 'ARRAY' ) { |
|
|
50
|
33
|
|
|
|
|
1242
|
6
|
|
|
|
|
19
|
push(@search , $_[$i]) ; |
1243
|
|
|
|
|
|
|
} elsif( ref($_[$i]) ne 'ARRAY' && ref($_[$i+1]) ne 'ARRAY' && ref($_[$i+2]) ne 'ARRAY' ) { |
1244
|
69
|
|
|
|
|
224
|
push(@search , [$_[$i] , $_[$i+1] , $_[$i+2]]) ; |
1245
|
69
|
|
|
|
|
209
|
$i += 2 ; |
1246
|
|
|
|
|
|
|
} |
1247
|
|
|
|
|
|
|
} |
1248
|
|
|
|
|
|
|
|
1249
|
|
|
|
|
|
|
#use Data::Dumper ; print Dumper(\@search); |
1250
|
|
|
|
|
|
|
#print "*** @search\n" ; |
1251
|
|
|
|
|
|
|
|
1252
|
72
|
50
|
|
|
|
164
|
if ( !@search ) { |
1253
|
0
|
|
|
|
|
0
|
return ; |
1254
|
|
|
|
|
|
|
} |
1255
|
|
|
|
|
|
|
|
1256
|
72
|
|
|
|
|
153
|
my $key = $$this->{key} ; |
1257
|
|
|
|
|
|
|
|
1258
|
72
|
|
|
|
|
98
|
my @hashes ; |
1259
|
|
|
|
|
|
|
|
1260
|
72
|
100
|
|
|
|
314
|
if( ref($$this->{array}) ) { |
1261
|
69
|
|
|
|
|
76
|
push( @hashes, @{$$this->{array}} ) ; |
|
69
|
|
|
|
|
158
|
|
1262
|
|
|
|
|
|
|
} else { |
1263
|
|
|
|
|
|
|
|
1264
|
3
|
|
|
|
|
7
|
push( @hashes, $$this->{point} ) ; |
1265
|
|
|
|
|
|
|
|
1266
|
3
|
50
|
|
|
|
15
|
if( ref $$this->{point} eq 'HASH' ) { |
1267
|
3
|
|
|
|
|
7
|
foreach my $k ( sort keys %{$$this->{point}} ) { |
|
3
|
|
|
|
|
23
|
|
1268
|
15
|
100
|
|
|
|
62
|
push( @hashes, [$k,$$this->{point}{$k}]) if( ref($$this->{point}{$k}) eq 'HASH' ) ; |
1269
|
|
|
|
|
|
|
} |
1270
|
|
|
|
|
|
|
} |
1271
|
|
|
|
|
|
|
} |
1272
|
|
|
|
|
|
|
|
1273
|
72
|
|
|
|
|
160
|
my $i = -1 ; |
1274
|
72
|
|
|
|
|
210
|
my (@hash , @i) ; |
1275
|
72
|
|
|
|
|
115
|
my $notwant = !wantarray ; |
1276
|
|
|
|
|
|
|
|
1277
|
72
|
|
|
|
|
132
|
foreach my $hash_i ( @hashes ) { |
1278
|
|
|
|
|
|
|
|
1279
|
219
|
|
|
|
|
305
|
foreach my $search_i ( @search ) { |
1280
|
|
|
|
|
|
|
|
1281
|
222
|
|
|
|
|
228
|
my ($name , $type , $value) = @{$search_i} ; |
|
222
|
|
|
|
|
2046
|
|
1282
|
222
|
|
|
|
|
443
|
$type =~ s/\s//gs ; |
1283
|
|
|
|
|
|
|
|
1284
|
222
|
|
|
|
|
221
|
$i++ ; |
1285
|
222
|
|
|
|
|
224
|
my $hash ; |
1286
|
222
|
100
|
|
|
|
442
|
if (ref $hash_i eq 'ARRAY') { $hash = @$hash_i[1] ;} |
|
12
|
|
|
|
|
24
|
|
1287
|
210
|
|
|
|
|
246
|
else { $hash = $hash_i ;} |
1288
|
|
|
|
|
|
|
|
1289
|
222
|
|
|
|
|
202
|
my $data ; |
1290
|
222
|
50
|
|
|
|
470
|
if ($name =~ /^content$/i) { $name = 'CONTENT' ;} |
|
0
|
|
|
|
|
0
|
|
1291
|
222
|
50
|
|
|
|
564
|
$data = ref($hash) eq 'HASH' ? $$hash{$name} : $hash ; |
1292
|
222
|
100
|
|
|
|
452
|
$data = $$data{CONTENT} if ref($data) eq 'HASH' ; |
1293
|
|
|
|
|
|
|
|
1294
|
222
|
|
|
|
|
2253
|
_unset_sig_warn() ; |
1295
|
222
|
100
|
100
|
|
|
4426
|
if ($type eq 'eq' && $data eq $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} |
|
63
|
50
|
33
|
|
|
89
|
|
|
63
|
50
|
33
|
|
|
83
|
|
|
63
|
50
|
33
|
|
|
116
|
|
|
|
50
|
33
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
50
|
33
|
|
|
|
|
|
|
50
|
33
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
50
|
33
|
|
|
|
|
|
|
50
|
33
|
|
|
|
|
|
|
50
|
33
|
|
|
|
|
1296
|
0
|
|
|
|
|
0
|
elsif ($type eq 'ne' && $data ne $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1297
|
0
|
|
|
|
|
0
|
elsif ($type eq '==' && $data == $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1298
|
0
|
|
|
|
|
0
|
elsif ($type eq '!=' && $data != $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1299
|
0
|
|
|
|
|
0
|
elsif ($type eq '<=' && $data <= $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1300
|
21
|
|
|
|
|
37
|
elsif ($type eq '>=' && $data >= $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} |
|
21
|
|
|
|
|
37
|
|
|
21
|
|
|
|
|
45
|
|
1301
|
0
|
|
|
|
|
0
|
elsif ($type eq '<' && $data < $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1302
|
0
|
|
|
|
|
0
|
elsif ($type eq '>' && $data > $value) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1303
|
6
|
|
|
|
|
11
|
elsif ($type eq '=~' && $data =~ /$value/s) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} |
|
6
|
|
|
|
|
7
|
|
|
6
|
|
|
|
|
15
|
|
1304
|
0
|
|
|
|
|
0
|
elsif ($type eq '=~i' && $data =~ /$value/is) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1305
|
0
|
|
|
|
|
0
|
elsif ($type eq '!~' && $data !~ /$value/s) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1306
|
0
|
|
|
|
|
0
|
elsif ($type eq '!~i' && $data !~ /$value/is) { push(@hash,$hash_i) ; push(@i,$i) ; last ;} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1307
|
132
|
|
|
|
|
318
|
_reset_sig_warn() ; |
1308
|
|
|
|
|
|
|
} |
1309
|
|
|
|
|
|
|
|
1310
|
219
|
100
|
100
|
|
|
971
|
if( $notwant && @hash ) { |
1311
|
63
|
|
|
|
|
80
|
last ; |
1312
|
|
|
|
|
|
|
} |
1313
|
|
|
|
|
|
|
} |
1314
|
|
|
|
|
|
|
|
1315
|
72
|
|
|
|
|
199
|
my $back = $$this->{back} ; |
1316
|
|
|
|
|
|
|
|
1317
|
|
|
|
|
|
|
#print "FIND>> @{$$this->{keyprev}} >> $i\n" ; |
1318
|
|
|
|
|
|
|
|
1319
|
72
|
50
|
|
|
|
150
|
if( @hash ) { |
1320
|
72
|
100
|
|
|
|
137
|
if( $notwant ) { |
1321
|
63
|
|
|
|
|
90
|
my ($k,$hash) = (undef) ; |
1322
|
63
|
50
|
|
|
|
136
|
if (ref $hash[0] eq 'ARRAY') { ($k,$hash) = @{$hash[0]} ;} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1323
|
63
|
|
|
|
|
84
|
else { $hash = $hash[0] ;} |
1324
|
63
|
|
|
|
|
154
|
return &XML::Smart::clone($this,$hash,$back,undef, $k,$i[0]) ; |
1325
|
|
|
|
|
|
|
} |
1326
|
|
|
|
|
|
|
else { |
1327
|
9
|
|
|
|
|
19
|
my $c = -1 ; |
1328
|
9
|
|
|
|
|
19
|
foreach my $hash_i ( @hash ) { |
1329
|
27
|
|
|
|
|
28
|
$c++ ; |
1330
|
27
|
|
|
|
|
851
|
my ($k,$hash) = (undef) ; |
1331
|
27
|
100
|
|
|
|
62
|
if (ref $hash_i eq 'ARRAY') { ($k,$hash) = @{$hash_i} ;} |
|
6
|
|
|
|
|
7
|
|
|
6
|
|
|
|
|
16
|
|
1332
|
21
|
|
|
|
|
26
|
else { $hash = $hash_i ;} |
1333
|
27
|
|
|
|
|
65
|
$hash_i = &XML::Smart::clone($this,$hash,$back,undef, $k,$i[$c]) ; |
1334
|
|
|
|
|
|
|
} |
1335
|
9
|
|
|
|
|
53
|
return( @hash ) ; |
1336
|
|
|
|
|
|
|
} |
1337
|
|
|
|
|
|
|
} |
1338
|
|
|
|
|
|
|
|
1339
|
0
|
0
|
|
|
|
0
|
if (wantarray) { return() ;} |
|
0
|
|
|
|
|
0
|
|
1340
|
0
|
|
|
|
|
0
|
return &XML::Smart::clone($this,'') ; |
1341
|
|
|
|
|
|
|
} |
1342
|
|
|
|
|
|
|
|
1343
|
|
|
|
|
|
|
########### |
1344
|
|
|
|
|
|
|
# CONTENT # |
1345
|
|
|
|
|
|
|
########### |
1346
|
|
|
|
|
|
|
sub content { |
1347
|
|
|
|
|
|
|
|
1348
|
250
|
|
|
250
|
1
|
17327
|
my $this = shift ; |
1349
|
250
|
100
|
|
|
|
656
|
my $set_i = $#_ > 0 ? shift : undef ; |
1350
|
|
|
|
|
|
|
|
1351
|
250
|
100
|
|
|
|
543
|
if ( $this->null ) { |
1352
|
3
|
|
|
|
|
25
|
&XML::Smart::Tie::_generate_nulltree( $$this ) ; |
1353
|
|
|
|
|
|
|
} |
1354
|
|
|
|
|
|
|
|
1355
|
|
|
|
|
|
|
##use Data::Dumper; print Dumper($$this) ; |
1356
|
|
|
|
|
|
|
|
1357
|
250
|
|
|
|
|
291
|
my $content_to_return ; |
1358
|
250
|
100
|
66
|
|
|
1125
|
if ( defined $$this->{content} and ( !defined( $content_to_return ) ) ) { |
1359
|
153
|
50
|
|
|
|
322
|
if (@_) { ${$$this->{content}} = $_[0] ;} |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1360
|
153
|
|
|
|
|
184
|
$content_to_return = ${$$this->{content}} ; |
|
153
|
|
|
|
|
374
|
|
1361
|
|
|
|
|
|
|
} |
1362
|
|
|
|
|
|
|
|
1363
|
250
|
|
|
|
|
334
|
my $key = 'CONTENT' ; |
1364
|
250
|
|
|
|
|
410
|
my $i = $$this->{i} ; |
1365
|
|
|
|
|
|
|
|
1366
|
250
|
50
|
33
|
|
|
737
|
if( ( ref($$this->{point}) eq 'ARRAY' ) and ( !defined( $content_to_return ) ) ) { |
1367
|
0
|
|
|
|
|
0
|
$content_to_return = $this->[0]->content($set_i,@_) ; |
1368
|
|
|
|
|
|
|
} |
1369
|
|
|
|
|
|
|
|
1370
|
250
|
50
|
33
|
|
|
713
|
if( ( ref($$this->{point}) ne 'HASH' ) and ( !defined( $content_to_return ) ) ) { |
1371
|
0
|
|
|
|
|
0
|
$content_to_return = '' ; |
1372
|
|
|
|
|
|
|
} |
1373
|
|
|
|
|
|
|
|
1374
|
250
|
100
|
66
|
|
|
803
|
if( ( !exists $$this->{point}{$key} ) and ( !defined( $content_to_return ) ) ) { |
1375
|
3
|
50
|
|
|
|
9
|
if( @_ ) { |
1376
|
3
|
|
|
|
|
10
|
$content_to_return = $$this->{point}{$key} = $_[0] ; |
1377
|
|
|
|
|
|
|
} else { |
1378
|
0
|
|
|
|
|
0
|
$content_to_return = '' ; |
1379
|
|
|
|
|
|
|
} |
1380
|
|
|
|
|
|
|
} |
1381
|
|
|
|
|
|
|
|
1382
|
250
|
100
|
|
|
|
478
|
if( defined( $content_to_return ) ) { |
1383
|
156
|
|
|
|
|
1068
|
return $content_to_return ; |
1384
|
|
|
|
|
|
|
} |
1385
|
|
|
|
|
|
|
|
1386
|
|
|
|
|
|
|
|
1387
|
94
|
50
|
33
|
|
|
665
|
if( ( ref($$this->{point}{$key}) eq 'ARRAY' ) and ( !defined( $content_to_return ) ) ) { |
|
|
50
|
33
|
|
|
|
|
1388
|
|
|
|
|
|
|
|
1389
|
0
|
0
|
|
|
|
0
|
if($i eq '') { |
1390
|
0
|
|
|
|
|
0
|
$i = 0 ; |
1391
|
|
|
|
|
|
|
} |
1392
|
|
|
|
|
|
|
|
1393
|
0
|
0
|
|
|
|
0
|
if(@_) { |
1394
|
0
|
|
|
|
|
0
|
$$this->{point}{$key}[$i] = $_[0] ; |
1395
|
|
|
|
|
|
|
} |
1396
|
|
|
|
|
|
|
|
1397
|
0
|
|
|
|
|
0
|
$content_to_return = $$this->{point}{$key}[$i] ; |
1398
|
|
|
|
|
|
|
|
1399
|
|
|
|
|
|
|
} elsif( ( exists $$this->{point}{$key} ) and ( !defined( $content_to_return ) ) ) { |
1400
|
|
|
|
|
|
|
|
1401
|
94
|
100
|
|
|
|
187
|
if ( @_ ) { |
1402
|
9
|
100
|
|
|
|
29
|
if ( my $tie = tied($$this->{point}{$key}) ) { |
1403
|
3
|
|
|
|
|
19
|
$tie->STORE($set_i , $_[0]) ; |
1404
|
|
|
|
|
|
|
} else { |
1405
|
6
|
|
|
|
|
19
|
$$this->{point}{$key} = $_[0] ; |
1406
|
|
|
|
|
|
|
} |
1407
|
|
|
|
|
|
|
} |
1408
|
|
|
|
|
|
|
|
1409
|
94
|
100
|
66
|
|
|
251
|
if( wantarray && ( my $tie = tied($$this->{point}{$key} ) ) ) { |
1410
|
3
|
|
|
|
|
12
|
my @tmp = $tie->FETCH(1) ; |
1411
|
3
|
|
|
|
|
8
|
$content_to_return = \@tmp ; |
1412
|
|
|
|
|
|
|
} else { |
1413
|
91
|
|
|
|
|
228
|
$content_to_return = $$this->{point}{$key} ; |
1414
|
|
|
|
|
|
|
} |
1415
|
|
|
|
|
|
|
|
1416
|
|
|
|
|
|
|
} |
1417
|
|
|
|
|
|
|
|
1418
|
94
|
50
|
|
|
|
186
|
unless( defined( $content_to_return ) ) { |
1419
|
0
|
|
|
|
|
0
|
$content_to_return = '' ; |
1420
|
|
|
|
|
|
|
} |
1421
|
|
|
|
|
|
|
|
1422
|
94
|
100
|
|
|
|
147
|
if( wantarray ) { |
1423
|
3
|
|
|
|
|
3
|
return @{ $content_to_return } ; |
|
3
|
|
|
|
|
14
|
|
1424
|
|
|
|
|
|
|
} else { |
1425
|
91
|
|
|
|
|
678
|
return $content_to_return ; |
1426
|
|
|
|
|
|
|
} |
1427
|
|
|
|
|
|
|
|
1428
|
|
|
|
|
|
|
} |
1429
|
|
|
|
|
|
|
|
1430
|
|
|
|
|
|
|
######## |
1431
|
|
|
|
|
|
|
# SAVE # |
1432
|
|
|
|
|
|
|
######## |
1433
|
|
|
|
|
|
|
|
1434
|
|
|
|
|
|
|
sub save { |
1435
|
|
|
|
|
|
|
|
1436
|
0
|
|
|
0
|
1
|
0
|
my $this = shift ; |
1437
|
0
|
|
|
|
|
0
|
my $file = shift ; |
1438
|
|
|
|
|
|
|
|
1439
|
0
|
0
|
0
|
|
|
0
|
if(-d $file || (-e $file && !-w $file)) { |
|
|
|
0
|
|
|
|
|
1440
|
0
|
|
|
|
|
0
|
return ; |
1441
|
|
|
|
|
|
|
} |
1442
|
|
|
|
|
|
|
|
1443
|
0
|
|
|
|
|
0
|
my( $data, $unicode ) = $this->data(@_) ; |
1444
|
|
|
|
|
|
|
|
1445
|
0
|
|
|
|
|
0
|
my $fh ; |
1446
|
0
|
|
|
|
|
0
|
open($fh,">$file") ; |
1447
|
0
|
0
|
|
|
|
0
|
binmode($fh) if $unicode ; |
1448
|
0
|
|
|
|
|
0
|
print $fh $data ; |
1449
|
0
|
|
|
|
|
0
|
close($fh) ; |
1450
|
|
|
|
|
|
|
|
1451
|
0
|
|
|
|
|
0
|
return( 1 ) ; |
1452
|
|
|
|
|
|
|
|
1453
|
|
|
|
|
|
|
} |
1454
|
|
|
|
|
|
|
|
1455
|
|
|
|
|
|
|
################ |
1456
|
|
|
|
|
|
|
# DATA_POINTER # |
1457
|
|
|
|
|
|
|
################ |
1458
|
|
|
|
|
|
|
|
1459
|
|
|
|
|
|
|
sub data_pointer { |
1460
|
|
|
|
|
|
|
|
1461
|
0
|
|
|
0
|
1
|
0
|
my $this = shift ; |
1462
|
0
|
0
|
|
|
|
0
|
if( $this->null ) { |
1463
|
0
|
|
|
|
|
0
|
return ; |
1464
|
|
|
|
|
|
|
} |
1465
|
|
|
|
|
|
|
|
1466
|
0
|
|
|
|
|
0
|
my( $point, $key ) ; |
1467
|
|
|
|
|
|
|
|
1468
|
0
|
0
|
|
|
|
0
|
if ( exists $$this->{content} ) { |
1469
|
0
|
|
|
|
|
0
|
my $back = $this->back ; |
1470
|
0
|
|
|
|
|
0
|
my $root = $back->key ; |
1471
|
0
|
|
|
|
|
0
|
my $k = $this->key ; |
1472
|
0
|
|
|
|
|
0
|
$point = $back->pointer ; |
1473
|
0
|
|
|
|
|
0
|
$point = $$point{ $this->key } ; |
1474
|
0
|
|
|
|
|
0
|
$point = {$root => {$k => $point} } ; |
1475
|
|
|
|
|
|
|
} else { |
1476
|
0
|
|
|
|
|
0
|
$point = $$this->{point} ; |
1477
|
0
|
|
|
|
|
0
|
$key = $this->key ; |
1478
|
|
|
|
|
|
|
} |
1479
|
|
|
|
|
|
|
|
1480
|
0
|
|
|
|
|
0
|
$this->data( tree => $point , root => $key , @_) ; |
1481
|
|
|
|
|
|
|
|
1482
|
|
|
|
|
|
|
} |
1483
|
|
|
|
|
|
|
|
1484
|
|
|
|
|
|
|
########### |
1485
|
|
|
|
|
|
|
# DESTROY # |
1486
|
|
|
|
|
|
|
########### |
1487
|
|
|
|
|
|
|
|
1488
|
|
|
|
|
|
|
sub DESTROY { |
1489
|
|
|
|
|
|
|
|
1490
|
1873
|
|
|
1873
|
|
254761
|
my $this = shift ; |
1491
|
|
|
|
|
|
|
|
1492
|
1873
|
50
|
|
|
|
5622
|
if( $$this->{ DEV_DEBUG } ) { |
1493
|
0
|
|
|
|
|
0
|
require Devel::Cycle ; |
1494
|
0
|
|
|
|
|
0
|
my $circ_ref = 0 ; |
1495
|
|
|
|
|
|
|
my $tmp = Devel::Cycle::find_cycle( |
1496
|
|
|
|
|
|
|
$this, |
1497
|
|
|
|
|
|
|
sub { |
1498
|
0
|
|
|
0
|
|
0
|
my $path = shift; |
1499
|
0
|
|
|
|
|
0
|
foreach (@$path) { |
1500
|
0
|
|
|
|
|
0
|
my ($type,$index,$ref,$value) = @$_; |
1501
|
0
|
|
|
|
|
0
|
$circ_ref = 1 ; |
1502
|
|
|
|
|
|
|
|
1503
|
|
|
|
|
|
|
} |
1504
|
|
|
|
|
|
|
|
1505
|
0
|
|
|
|
|
0
|
}); |
1506
|
|
|
|
|
|
|
|
1507
|
0
|
0
|
|
|
|
0
|
if( $circ_ref ) { |
1508
|
0
|
|
|
|
|
0
|
$this->ANNIHILATE() ; |
1509
|
|
|
|
|
|
|
my $tmp = Devel::Cycle::find_cycle( |
1510
|
|
|
|
|
|
|
$this, |
1511
|
|
|
|
|
|
|
sub { |
1512
|
0
|
|
|
0
|
|
0
|
print STDERR "Circular reference found while destroying object - AFTER ANNIHILATE\n" ; |
1513
|
0
|
|
|
|
|
0
|
}); |
1514
|
|
|
|
|
|
|
} |
1515
|
|
|
|
|
|
|
} |
1516
|
|
|
|
|
|
|
|
1517
|
1873
|
100
|
66
|
|
|
4957
|
$$this->clean if( $this && $$this ) ; # In case object was messed with ( bug 62091 ) |
1518
|
|
|
|
|
|
|
|
1519
|
|
|
|
|
|
|
|
1520
|
|
|
|
|
|
|
} |
1521
|
|
|
|
|
|
|
|
1522
|
|
|
|
|
|
|
sub ANNIHILATE { |
1523
|
|
|
|
|
|
|
|
1524
|
0
|
|
|
0
|
1
|
|
my $this = shift ; |
1525
|
0
|
|
|
|
|
|
my $base = shift ; |
1526
|
|
|
|
|
|
|
|
1527
|
0
|
0
|
|
|
|
|
if( ref $$this->{ point } eq 'HASH' ) { |
1528
|
0
|
|
|
|
|
|
my %clean ; |
1529
|
0
|
|
|
|
|
|
$$this->{ point } = \%clean ; |
1530
|
|
|
|
|
|
|
} else { |
1531
|
0
|
|
|
|
|
|
$this->{ point }->ANNIHILATE( ) ; |
1532
|
|
|
|
|
|
|
} |
1533
|
|
|
|
|
|
|
|
1534
|
0
|
0
|
|
|
|
|
if( ref $$this->{ tree } eq 'HASH' ) { |
1535
|
0
|
|
|
|
|
|
my %clean ; |
1536
|
0
|
|
|
|
|
|
$$this->{ tree } = \%clean ; |
1537
|
|
|
|
|
|
|
} else { |
1538
|
0
|
|
|
|
|
|
$this->{ tree }->ANNIHILATE( ) ; |
1539
|
|
|
|
|
|
|
} |
1540
|
|
|
|
|
|
|
|
1541
|
|
|
|
|
|
|
|
1542
|
0
|
0
|
|
|
|
|
if( ref $$this->{ back } eq 'HASH' ) { |
1543
|
0
|
|
|
|
|
|
my %clean ; |
1544
|
0
|
|
|
|
|
|
$$this->{ back } = \%clean ; |
1545
|
|
|
|
|
|
|
} else { |
1546
|
0
|
|
|
|
|
|
$this->{ back }->ANNIHILATE( ) ; |
1547
|
|
|
|
|
|
|
} |
1548
|
|
|
|
|
|
|
|
1549
|
0
|
0
|
|
|
|
|
if( $$this->{ XPATH } ) { # and ( ref $$this->{ XPATH } eq 'XML::XPath' ) ) { |
1550
|
0
|
|
|
|
|
|
my $xpath = $$this->{ XPATH } ; |
1551
|
0
|
|
|
|
|
|
$$xpath->cleanup() ; |
1552
|
0
|
|
|
|
|
|
my $context = $$xpath->{ _context } ; |
1553
|
0
|
|
|
|
|
|
my $context_ref = ref $context ; |
1554
|
0
|
0
|
|
|
|
|
if( $context_ref =~ /XML\:\:XPath\:\:Node\:\:/ ) { |
1555
|
0
|
|
|
|
|
|
_xml_xpath_clean( $context ) ; |
1556
|
|
|
|
|
|
|
} |
1557
|
|
|
|
|
|
|
} |
1558
|
|
|
|
|
|
|
|
1559
|
0
|
|
|
|
|
|
$$this->DESTROY(); |
1560
|
|
|
|
|
|
|
|
1561
|
0
|
|
|
|
|
|
return 1 ; |
1562
|
|
|
|
|
|
|
|
1563
|
|
|
|
|
|
|
} |
1564
|
|
|
|
|
|
|
|
1565
|
|
|
|
|
|
|
|
1566
|
|
|
|
|
|
|
sub _xml_xpath_clean { |
1567
|
|
|
|
|
|
|
|
1568
|
0
|
|
|
0
|
|
|
my $path = shift ; |
1569
|
|
|
|
|
|
|
|
1570
|
0
|
|
|
|
|
|
$path->dispose() ; |
1571
|
|
|
|
|
|
|
# Data::Structure::Util::unbless( $path ) ; |
1572
|
|
|
|
|
|
|
|
1573
|
0
|
|
|
|
|
|
return ; |
1574
|
|
|
|
|
|
|
|
1575
|
|
|
|
|
|
|
} |
1576
|
|
|
|
|
|
|
|
1577
|
|
|
|
|
|
|
################### |
1578
|
|
|
|
|
|
|
# STORABLE_FREEZE # |
1579
|
|
|
|
|
|
|
################### |
1580
|
|
|
|
|
|
|
|
1581
|
|
|
|
|
|
|
sub STORABLE_freeze { |
1582
|
0
|
|
|
0
|
0
|
|
my $this = shift ; |
1583
|
0
|
|
|
|
|
|
return($this , [$$this->{tree} , $$this->{pointer}]) ; |
1584
|
|
|
|
|
|
|
} |
1585
|
|
|
|
|
|
|
|
1586
|
|
|
|
|
|
|
################# |
1587
|
|
|
|
|
|
|
# STORABLE_THAW # |
1588
|
|
|
|
|
|
|
################# |
1589
|
|
|
|
|
|
|
|
1590
|
|
|
|
|
|
|
sub STORABLE_thaw { |
1591
|
0
|
|
|
0
|
0
|
|
my $this = shift ; |
1592
|
0
|
|
|
|
|
|
$$this->{tree} = $_[1]->[0] ; |
1593
|
0
|
|
|
|
|
|
$$this->{pointer} = $_[1]->[1] ; |
1594
|
0
|
|
|
|
|
|
return ; |
1595
|
|
|
|
|
|
|
} |
1596
|
|
|
|
|
|
|
|
1597
|
|
|
|
|
|
|
####### |
1598
|
|
|
|
|
|
|
# END # |
1599
|
|
|
|
|
|
|
####### |
1600
|
|
|
|
|
|
|
|
1601
|
|
|
|
|
|
|
1; |
1602
|
|
|
|
|
|
|
|
1603
|
|
|
|
|
|
|
__END__ |