line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package XML::miniXQL;
|
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
576
|
use strict;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
28
|
|
4
|
1
|
|
|
1
|
|
5
|
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
66
|
|
5
|
|
|
|
|
|
|
|
6
|
1
|
|
|
1
|
|
422
|
use XML::miniXQL::Parser;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
45
|
|
7
|
1
|
|
|
1
|
|
1246
|
use XML::Parser;
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
require Exporter;
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
@ISA = qw(Exporter);
|
12
|
|
|
|
|
|
|
@EXPORT = qw(
|
13
|
|
|
|
|
|
|
);
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
$VERSION = '0.04';
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
sub queryXML {
|
19
|
|
|
|
|
|
|
my $param = shift;
|
20
|
|
|
|
|
|
|
my $xml;
|
21
|
|
|
|
|
|
|
if (ref $param eq 'HASH') {
|
22
|
|
|
|
|
|
|
$xml = shift;
|
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
}
|
25
|
|
|
|
|
|
|
else {
|
26
|
|
|
|
|
|
|
$xml = $param;
|
27
|
|
|
|
|
|
|
$param = {Style => 'List'};
|
28
|
|
|
|
|
|
|
}
|
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
my @queries = @_;
|
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# print "Queries:\n", join "\n", @queries;
|
33
|
|
|
|
|
|
|
# print "\n\n";
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
my @Requests;
|
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
my $req = new XML::miniXQL::Parser();
|
38
|
|
|
|
|
|
|
do {
|
39
|
|
|
|
|
|
|
$req = new XML::miniXQL::Parser(shift @queries, $req);
|
40
|
|
|
|
|
|
|
push @Requests, $req;
|
41
|
|
|
|
|
|
|
} while @queries;
|
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
my $currenttree = new XML::miniXQL::Parser();
|
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
my $p = new XML::Parser(Style => 'Stream',
|
46
|
|
|
|
|
|
|
_parseresults => {},
|
47
|
|
|
|
|
|
|
_currenttree => $currenttree,
|
48
|
|
|
|
|
|
|
_requests => \@Requests,
|
49
|
|
|
|
|
|
|
_style => $param->{Style},
|
50
|
|
|
|
|
|
|
);
|
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
my $results;
|
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
# Using exceptions for a more fine-grained control. Not completely necessary ATM though.
|
55
|
|
|
|
|
|
|
eval {
|
56
|
|
|
|
|
|
|
$results = $p->parse($xml);
|
57
|
|
|
|
|
|
|
# warn "Parse returned ", @{$results}, "\n";
|
58
|
|
|
|
|
|
|
};
|
59
|
|
|
|
|
|
|
if ($@) {
|
60
|
|
|
|
|
|
|
die $@;
|
61
|
|
|
|
|
|
|
}
|
62
|
|
|
|
|
|
|
else {
|
63
|
|
|
|
|
|
|
return $results;
|
64
|
|
|
|
|
|
|
}
|
65
|
|
|
|
|
|
|
}
|
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
sub StartTag {
|
68
|
|
|
|
|
|
|
my $expat = shift;
|
69
|
|
|
|
|
|
|
return $expat->finish() if $expat->{_done};
|
70
|
|
|
|
|
|
|
my $element = shift;
|
71
|
|
|
|
|
|
|
# my %attribs = %_;
|
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
#warn "Start: $element\n";
|
74
|
|
|
|
|
|
|
$expat->{_currenttree}->Append($element, %_);
|
75
|
|
|
|
|
|
|
my $current = $expat->{_currenttree};
|
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
#warn "Path now: ", $expat->{_currenttree}->Path, "\n";
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
my $removed = 0;
|
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
foreach (0..$#{$expat->{_requests}}) {
|
82
|
|
|
|
|
|
|
next unless defined $expat->{_requests}->[$_]->Attrib;
|
83
|
|
|
|
|
|
|
# warn "Looking for attrib: ", $expat->{_requests}->[$_]->Attrib, "\n";
|
84
|
|
|
|
|
|
|
if (defined $_{$expat->{_requests}->[$_]->Attrib}) {
|
85
|
|
|
|
|
|
|
# Looking for attrib
|
86
|
|
|
|
|
|
|
if ($expat->{_requests}->[$_]->isEqual($current)) {
|
87
|
|
|
|
|
|
|
# We have equality!
|
88
|
|
|
|
|
|
|
# print "Found\n";
|
89
|
|
|
|
|
|
|
found($expat, $expat->{_requests}->[$_], $_{$expat->{_requests}->[$_]->Attrib});
|
90
|
|
|
|
|
|
|
splice(@{$expat->{_requests}}, $_ - $removed, 1) unless $expat->{_requests}->[$_]->isRepeat;
|
91
|
|
|
|
|
|
|
$expat->{_done} = 1 if (@{$expat->{_requests}} == 0);
|
92
|
|
|
|
|
|
|
$removed++;
|
93
|
|
|
|
|
|
|
# return;
|
94
|
|
|
|
|
|
|
}
|
95
|
|
|
|
|
|
|
}
|
96
|
|
|
|
|
|
|
}
|
97
|
|
|
|
|
|
|
}
|
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
sub EndTag {
|
100
|
|
|
|
|
|
|
my $expat = shift;
|
101
|
|
|
|
|
|
|
return $expat->finish() if $expat->{_done};
|
102
|
|
|
|
|
|
|
# warn "End: $_\n";
|
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
$expat->{_currenttree}->Pop();
|
105
|
|
|
|
|
|
|
}
|
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
sub Text {
|
108
|
|
|
|
|
|
|
my $expat = shift;
|
109
|
|
|
|
|
|
|
my $text = $_;
|
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
return $expat->finish() if $expat->{_done};
|
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
my @Requests = @{$expat->{_requests}};
|
114
|
|
|
|
|
|
|
my $current = $expat->{_currenttree};
|
115
|
|
|
|
|
|
|
my $removed = 0;
|
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
foreach (0..$#Requests) {
|
118
|
|
|
|
|
|
|
# print "(",$expat->current_element, ")Searching for: ",
|
119
|
|
|
|
|
|
|
# $Requests[$_]->Path, ($Requests[$_]->isRepeat ? "*" : ''), "\n";
|
120
|
|
|
|
|
|
|
if (!$Requests[$_]->Attrib) {
|
121
|
|
|
|
|
|
|
# Not looking for an attrib
|
122
|
|
|
|
|
|
|
# warn "Comparing : ", $Requests[$_]->Path, " : ", $expat->{_currenttree}->Path, "\n";
|
123
|
|
|
|
|
|
|
if ($Requests[$_]->isEqual($current)) {
|
124
|
|
|
|
|
|
|
# print "Found\n";
|
125
|
|
|
|
|
|
|
found($expat, $Requests[$_], $text);
|
126
|
|
|
|
|
|
|
splice(@{$expat->{_requests}}, $_ - $removed, 1) unless $Requests[$_]->isRepeat;
|
127
|
|
|
|
|
|
|
$expat->{_done} = 1 if (@Requests == 0);
|
128
|
|
|
|
|
|
|
$removed++;
|
129
|
|
|
|
|
|
|
# return;
|
130
|
|
|
|
|
|
|
}
|
131
|
|
|
|
|
|
|
}
|
132
|
|
|
|
|
|
|
}
|
133
|
|
|
|
|
|
|
}
|
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
sub found {
|
136
|
|
|
|
|
|
|
my $expat = shift;
|
137
|
|
|
|
|
|
|
my ($request, $found) = @_;
|
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
# warn "Found: ", $request->Path, " : $found\n";
|
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
if ($request->Path =~ /\.\*/) {
|
142
|
|
|
|
|
|
|
# Request path contains a regexp
|
143
|
|
|
|
|
|
|
my $match = $request->Path;
|
144
|
|
|
|
|
|
|
$match =~ s/\[(.*?)\]/\\\[$1\\\]/g;
|
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
# warn "Regexp: ", $expat->{_currenttree}->Path, " =~ |$match|\n";
|
147
|
|
|
|
|
|
|
$expat->{_currenttree}->Path =~ /$match/;
|
148
|
|
|
|
|
|
|
if ($expat->{_style} eq 'List') {
|
149
|
|
|
|
|
|
|
push @{$expat->{_parseresults}}, $&, $found;
|
150
|
|
|
|
|
|
|
}
|
151
|
|
|
|
|
|
|
elsif ($expat->{_style} eq 'Hash') {
|
152
|
|
|
|
|
|
|
push @{$expat->{_parseresults}->{$&}}, $found;
|
153
|
|
|
|
|
|
|
}
|
154
|
|
|
|
|
|
|
}
|
155
|
|
|
|
|
|
|
else {
|
156
|
|
|
|
|
|
|
if ($expat->{_style} eq 'List') {
|
157
|
|
|
|
|
|
|
push @{$expat->{_parseresults}}, $request->Path, $found;
|
158
|
|
|
|
|
|
|
}
|
159
|
|
|
|
|
|
|
elsif ($expat->{_style} eq 'Hash') {
|
160
|
|
|
|
|
|
|
push @{$expat->{_parseresults}->{$request->Path}}, $found;
|
161
|
|
|
|
|
|
|
}
|
162
|
|
|
|
|
|
|
}
|
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
}
|
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sub EndDocument {
|
167
|
|
|
|
|
|
|
my $expat = shift;
|
168
|
|
|
|
|
|
|
delete $expat->{_done};
|
169
|
|
|
|
|
|
|
delete $expat->{_currenttree};
|
170
|
|
|
|
|
|
|
delete $expat->{_requests};
|
171
|
|
|
|
|
|
|
return $expat->{_parseresults};
|
172
|
|
|
|
|
|
|
}
|
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
1;
|
175
|
|
|
|
|
|
|
__END__
|