File: | lib/XML/Parser/Lite/Tree/XPath/Eval.pm |
Coverage: | 87.4% |
line | stmt | bran | cond | sub | time | code |
---|---|---|---|---|---|---|
1 | package XML::Parser::Lite::Tree::XPath::Eval; | |||||
2 | ||||||
3 | 29 29 29 | 111 48 147 | use XML::Parser::Lite::Tree::XPath::Token; | |||
4 | 29 29 29 | 128 49 182 | use Data::Dumper; | |||
5 | 29 29 29 | 149 52 112 | use strict; | |||
6 | ||||||
7 | sub new { | |||||
8 | 130 | 360 | my ($class) = @_; | |||
9 | 130 | 629 | my $self = bless {}, $class; | |||
10 | 130 | 400 | $self->{error} = 0; | |||
11 | 130 | 373 | return $self; | |||
12 | } | |||||
13 | ||||||
14 | sub query { | |||||
15 | 130 | 452 | my ($self, $xpath, $tree) = @_; | |||
16 | 130 | 344 | $self->{error} = 0; | |||
17 | 130 | 336 | $self->{tree} = $tree; | |||
18 | ||||||
19 | 130 | 748 | $self->{root} = XML::Parser::Lite::Tree::XPath::Result->new('nodeset', [$self->{tree}]); | |||
20 | 130 | 572 | $self->{max_order} = $self->mark_orders($self->{tree}, 1, undef); | |||
21 | ||||||
22 | 130 | 475 | $self->{uids} = {}; | |||
23 | 130 | 508 | $self->mark_uids($self->{tree}); | |||
24 | ||||||
25 | 130 | 462 | my $token = $xpath->{tokens}->[0]; | |||
26 | 130 | 402 | unless (defined $token){ | |||
27 | 0 | 0 | $self->{error} = "couldn't get root token to eval."; | |||
28 | 0 | 0 | return 0; | |||
29 | } | |||||
30 | ||||||
31 | 130 | 420 | $self->mark_token($token); | |||
32 | ||||||
33 | 130 | 645 | my $out = $token->eval($self->{root}); | |||
34 | ||||||
35 | 130 | 494 | if ($out->is_error){ | |||
36 | 1 | 5 | $self->{error} = $out->{value}; | |||
37 | 1 | 4 | return 0; | |||
38 | } | |||||
39 | ||||||
40 | 129 | 458 | return $out; | |||
41 | ||||||
42 | 0 | 0 | if ($out->{type} ne 'nodeset'){ | |||
43 | 0 | 0 | $self->{error} = "Result was not a nodeset (was a $out->{type})"; | |||
44 | 0 | 0 | return 0; | |||
45 | } | |||||
46 | ||||||
47 | 0 | 0 | return $out->{value}; | |||
48 | } | |||||
49 | ||||||
50 | sub mark_orders { | |||||
51 | 1185 | 3529 | my ($self, $tag, $i, $parent) = @_; | |||
52 | ||||||
53 | 1185 | 3322 | $tag->{order} = $i++; | |||
54 | 1185 | 2959 | $tag->{parent} = $parent; | |||
55 | ||||||
56 | 1185 1185 | 1840 4087 | for my $child(@{$tag->{children}}){ | |||
57 | 1055 | 3208 | $i = $self->mark_orders($child, $i, $tag); | |||
58 | } | |||||
59 | ||||||
60 | 1185 | 3979 | return $i; | |||
61 | } | |||||
62 | ||||||
63 | sub mark_token { | |||||
64 | 926 | 2343 | my ($self, $token) = @_; | |||
65 | ||||||
66 | 926 | 2866 | $token->{root} = $self->{root}; | |||
67 | 926 | 2837 | $token->{max_order} = $self->{max_order}; | |||
68 | ||||||
69 | 926 926 | 1436 4229 | for my $child(@{$token->{tokens}}){ | |||
70 | 796 | 2259 | $self->mark_token($child); | |||
71 | } | |||||
72 | } | |||||
73 | ||||||
74 | sub mark_uids { | |||||
75 | 1185 | 3111 | my ($self, $tag) = @_; | |||
76 | ||||||
77 | # | |||||
78 | # mark | |||||
79 | # | |||||
80 | ||||||
81 | 1185 | 4507 | if ($tag->{type} eq 'element'){ | |||
82 | ||||||
83 | 985 | 2637 | $tag->{uid} = ''; | |||
84 | ||||||
85 | 985 | 3131 | my $id = $tag->{attributes}->{id}; | |||
86 | ||||||
87 | 985 | 5731 | if (defined $id && length $id){ | |||
88 | 710 | 3022 | unless (defined $self->{uids}->{$id}){ | |||
89 | ||||||
90 | 710 | 1819 | $tag->{uid} = $id; | |||
91 | 710 | 2880 | $self->{uids}->{$id} = 1; | |||
92 | } | |||||
93 | } | |||||
94 | } | |||||
95 | ||||||
96 | ||||||
97 | # | |||||
98 | # descend | |||||
99 | # | |||||
100 | ||||||
101 | 1185 | 9223 | if ($tag->{type} eq 'root' || $tag->{type} eq 'element'){ | |||
102 | ||||||
103 | 1115 1115 | 1755 5199 | for my $child (@{$tag->{children}}){ | |||
104 | ||||||
105 | 1055 | 2982 | $self->mark_uids($child); | |||
106 | } | |||||
107 | } | |||||
108 | } | |||||
109 | ||||||
110 | 1; |