File Coverage

blib/lib/XML/Stream/XPath/Op.pm
Criterion Covered Total %
statement 301 381 79.0
branch 54 86 62.7
condition 12 18 66.6
subroutine 49 59 83.0
pod 0 7 0.0
total 416 551 75.5


line stmt bran cond sub pod time code
1             ##############################################################################
2             #
3             # This library is free software; you can redistribute it and/or
4             # modify it under the terms of the GNU Library General Public
5             # License as published by the Free Software Foundation; either
6             # version 2 of the License, or (at your option) any later version.
7             #
8             # This library is distributed in the hope that it will be useful,
9             # but WITHOUT ANY WARRANTY; without even the implied warranty of
10             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11             # Library General Public License for more details.
12             #
13             # You should have received a copy of the GNU Library General Public
14             # License along with this library; if not, write to the
15             # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16             # Boston, MA 02111-1307, USA.
17             #
18             # Jabber
19             # Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
20             #
21             ##############################################################################
22              
23              
24             ##############################################################################
25             #
26             # Op - Base Op class
27             #
28             ##############################################################################
29             package XML::Stream::XPath::Op;
30              
31 12     12   188 use 5.008;
  12         32  
  12         416  
32 12     12   55 use strict;
  12         19  
  12         320  
33 12     12   52 use warnings;
  12         16  
  12         362  
34 12     12   52 use vars qw( $VERSION );
  12         16  
  12         3381  
35              
36             $VERSION = "1.24";
37              
38             sub new
39             {
40 156     156 0 227 my $proto = shift;
41 156         299 return &allocate($proto,@_);
42             }
43              
44             sub allocate
45             {
46 765     765 0 680 my $proto = shift;
47 765         852 my $self = { };
48              
49 765         1665 bless($self,$proto);
50              
51 765         1545 $self->{TYPE} = shift;
52 765         1183 $self->{VALUE} = shift;
53            
54 765         1174 return $self;
55             }
56              
57             sub getValue
58             {
59 23     23 0 30 my $self = shift;
60 23         62 return $self->{VALUE};
61             }
62              
63             sub calcStr
64             {
65 40     40 0 40 my $self = shift;
66 40         113 return $self->{VALUE};
67             }
68              
69             sub getType
70             {
71 23     23 0 26 my $self = shift;
72 23         94 return $self->{TYPE};
73             }
74              
75              
76             sub isValid
77             {
78 32     32 0 42 my $self = shift;
79 32         29 my $ctxt = shift;
80 32         83 return 1;
81             }
82              
83             sub display
84             {
85 0     0 0 0 my $self = shift;
86 0         0 my $space = shift;
87 0 0       0 $space = "" unless defined($space);
88              
89 0         0 print $space,"OP: type($self->{TYPE}) value($self->{VALUE})\n";
90             }
91              
92              
93              
94             ##############################################################################
95             #
96             # PositionOp - class to handle [0] ops
97             #
98             ##############################################################################
99             package XML::Stream::XPath::PositionOp;
100              
101 12     12   65 use vars qw (@ISA);
  12         16  
  12         2322  
102             @ISA = ( "XML::Stream::XPath::Op" );
103              
104             sub new
105             {
106 0     0   0 my $proto = shift;
107 0         0 my $self = $proto->allocate("POSITION","");
108 0         0 $self->{POS} = shift;
109              
110 0         0 return $self;
111             }
112              
113              
114             sub isValid
115             {
116 0     0   0 my $self = shift;
117 0         0 my $ctxt = shift;
118              
119 0         0 my @elems = $$ctxt->getList();
120 0         0 my @valid_elems;
121 0 0       0 if ($#elems+1 < $self->{POS})
122             {
123 0         0 return;
124             }
125              
126 0         0 push(@valid_elems, $elems[$self->{POS}-1]);
127              
128 0         0 $$ctxt->setList(@valid_elems);
129              
130 0         0 return 1;
131             }
132              
133              
134              
135             ##############################################################################
136             #
137             # ContextOp - class to handle [...] ops
138             #
139             ##############################################################################
140             package XML::Stream::XPath::ContextOp;
141              
142 12     12   72 use vars qw (@ISA);
  12         16  
  12         3202  
143             @ISA = ( "XML::Stream::XPath::Op" );
144              
145             sub new
146             {
147 92     92   122 my $proto = shift;
148 92         235 my $self = $proto->allocate("CONTEXT","");
149 92         172 $self->{OP} = shift;
150 92         230 return $self;
151             }
152              
153              
154             sub isValid
155             {
156 92     92   127 my $self = shift;
157 92         108 my $ctxt = shift;
158              
159 92         1089 my @elems = $$ctxt->getList();
160 92         122 my @valid_elems;
161 92         135 foreach my $elem (@elems)
162             {
163 132         348 my $tmp_ctxt = XML::Stream::XPath::Value->new($elem);
164 132         272 $tmp_ctxt->in_context(1);
165 132 100       391 if ($self->{OP}->isValid(\$tmp_ctxt))
166             {
167 23         57 push(@valid_elems,$elem);
168             }
169             }
170              
171 92         284 $$ctxt->setList(@valid_elems);
172            
173 92 100       228 if ($#valid_elems == -1)
174             {
175 75         233 return;
176             }
177              
178 17         65 return 1;
179             }
180              
181              
182             sub display
183             {
184 0     0   0 my $self = shift;
185 0         0 my $space = shift;
186 0 0       0 $space = "" unless defined($space);
187              
188 0         0 print "${space}OP: type(CONTEXT) op: \n";
189 0         0 $self->{OP}->display("$space ");
190             }
191              
192              
193              
194              
195             ##############################################################################
196             #
197             # AllOp - class to handle // ops
198             #
199             ##############################################################################
200             package XML::Stream::XPath::AllOp;
201              
202 12     12   68 use vars qw (@ISA);
  12         14  
  12         3750  
203             @ISA = ( "XML::Stream::XPath::Op" );
204              
205             sub new
206             {
207 14     14   16 my $proto = shift;
208 14         14 my $name = shift;
209 14         36 my $self = $proto->allocate("ALL",$name);
210 14         30 return $self;
211             }
212              
213              
214             sub isValid
215             {
216 14     14   18 my $self = shift;
217 14         13 my $ctxt = shift;
218              
219 14         33 my @elems = $$ctxt->getList();
220              
221 14 50       42 if ($#elems == -1)
222             {
223 0         0 return;
224             }
225              
226 14         17 my @valid_elems;
227            
228 14         14 foreach my $elem (@elems)
229             {
230 18         34 push(@valid_elems,$self->descend($elem));
231             }
232            
233 14         45 $$ctxt->setList(@valid_elems);
234              
235 14 50       31 if ($#valid_elems == -1)
236             {
237 0         0 return;
238             }
239              
240 14         54 return 1;
241             }
242              
243              
244             sub descend
245             {
246 344     344   271 my $self = shift;
247 344         290 my $elem = shift;
248              
249 344         228 my @valid_elems;
250            
251 344 100 66     806 if (($self->{VALUE} eq "*") || (&XML::Stream::GetXMLData("tag",$elem) eq $self->{VALUE}))
252             {
253 46         43 push(@valid_elems,$elem);
254             }
255            
256 344         540 foreach my $child (&XML::Stream::GetXMLData("child array",$elem,"*"))
257             {
258 326         451 push(@valid_elems,$self->descend($child));
259             }
260            
261 344         498 return @valid_elems;
262             }
263              
264              
265              
266             ##############################################################################
267             #
268             # NodeOp - class to handle ops based on node names
269             #
270             ##############################################################################
271             package XML::Stream::XPath::NodeOp;
272              
273 12     12   66 use vars qw (@ISA);
  12         20  
  12         4256  
274             @ISA = ( "XML::Stream::XPath::Op" );
275              
276             sub new
277             {
278 90     90   83 my $proto = shift;
279 90         92 my $name = shift;
280 90         75 my $is_root = shift;
281 90 50       253 $is_root = 0 unless defined($is_root);
282 90         225 my $self = $proto->allocate("NODE",$name);
283 90         110 $self->{ISROOT} = $is_root;
284 90         170 return $self;
285             }
286              
287              
288             sub isValid
289             {
290 77     77   65 my $self = shift;
291 77         73 my $ctxt = shift;
292              
293 77 50       140 if ($self->{ISROOT})
294             {
295 0         0 my $elem = $$ctxt->getFirstElem();
296 0 0       0 if (&XML::Stream::GetXMLData("tag",$elem) ne $self->{VALUE})
297             {
298 0         0 return;
299             }
300 0         0 return 1;
301             }
302              
303 77         69 my @valid_elems;
304              
305 77         156 foreach my $elem ($$ctxt->getList())
306             {
307 73         71 my $valid = 0;
308              
309 73         194 foreach my $child (&XML::Stream::GetXMLData("child array",$elem,"*"))
310             {
311 514 100 100     1144 if (($self->{VALUE} eq "*") ||
312             (&XML::Stream::GetXMLData("tag",$child) eq $self->{VALUE}))
313             {
314 108 50       221 if ($$ctxt->in_context())
315             {
316 0         0 $valid = 1;
317             }
318             else
319             {
320 108         178 push(@valid_elems,$child);
321             }
322             }
323             }
324 73 50       193 if ($valid)
325             {
326 0         0 push(@valid_elems,$elem);
327             }
328             }
329            
330 77         172 $$ctxt->setList(@valid_elems);
331              
332 77 100       148 if ($#valid_elems == -1)
333             {
334 10         22 return;
335             }
336              
337 67         1045 return 1;
338             }
339              
340              
341             sub calcStr
342             {
343 2     2   4 my $self = shift;
344 2         4 my $elem = shift;
345 2         5 return &XML::Stream::GetXMLData("value",$elem);
346             }
347              
348              
349             ##############################################################################
350             #
351             # EqualOp - class to handle [ x = y ] ops
352             #
353             ##############################################################################
354             package XML::Stream::XPath::EqualOp;
355              
356 12     12   68 use vars qw (@ISA);
  12         17  
  12         4595  
357             @ISA = ( "XML::Stream::XPath::Op" );
358              
359             sub new
360             {
361 152     152   196 my $proto = shift;
362 152         316 my $self = $proto->allocate("EQUAL","");
363 152         227 $self->{OP_L} = shift;
364 152         220 $self->{OP_R} = shift;
365 152         453 return $self;
366             }
367              
368              
369             sub isValid
370             {
371 174     174   200 my $self = shift;
372 174         167 my $ctxt = shift;
373              
374 174         445 my $tmp_ctxt = XML::Stream::XPath::Value->new();
375 174         435 $tmp_ctxt->setList($$ctxt->getList());
376 174         428 $tmp_ctxt->in_context(0);
377            
378 174 100 66     506 if (!$self->{OP_L}->isValid(\$tmp_ctxt) || !$self->{OP_R}->isValid(\$tmp_ctxt))
379             {
380 148         222 return;
381             }
382              
383 26         34 my @valid_elems;
384 26         55 foreach my $elem ($tmp_ctxt->getList)
385             {
386 26 100       49 if ($self->{OP_L}->calcStr($elem) eq $self->{OP_R}->calcStr($elem))
387             {
388 9         23 push(@valid_elems,$elem);
389             }
390             }
391              
392 26 100       57 if ( $#valid_elems > -1)
393             {
394 9         25 @valid_elems = $$ctxt->getList();
395             }
396            
397 26         57 $$ctxt->setList(@valid_elems);
398              
399 26 100       60 if ($#valid_elems == -1)
400             {
401 17         70 return;
402             }
403              
404 9         39 return 1;
405             }
406              
407              
408             sub display
409             {
410 0     0   0 my $self = shift;
411 0         0 my $space = shift;
412 0 0       0 $space = "" unless defined($space);
413              
414 0         0 print $space,"OP: type(EQUAL)\n";
415 0         0 print $space," op_l: ";
416 0         0 $self->{OP_L}->display($space." ");
417            
418 0         0 print $space," op_r: ";
419 0         0 $self->{OP_R}->display($space." ");
420             }
421              
422              
423              
424             ##############################################################################
425             #
426             # NotEqualOp - class to handle [ x != y ] ops
427             #
428             ##############################################################################
429             package XML::Stream::XPath::NotEqualOp;
430              
431 12     12   162 use vars qw (@ISA);
  12         22  
  12         4955  
432             @ISA = ( "XML::Stream::XPath::Op" );
433              
434             sub new
435             {
436 2     2   4 my $proto = shift;
437 2         11 my $self = $proto->allocate("NOTEQUAL","");
438 2         4 $self->{OP_L} = shift;
439 2         6 $self->{OP_R} = shift;
440 2         4 return $self;
441             }
442              
443              
444             sub isValid
445             {
446 6     6   7 my $self = shift;
447 6         6 my $ctxt = shift;
448              
449 6         11 my $tmp_ctxt = XML::Stream::XPath::Value->new();
450 6         14 $tmp_ctxt->setList($$ctxt->getList());
451 6         12 $tmp_ctxt->in_context(0);
452            
453 6 50 33     15 if (!$self->{OP_L}->isValid(\$tmp_ctxt) || !$self->{OP_R}->isValid(\$tmp_ctxt))
454             {
455 0         0 return;
456             }
457              
458 6         9 my @valid_elems;
459 6         22 foreach my $elem ($tmp_ctxt->getList)
460             {
461 6 100       15 if ($self->{OP_L}->calcStr($elem) ne $self->{OP_R}->calcStr($elem))
462             {
463 4         8 push(@valid_elems,$elem);
464             }
465             }
466              
467 6 100       14 if ( $#valid_elems > -1)
468             {
469 4         11 @valid_elems = $$ctxt->getList();
470             }
471            
472 6         14 $$ctxt->setList(@valid_elems);
473              
474 6 100       12 if ($#valid_elems == -1)
475             {
476 2         11 return;
477             }
478              
479 4         14 return 1;
480             }
481              
482              
483             sub display
484             {
485 0     0   0 my $self = shift;
486 0         0 my $space = shift;
487 0 0       0 $space = "" unless defined($space);
488              
489 0         0 print $space,"OP: type(NOTEQUAL)\n";
490 0         0 print $space," op_l: ";
491 0         0 $self->{OP_L}->display($space." ");
492            
493 0         0 print $space," op_r: ";
494 0         0 $self->{OP_R}->display($space." ");
495             }
496              
497              
498              
499             ##############################################################################
500             #
501             # AttributeOp - class to handle @foo ops.
502             #
503             ##############################################################################
504             package XML::Stream::XPath::AttributeOp;
505              
506 12     12   67 use vars qw (@ISA);
  12         28  
  12         4533  
507             @ISA = ( "XML::Stream::XPath::Op" );
508              
509             sub new
510             {
511 164     164   220 my $proto = shift;
512 164         201 my $name = shift;
513 164         427 my $self = $proto->allocate("ATTRIBUTE",$name);
514 164         357 return $self;
515             }
516              
517              
518             sub isValid
519             {
520 198     198   208 my $self = shift;
521 198         212 my $ctxt = shift;
522              
523 198         403 my @elems = $$ctxt->getList();
524 198         228 my @valid_elems;
525             my @values;
526 0         0 my %attribs;
527            
528 198         282 foreach my $elem (@elems)
529             {
530 206 100       422 if ($self->{VALUE} ne "*")
531             {
532 204 100       571 if (&XML::Stream::GetXMLData("value",$elem,"",$self->{VALUE}))
533             {
534 48         97 $self->{VAL} = $self->calcStr($elem);
535 48         74 push(@valid_elems,$elem);
536 48         107 push(@values,$self->{VAL});
537             }
538             }
539             else
540             {
541 2         7 my %attrib = &XML::Stream::GetXMLData("attribs",$elem);
542 2 50       8 if (scalar(keys(%attrib)) > 0)
543             {
544 2         4 push(@valid_elems,$elem);
545 2         4 foreach my $key (keys(%attrib))
546             {
547 2         9 $attribs{$key} = $attrib{$key};
548             }
549             }
550             }
551             }
552              
553 198         572 $$ctxt->setList(@valid_elems);
554 198         508 $$ctxt->setValues(@values);
555 198         571 $$ctxt->setAttribs(%attribs);
556              
557 198 100       508 if ($#valid_elems == -1)
558             {
559 150         495 return;
560             }
561            
562 48         201 return 1;
563             }
564              
565              
566             sub getValue
567             {
568 0     0   0 my $self = shift;
569 0         0 return $self->{VAL};
570             }
571              
572              
573             sub calcStr
574             {
575 72     72   64 my $self = shift;
576 72         59 my $elem = shift;
577 72         144 return &XML::Stream::GetXMLData("value",$elem,"",$self->{VALUE});
578             }
579              
580              
581              
582              
583             ##############################################################################
584             #
585             # AndOp - class to handle [ .... and .... ] ops
586             #
587             ##############################################################################
588             package XML::Stream::XPath::AndOp;
589              
590 12     12   76 use vars qw (@ISA);
  12         27  
  12         3258  
591             @ISA = ( "XML::Stream::XPath::Op" );
592              
593             sub new
594             {
595 4     4   8 my $proto = shift;
596 4         14 my $self = $proto->allocate("AND","and");
597 4         5 $self->{OP_L} = shift;
598 4         8 $self->{OP_R} = shift;
599 4         6 return $self;
600             }
601              
602              
603             sub isValid
604             {
605 18     18   14 my $self = shift;
606 18         17 my $ctxt = shift;
607              
608 18         32 my $opl = $self->{OP_L}->isValid($ctxt);
609 18         40 my $opr = $self->{OP_R}->isValid($ctxt);
610            
611 18 100 100     60 if ($opl && $opr)
612             {
613 4         13 return 1;
614             }
615             else
616             {
617 14         37 return;
618             }
619             }
620              
621              
622             sub display
623             {
624 0     0   0 my $self = shift;
625 0         0 my $space = shift;
626 0 0       0 $space = "" unless defined($space);
627              
628 0         0 print $space,"OP: type(AND)\n";
629 0         0 print $space," op_l: \n";
630 0         0 $self->{OP_L}->display($space." ");
631            
632 0         0 print $space," op_r: \n";
633 0         0 $self->{OP_R}->display($space." ");
634             }
635              
636              
637              
638             ##############################################################################
639             #
640             # OrOp - class to handle [ .... or .... ] ops
641             #
642             ##############################################################################
643             package XML::Stream::XPath::OrOp;
644              
645 12     12   76 use vars qw (@ISA);
  12         28  
  12         4754  
646             @ISA = ( "XML::Stream::XPath::Op" );
647              
648             sub new
649             {
650 68     68   94 my $proto = shift;
651 68         195 my $self = $proto->allocate("OR","or");
652 68         115 $self->{OP_L} = shift;
653 68         125 $self->{OP_R} = shift;
654 68         181 return $self;
655             }
656              
657              
658             sub isValid
659             {
660 68     68   98 my $self = shift;
661 68         87 my $ctxt = shift;
662              
663 68         183 my @elems = $$ctxt->getList();
664 68         90 my @valid_elems;
665              
666 68         127 foreach my $elem (@elems)
667             {
668 68         216 my $tmp_ctxt_l = XML::Stream::XPath::Value->new($elem);
669 68         175 $tmp_ctxt_l->in_context(1);
670 68         169 my $tmp_ctxt_r = XML::Stream::XPath::Value->new($elem);
671 68         161 $tmp_ctxt_r->in_context(1);
672              
673 68         219 my $opl = $self->{OP_L}->isValid(\$tmp_ctxt_l);
674 68         291 my $opr = $self->{OP_R}->isValid(\$tmp_ctxt_r);
675            
676 68 50 33     609 if ($opl || $opr)
677             {
678 0         0 push(@valid_elems,$elem);
679             }
680             }
681              
682 68         214 $$ctxt->setList(@valid_elems);
683            
684 68 50       182 if ($#valid_elems == -1)
685             {
686 68         291 return;
687             }
688              
689 0         0 return 1;
690             }
691              
692              
693             sub display
694             {
695 0     0   0 my $self = shift;
696 0         0 my $space = shift;
697 0 0       0 $space = "" unless defined($space);
698              
699 0         0 print "${space}OP: type(OR)\n";
700 0         0 print "$space op_l: ";
701 0         0 $self->{OP_L}->display("$space ");
702            
703 0         0 print "$space op_r: ";
704 0         0 $self->{OP_R}->display("$space ");
705             }
706              
707              
708              
709             ##############################################################################
710             #
711             # FunctionOp - class to handle xxxx(...) ops
712             #
713             ##############################################################################
714             package XML::Stream::XPath::FunctionOp;
715              
716 12     12   69 use vars qw (@ISA);
  12         14  
  12         11476  
717             @ISA = ( "XML::Stream::XPath::Op" );
718              
719             sub new
720             {
721 23     23   32 my $proto = shift;
722 23         32 my $function = shift;
723 23         65 my $self = $proto->allocate("FUNCTION",$function);
724 23         43 $self->{CLOSED} = 0;
725 23         48 return $self;
726             }
727              
728              
729             sub addArg
730             {
731 6     6   8 my $self = shift;
732 6         9 my $arg = shift;
733              
734 6         5 push(@{$self->{ARGOPS}},$arg);
  6         21  
735             }
736              
737              
738             sub isValid
739             {
740 35     35   41 my $self = shift;
741 35         31 my $ctxt = shift;
742              
743 35         42 my $result;
744 35         3047 eval("\$result = &{\$XML::Stream::XPath::FUNCTIONS{\$self->{VALUE}}}(\$ctxt,\@{\$self->{ARGOPS}});");
745 35         190 return $result;
746             }
747              
748              
749             sub calcStr
750             {
751 14     14   15 my $self = shift;
752 14         11 my $elem = shift;
753            
754 14         14 my $result;
755 14         698 eval("\$result = &{\$XML::Stream::XPath::VALUES{\$self->{VALUE}}}(\$elem);");
756 14         42 return $result;
757              
758             }
759              
760              
761             sub display
762             {
763 0     0   0 my $self = shift;
764 0         0 my $space = shift;
765 0 0       0 $space = "" unless defined($space);
766              
767 0         0 print $space,"OP: type(FUNCTION)\n";
768 0         0 print $space," $self->{VALUE}(\n";
769 0         0 foreach my $arg (@{$self->{ARGOPS}})
  0         0  
770             {
771 0         0 print $arg,"\n";
772 0         0 $arg->display($space." ");
773             }
774 0         0 print "$space )\n";
775             }
776              
777              
778             sub function_name
779             {
780 14     14   27 my $ctxt = shift;
781 14         22 my (@args) = @_;
782              
783 14         50 my @elems = $$ctxt->getList();
784 14         17 my @valid_elems;
785             my @valid_values;
786 14         26 foreach my $elem (@elems)
787             {
788 14         40 my $text = &value_name($elem);
789 14 50       32 if (defined($text))
790             {
791 14         21 push(@valid_elems,$elem);
792 14         32 push(@valid_values,$text);
793             }
794             }
795              
796 14         41 $$ctxt->setList(@valid_elems);
797 14         38 $$ctxt->setValues(@valid_values);
798            
799 14 50       33 if ($#valid_elems == -1)
800             {
801 0         0 return;
802             }
803              
804 14         155 return 1;
805             }
806              
807              
808             sub function_not
809             {
810 6     6   7 my $ctxt = shift;
811 6         9 my (@args) = @_;
812              
813 6         32 my @elems = $$ctxt->getList();
814 6         6 my @valid_elems;
815 6         7 foreach my $elem (@elems)
816             {
817 6         146 my $tmp_ctxt = XML::Stream::XPath::Value->new($elem);
818 6         11 $tmp_ctxt->in_context(1);
819 6 100       13 if (!($args[0]->isValid(\$tmp_ctxt)))
820             {
821 2         8 push(@valid_elems,$elem);
822             }
823             }
824              
825 6         13 $$ctxt->setList(@valid_elems);
826            
827 6 100       13 if ($#valid_elems == -1)
828             {
829 4         32 return;
830             }
831              
832 2         24 return 1;
833             }
834              
835              
836             sub function_text
837             {
838 7     7   17 my $ctxt = shift;
839 7         14 my (@args) = @_;
840              
841 7         25 my @elems = $$ctxt->getList();
842 7         11 my @valid_elems;
843             my @valid_values;
844 7         20 foreach my $elem (@elems)
845             {
846 12         29 my $text = &value_text($elem);
847 12 50       28 if (defined($text))
848             {
849 12         21 push(@valid_elems,$elem);
850 12         21 push(@valid_values,$text);
851             }
852             }
853              
854 7         23 $$ctxt->setList(@valid_elems);
855 7         22 $$ctxt->setValues(@valid_values);
856            
857 7 50       21 if ($#valid_elems == -1)
858             {
859 0         0 return;
860             }
861              
862 7         64 return 1;
863             }
864              
865              
866             sub function_startswith
867             {
868 8     8   11 my $ctxt = shift;
869 8         11 my (@args) = @_;
870              
871 8         21 my @elems = $$ctxt->getList();
872 8         9 my @valid_elems;
873 8         11 foreach my $elem (@elems)
874             {
875 8         15 my $val1 = $args[0]->calcStr($elem);
876 8         21 my $val2 = $args[1]->calcStr($elem);
877              
878 8 100       26 if (substr($val1,0,length($val2)) eq $val2)
879             {
880 4         7 push(@valid_elems,$elem);
881             }
882             }
883              
884 8         22 $$ctxt->setList(@valid_elems);
885            
886 8 100       19 if ($#valid_elems == -1)
887             {
888 4         26 return;
889             }
890              
891 4         21 return 1;
892             }
893              
894              
895             sub value_name
896             {
897 20     20   23 my $elem = shift;
898 20         51 return &XML::Stream::GetXMLData("tag",$elem);
899             }
900              
901              
902             sub value_text
903             {
904 20     20   27 my $elem = shift;
905 20         44 return &XML::Stream::GetXMLData("value",$elem);
906             }
907              
908              
909              
910             $XML::Stream::XPath::FUNCTIONS{'name'} = \&function_name;
911             $XML::Stream::XPath::FUNCTIONS{'not'} = \&function_not;
912             $XML::Stream::XPath::FUNCTIONS{'text'} = \&function_text;
913             $XML::Stream::XPath::FUNCTIONS{'starts-with'} = \&function_startswith;
914              
915             $XML::Stream::XPath::VALUES{'name'} = \&value_name;
916             $XML::Stream::XPath::VALUES{'text'} = \&value_text;
917              
918             1;
919              
920