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 11     11   268 use 5.008;
  11         40  
  11         488  
32 11     11   62 use strict;
  11         24  
  11         362  
33 11     11   56 use warnings;
  11         23  
  11         389  
34 11     11   56 use vars qw( $VERSION );
  11         22  
  11         5812  
35              
36             $VERSION = "1.23_06";
37              
38             sub new
39             {
40 156     156 0 227 my $proto = shift;
41 156         316 return &allocate($proto,@_);
42             }
43              
44             sub allocate
45             {
46 765     765 0 1040 my $proto = shift;
47 765         1271 my $self = { };
48              
49 765         2025 bless($self,$proto);
50              
51 765         1854 $self->{TYPE} = shift;
52 765         1572 $self->{VALUE} = shift;
53            
54 765         1552 return $self;
55             }
56              
57             sub getValue
58             {
59 23     23 0 54 my $self = shift;
60 23         76 return $self->{VALUE};
61             }
62              
63             sub calcStr
64             {
65 40     40 0 66 my $self = shift;
66 40         171 return $self->{VALUE};
67             }
68              
69             sub getType
70             {
71 23     23 0 78 my $self = shift;
72 23         121 return $self->{TYPE};
73             }
74              
75              
76             sub isValid
77             {
78 32     32 0 95 my $self = shift;
79 32         93 my $ctxt = shift;
80 32         114 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 11     11   70 use vars qw (@ISA);
  11         28  
  11         2468  
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 11     11   59 use vars qw (@ISA);
  11         40  
  11         3877  
143             @ISA = ( "XML::Stream::XPath::Op" );
144              
145             sub new
146             {
147 92     92   235 my $proto = shift;
148 92         277 my $self = $proto->allocate("CONTEXT","");
149 92         203 $self->{OP} = shift;
150 92         256 return $self;
151             }
152              
153              
154             sub isValid
155             {
156 92     92   155 my $self = shift;
157 92         2791 my $ctxt = shift;
158              
159 92         434 my @elems = $$ctxt->getList();
160 92         139 my @valid_elems;
161 92         175 foreach my $elem (@elems)
162             {
163 132         542 my $tmp_ctxt = XML::Stream::XPath::Value->new($elem);
164 132         384 $tmp_ctxt->in_context(1);
165 132 100       433 if ($self->{OP}->isValid(\$tmp_ctxt))
166             {
167 23         98 push(@valid_elems,$elem);
168             }
169             }
170              
171 92         312 $$ctxt->setList(@valid_elems);
172            
173 92 100       287 if ($#valid_elems == -1)
174             {
175 75         270 return;
176             }
177              
178 17         111 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 11     11   67 use vars qw (@ISA);
  11         19  
  11         3749  
203             @ISA = ( "XML::Stream::XPath::Op" );
204              
205             sub new
206             {
207 14     14   24 my $proto = shift;
208 14         25 my $name = shift;
209 14         56 my $self = $proto->allocate("ALL",$name);
210 14         43 return $self;
211             }
212              
213              
214             sub isValid
215             {
216 14     14   26 my $self = shift;
217 14         22 my $ctxt = shift;
218              
219 14         55 my @elems = $$ctxt->getList();
220              
221 14 50       48 if ($#elems == -1)
222             {
223 0         0 return;
224             }
225              
226 14         24 my @valid_elems;
227            
228 14         27 foreach my $elem (@elems)
229             {
230 18         51 push(@valid_elems,$self->descend($elem));
231             }
232            
233 14         66 $$ctxt->setList(@valid_elems);
234              
235 14 50       53 if ($#valid_elems == -1)
236             {
237 0         0 return;
238             }
239              
240 14         82 return 1;
241             }
242              
243              
244             sub descend
245             {
246 344     344   654 my $self = shift;
247 344         387 my $elem = shift;
248              
249 344         362 my @valid_elems;
250            
251 344 100 66     1410 if (($self->{VALUE} eq "*") || (&XML::Stream::GetXMLData("tag",$elem) eq $self->{VALUE}))
252             {
253 46         85 push(@valid_elems,$elem);
254             }
255            
256 344         1068 foreach my $child (&XML::Stream::GetXMLData("child array",$elem,"*"))
257             {
258 326         792 push(@valid_elems,$self->descend($child));
259             }
260            
261 344         1048 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 11     11   70 use vars qw (@ISA);
  11         26  
  11         4795  
274             @ISA = ( "XML::Stream::XPath::Op" );
275              
276             sub new
277             {
278 90     90   156 my $proto = shift;
279 90         131 my $name = shift;
280 90         133 my $is_root = shift;
281 90 50       205 $is_root = 0 unless defined($is_root);
282 90         1124 my $self = $proto->allocate("NODE",$name);
283 90         626 $self->{ISROOT} = $is_root;
284 90         273 return $self;
285             }
286              
287              
288             sub isValid
289             {
290 77     77   107 my $self = shift;
291 77         99 my $ctxt = shift;
292              
293 77 50       187 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         183 my @valid_elems;
304              
305 77         359 foreach my $elem ($$ctxt->getList())
306             {
307 73         113 my $valid = 0;
308              
309 73         237 foreach my $child (&XML::Stream::GetXMLData("child array",$elem,"*"))
310             {
311 513 100 100     3382 if (($self->{VALUE} eq "*") ||
312             (&XML::Stream::GetXMLData("tag",$child) eq $self->{VALUE}))
313             {
314 107 50       358 if ($$ctxt->in_context())
315             {
316 0         0 $valid = 1;
317             }
318             else
319             {
320 107         267 push(@valid_elems,$child);
321             }
322             }
323             }
324 73 50       412 if ($valid)
325             {
326 0         0 push(@valid_elems,$elem);
327             }
328             }
329            
330 77         272 $$ctxt->setList(@valid_elems);
331              
332 77 100       226 if ($#valid_elems == -1)
333             {
334 11         79 return;
335             }
336              
337 66         303 return 1;
338             }
339              
340              
341             sub calcStr
342             {
343 2     2   6 my $self = shift;
344 2         4 my $elem = shift;
345 2         7 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 11     11   64 use vars qw (@ISA);
  11         24  
  11         7801  
357             @ISA = ( "XML::Stream::XPath::Op" );
358              
359             sub new
360             {
361 152     152   228 my $proto = shift;
362 152         435 my $self = $proto->allocate("EQUAL","");
363 152         298 $self->{OP_L} = shift;
364 152         234 $self->{OP_R} = shift;
365 152         573 return $self;
366             }
367              
368              
369             sub isValid
370             {
371 174     174   227 my $self = shift;
372 174         201 my $ctxt = shift;
373              
374 174         509 my $tmp_ctxt = XML::Stream::XPath::Value->new();
375 174         510 $tmp_ctxt->setList($$ctxt->getList());
376 174         529 $tmp_ctxt->in_context(0);
377            
378 174 100 66     509 if (!$self->{OP_L}->isValid(\$tmp_ctxt) || !$self->{OP_R}->isValid(\$tmp_ctxt))
379             {
380 148         301 return;
381             }
382              
383 26         48 my @valid_elems;
384 26         89 foreach my $elem ($tmp_ctxt->getList)
385             {
386 26 100       150 if ($self->{OP_L}->calcStr($elem) eq $self->{OP_R}->calcStr($elem))
387             {
388 9         32 push(@valid_elems,$elem);
389             }
390             }
391              
392 26 100       80 if ( $#valid_elems > -1)
393             {
394 9         30 @valid_elems = $$ctxt->getList();
395             }
396            
397 26         92 $$ctxt->setList(@valid_elems);
398              
399 26 100       82 if ($#valid_elems == -1)
400             {
401 17         213 return;
402             }
403              
404 9         46 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 11     11   285 use vars qw (@ISA);
  11         52  
  11         6066  
432             @ISA = ( "XML::Stream::XPath::Op" );
433              
434             sub new
435             {
436 2     2   5 my $proto = shift;
437 2         12 my $self = $proto->allocate("NOTEQUAL","");
438 2         5 $self->{OP_L} = shift;
439 2         6 $self->{OP_R} = shift;
440 2         6 return $self;
441             }
442              
443              
444             sub isValid
445             {
446 6     6   9 my $self = shift;
447 6         8 my $ctxt = shift;
448              
449 6         19 my $tmp_ctxt = XML::Stream::XPath::Value->new();
450 6         18 $tmp_ctxt->setList($$ctxt->getList());
451 6         19 $tmp_ctxt->in_context(0);
452            
453 6 50 33     20 if (!$self->{OP_L}->isValid(\$tmp_ctxt) || !$self->{OP_R}->isValid(\$tmp_ctxt))
454             {
455 0         0 return;
456             }
457              
458 6         26 my @valid_elems;
459 6         17 foreach my $elem ($tmp_ctxt->getList)
460             {
461 6 100       19 if ($self->{OP_L}->calcStr($elem) ne $self->{OP_R}->calcStr($elem))
462             {
463 4         13 push(@valid_elems,$elem);
464             }
465             }
466              
467 6 100       16 if ( $#valid_elems > -1)
468             {
469 4         15 @valid_elems = $$ctxt->getList();
470             }
471            
472 6         20 $$ctxt->setList(@valid_elems);
473              
474 6 100       19 if ($#valid_elems == -1)
475             {
476 2         16 return;
477             }
478              
479 4         19 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 11     11   76 use vars qw (@ISA);
  11         22  
  11         5247  
507             @ISA = ( "XML::Stream::XPath::Op" );
508              
509             sub new
510             {
511 164     164   264 my $proto = shift;
512 164         248 my $name = shift;
513 164         488 my $self = $proto->allocate("ATTRIBUTE",$name);
514 164         450 return $self;
515             }
516              
517              
518             sub isValid
519             {
520 198     198   257 my $self = shift;
521 198         219 my $ctxt = shift;
522              
523 198         574 my @elems = $$ctxt->getList();
524 198         282 my @valid_elems;
525             my @values;
526 0         0 my %attribs;
527            
528 198         319 foreach my $elem (@elems)
529             {
530 206 100       505 if ($self->{VALUE} ne "*")
531             {
532 204 100       690 if (&XML::Stream::GetXMLData("value",$elem,"",$self->{VALUE}))
533             {
534 48         250 $self->{VAL} = $self->calcStr($elem);
535 48         88 push(@valid_elems,$elem);
536 48         168 push(@values,$self->{VAL});
537             }
538             }
539             else
540             {
541 2         214 my %attrib = &XML::Stream::GetXMLData("attribs",$elem);
542 2 50       11 if (scalar(keys(%attrib)) > 0)
543             {
544 2         6 push(@valid_elems,$elem);
545 2         6 foreach my $key (keys(%attrib))
546             {
547 2         44 $attribs{$key} = $attrib{$key};
548             }
549             }
550             }
551             }
552              
553 198         665 $$ctxt->setList(@valid_elems);
554 198         608 $$ctxt->setValues(@values);
555 198         872 $$ctxt->setAttribs(%attribs);
556              
557 198 100       679 if ($#valid_elems == -1)
558             {
559 150         545 return;
560             }
561            
562 48         404 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   98 my $self = shift;
576 72         98 my $elem = shift;
577 72         254 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 11     11   71 use vars qw (@ISA);
  11         22  
  11         5623  
591             @ISA = ( "XML::Stream::XPath::Op" );
592              
593             sub new
594             {
595 4     4   7 my $proto = shift;
596 4         14 my $self = $proto->allocate("AND","and");
597 4         8 $self->{OP_L} = shift;
598 4         9 $self->{OP_R} = shift;
599 4         10 return $self;
600             }
601              
602              
603             sub isValid
604             {
605 18     18   20 my $self = shift;
606 18         20 my $ctxt = shift;
607              
608 18         43 my $opl = $self->{OP_L}->isValid($ctxt);
609 18         50 my $opr = $self->{OP_R}->isValid($ctxt);
610            
611 18 100 100     98 if ($opl && $opr)
612             {
613 4         13 return 1;
614             }
615             else
616             {
617 14         60 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 11     11   145 use vars qw (@ISA);
  11         27  
  11         5443  
646             @ISA = ( "XML::Stream::XPath::Op" );
647              
648             sub new
649             {
650 68     68   99 my $proto = shift;
651 68         190 my $self = $proto->allocate("OR","or");
652 68         120 $self->{OP_L} = shift;
653 68         100 $self->{OP_R} = shift;
654 68         221 return $self;
655             }
656              
657              
658             sub isValid
659             {
660 68     68   90 my $self = shift;
661 68         85 my $ctxt = shift;
662              
663 68         175 my @elems = $$ctxt->getList();
664 68         99 my @valid_elems;
665              
666 68         129 foreach my $elem (@elems)
667             {
668 68         213 my $tmp_ctxt_l = XML::Stream::XPath::Value->new($elem);
669 68         204 $tmp_ctxt_l->in_context(1);
670 68         206 my $tmp_ctxt_r = XML::Stream::XPath::Value->new($elem);
671 68         177 $tmp_ctxt_r->in_context(1);
672              
673 68         233 my $opl = $self->{OP_L}->isValid(\$tmp_ctxt_l);
674 68         349 my $opr = $self->{OP_R}->isValid(\$tmp_ctxt_r);
675            
676 68 50 33     718 if ($opl || $opr)
677             {
678 0         0 push(@valid_elems,$elem);
679             }
680             }
681              
682 68         228 $$ctxt->setList(@valid_elems);
683            
684 68 50       201 if ($#valid_elems == -1)
685             {
686 68         347 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 11     11   70 use vars qw (@ISA);
  11         20  
  11         52016  
717             @ISA = ( "XML::Stream::XPath::Op" );
718              
719             sub new
720             {
721 23     23   52 my $proto = shift;
722 23         48 my $function = shift;
723 23         96 my $self = $proto->allocate("FUNCTION",$function);
724 23         53 $self->{CLOSED} = 0;
725 23         65 return $self;
726             }
727              
728              
729             sub addArg
730             {
731 6     6   11 my $self = shift;
732 6         9 my $arg = shift;
733              
734 6         7 push(@{$self->{ARGOPS}},$arg);
  6         31  
735             }
736              
737              
738             sub isValid
739             {
740 35     35   63 my $self = shift;
741 35         42 my $ctxt = shift;
742              
743 35         46 my $result;
744 35         14479 eval("\$result = &{\$XML::Stream::XPath::FUNCTIONS{\$self->{VALUE}}}(\$ctxt,\@{\$self->{ARGOPS}});");
745 35         252 return $result;
746             }
747              
748              
749             sub calcStr
750             {
751 14     14   21 my $self = shift;
752 14         15 my $elem = shift;
753            
754 14         15 my $result;
755 14         873 eval("\$result = &{\$XML::Stream::XPath::VALUES{\$self->{VALUE}}}(\$elem);");
756 14         94 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   47 my $ctxt = shift;
781 14         34 my (@args) = @_;
782              
783 14         62 my @elems = $$ctxt->getList();
784 14         26 my @valid_elems;
785             my @valid_values;
786 14         34 foreach my $elem (@elems)
787             {
788 14         49 my $text = &value_name($elem);
789 14 50       45 if (defined($text))
790             {
791 14         26 push(@valid_elems,$elem);
792 14         631 push(@valid_values,$text);
793             }
794             }
795              
796 14         56 $$ctxt->setList(@valid_elems);
797 14         60 $$ctxt->setValues(@valid_values);
798            
799 14 50       50 if ($#valid_elems == -1)
800             {
801 0         0 return;
802             }
803              
804 14         163 return 1;
805             }
806              
807              
808             sub function_not
809             {
810 6     6   14 my $ctxt = shift;
811 6         12 my (@args) = @_;
812              
813 6         66 my @elems = $$ctxt->getList();
814 6         11 my @valid_elems;
815 6         12 foreach my $elem (@elems)
816             {
817 6         201 my $tmp_ctxt = XML::Stream::XPath::Value->new($elem);
818 6         20 $tmp_ctxt->in_context(1);
819 6 100       21 if (!($args[0]->isValid(\$tmp_ctxt)))
820             {
821 2         10 push(@valid_elems,$elem);
822             }
823             }
824              
825 6         21 $$ctxt->setList(@valid_elems);
826            
827 6 100       23 if ($#valid_elems == -1)
828             {
829 4         45 return;
830             }
831              
832 2         36 return 1;
833             }
834              
835              
836             sub function_text
837             {
838 7     7   16 my $ctxt = shift;
839 7         20 my (@args) = @_;
840              
841 7         31 my @elems = $$ctxt->getList();
842 7         21 my @valid_elems;
843             my @valid_values;
844 7         21 foreach my $elem (@elems)
845             {
846 12         36 my $text = &value_text($elem);
847 12 50       39 if (defined($text))
848             {
849 12         20 push(@valid_elems,$elem);
850 12         34 push(@valid_values,$text);
851             }
852             }
853              
854 7         31 $$ctxt->setList(@valid_elems);
855 7         34 $$ctxt->setValues(@valid_values);
856            
857 7 50       26 if ($#valid_elems == -1)
858             {
859 0         0 return;
860             }
861              
862 7         84 return 1;
863             }
864              
865              
866             sub function_startswith
867             {
868 8     8   11 my $ctxt = shift;
869 8         18 my (@args) = @_;
870              
871 8         29 my @elems = $$ctxt->getList();
872 8         11 my @valid_elems;
873 8         11 foreach my $elem (@elems)
874             {
875 8         22 my $val1 = $args[0]->calcStr($elem);
876 8         21 my $val2 = $args[1]->calcStr($elem);
877              
878 8 100       158 if (substr($val1,0,length($val2)) eq $val2)
879             {
880 4         12 push(@valid_elems,$elem);
881             }
882             }
883              
884 8         25 $$ctxt->setList(@valid_elems);
885            
886 8 100       22 if ($#valid_elems == -1)
887             {
888 4         30 return;
889             }
890              
891 4         30 return 1;
892             }
893              
894              
895             sub value_name
896             {
897 20     20   35 my $elem = shift;
898 20         240 return &XML::Stream::GetXMLData("tag",$elem);
899             }
900              
901              
902             sub value_text
903             {
904 20     20   35 my $elem = shift;
905 20         70 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