line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
##---------------------------------------------------------------------------- |
2
|
|
|
|
|
|
|
## HTML Object - ~/lib/HTML/Object/XPath/Function.pm |
3
|
|
|
|
|
|
|
## Version v0.2.0 |
4
|
|
|
|
|
|
|
## Copyright(c) 2021 DEGUEST Pte. Ltd. |
5
|
|
|
|
|
|
|
## Author: Jacques Deguest <jack@deguest.jp> |
6
|
|
|
|
|
|
|
## Created 2021/12/05 |
7
|
|
|
|
|
|
|
## Modified 2022/09/18 |
8
|
|
|
|
|
|
|
## All rights reserved |
9
|
|
|
|
|
|
|
## |
10
|
|
|
|
|
|
|
## |
11
|
|
|
|
|
|
|
## This program is free software; you can redistribute it and/or modify it |
12
|
|
|
|
|
|
|
## under the same terms as Perl itself. |
13
|
|
|
|
|
|
|
##---------------------------------------------------------------------------- |
14
|
|
|
|
|
|
|
package HTML::Object::XPath::Function; |
15
|
|
|
|
|
|
|
BEGIN |
16
|
|
|
|
|
|
|
{ |
17
|
8
|
|
|
8
|
|
63
|
use strict; |
|
8
|
|
|
|
|
18
|
|
|
8
|
|
|
|
|
261
|
|
18
|
8
|
|
|
8
|
|
66
|
use warnings; |
|
8
|
|
|
|
|
18
|
|
|
8
|
|
|
|
|
243
|
|
19
|
8
|
|
|
8
|
|
43
|
use parent qw( Module::Generic ); |
|
8
|
|
|
|
|
16
|
|
|
8
|
|
|
|
|
45
|
|
20
|
8
|
|
|
8
|
|
526
|
use vars qw( $TRUE $FALSE $BASE_CLASS $DEBUG $VERSION ); |
|
8
|
|
|
|
|
17
|
|
|
8
|
|
|
|
|
861
|
|
21
|
8
|
|
|
8
|
|
54
|
use HTML::Object::XPath::Boolean; |
|
8
|
|
|
|
|
22
|
|
|
8
|
|
|
|
|
604
|
|
22
|
8
|
|
|
8
|
|
189
|
our $TRUE = HTML::Object::XPath::Boolean->True; |
23
|
8
|
|
|
|
|
41
|
our $FALSE = HTML::Object::XPath::Boolean->False; |
24
|
8
|
|
|
|
|
204
|
our $BASE_CLASS = 'HTML::Object::XPath'; |
25
|
8
|
|
|
|
|
19
|
our $DEBUG = 0; |
26
|
8
|
|
|
|
|
201
|
our $VERSION = 'v0.2.0'; |
27
|
|
|
|
|
|
|
}; |
28
|
|
|
|
|
|
|
|
29
|
8
|
|
|
8
|
|
50
|
use strict; |
|
8
|
|
|
|
|
26
|
|
|
8
|
|
|
|
|
160
|
|
30
|
8
|
|
|
8
|
|
38
|
use warnings; |
|
8
|
|
|
|
|
22
|
|
|
8
|
|
|
|
|
25538
|
|
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
sub init |
33
|
|
|
|
|
|
|
{ |
34
|
25
|
|
|
25
|
1
|
2154
|
my $self = shift( @_ ); |
35
|
|
|
|
|
|
|
# XPath Parser -> HTML::Object::XPath |
36
|
25
|
|
|
|
|
238
|
$self->{pp} = shift( @_ ); |
37
|
25
|
|
|
|
|
54
|
$self->{name} = shift( @_ ); |
38
|
25
|
|
|
|
|
47
|
$self->{params} = shift( @_ ); |
39
|
25
|
|
|
|
|
54
|
$self->{_init_strict_use_sub} = 1; |
40
|
25
|
50
|
|
|
|
82
|
$self->SUPER::init( @_ ) || return( $self->pass_error ); |
41
|
25
|
|
|
|
|
1688
|
return( $self ); |
42
|
|
|
|
|
|
|
} |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
sub as_string |
45
|
|
|
|
|
|
|
{ |
46
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
47
|
0
|
|
|
|
|
0
|
my $string = $self->{name} . '('; |
48
|
0
|
|
|
|
|
0
|
my $second; |
49
|
0
|
|
|
|
|
0
|
foreach( @{$self->{params}} ) |
|
0
|
|
|
|
|
0
|
|
50
|
|
|
|
|
|
|
{ |
51
|
0
|
0
|
|
|
|
0
|
$string .= ',' if( $second++ ); |
52
|
0
|
|
|
|
|
0
|
$string .= $_->as_string; |
53
|
|
|
|
|
|
|
} |
54
|
0
|
|
|
|
|
0
|
$string .= ')'; |
55
|
0
|
|
|
|
|
0
|
return( $string ); |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
sub as_xml |
59
|
|
|
|
|
|
|
{ |
60
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
61
|
0
|
|
|
|
|
0
|
my $string = sprintf( '<Function name="%s"', $self->{name} ); |
62
|
0
|
|
|
|
|
0
|
my $params = ''; |
63
|
0
|
|
|
|
|
0
|
foreach( @{$self->{params}} ) |
|
0
|
|
|
|
|
0
|
|
64
|
|
|
|
|
|
|
{ |
65
|
0
|
|
|
|
|
0
|
$params .= '<Param>' . $_->as_xml . "</Param>\n"; |
66
|
|
|
|
|
|
|
} |
67
|
0
|
0
|
|
|
|
0
|
if( $params ) |
68
|
|
|
|
|
|
|
{ |
69
|
0
|
|
|
|
|
0
|
$string .= ">\n$params</Function>\n"; |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
else |
72
|
|
|
|
|
|
|
{ |
73
|
0
|
|
|
|
|
0
|
$string .= " />\n"; |
74
|
|
|
|
|
|
|
} |
75
|
0
|
|
|
|
|
0
|
return( $string ); |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub boolean |
79
|
|
|
|
|
|
|
{ |
80
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
81
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
82
|
0
|
0
|
|
|
|
0
|
die( "boolean: Incorrect number of parameters\n" ) if( @params != 1 ); |
83
|
0
|
|
|
|
|
0
|
return( $params[0]->to_boolean ); |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub ceiling |
87
|
|
|
|
|
|
|
{ |
88
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
89
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
90
|
0
|
|
|
|
|
0
|
require POSIX; |
91
|
0
|
|
|
|
|
0
|
my $num = $self->number( $node, @params ); |
92
|
0
|
|
|
|
|
0
|
return( $self->new_number( POSIX::ceil( $num->value ) ) ); |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
sub concat |
96
|
|
|
|
|
|
|
{ |
97
|
8
|
|
|
8
|
1
|
17
|
my $self = shift( @_ ); |
98
|
8
|
|
|
|
|
22
|
my( $node, @params ) = @_; |
99
|
8
|
50
|
|
|
|
28
|
die( "concat: Too few parameters\n" ) if( @params < 2 ); |
100
|
|
|
|
|
|
|
# TODO: Check for improvement |
101
|
8
|
|
|
|
|
22
|
my $string = join( '', map{ $_->string_value } @params ); |
|
24
|
|
|
|
|
81
|
|
102
|
8
|
|
|
|
|
55
|
return( $self->new_literal( $string ) ); |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
sub contains |
106
|
|
|
|
|
|
|
{ |
107
|
8
|
|
|
8
|
1
|
19
|
my $self = shift( @_ ); |
108
|
8
|
|
|
|
|
22
|
my( $node, @params ) = @_; |
109
|
8
|
50
|
|
|
|
32
|
die( "starts-with: incorrect number of params\n" ) unless( @params == 2 ); |
110
|
8
|
|
|
|
|
28
|
my $value = $params[1]->string_value; |
111
|
8
|
100
|
|
|
|
31
|
if( $params[0]->string_value =~ /(.*?)\Q$value\E(.*)/ ) |
112
|
|
|
|
|
|
|
{ |
113
|
4
|
|
|
|
|
27
|
return( $TRUE ); |
114
|
|
|
|
|
|
|
} |
115
|
4
|
|
|
|
|
22
|
return( $FALSE ); |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
sub count |
119
|
|
|
|
|
|
|
{ |
120
|
20
|
|
|
20
|
1
|
31
|
my $self = shift( @_ ); |
121
|
20
|
|
|
|
|
39
|
my( $node, @params ) = @_; |
122
|
20
|
50
|
|
|
|
73
|
die( "count: Parameter must be a NodeSet\n" ) unless( $params[0]->isa( 'HTML::Object::XPath::NodeSet' ) ); |
123
|
20
|
|
|
|
|
63
|
return( $self->new_number( $params[0]->size ) ); |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
sub evaluate |
127
|
|
|
|
|
|
|
{ |
128
|
50
|
|
|
50
|
1
|
90
|
my $self = shift( @_ ); |
129
|
50
|
|
|
|
|
78
|
my $node = shift( @_ ); |
130
|
50
|
|
|
|
|
284
|
while( $node->isa( 'HTML::Object::XPath::NodeSet' ) ) |
131
|
|
|
|
|
|
|
{ |
132
|
6
|
|
|
|
|
16
|
$node = $node->get_node(1); |
133
|
|
|
|
|
|
|
} |
134
|
50
|
|
|
|
|
76
|
my @params; |
135
|
50
|
|
|
|
|
79
|
foreach my $param ( @{$self->{params}} ) |
|
50
|
|
|
|
|
162
|
|
136
|
|
|
|
|
|
|
{ |
137
|
76
|
|
|
|
|
208
|
my $results = $param->evaluate( $node ); |
138
|
76
|
|
|
|
|
234
|
push( @params, $results ); |
139
|
|
|
|
|
|
|
} |
140
|
50
|
|
|
|
|
278
|
return( $self->_execute( $self->{name}, $node, @params ) ); |
141
|
|
|
|
|
|
|
} |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
sub false |
144
|
|
|
|
|
|
|
{ |
145
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
146
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
147
|
0
|
0
|
|
|
|
0
|
die( "true: function takes no parameters\n" ) if( @params > 0 ); |
148
|
0
|
|
|
|
|
0
|
return( $FALSE ); |
149
|
|
|
|
|
|
|
} |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
sub floor |
152
|
|
|
|
|
|
|
{ |
153
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
154
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
155
|
0
|
|
|
|
|
0
|
require POSIX; |
156
|
0
|
|
|
|
|
0
|
my $num = $self->number( $node, @params ); |
157
|
0
|
|
|
|
|
0
|
return( $self->new_number( POSIX::floor( $num->value ) ) ); |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
sub id |
161
|
|
|
|
|
|
|
{ |
162
|
4
|
|
|
4
|
1
|
11
|
my $self = shift( @_ ); |
163
|
4
|
|
|
|
|
14
|
my( $node, @params ) = @_; |
164
|
4
|
50
|
|
|
|
13
|
die( "id: Function takes 1 parameter\n" ) unless( @params == 1 ); |
165
|
4
|
|
|
|
|
14
|
my $results = $self->new_nodeset(); |
166
|
4
|
50
|
|
|
|
28
|
if( $self->_is_a( $params[0] => 'HTML::Object::XPath::NodeSet' ) ) |
167
|
|
|
|
|
|
|
{ |
168
|
|
|
|
|
|
|
# result is the union of applying id() to the |
169
|
|
|
|
|
|
|
# string value of each node in the nodeset. |
170
|
0
|
|
|
|
|
0
|
foreach my $node ( $params[0]->get_nodelist ) |
171
|
|
|
|
|
|
|
{ |
172
|
0
|
|
|
|
|
0
|
my $string = $node->string_value; |
173
|
0
|
|
|
|
|
0
|
$results->append( $self->id( $node, $self->new_literal( $string ) ) ); |
174
|
|
|
|
|
|
|
} |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
# The actual id() function... |
177
|
|
|
|
|
|
|
else |
178
|
|
|
|
|
|
|
{ |
179
|
4
|
|
|
|
|
191
|
my $string = $self->string( $node, $params[0] ); |
180
|
|
|
|
|
|
|
# get perl scalar |
181
|
|
|
|
|
|
|
# $_ = $string->value; |
182
|
|
|
|
|
|
|
# split $_ |
183
|
|
|
|
|
|
|
# my @ids = split; |
184
|
|
|
|
|
|
|
# die( "Splitting '", $string->value, "' with result: '", join( "', '", @ids ), "'\n" ); |
185
|
4
|
|
|
|
|
17
|
my @ids = split( /[[:blank:]]/, $string->value ); |
186
|
4
|
50
|
|
|
|
25
|
if( $node->isAttributeNode ) |
187
|
|
|
|
|
|
|
{ |
188
|
0
|
|
|
|
|
0
|
warn( "calling \($node->getParentNode->getRootNode->getChildNodes)->[0] on attribute node\n" ); |
189
|
0
|
|
|
|
|
0
|
$node = ( $node->getParentNode->getRootNode->getChildNodes )->[0]; |
190
|
|
|
|
|
|
|
} |
191
|
4
|
|
|
|
|
23
|
foreach my $id ( @ids ) |
192
|
|
|
|
|
|
|
{ |
193
|
4
|
50
|
|
|
|
17
|
if( my $found = $node->getElementById( $id ) ) |
194
|
|
|
|
|
|
|
{ |
195
|
4
|
|
|
|
|
620
|
$results->push( $found ); |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
} |
198
|
|
|
|
|
|
|
} |
199
|
4
|
|
|
|
|
26
|
return( $results ); |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
sub lang |
203
|
|
|
|
|
|
|
{ |
204
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
205
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
206
|
0
|
0
|
|
|
|
0
|
die( "lang: function takes 1 parameter\n" ) if( @params != 1 ); |
207
|
0
|
|
|
|
|
0
|
my $lang = $node->findvalue( '(ancestor-or-self::*[@xml:lang]/@xml:lang)[1]' ); |
208
|
0
|
|
|
|
|
0
|
my $lclang = lc( $params[0]->string_value ); |
209
|
|
|
|
|
|
|
# warn("Looking for lang($lclang) in $lang\n"); |
210
|
0
|
0
|
|
|
|
0
|
if( substr( lc( $lang ), 0, length( $lclang ) ) eq $lclang ) |
211
|
|
|
|
|
|
|
{ |
212
|
0
|
|
|
|
|
0
|
return( $TRUE ); |
213
|
|
|
|
|
|
|
} |
214
|
|
|
|
|
|
|
else |
215
|
|
|
|
|
|
|
{ |
216
|
0
|
|
|
|
|
0
|
return( $FALSE ); |
217
|
|
|
|
|
|
|
} |
218
|
|
|
|
|
|
|
} |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
sub last |
221
|
|
|
|
|
|
|
{ |
222
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
223
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
224
|
0
|
0
|
|
|
|
0
|
die( "last: function doesn't take parameters\n" ) if( scalar( @params ) ); |
225
|
0
|
|
|
|
|
0
|
return( $self->new_number( $self->{pp}->_get_context_size ) ); |
226
|
|
|
|
|
|
|
} |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
sub local_name |
229
|
|
|
|
|
|
|
{ |
230
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
231
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
232
|
0
|
0
|
|
|
|
0
|
if( @params > 1 ) |
|
|
0
|
|
|
|
|
|
233
|
|
|
|
|
|
|
{ |
234
|
0
|
|
|
|
|
0
|
die( "name() function takes one or no parameters\n" ); |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
elsif( @params ) |
237
|
|
|
|
|
|
|
{ |
238
|
0
|
|
|
|
|
0
|
my $nodeset = shift( @params ); |
239
|
0
|
|
|
|
|
0
|
$node = $nodeset->get_node(1); |
240
|
|
|
|
|
|
|
} |
241
|
0
|
|
|
|
|
0
|
return( $self->new_literal( $node->getLocalName ) ); |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
sub name |
245
|
|
|
|
|
|
|
{ |
246
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
247
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
248
|
0
|
0
|
|
|
|
0
|
if( @params > 1 ) |
|
|
0
|
|
|
|
|
|
249
|
|
|
|
|
|
|
{ |
250
|
0
|
|
|
|
|
0
|
die( "name() function takes one or no parameters\n" ); |
251
|
|
|
|
|
|
|
} |
252
|
|
|
|
|
|
|
elsif( @params ) |
253
|
|
|
|
|
|
|
{ |
254
|
0
|
|
|
|
|
0
|
my $nodeset = shift( @params ); |
255
|
0
|
|
|
|
|
0
|
$node = $nodeset->get_node(1); |
256
|
|
|
|
|
|
|
} |
257
|
0
|
|
|
|
|
0
|
return( $self->new_literal( $node->getName ) ); |
258
|
|
|
|
|
|
|
} |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
sub namespace_uri |
261
|
|
|
|
|
|
|
{ |
262
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
263
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
264
|
0
|
|
|
|
|
0
|
die( "namespace-uri: Function not supported\n" ); |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
|
267
|
22
|
|
|
22
|
1
|
79
|
sub new_literal { return( shift->_class_for( 'Literal' )->new( @_ ) ); } |
268
|
|
|
|
|
|
|
|
269
|
4
|
|
|
4
|
1
|
16
|
sub new_nodeset { return( shift->_class_for( 'NodeSet' )->new( @_ ) ); } |
270
|
|
|
|
|
|
|
|
271
|
20
|
|
|
20
|
1
|
53
|
sub new_number { return( shift->_class_for( 'Number' )->new( @_ ) ); } |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
sub normalize_space |
274
|
|
|
|
|
|
|
{ |
275
|
8
|
|
|
8
|
1
|
21
|
my $self = shift( @_ ); |
276
|
8
|
|
|
|
|
17
|
my( $node, @params ) = @_; |
277
|
8
|
50
|
|
|
|
35
|
die( "normalize-space: Wrong number of params\n" ) if( @params > 1 ); |
278
|
8
|
|
|
|
|
15
|
my $str; |
279
|
8
|
50
|
|
|
|
25
|
if( @params ) |
280
|
|
|
|
|
|
|
{ |
281
|
8
|
|
|
|
|
43
|
$str = $params[0]->string_value; |
282
|
|
|
|
|
|
|
} |
283
|
|
|
|
|
|
|
else |
284
|
|
|
|
|
|
|
{ |
285
|
0
|
|
|
|
|
0
|
$str = $node->string_value; |
286
|
|
|
|
|
|
|
} |
287
|
|
|
|
|
|
|
# $str =~ s/^\s*//; |
288
|
|
|
|
|
|
|
# $str =~ s/\s*$//; |
289
|
8
|
|
|
|
|
6664
|
$str =~ s/^[[:blank:]\h]+|[[:blank:]\h]+$//g; |
290
|
|
|
|
|
|
|
# $str =~ s/\s+/ /g; |
291
|
8
|
|
|
|
|
79
|
$str =~ s/[[:blank:]\h]+/ /g; |
292
|
8
|
|
|
|
|
64
|
return( $self->new_literal( $str ) ); |
293
|
|
|
|
|
|
|
} |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
sub not |
296
|
|
|
|
|
|
|
{ |
297
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
298
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
299
|
0
|
0
|
|
|
|
0
|
$params[0] = $params[0]->to_boolean unless( $params[0]->isa( 'HTML::Object::XPath::Boolean' ) ); |
300
|
0
|
0
|
|
|
|
0
|
return( $params[0]->value ? $FALSE : $TRUE ); |
301
|
|
|
|
|
|
|
} |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
sub number |
304
|
|
|
|
|
|
|
{ |
305
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
306
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
307
|
0
|
0
|
|
|
|
0
|
die( "number: Too many parameters\n" ) if( @params > 1 ); |
308
|
0
|
0
|
|
|
|
0
|
if( @params ) |
309
|
|
|
|
|
|
|
{ |
310
|
0
|
0
|
|
|
|
0
|
if( $params[0]->isa( 'HTML::Object::XPath::Node' ) ) |
311
|
|
|
|
|
|
|
{ |
312
|
0
|
|
|
|
|
0
|
return( $self->new_number( $params[0]->string_value ) ); |
313
|
|
|
|
|
|
|
} |
314
|
0
|
|
|
|
|
0
|
return( $params[0]->to_number ); |
315
|
|
|
|
|
|
|
} |
316
|
0
|
|
|
|
|
0
|
return( $self->new_number( $node->string_value ) ); |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
sub position |
320
|
|
|
|
|
|
|
{ |
321
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
322
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
323
|
0
|
0
|
|
|
|
0
|
if( scalar( @params ) ) |
324
|
|
|
|
|
|
|
{ |
325
|
0
|
|
|
|
|
0
|
die( "position: function doesn't take parameters [ ", @params, " ]\n" ); |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
# return pos relative to axis direction |
328
|
0
|
|
|
|
|
0
|
return( $self->new_number( $self->{pp}->_get_context_pos ) ); |
329
|
|
|
|
|
|
|
} |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
sub round |
332
|
|
|
|
|
|
|
{ |
333
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
334
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
335
|
0
|
|
|
|
|
0
|
my $num = $self->number( $node, @params ); |
336
|
0
|
|
|
|
|
0
|
require POSIX; |
337
|
|
|
|
|
|
|
# Yes, I know the spec says do not do this... |
338
|
|
|
|
|
|
|
# return( $self->new_number( POSIX::floor( $num->value + 0.5 ) ) ); |
339
|
0
|
|
|
|
|
0
|
return( $self->new_number( CORE::sprintf( '%.*f', $num->value ) ) ); |
340
|
|
|
|
|
|
|
} |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
sub starts_with |
343
|
|
|
|
|
|
|
{ |
344
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
345
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
346
|
0
|
0
|
|
|
|
0
|
die( "starts-with: incorrect number of params\n" ) unless( @params == 2 ); |
347
|
0
|
|
|
|
|
0
|
my( $string1, $string2 ) = ( $params[0]->string_value, $params[1]->string_value ); |
348
|
0
|
0
|
|
|
|
0
|
if( substr( $string1, 0, length( $string2 ) ) eq $string2 ) |
349
|
|
|
|
|
|
|
{ |
350
|
0
|
|
|
|
|
0
|
return( $TRUE ); |
351
|
|
|
|
|
|
|
} |
352
|
0
|
|
|
|
|
0
|
return( $FALSE ); |
353
|
|
|
|
|
|
|
} |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
sub string |
356
|
|
|
|
|
|
|
{ |
357
|
4
|
|
|
4
|
1
|
10
|
my $self = shift( @_ ); |
358
|
4
|
|
|
|
|
13
|
my( $node, @params ) = @_; |
359
|
4
|
50
|
|
|
|
13
|
die( "string: Too many parameters\n" ) if( @params > 1 ); |
360
|
4
|
50
|
|
|
|
13
|
if( @params ) |
361
|
|
|
|
|
|
|
{ |
362
|
4
|
|
|
|
|
18
|
return( $self->new_literal( $params[0]->string_value ) ); |
363
|
|
|
|
|
|
|
} |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
# TODO - this MUST be wrong! - not sure now. -matt |
366
|
0
|
|
|
|
|
0
|
return( $self->new_literal( $node->string_value ) ); |
367
|
|
|
|
|
|
|
# default to nodeset with just $node in. |
368
|
|
|
|
|
|
|
} |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
sub string_length |
371
|
|
|
|
|
|
|
{ |
372
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
373
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
374
|
0
|
0
|
|
|
|
0
|
die( "string-length: Wrong number of params\n" ) if( @params > 1 ); |
375
|
0
|
0
|
|
|
|
0
|
if( @params ) |
376
|
|
|
|
|
|
|
{ |
377
|
0
|
|
|
|
|
0
|
return( $self->new_number( length( $params[0]->string_value ) ) ); |
378
|
|
|
|
|
|
|
} |
379
|
|
|
|
|
|
|
else |
380
|
|
|
|
|
|
|
{ |
381
|
0
|
|
|
|
|
0
|
return( $self->new_number( length( $node->string_value ) ) ); |
382
|
|
|
|
|
|
|
} |
383
|
|
|
|
|
|
|
} |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
sub substring |
386
|
|
|
|
|
|
|
{ |
387
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
388
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
389
|
0
|
0
|
0
|
|
|
0
|
die( "substring: Wrong number of parameters\n" ) if( @params < 2 || @params > 3 ); |
390
|
0
|
|
|
|
|
0
|
my( $str, $offset, $len ); |
391
|
0
|
|
|
|
|
0
|
$str = $params[0]->string_value; |
392
|
0
|
|
|
|
|
0
|
$offset = $params[1]->value; |
393
|
|
|
|
|
|
|
# uses 1 based offsets |
394
|
0
|
|
|
|
|
0
|
$offset--; |
395
|
0
|
0
|
|
|
|
0
|
if( @params == 3 ) |
396
|
|
|
|
|
|
|
{ |
397
|
0
|
|
|
|
|
0
|
$len = $params[2]->value; |
398
|
0
|
|
|
|
|
0
|
return( $self->new_literal( substr( $str, $offset, $len ) ) ); |
399
|
|
|
|
|
|
|
} |
400
|
|
|
|
|
|
|
else |
401
|
|
|
|
|
|
|
{ |
402
|
0
|
|
|
|
|
0
|
return( $self->new_literal( substr( $str, $offset ) ) ); |
403
|
|
|
|
|
|
|
} |
404
|
|
|
|
|
|
|
} |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
sub substring_after |
407
|
|
|
|
|
|
|
{ |
408
|
2
|
|
|
2
|
1
|
7
|
my $self = shift( @_ ); |
409
|
2
|
|
|
|
|
17
|
my( $node, @params ) = @_; |
410
|
2
|
50
|
|
|
|
8
|
die( "starts-with: incorrect number of params\n" ) unless( @params == 2 ); |
411
|
2
|
|
|
|
|
18
|
my $long = $params[0]->string_value; |
412
|
2
|
|
|
|
|
41
|
my $short = $params[1]->string_value; |
413
|
2
|
50
|
|
|
|
37
|
if( $long =~ m{\Q$short\E(.*)$} ) |
414
|
|
|
|
|
|
|
{ |
415
|
2
|
|
|
|
|
15
|
return( $self->new_literal( $1 ) ); |
416
|
|
|
|
|
|
|
} |
417
|
|
|
|
|
|
|
else |
418
|
|
|
|
|
|
|
{ |
419
|
0
|
|
|
|
|
0
|
return( $self->new_literal( '' ) ); |
420
|
|
|
|
|
|
|
} |
421
|
|
|
|
|
|
|
} |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
sub substring_before |
424
|
|
|
|
|
|
|
{ |
425
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
426
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
427
|
0
|
0
|
|
|
|
0
|
die( "starts-with: incorrect number of params\n" ) unless( @params == 2 ); |
428
|
0
|
|
|
|
|
0
|
my $long = $params[0]->string_value; |
429
|
0
|
|
|
|
|
0
|
my $short = $params[1]->string_value; |
430
|
0
|
0
|
|
|
|
0
|
if( $long =~ m{^(.*?)\Q$short} ) |
431
|
|
|
|
|
|
|
{ |
432
|
0
|
|
|
|
|
0
|
return( $self->new_literal( $1 ) ); |
433
|
|
|
|
|
|
|
} |
434
|
|
|
|
|
|
|
else |
435
|
|
|
|
|
|
|
{ |
436
|
0
|
|
|
|
|
0
|
return( $self->new_literal( '' ) ); |
437
|
|
|
|
|
|
|
} |
438
|
|
|
|
|
|
|
} |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
sub sum |
441
|
|
|
|
|
|
|
{ |
442
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
443
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
444
|
0
|
0
|
|
|
|
0
|
die( "sum: Parameter must be a NodeSet\n" ) unless( $params[0]->isa( 'HTML::Object::XPath::NodeSet' ) ); |
445
|
0
|
|
|
|
|
0
|
my $sum = 0; |
446
|
0
|
|
|
|
|
0
|
foreach my $node ( $params[0]->get_nodelist ) |
447
|
|
|
|
|
|
|
{ |
448
|
0
|
|
|
|
|
0
|
$sum += $self->number( $node )->value; |
449
|
|
|
|
|
|
|
} |
450
|
0
|
|
|
|
|
0
|
return( $self->new_number( $sum ) ); |
451
|
|
|
|
|
|
|
} |
452
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
sub translate |
454
|
|
|
|
|
|
|
{ |
455
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
456
|
0
|
|
|
|
|
0
|
my( $node, @params ) = @_; |
457
|
0
|
0
|
|
|
|
0
|
die( "translate: Wrong number of params\n" ) if( @params != 3 ); |
458
|
0
|
|
|
|
|
0
|
local $_ = $params[0]->string_value; |
459
|
0
|
|
|
|
|
0
|
my $find = $params[1]->string_value; |
460
|
0
|
|
|
|
|
0
|
my $repl = $params[2]->string_value; |
461
|
0
|
|
|
|
|
0
|
$repl= substr( $repl, 0, length( $find ) ); |
462
|
0
|
|
|
|
|
0
|
my %repl; |
463
|
0
|
|
|
|
|
0
|
@repl{split( //, $find )} = split( //, $repl ); |
464
|
0
|
|
|
|
|
0
|
s{(.)} |
465
|
0
|
0
|
|
|
|
0
|
{ |
|
|
0
|
|
|
|
|
|
466
|
|
|
|
|
|
|
CORE::exists( $repl{$1} ) ? defined( $repl{$1} ) ? $repl{$1} : '' : $1 |
467
|
0
|
|
|
|
|
0
|
}ges; |
468
|
|
|
|
|
|
|
return( $self->new_literal( $_ ) ); |
469
|
|
|
|
|
|
|
} |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
sub true |
472
|
0
|
|
|
0
|
1
|
0
|
{ |
473
|
0
|
|
|
|
|
0
|
my $self = shift( @_ ); |
474
|
0
|
0
|
|
|
|
0
|
my( $node, @params ) = @_; |
475
|
0
|
|
|
|
|
0
|
die( "true: function takes no parameters\n" ) if( @params > 0 ); |
476
|
|
|
|
|
|
|
return( $TRUE ); |
477
|
|
|
|
|
|
|
} |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
sub _class_for |
480
|
46
|
|
|
46
|
|
104
|
{ |
481
|
46
|
|
|
|
|
2477
|
my( $self, $mod ) = @_; |
482
|
46
|
50
|
|
|
|
233
|
eval( "require ${BASE_CLASS}\::${mod};" ); |
483
|
|
|
|
|
|
|
die( $@ ) if( $@ ); |
484
|
46
|
|
50
|
|
|
2088
|
# ${"${BASE_CLASS}\::${mod}\::DEBUG"} = $DEBUG; |
485
|
46
|
|
|
|
|
377
|
eval( "\$${BASE_CLASS}\::${mod}\::DEBUG = " . ( $DEBUG // 0 ) ); |
486
|
|
|
|
|
|
|
return( "${BASE_CLASS}::${mod}" ); |
487
|
|
|
|
|
|
|
} |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
sub _execute |
490
|
50
|
|
|
50
|
|
101
|
{ |
491
|
50
|
|
|
|
|
159
|
my $self = shift( @_ ); |
492
|
50
|
|
|
|
|
160
|
my( $name, $node, @params ) = @_; |
493
|
8
|
|
|
8
|
|
81
|
$name =~ s/-/_/g; |
|
8
|
|
|
|
|
22
|
|
|
8
|
|
|
|
|
483
|
|
494
|
50
|
|
|
|
|
234
|
no strict 'refs'; |
495
|
|
|
|
|
|
|
return( $self->$name( $node, @params ) ); |
496
|
|
|
|
|
|
|
} |
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
1; |
499
|
|
|
|
|
|
|
# NOTE: POD |
500
|
|
|
|
|
|
|
__END__ |
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
=encoding utf-8 |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
=head1 NAME |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
HTML::Object::XPath::Function - HTML Object XPath Functions |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
=head1 SYNOPSIS |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
use HTML::Object::XPath::Function; |
511
|
|
|
|
|
|
|
my $func = HTML::Object::XPath::Function->new || |
512
|
|
|
|
|
|
|
die( HTML::Object::XPath::Function->error, "\n" ); |
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
=head1 VERSION |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
v0.2.0 |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
=head1 DESCRIPTION |
519
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
This module implements various XPath functions described below. |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
=head1 CONSTRUCTOR |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
Provided with a L<XPath object|HTML::Object::XPath>, a function C<name> and function C<parameters> and this will instantiate a new L<HTML::Object::Function> object and return it. |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
=head1 METHODS |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
=head2 as_string |
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
Returns a string representation of this function object. |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
=head2 as_xml |
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
Returns a xml representation of this function object. |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
=head2 boolean |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and a list of parameters and this will return the first parameter as a L<boolean object|HTML::Object::XPath::Booleab>. It will raise an exception if there are more than one arguments provided. |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
=head2 ceiling |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and an optional parameter, and this will return the L<ceiling|POSIX/ceil> of the string value of the node or that of the parameter provided, if any. |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
It returns its value as a new L<number object|HTML::Object::XPath::Number>. It will raise an exception if more than one parameter was provided. |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
=head2 concat |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and a list of 2 parameters or more and this will return a new L<literal object|HTML::Object::XPath::Literal> from the concatenation of each parameter string value. |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
=head2 contains |
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and a list of exactly 2 parameters and this will return L<true|HTML::Object::XPath::Boolean> if the first parameter match the second one as a regular expression, or returns L<false|HTML::Object::XPath::Boolean> otherwise. |
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
=head2 count |
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and a L<node set|HTML::Object::XPath::NodeSet> and this will return the size of the node set as a L<number|HTML::Object::XPath::Number> |
557
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
=head2 evaluate |
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and this will evaluate the node using each parameter set during object instantiation and add the result for each in a new array. |
561
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
It will then return the execution of the function name on the node passing it the list of previously collected results. |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
=head2 false |
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
Returns L<false|HTML::Object::XPath::Boolean> and it will raise an exception if any arguments was provided. |
567
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
=head2 floor |
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and an optional parameter, and this will return the L<floor| |
571
|
|
|
|
|
|
|
POSIX/floor> of the string value of the node or that of the parameter provided, if any. |
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
It returns its value as a new L<number object|HTML::Object::XPath::Number>. It will raise an exception if more than one parameter was provided. |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
=head2 id |
576
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and 1 parameter, and this will return a new L<node set|HTML::Object::XPath::NodeSet> of L<element object|HTML::Object::Element> who match the id found in the node provided. |
578
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
=head2 lang |
580
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and 1 parameter, and this will return L<true|HTML::Object::XPath::Boolean> if the node lang, if any at all, match the one provide as a parameter, otherwise it returns L<false|HTML::Object::XPath::Boolean>. |
582
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
=head2 last |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
This takes no argument and returns the size, as a L<number|HTML::Object::XPath::Number> of the nodes in the context set in XPath. |
586
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
=head2 local_name |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and optionally some parameter and this will return the local name of the node, or that of the first parameter provided, if any, as a L<literal object|HTML::Object::XPath::Literal> |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
=head2 name |
592
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and optionally some parameter and this will return the name of the node, or that of the first parameter provided, if any, as a L<literal object|HTML::Object::XPath::Literal> |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
=head2 namespace_uri |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
This is an unsupported function and it will raise an exception when called. |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
=head2 new_literal |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
Returns a new L<literal object|HTML::Object::XPath::Literal> passing it whatever arguments was provided. |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
=head2 new_nodeset |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
Returns a new L<node set object|HTML::Object::XPath::NodeSet> passing it whatever arguments was provided. |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
=head2 new_number |
608
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
Returns a new L<number object|HTML::Object::XPath::Number> passing it whatever arguments was provided. |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
=head2 normalize_space |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and optionally some parameter and this will take the string value of the node, or that of the first parameter, if any at al, and remove any leading or trailing spaces as well as replacing multiple spaces by just one space, and return the new string as a L<literal object|HTML::Object::XPath::Literal> |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
=head2 not |
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and one parameter and this will return L<true|HTML::Object::XPath::Boolean> if the value of the first parameter is B<not> true, or L<false|HTML::Object::XPath::Boolean> otherwise. |
618
|
|
|
|
|
|
|
|
619
|
|
|
|
|
|
|
=head2 number |
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and optionally one parameter and this will return the node string value, or that of the parameter provided, if any, as a new L<number object|HTML::Object::XPath::Number> |
622
|
|
|
|
|
|
|
|
623
|
|
|
|
|
|
|
=head2 position |
624
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
Returns th context position as a L<number|HTML::Object::XPath::Number>. It will raise an exception if any parameter was provided. |
626
|
|
|
|
|
|
|
|
627
|
|
|
|
|
|
|
=head2 round |
628
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
=head2 starts_with |
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and two parameters and this will return L<true|HTML::Object::XPath::Boolean> if the string value of the second parameter is at the beginning of the first parameter, or L<false|HTML::Object::XPath::Boolean> otherwise. |
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
=head2 string |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and one parameter and this returns the parameter string value as a new L<literal object|HTML::Object::XPath::Literal> |
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
It will raise an exception if more than one parameter was provided. |
638
|
|
|
|
|
|
|
|
639
|
|
|
|
|
|
|
=head2 string_length |
640
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and optionally one parameter and this will return the size, as a L<number|HTML::Object::XPath::Number>, of the string value of the node or that of the parameter if any was provided. |
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
=head2 substring |
644
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and two or three parameters and this returns the substring of of the first parameter as a value, at offset specified by the second parameter, and optionally for a length defined by a third parameter, if any. If no third parameter is provided, then it will be until the end of the string. |
646
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
It returns the substring as a new L<literal object|HTML::Object::XPath::Literal>. It will raise an exception if less than 2 or more than 3 parameters were provided. |
648
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
=head2 substring_after |
650
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and two parameters and this will return the string that follows the string value of the second parameter in the first one up to its end. |
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
It returns the substring as a new L<literal object|HTML::Object::XPath::Literal>. It will raise an exception if less or more than 2 parameters were provided. |
654
|
|
|
|
|
|
|
|
655
|
|
|
|
|
|
|
=head2 substring_before |
656
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and two parameters and this will return the string that precede the string value of the second parameter in the first one up to its start. |
658
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
It returns the substring as a new L<literal object|HTML::Object::XPath::Literal>. It will raise an exception if less or more than 2 parameters were provided. |
660
|
|
|
|
|
|
|
|
661
|
|
|
|
|
|
|
=head2 sum |
662
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and a parameters that must be a L<node set|HTML::Object::XPath::NodeSet> and this will return the cumulative string value of each node as a number. |
664
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
It returns the resulting total as a new L<number> object|HTML::Object::XPath::Number>. It will raise an exception if the parameter provided is not a L<HTML::Object::XPath::NodeSet> object. |
666
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
=head2 translate |
668
|
|
|
|
|
|
|
|
669
|
|
|
|
|
|
|
Provided with a L<node object|HTML::Object::Element> and three parameters, and this will search in the first parameter for any occurrence of characters found in the second parameter and replace them with their alternative at the exact same position in string in the third parameter. |
670
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
It returns the substring as a new L<literal object|HTML::Object::XPath::Literal>. It will raise an exception if less or more than 3 parameters were provided. |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
=head2 true |
674
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
Returns L<true|HTML::Object::XPath::Boolean> and it will raise an exception if any arguments was provided. |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
=head1 AUTHOR |
678
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
Jacques Deguest E<lt>F<jack@deguest.jp>E<gt> |
680
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
=head1 SEE ALSO |
682
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
L<HTML::Object::XPath>, L<HTML::Object::XPath::Boolean>, L<HTML::Object::XPath::Expr>, L<HTML::Object::XPath::Function>, L<HTML::Object::XPath::Literal>, L<HTML::Object::XPath::LocationPath>, L<HTML::Object::XPath::NodeSet>, L<HTML::Object::XPath::Number>, L<HTML::Object::XPath::Root>, L<HTML::Object::XPath::Step>, L<HTML::Object::XPath::Variable> |
684
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
686
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
Copyright(c) 2021 DEGUEST Pte. Ltd. |
688
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
All rights reserved |
690
|
|
|
|
|
|
|
|
691
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. |
692
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
=cut |