| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# $Id: TagTree.pm 11693 2007-09-17 20:54:04Z cjfields $ |
|
2
|
|
|
|
|
|
|
# |
|
3
|
|
|
|
|
|
|
# BioPerl module for Bio::Annotation::TagTree |
|
4
|
|
|
|
|
|
|
# |
|
5
|
|
|
|
|
|
|
# Cared for Chris Fields |
|
6
|
|
|
|
|
|
|
# |
|
7
|
|
|
|
|
|
|
# You may distribute this module under the same terms as perl itself. |
|
8
|
|
|
|
|
|
|
# Refer to the Perl Artistic License (see the license accompanying this |
|
9
|
|
|
|
|
|
|
# software package, or see http://www.perl.com/language/misc/Artistic.html) |
|
10
|
|
|
|
|
|
|
# for the terms under which you may use, modify, and redistribute this module. |
|
11
|
|
|
|
|
|
|
# |
|
12
|
|
|
|
|
|
|
# THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED |
|
13
|
|
|
|
|
|
|
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF |
|
14
|
|
|
|
|
|
|
# MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
|
15
|
|
|
|
|
|
|
# |
|
16
|
|
|
|
|
|
|
# POD documentation - main docs before the code |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
=head1 NAME |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
Bio::Annotation::TagTree - AnnotationI with tree-like hierarchal key-value |
|
21
|
|
|
|
|
|
|
relationships ('structured tags') that can be represented as simple text. |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
use Bio::Annotation::TagTree; |
|
26
|
|
|
|
|
|
|
use Bio::Annotation::Collection; |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
my $col = Bio::Annotation::Collection->new(); |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# data structure can be an array reference with a data structure |
|
31
|
|
|
|
|
|
|
# corresponding to that defined by Data::Stag: |
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
my $sv = Bio::Annotation::TagTree->new(-tagname => 'mytag1', |
|
34
|
|
|
|
|
|
|
-value => $data_structure); |
|
35
|
|
|
|
|
|
|
$col->add_Annotation($sv); |
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# regular text passed is parsed based on the tagformat(). |
|
38
|
|
|
|
|
|
|
my $sv2 = Bio::Annotation::TagTree->new(-tagname => 'mytag2', |
|
39
|
|
|
|
|
|
|
-tagformat => 'xml', |
|
40
|
|
|
|
|
|
|
-value => $xmltext); |
|
41
|
|
|
|
|
|
|
$col->add_Annotation($sv2); |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
This takes tagged data values and stores them in a hierarchal structured |
|
46
|
|
|
|
|
|
|
element-value hierarchy (complements of Chris Mungall's Data::Stag module). Data |
|
47
|
|
|
|
|
|
|
can then be represented as text using a variety of output formats (indention, |
|
48
|
|
|
|
|
|
|
itext, xml, spxr). Furthermore, the data structure can be queried using various |
|
49
|
|
|
|
|
|
|
means. See L for details. |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
Data passed in using value() or the '-value' parameter upon instantiation |
|
52
|
|
|
|
|
|
|
can either be: |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
1) an array reference corresponding to the data structure for Data::Stag; |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
2) a text string in 'xml', 'itext', 'spxr', or 'indent' format. The default |
|
57
|
|
|
|
|
|
|
format is 'xml'; this can be changed using tagformat() prior to using value() or |
|
58
|
|
|
|
|
|
|
by passing in the proper format using '-tagformat' upon instantiation; |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
3) another Bio::Annotation::TagTree or Data::Stag node instance. In both cases |
|
61
|
|
|
|
|
|
|
a deep copy (duplicate) of the instance is generated. |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
Beyond checking for an array reference no format guessing occurs (so, for |
|
64
|
|
|
|
|
|
|
roundtrip tests ensure that the IO formats correspond). For now, we recommend |
|
65
|
|
|
|
|
|
|
when using text input to set tagformat() to one of these formats prior to data |
|
66
|
|
|
|
|
|
|
loading to ensure the proper Data::Stag parser is selected. After data loading, |
|
67
|
|
|
|
|
|
|
the tagformat() can be changed to change the text string format returned by |
|
68
|
|
|
|
|
|
|
value(). (this may be rectified in the future) |
|
69
|
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
This Annotation type is fully BioSQL compatible and could be considered a |
|
71
|
|
|
|
|
|
|
temporary replacement for nested Bio::Annotation::Collections, at least until |
|
72
|
|
|
|
|
|
|
BioSQL and bioperl-db can support nested annotation collections. |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=head1 FEEDBACK |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
=head2 Mailing Lists |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
User feedback is an integral part of the evolution of this and other |
|
79
|
|
|
|
|
|
|
Bioperl modules. Send your comments and suggestions preferably to one |
|
80
|
|
|
|
|
|
|
of the Bioperl mailing lists. Your participation is much appreciated. |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
bioperl-l@bioperl.org - General discussion |
|
83
|
|
|
|
|
|
|
http://bioperl.org/wiki/Mailing_lists - About the mailing lists |
|
84
|
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
=head2 Support |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
Please direct usage questions or support issues to the mailing list: |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
I |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
rather than to the module maintainer directly. Many experienced and |
|
92
|
|
|
|
|
|
|
reponsive experts will be able look at the problem and quickly |
|
93
|
|
|
|
|
|
|
address it. Please include a thorough description of the problem |
|
94
|
|
|
|
|
|
|
with code and data examples if at all possible. |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=head2 Reporting Bugs |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
Report bugs to the Bioperl bug tracking system to help us keep track |
|
99
|
|
|
|
|
|
|
the bugs and their resolution. Bug reports can be submitted via |
|
100
|
|
|
|
|
|
|
or the web: |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
https://github.com/bioperl/bioperl-live/issues |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=head1 AUTHOR |
|
105
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
Chris Fields |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=head1 APPENDIX |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
The rest of the documentation details each of the object methods. Internal |
|
111
|
|
|
|
|
|
|
methods are usually preceded with a _ |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
=cut |
|
114
|
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
# Let the code begin... |
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
package Bio::Annotation::TagTree; |
|
118
|
8
|
|
|
8
|
|
717
|
use strict; |
|
|
8
|
|
|
|
|
16
|
|
|
|
8
|
|
|
|
|
233
|
|
|
119
|
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
# Object preamble - inherits from Bio::Root::Root |
|
121
|
|
|
|
|
|
|
|
|
122
|
8
|
|
|
8
|
|
35
|
use base qw(Bio::Annotation::SimpleValue); |
|
|
8
|
|
|
|
|
14
|
|
|
|
8
|
|
|
|
|
637
|
|
|
123
|
8
|
|
|
8
|
|
44
|
use Data::Stag; |
|
|
8
|
|
|
|
|
62
|
|
|
|
8
|
|
|
|
|
9201
|
|
|
124
|
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=head2 new |
|
126
|
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
Title : new |
|
128
|
|
|
|
|
|
|
Usage : my $sv = Bio::Annotation::TagTree->new(); |
|
129
|
|
|
|
|
|
|
Function: Instantiate a new TagTree object |
|
130
|
|
|
|
|
|
|
Returns : Bio::Annotation::TagTree object |
|
131
|
|
|
|
|
|
|
Args : -value => $value to initialize the object data field [optional] |
|
132
|
|
|
|
|
|
|
-tagname => $tag to initialize the tagname [optional] |
|
133
|
|
|
|
|
|
|
-tagformat => format for output [optional] |
|
134
|
|
|
|
|
|
|
(types 'xml', 'itext', 'sxpr', 'indent', default = 'itext') |
|
135
|
|
|
|
|
|
|
-node => Data::Stag node or Bio::Annotation::TagTree instance |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=cut |
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
sub new { |
|
140
|
60
|
|
|
60
|
1
|
4423
|
my ( $class, @args ) = @_; |
|
141
|
60
|
|
|
|
|
338
|
my $self = $class->SUPER::new(); |
|
142
|
60
|
|
|
|
|
345
|
my ( $node, $value, $tag, $format, $verbose ) = $self->_rearrange( |
|
143
|
|
|
|
|
|
|
[ |
|
144
|
|
|
|
|
|
|
qw( |
|
145
|
|
|
|
|
|
|
NODE |
|
146
|
|
|
|
|
|
|
VALUE |
|
147
|
|
|
|
|
|
|
TAGNAME |
|
148
|
|
|
|
|
|
|
TAGFORMAT |
|
149
|
|
|
|
|
|
|
VERBOSE) |
|
150
|
|
|
|
|
|
|
], |
|
151
|
|
|
|
|
|
|
@args |
|
152
|
|
|
|
|
|
|
); |
|
153
|
60
|
50
|
33
|
|
|
317
|
$self->throw("Cant use both node and value; mutually exclusive") |
|
154
|
|
|
|
|
|
|
if defined $node && defined $value; |
|
155
|
60
|
100
|
|
|
|
335
|
defined $tag && $self->tagname($tag); |
|
156
|
60
|
|
50
|
|
|
328
|
$format ||= 'itext'; |
|
157
|
60
|
|
|
|
|
228
|
$self->tagformat($format); |
|
158
|
60
|
100
|
|
|
|
289
|
defined $value && $self->value($value); |
|
159
|
60
|
50
|
|
|
|
70554
|
defined $node && $self->node($node); |
|
160
|
60
|
100
|
|
|
|
243
|
defined $verbose && $self->verbose($verbose); |
|
161
|
60
|
|
|
|
|
267
|
return $self; |
|
162
|
|
|
|
|
|
|
} |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
=head1 AnnotationI implementing functions |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=cut |
|
167
|
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
=head2 as_text |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
Title : as_text |
|
171
|
|
|
|
|
|
|
Usage : my $text = $obj->as_text |
|
172
|
|
|
|
|
|
|
Function: return the string "Value: $v" where $v is the value |
|
173
|
|
|
|
|
|
|
Returns : string |
|
174
|
|
|
|
|
|
|
Args : none |
|
175
|
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
=cut |
|
177
|
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
sub as_text { |
|
179
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
|
180
|
0
|
|
|
|
|
0
|
return "TagTree: " . $self->value; |
|
181
|
|
|
|
|
|
|
} |
|
182
|
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
=head2 display_text |
|
184
|
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
Title : display_text |
|
186
|
|
|
|
|
|
|
Usage : my $str = $ann->display_text(); |
|
187
|
|
|
|
|
|
|
Function: returns a string. Unlike as_text(), this method returns a string |
|
188
|
|
|
|
|
|
|
formatted as would be expected for the specific implementation. |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
One can pass a callback as an argument which allows custom text |
|
191
|
|
|
|
|
|
|
generation; the callback is passed the current instance and any text |
|
192
|
|
|
|
|
|
|
returned |
|
193
|
|
|
|
|
|
|
Example : |
|
194
|
|
|
|
|
|
|
Returns : a string |
|
195
|
|
|
|
|
|
|
Args : [optional] callback |
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=cut |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
{ |
|
200
|
|
|
|
|
|
|
my $DEFAULT_CB = sub { $_[0]->value || '' }; |
|
201
|
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
sub display_text { |
|
203
|
0
|
|
|
0
|
1
|
0
|
my ( $self, $cb ) = @_; |
|
204
|
0
|
|
0
|
|
|
0
|
$cb ||= $DEFAULT_CB; |
|
205
|
0
|
0
|
|
|
|
0
|
$self->throw("Callback must be a code reference") if ref $cb ne 'CODE'; |
|
206
|
0
|
|
|
|
|
0
|
return $cb->($self); |
|
207
|
|
|
|
|
|
|
} |
|
208
|
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
} |
|
210
|
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
=head2 hash_tree |
|
212
|
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
Title : hash_tree |
|
214
|
|
|
|
|
|
|
Usage : my $hashtree = $value->hash_tree |
|
215
|
|
|
|
|
|
|
Function: For supporting the AnnotationI interface just returns the value |
|
216
|
|
|
|
|
|
|
as a hashref with the key 'value' pointing to the value |
|
217
|
|
|
|
|
|
|
Maybe reimplement using Data::Stag::hash()? |
|
218
|
|
|
|
|
|
|
Returns : hashrf |
|
219
|
|
|
|
|
|
|
Args : none |
|
220
|
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
=cut |
|
222
|
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
sub hash_tree { |
|
224
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
|
225
|
0
|
|
|
|
|
0
|
my $h = {}; |
|
226
|
0
|
|
|
|
|
0
|
$h->{'value'} = $self->value; |
|
227
|
|
|
|
|
|
|
} |
|
228
|
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
=head2 tagname |
|
230
|
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
Title : tagname |
|
232
|
|
|
|
|
|
|
Usage : $obj->tagname($newval) |
|
233
|
|
|
|
|
|
|
Function: Get/set the tagname for this annotation value. |
|
234
|
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
Setting this is optional. If set, it obviates the need to provide |
|
236
|
|
|
|
|
|
|
a tag to AnnotationCollection when adding this object. |
|
237
|
|
|
|
|
|
|
Example : |
|
238
|
|
|
|
|
|
|
Returns : value of tagname (a scalar) |
|
239
|
|
|
|
|
|
|
Args : new value (a scalar, optional) |
|
240
|
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
=cut |
|
242
|
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
sub tagname { |
|
244
|
78
|
|
|
78
|
1
|
223
|
my ( $self, $value ) = @_; |
|
245
|
78
|
100
|
|
|
|
234
|
if ( defined $value ) { |
|
246
|
58
|
|
|
|
|
203
|
$self->{'tagname'} = $value; |
|
247
|
|
|
|
|
|
|
} |
|
248
|
78
|
|
|
|
|
208
|
return $self->{'tagname'}; |
|
249
|
|
|
|
|
|
|
} |
|
250
|
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
=head1 Specific accessors for TagTree |
|
252
|
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
=cut |
|
254
|
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
=head2 value |
|
256
|
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
Title : value |
|
258
|
|
|
|
|
|
|
Usage : $obj->value($newval) |
|
259
|
|
|
|
|
|
|
Function: Get/set the value for this annotation. |
|
260
|
|
|
|
|
|
|
Returns : value of value |
|
261
|
|
|
|
|
|
|
Args : newvalue (optional) |
|
262
|
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
=cut |
|
264
|
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
sub value { |
|
266
|
81
|
|
|
81
|
1
|
9631
|
my ( $self, $value ) = @_; |
|
267
|
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
# set mode? This resets the entire tagged database |
|
269
|
81
|
|
|
|
|
198
|
my $format = $self->tagformat; |
|
270
|
81
|
100
|
|
|
|
491
|
if ($value) { |
|
271
|
58
|
100
|
|
|
|
176
|
if ( ref $value ) { |
|
272
|
57
|
100
|
|
|
|
206
|
if ( ref $value eq 'ARRAY' ) { |
|
273
|
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
# note the tagname() is not used here; it is only used for |
|
275
|
|
|
|
|
|
|
# storing this AnnotationI in the annotation collection |
|
276
|
53
|
|
|
|
|
113
|
eval { $self->{db} = Data::Stag->nodify($value) }; |
|
|
53
|
|
|
|
|
817
|
|
|
277
|
|
|
|
|
|
|
} |
|
278
|
|
|
|
|
|
|
else { |
|
279
|
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
# assuming this is blessed; passing on to node() and copy |
|
281
|
4
|
|
|
|
|
7
|
$self->node( $value, 'copy' ); |
|
282
|
|
|
|
|
|
|
} |
|
283
|
|
|
|
|
|
|
} |
|
284
|
|
|
|
|
|
|
else { |
|
285
|
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
# not trying to guess here for now; we go by the tagformat() setting |
|
287
|
1
|
|
|
|
|
11
|
my $h = Data::Stag->getformathandler($format); |
|
288
|
1
|
|
|
|
|
175
|
eval { $self->{db} = Data::Stag->from( $format . 'str', $value ) }; |
|
|
1
|
|
|
|
|
9
|
|
|
289
|
|
|
|
|
|
|
} |
|
290
|
58
|
50
|
|
|
|
10112
|
$self->throw("Data::Stag error:\n$@") if $@; |
|
291
|
|
|
|
|
|
|
} |
|
292
|
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
# get mode? |
|
294
|
|
|
|
|
|
|
# How do we return a data structure? |
|
295
|
|
|
|
|
|
|
# for now, we use the output (if there is a Data::Stag node present) |
|
296
|
|
|
|
|
|
|
# may need to run an eval {} to catch Data::Stag output errors |
|
297
|
81
|
|
|
|
|
498
|
$self->node->$format; |
|
298
|
|
|
|
|
|
|
} |
|
299
|
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
=head2 tagformat |
|
301
|
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
Title : tagformat |
|
303
|
|
|
|
|
|
|
Usage : $obj->tagformat($newval) |
|
304
|
|
|
|
|
|
|
Function: Get/set the output tag format for this annotation. |
|
305
|
|
|
|
|
|
|
Returns : value of tagformat |
|
306
|
|
|
|
|
|
|
Args : newvalue (optional) - format for the data passed into value |
|
307
|
|
|
|
|
|
|
must be of values 'xml', 'indent', 'sxpr', 'itext', 'perl' |
|
308
|
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
=cut |
|
310
|
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
my %IS_VALID_FORMAT = map { $_ => 1 } qw(xml indent sxpr itext); |
|
312
|
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
sub tagformat { |
|
314
|
144
|
|
|
144
|
1
|
11854
|
my ( $self, $value ) = @_; |
|
315
|
144
|
100
|
|
|
|
337
|
if ( defined $value ) { |
|
316
|
|
|
|
|
|
|
$self->throw( "$value is not a valid format; valid format types:\n" |
|
317
|
0
|
|
|
|
|
0
|
. join( ',', map { "'$_'" } keys %IS_VALID_FORMAT ) ) |
|
318
|
63
|
50
|
|
|
|
251
|
if !exists $IS_VALID_FORMAT{$value}; |
|
319
|
63
|
|
|
|
|
178
|
$self->{'tagformat'} = $value; |
|
320
|
|
|
|
|
|
|
} |
|
321
|
144
|
|
|
|
|
253
|
return $self->{'tagformat'}; |
|
322
|
|
|
|
|
|
|
} |
|
323
|
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
=head2 node |
|
325
|
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
Title : node |
|
327
|
|
|
|
|
|
|
Usage : $obj->node() |
|
328
|
|
|
|
|
|
|
Function: Get/set the topmost Data::Stag node used for this annotation. |
|
329
|
|
|
|
|
|
|
Returns : Data::Stag node implementation |
|
330
|
|
|
|
|
|
|
(default is Data::Stag::StagImpl) |
|
331
|
|
|
|
|
|
|
Args : (optional) Data::Stag node implementation |
|
332
|
|
|
|
|
|
|
(optional)'copy' => flag to create a copy of the node |
|
333
|
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
=cut |
|
335
|
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
sub node { |
|
337
|
120
|
|
|
120
|
1
|
6736
|
my ( $self, $value, $copy ) = @_; |
|
338
|
120
|
100
|
66
|
|
|
411
|
if ( defined $value && ref $value ) { |
|
339
|
6
|
100
|
66
|
|
|
48
|
$self->{'db'} = |
|
|
|
50
|
33
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
$value->isa('Data::Stag::StagI') |
|
341
|
|
|
|
|
|
|
? ( $copy && $copy eq 'copy' ? $value->duplicate : $value ) |
|
342
|
|
|
|
|
|
|
: $value->isa('Bio::Annotation::TagTree') ? ( $copy |
|
343
|
|
|
|
|
|
|
&& $copy eq 'copy' ? $value->node->duplicate : $value->node ) |
|
344
|
|
|
|
|
|
|
: $self->throw( |
|
345
|
|
|
|
|
|
|
'Object must be Data::Stag::StagI or Bio::Annotation::TagTree'); |
|
346
|
|
|
|
|
|
|
} |
|
347
|
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
# lazily create Data::Stag instance if not present |
|
349
|
120
|
100
|
|
|
|
2310
|
if (!$self->{'db'}) { |
|
350
|
4
|
|
|
|
|
14
|
$self->{'db'} = Data::Stag->new(); |
|
351
|
|
|
|
|
|
|
} |
|
352
|
120
|
|
|
|
|
772
|
return $self->{'db'}; |
|
353
|
|
|
|
|
|
|
} |
|
354
|
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
=head2 Data::Stag convenience methods |
|
356
|
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
Because Data::Stag uses blessed arrays and the core Bioperl class uses blessed |
|
358
|
|
|
|
|
|
|
hashes, TagTree uses an internal instance of a Data::Stag node for data storage. |
|
359
|
|
|
|
|
|
|
Therefore the following methods actually delegate to the Data:::Stag internal |
|
360
|
|
|
|
|
|
|
instance. |
|
361
|
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
For consistency (since one could recursively check child nodes), methods retain |
|
363
|
|
|
|
|
|
|
the same names as Data::Stag. Also, no 'magic' (AUTOLOAD'ed) methods are |
|
364
|
|
|
|
|
|
|
employed, simply b/c full-fledged Data::Stag functionality can be attained by |
|
365
|
|
|
|
|
|
|
grabbing the Data::Stag instance using node(). |
|
366
|
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
=head2 element |
|
368
|
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
Title : element |
|
370
|
|
|
|
|
|
|
Usage : |
|
371
|
|
|
|
|
|
|
Function: Returns the element name (key name) for this node |
|
372
|
|
|
|
|
|
|
Example : |
|
373
|
|
|
|
|
|
|
Returns : scalar |
|
374
|
|
|
|
|
|
|
Args : none |
|
375
|
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
=cut |
|
377
|
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
sub element { |
|
379
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
|
380
|
0
|
|
|
|
|
0
|
return $self->node->element; |
|
381
|
|
|
|
|
|
|
} |
|
382
|
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
=head2 data |
|
384
|
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
Title : data |
|
386
|
|
|
|
|
|
|
Usage : |
|
387
|
|
|
|
|
|
|
Function: Returns the data structure (array ref) for this node |
|
388
|
|
|
|
|
|
|
Example : |
|
389
|
|
|
|
|
|
|
Returns : array ref |
|
390
|
|
|
|
|
|
|
Args : none |
|
391
|
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
=cut |
|
393
|
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
sub data { |
|
395
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
|
396
|
0
|
|
|
|
|
0
|
return $self->node->data; |
|
397
|
|
|
|
|
|
|
} |
|
398
|
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
=head2 children |
|
400
|
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
Title : children |
|
402
|
|
|
|
|
|
|
Usage : |
|
403
|
|
|
|
|
|
|
Function: Get the top-level array of Data::Stag nodes or (if the top level is |
|
404
|
|
|
|
|
|
|
a terminal node) a scalar value. |
|
405
|
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
This is similar to StructuredValue's get_values() method, with the |
|
407
|
|
|
|
|
|
|
key difference being instead of array refs and scalars you get either |
|
408
|
|
|
|
|
|
|
Data::Stag nodes or the value for this particular node. |
|
409
|
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
For consistency (since one could recursively check nodes), |
|
411
|
|
|
|
|
|
|
we use the same method name as Data::Stag children(). |
|
412
|
|
|
|
|
|
|
Example : |
|
413
|
|
|
|
|
|
|
Returns : an array |
|
414
|
|
|
|
|
|
|
Args : none |
|
415
|
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
=cut |
|
417
|
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
sub children { |
|
419
|
6
|
|
|
6
|
1
|
4234
|
my $self = shift; |
|
420
|
6
|
|
|
|
|
33
|
return $self->node->children; |
|
421
|
|
|
|
|
|
|
} |
|
422
|
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
=head2 subnodes |
|
424
|
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
Title : subnodes |
|
426
|
|
|
|
|
|
|
Usage : |
|
427
|
|
|
|
|
|
|
Function: Get the top-level array of Data::Stag nodes. Unlike children(), |
|
428
|
|
|
|
|
|
|
this only returns an array of nodes (if this is a terminal node, |
|
429
|
|
|
|
|
|
|
no value is returned) |
|
430
|
|
|
|
|
|
|
Example : |
|
431
|
|
|
|
|
|
|
Returns : an array of nodes |
|
432
|
|
|
|
|
|
|
Args : none |
|
433
|
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
=cut |
|
435
|
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
sub subnodes { |
|
437
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
|
438
|
0
|
|
|
|
|
0
|
return $self->node->subnodes; |
|
439
|
|
|
|
|
|
|
} |
|
440
|
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
=head2 get |
|
442
|
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
Title : get |
|
444
|
|
|
|
|
|
|
Usage : |
|
445
|
|
|
|
|
|
|
Function: Returns the nodes or value for the named element or path |
|
446
|
|
|
|
|
|
|
Example : |
|
447
|
|
|
|
|
|
|
Returns : returns array of nodes or a scalar (if node is terminal) |
|
448
|
|
|
|
|
|
|
dependent on wantarray |
|
449
|
|
|
|
|
|
|
Args : none |
|
450
|
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
=cut |
|
452
|
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
sub get { |
|
454
|
0
|
|
|
0
|
1
|
0
|
my ( $self, @vals ) = @_; |
|
455
|
0
|
|
|
|
|
0
|
return $self->node->get(@vals); |
|
456
|
|
|
|
|
|
|
} |
|
457
|
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
=head2 find |
|
459
|
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
Title : find |
|
461
|
|
|
|
|
|
|
Usage : |
|
462
|
|
|
|
|
|
|
Function: Recursively searches for and returns the nodes or values for the |
|
463
|
|
|
|
|
|
|
named element or path |
|
464
|
|
|
|
|
|
|
Example : |
|
465
|
|
|
|
|
|
|
Returns : returns array of nodes or scalars (for terminal nodes) |
|
466
|
|
|
|
|
|
|
Args : none |
|
467
|
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
=cut |
|
469
|
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
sub find { |
|
471
|
0
|
|
|
0
|
1
|
0
|
my ( $self, @vals ) = @_; |
|
472
|
0
|
|
|
|
|
0
|
return $self->node->find(@vals); |
|
473
|
|
|
|
|
|
|
} |
|
474
|
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
=head2 findnode |
|
476
|
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
Title : findnode |
|
478
|
|
|
|
|
|
|
Usage : |
|
479
|
|
|
|
|
|
|
Function: Recursively searches for and returns a list of nodes |
|
480
|
|
|
|
|
|
|
of the given element path |
|
481
|
|
|
|
|
|
|
Example : |
|
482
|
|
|
|
|
|
|
Returns : returns array of nodes |
|
483
|
|
|
|
|
|
|
Args : none |
|
484
|
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
=cut |
|
486
|
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
sub findnode { |
|
488
|
6
|
|
|
6
|
1
|
2306
|
my ( $self, @vals ) = @_; |
|
489
|
6
|
|
|
|
|
27
|
return $self->node->findnode(@vals); |
|
490
|
|
|
|
|
|
|
} |
|
491
|
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
=head2 findval |
|
493
|
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
Title : findval |
|
495
|
|
|
|
|
|
|
Usage : |
|
496
|
|
|
|
|
|
|
Function: |
|
497
|
|
|
|
|
|
|
Example : |
|
498
|
|
|
|
|
|
|
Returns : returns array of nodes or values |
|
499
|
|
|
|
|
|
|
Args : none |
|
500
|
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
=cut |
|
502
|
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
sub findval { |
|
504
|
4
|
|
|
4
|
1
|
935
|
my ( $self, @vals ) = @_; |
|
505
|
4
|
|
|
|
|
17
|
return $self->node->findval(@vals); |
|
506
|
|
|
|
|
|
|
} |
|
507
|
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
=head2 addchild |
|
509
|
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
Title : addchild |
|
511
|
|
|
|
|
|
|
Usage : $struct->addchild(['name' => [['foo'=> 'bar1']]]); |
|
512
|
|
|
|
|
|
|
Function: add new child node to the current node. One can pass in a node, TagTree, |
|
513
|
|
|
|
|
|
|
or data structure; for instance, in the above, this would translate |
|
514
|
|
|
|
|
|
|
to (in XML): |
|
515
|
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
bar1 |
|
518
|
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
Returns : node |
|
521
|
|
|
|
|
|
|
Args : first arg = element name |
|
522
|
|
|
|
|
|
|
all other args are added as tag-value pairs |
|
523
|
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
=cut |
|
525
|
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
sub addchild { |
|
527
|
0
|
|
|
0
|
1
|
0
|
my ( $self, @vals ) = @_; |
|
528
|
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
# check for element tag first (if no element, must be empty Data::Stag node) |
|
530
|
0
|
0
|
|
|
|
0
|
if ( !$self->element ) { |
|
|
|
0
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
# try to do the right thing; if more than one element, wrap in array ref |
|
533
|
0
|
0
|
|
|
|
0
|
@vals > 1 ? $self->value( \@vals ) : $self->value( $vals[0] ); |
|
534
|
0
|
|
|
|
|
0
|
return $self->{db}; |
|
535
|
|
|
|
|
|
|
} |
|
536
|
|
|
|
|
|
|
elsif ( !$self->node->ntnodes ) { |
|
537
|
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
# if this is a terminal node, can't add to it (use set?) |
|
539
|
0
|
|
|
|
|
0
|
$self->throw("Can't add child to node; only terminal node is present!"); |
|
540
|
|
|
|
|
|
|
} |
|
541
|
|
|
|
|
|
|
else { |
|
542
|
0
|
|
|
|
|
0
|
return $self->node->addchild(@vals); |
|
543
|
|
|
|
|
|
|
} |
|
544
|
|
|
|
|
|
|
} |
|
545
|
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
=head2 add |
|
547
|
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
Title : add |
|
549
|
|
|
|
|
|
|
Usage : $struct->add('foo', 'bar1', 'bar2', 'bar3'); |
|
550
|
|
|
|
|
|
|
Function: add tag-value nodes to the current node. In the above, this would |
|
551
|
|
|
|
|
|
|
translate to (in XML): |
|
552
|
|
|
|
|
|
|
bar1 |
|
553
|
|
|
|
|
|
|
bar2 |
|
554
|
|
|
|
|
|
|
bar3 |
|
555
|
|
|
|
|
|
|
Returns : |
|
556
|
|
|
|
|
|
|
Args : first arg = element name |
|
557
|
|
|
|
|
|
|
all other args are added as tag-value pairs |
|
558
|
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
=cut |
|
560
|
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
sub add { |
|
562
|
0
|
|
|
0
|
1
|
0
|
my ( $self, @vals ) = @_; |
|
563
|
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
# check for empty object and die for now |
|
565
|
0
|
0
|
|
|
|
0
|
if ( !$self->node->element ) { |
|
566
|
0
|
|
|
|
|
0
|
$self->throw("Can't add to terminal element!"); |
|
567
|
|
|
|
|
|
|
} |
|
568
|
0
|
|
|
|
|
0
|
return $self->node->add(@vals); |
|
569
|
|
|
|
|
|
|
} |
|
570
|
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
=head2 set |
|
572
|
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
Title : set |
|
574
|
|
|
|
|
|
|
Usage : $struct->set('foo','bar'); |
|
575
|
|
|
|
|
|
|
Function: sets a single tag-value pair in the current node. Note this |
|
576
|
|
|
|
|
|
|
differs from add() in that this replaces any data already present |
|
577
|
|
|
|
|
|
|
Returns : node |
|
578
|
|
|
|
|
|
|
Args : first arg = element name |
|
579
|
|
|
|
|
|
|
all other args are added as tag-value pairs |
|
580
|
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
=cut |
|
582
|
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
sub set { |
|
584
|
0
|
|
|
0
|
1
|
0
|
my ( $self, @vals ) = @_; |
|
585
|
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
# check for empty object |
|
587
|
0
|
0
|
|
|
|
0
|
if ( !$self->node->element ) { |
|
588
|
0
|
|
|
|
|
0
|
$self->throw("Can't add to tree; empty tree!"); |
|
589
|
|
|
|
|
|
|
} |
|
590
|
0
|
|
|
|
|
0
|
return $self->node->set(@vals); |
|
591
|
|
|
|
|
|
|
} |
|
592
|
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
=head2 unset |
|
594
|
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
Title : unset |
|
596
|
|
|
|
|
|
|
Usage : $struct->unset('foo'); |
|
597
|
|
|
|
|
|
|
Function: unsets all key-value pairs of the passed element from the |
|
598
|
|
|
|
|
|
|
current node |
|
599
|
|
|
|
|
|
|
Returns : node |
|
600
|
|
|
|
|
|
|
Args : element name |
|
601
|
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
=cut |
|
603
|
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
sub unset { |
|
605
|
0
|
|
|
0
|
1
|
0
|
my ( $self, @vals ) = @_; |
|
606
|
0
|
|
|
|
|
0
|
return $self->node->unset(@vals); |
|
607
|
|
|
|
|
|
|
} |
|
608
|
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
=head2 free |
|
610
|
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
Title : free |
|
612
|
|
|
|
|
|
|
Usage : $struct->free |
|
613
|
|
|
|
|
|
|
Function: removes all data from the current node |
|
614
|
|
|
|
|
|
|
Returns : |
|
615
|
|
|
|
|
|
|
Args : |
|
616
|
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
=cut |
|
618
|
|
|
|
|
|
|
|
|
619
|
|
|
|
|
|
|
sub free { |
|
620
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
|
621
|
0
|
|
|
|
|
0
|
return $self->node->free; |
|
622
|
|
|
|
|
|
|
} |
|
623
|
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
=head2 hash |
|
625
|
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
Title : hash |
|
627
|
|
|
|
|
|
|
Usage : $struct->hash; |
|
628
|
|
|
|
|
|
|
Function: turns the tag-value tree into a hash, all data values are array refs |
|
629
|
|
|
|
|
|
|
Returns : hash |
|
630
|
|
|
|
|
|
|
Args : first arg = element name |
|
631
|
|
|
|
|
|
|
all other args are added as tag-value pairs |
|
632
|
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
=cut |
|
634
|
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
sub hash { |
|
636
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
|
637
|
0
|
|
|
|
|
0
|
return $self->node->hash; |
|
638
|
|
|
|
|
|
|
} |
|
639
|
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
=head2 pairs |
|
641
|
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
Title : pairs |
|
643
|
|
|
|
|
|
|
Usage : $struct->pairs; |
|
644
|
|
|
|
|
|
|
Function: turns the tag-value tree into a hash, all data values are scalar |
|
645
|
|
|
|
|
|
|
Returns : hash |
|
646
|
|
|
|
|
|
|
Args : first arg = element name |
|
647
|
|
|
|
|
|
|
all other args are added as tag-value pairs, note that duplicates |
|
648
|
|
|
|
|
|
|
will be lost |
|
649
|
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
=cut |
|
651
|
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
sub pairs { |
|
653
|
4
|
|
|
4
|
1
|
1610
|
my ($self) = @_; |
|
654
|
4
|
|
|
|
|
9
|
return $self->node->pairs; |
|
655
|
|
|
|
|
|
|
} |
|
656
|
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
=head2 qmatch |
|
658
|
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
Title : qmatch |
|
660
|
|
|
|
|
|
|
Usage : @persons = $s->qmatch('person', ('name'=>'fred')); |
|
661
|
|
|
|
|
|
|
Function : returns all elements in the node tree which match the |
|
662
|
|
|
|
|
|
|
element name and the key-value pair |
|
663
|
|
|
|
|
|
|
Returns : Array of nodes |
|
664
|
|
|
|
|
|
|
Args : return-element str, match-element str, match-value str |
|
665
|
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
=cut |
|
667
|
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
sub qmatch { |
|
669
|
0
|
|
|
0
|
1
|
0
|
my ( $self, @vals ) = @_; |
|
670
|
0
|
|
|
|
|
0
|
return $self->node->qmatch(@vals); |
|
671
|
|
|
|
|
|
|
} |
|
672
|
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
=head2 tnodes |
|
674
|
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
Title : tnodes |
|
676
|
|
|
|
|
|
|
Usage : @termini = $s->tnodes; |
|
677
|
|
|
|
|
|
|
Function : returns all terminal nodes below this node |
|
678
|
|
|
|
|
|
|
Returns : Array of nodes |
|
679
|
|
|
|
|
|
|
Args : return-element str, match-element str, match-value str |
|
680
|
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
=cut |
|
682
|
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
sub tnodes { |
|
684
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
|
685
|
0
|
|
|
|
|
0
|
return $self->node->tnodes; |
|
686
|
|
|
|
|
|
|
} |
|
687
|
|
|
|
|
|
|
|
|
688
|
|
|
|
|
|
|
=head2 ntnodes |
|
689
|
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
Title : ntnodes |
|
691
|
|
|
|
|
|
|
Usage : @termini = $s->ntnodes; |
|
692
|
|
|
|
|
|
|
Function : returns all nonterminal nodes below this node |
|
693
|
|
|
|
|
|
|
Returns : Array of nodes |
|
694
|
|
|
|
|
|
|
Args : return-element str, match-element str, match-value str |
|
695
|
|
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
=cut |
|
697
|
|
|
|
|
|
|
|
|
698
|
|
|
|
|
|
|
sub ntnodes { |
|
699
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
|
700
|
0
|
|
|
|
|
0
|
return $self->node->ntnodes; |
|
701
|
|
|
|
|
|
|
} |
|
702
|
|
|
|
|
|
|
|
|
703
|
|
|
|
|
|
|
=head2 StructureValue-like methods |
|
704
|
|
|
|
|
|
|
|
|
705
|
|
|
|
|
|
|
=cut |
|
706
|
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
=head2 get_all_values |
|
708
|
|
|
|
|
|
|
|
|
709
|
|
|
|
|
|
|
Title : get_all_values |
|
710
|
|
|
|
|
|
|
Usage : @termini = $s->get_all_values; |
|
711
|
|
|
|
|
|
|
Function : returns all terminal node values |
|
712
|
|
|
|
|
|
|
Returns : Array of values |
|
713
|
|
|
|
|
|
|
Args : return-element str, match-element str, match-value str |
|
714
|
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
This is meant to emulate the values one would get from StructureValue's |
|
716
|
|
|
|
|
|
|
get_all_values() method. Note, however, using this method dissociates the |
|
717
|
|
|
|
|
|
|
tag-value relationship (i.e. you only get the value list, no elements) |
|
718
|
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
=cut |
|
720
|
|
|
|
|
|
|
|
|
721
|
|
|
|
|
|
|
sub get_all_values { |
|
722
|
4
|
|
|
4
|
1
|
428
|
my $self = shift; |
|
723
|
4
|
|
|
|
|
40
|
my @kids = $self->children; |
|
724
|
4
|
|
|
|
|
208
|
my @vals; |
|
725
|
4
|
|
|
|
|
23
|
while ( my $val = shift @kids ) { |
|
726
|
92
|
100
|
|
|
|
933
|
( ref $val ) ? push @kids, $val->children : push @vals, $val; |
|
727
|
|
|
|
|
|
|
} |
|
728
|
4
|
|
|
|
|
29
|
return @vals; |
|
729
|
|
|
|
|
|
|
} |
|
730
|
|
|
|
|
|
|
|
|
731
|
|
|
|
|
|
|
1; |