| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package XML::Essex; |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
$VERSION = 0.000_1; |
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 NAME |
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
XML::Essex - Essex XML processing primitives |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
TODO |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head2 Result Value |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
The return value will be returned to the caller. For handlers, this is |
|
18
|
|
|
|
|
|
|
usually a "1" for success or some other value, such as a data |
|
19
|
|
|
|
|
|
|
structure that has been built or the result of a query. |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
For generators and filters, it is important that the result of the next |
|
22
|
|
|
|
|
|
|
filter's end_document() is returned at the end of your Essex script, so |
|
23
|
|
|
|
|
|
|
that it may be used upstream of such modules as XML::Simple. |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
Errors should be reported using die(). |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=cut |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
#=head2 A short word on abbreviations |
|
30
|
|
|
|
|
|
|
# |
|
31
|
|
|
|
|
|
|
#A goal of essex is to allow code to be as terse or verbose as |
|
32
|
|
|
|
|
|
|
#appropriate for the job at hand. So almost every object may be |
|
33
|
|
|
|
|
|
|
#abbreviated. For instance, C may be abbreviated as |
|
34
|
|
|
|
|
|
|
#C when using L|/isa> to check o. |
|
35
|
|
|
|
|
|
|
# |
|
36
|
|
|
|
|
|
|
#Most of the examples use the abbreviated form, though you can spell |
|
37
|
|
|
|
|
|
|
#them out longhand if you like. Here's a list of abbreviations: |
|
38
|
|
|
|
|
|
|
# |
|
39
|
|
|
|
|
|
|
# document doc |
|
40
|
|
|
|
|
|
|
# element elt |
|
41
|
|
|
|
|
|
|
# characters chars |
|
42
|
|
|
|
|
|
|
# processing instruction pi |
|
43
|
|
|
|
|
|
|
# namespace ns |
|
44
|
|
|
|
|
|
|
# attribute attr |
|
45
|
|
|
|
|
|
|
# |
|
46
|
|
|
|
|
|
|
#Class names, functions, and parameters to the Essex C |
|
47
|
|
|
|
|
|
|
#function/method are all encouraged to use these abbreviations. |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=head2 Result Values |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
=for Document maintainers: if you edit this section, copy and paste it |
|
52
|
|
|
|
|
|
|
over the first section of lib/XML/Essex/ResultValues.pod. Thanks. |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
Essex is designed to Do The Right Thing for the vast majority of |
|
55
|
|
|
|
|
|
|
uses, so it manages result values automatically unless you take |
|
56
|
|
|
|
|
|
|
control. Below is a set of detailed rules for how it manages |
|
57
|
|
|
|
|
|
|
the result value for a filter's processing run, but the overview is: |
|
58
|
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=over |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=item * |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
Filters normally do not need to manage a result. The result from the |
|
64
|
|
|
|
|
|
|
next filter downstream will be returned automatically, or an exception |
|
65
|
|
|
|
|
|
|
will be thrown if an incomplete document is sent downstream. |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=item * |
|
68
|
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
Generators act like filters mostly, except that if a generator decides |
|
70
|
|
|
|
|
|
|
not to send any results downstream, it should either set a result value |
|
71
|
|
|
|
|
|
|
by calling C with it, or C that result normally, just |
|
72
|
|
|
|
|
|
|
like a handler. |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=item * |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
Handlers should either set a result value |
|
77
|
|
|
|
|
|
|
by calling C with it, or C that result normally. |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=item * |
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
Generators, filters and handlers should all die() on unexpected |
|
82
|
|
|
|
|
|
|
conditions and most error conditions (a FALSE or undefined result is not |
|
83
|
|
|
|
|
|
|
necessarily an error condition for a handler). |
|
84
|
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
Generators and filters generally should not return a value of their own |
|
86
|
|
|
|
|
|
|
because this will surprise calling code which is expecting a return |
|
87
|
|
|
|
|
|
|
value of the type that the final SAX handler returns. |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
=for Document maintainers: if you edit this section, copy and paste it |
|
90
|
|
|
|
|
|
|
over the first section of lib/XML/Essex/ResultValues.pod. Thanks. |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=cut |
|
93
|
|
|
|
|
|
|
|
|
94
|
2
|
|
|
2
|
|
5333
|
use Carp; |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
146
|
|
|
95
|
2
|
|
|
2
|
|
11
|
use Exporter; |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
70
|
|
|
96
|
2
|
|
|
2
|
|
2319
|
use Filter::Util::Call; |
|
|
2
|
|
|
|
|
2425
|
|
|
|
2
|
|
|
|
|
149
|
|
|
97
|
2
|
|
|
2
|
|
2398
|
use UNIVERSAL; |
|
|
2
|
|
|
|
|
26
|
|
|
|
2
|
|
|
|
|
10
|
|
|
98
|
|
|
|
|
|
|
|
|
99
|
2
|
|
|
2
|
|
53
|
use strict; |
|
|
2
|
|
|
|
|
2
|
|
|
|
2
|
|
|
|
|
60
|
|
|
100
|
2
|
|
|
2
|
|
9
|
use vars qw( %EXPORT_TAGS @EXPORT ); ## Set by the controlling process |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
91
|
|
|
101
|
2
|
|
|
2
|
|
1236
|
use XML::Essex::Constants qw( EOD ); |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
13
|
|
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
sub EOL() { "XML::Essex: End of last document" } |
|
104
|
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
{ |
|
106
|
|
|
|
|
|
|
%EXPORT_TAGS = ( |
|
107
|
|
|
|
|
|
|
read => [qw( |
|
108
|
|
|
|
|
|
|
get |
|
109
|
|
|
|
|
|
|
read_from |
|
110
|
|
|
|
|
|
|
parse_doc |
|
111
|
|
|
|
|
|
|
isa |
|
112
|
|
|
|
|
|
|
next_event |
|
113
|
|
|
|
|
|
|
path |
|
114
|
|
|
|
|
|
|
type |
|
115
|
|
|
|
|
|
|
xeof |
|
116
|
|
|
|
|
|
|
)], |
|
117
|
|
|
|
|
|
|
rules => [qw( |
|
118
|
|
|
|
|
|
|
on |
|
119
|
|
|
|
|
|
|
xvalue |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
xpush |
|
122
|
|
|
|
|
|
|
xpop |
|
123
|
|
|
|
|
|
|
xset |
|
124
|
|
|
|
|
|
|
xadd |
|
125
|
|
|
|
|
|
|
)], |
|
126
|
|
|
|
|
|
|
write => [qw( |
|
127
|
|
|
|
|
|
|
put |
|
128
|
|
|
|
|
|
|
write_to |
|
129
|
|
|
|
|
|
|
push_output_filters |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
characters |
|
132
|
|
|
|
|
|
|
chars |
|
133
|
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
end_document |
|
135
|
|
|
|
|
|
|
end_doc |
|
136
|
|
|
|
|
|
|
end_element |
|
137
|
|
|
|
|
|
|
end_elt |
|
138
|
|
|
|
|
|
|
start_document |
|
139
|
|
|
|
|
|
|
start_doc |
|
140
|
|
|
|
|
|
|
start_element |
|
141
|
|
|
|
|
|
|
start_elt |
|
142
|
|
|
|
|
|
|
xml_decl |
|
143
|
|
|
|
|
|
|
)], |
|
144
|
|
|
|
|
|
|
); |
|
145
|
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
my %seen; |
|
147
|
|
|
|
|
|
|
$EXPORT_TAGS{filter} = [ |
|
148
|
|
|
|
|
|
|
grep !$seen{$_}++, |
|
149
|
|
|
|
|
|
|
map @$_, |
|
150
|
|
|
|
|
|
|
@EXPORT_TAGS{qw( read write )} |
|
151
|
|
|
|
|
|
|
]; |
|
152
|
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
%seen = (); |
|
154
|
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
@EXPORT = grep !$seen{$_}++, map @$_, values %EXPORT_TAGS; |
|
156
|
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
$EXPORT_TAGS{all} = \@EXPORT; |
|
158
|
|
|
|
|
|
|
} |
|
159
|
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
sub import { |
|
162
|
2
|
|
|
2
|
|
10
|
my ( undef, @args ) = @_; |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
## Figure out whether to read, write, or do both. |
|
165
|
2
|
|
|
|
|
3
|
my %exports; |
|
166
|
2
|
0
|
|
|
|
39
|
$exports{$_} = 1 for |
|
|
0
|
0
|
|
|
|
0
|
|
|
|
|
50
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
@args |
|
168
|
|
|
|
|
|
|
? map s/^:// |
|
169
|
|
|
|
|
|
|
? exists $EXPORT_TAGS{$_} |
|
170
|
|
|
|
|
|
|
? @{$EXPORT_TAGS{$_}} |
|
171
|
|
|
|
|
|
|
: croak "Unkown export tag ':$_' for ", __PACKAGE__ |
|
172
|
|
|
|
|
|
|
: $_, @args |
|
173
|
|
|
|
|
|
|
: @EXPORT; |
|
174
|
|
|
|
|
|
|
|
|
175
|
2
|
|
33
|
|
|
14
|
my $is_reader = exists $exports{get} || exists $exports{on} || exists $exports{parse_doc}; |
|
176
|
2
|
|
|
|
|
5
|
my $is_writer = exists $exports{put}; |
|
177
|
|
|
|
|
|
|
|
|
178
|
2
|
50
|
33
|
|
|
8
|
croak "XML::Essex not used as a reader (with :read, get(), :rules or on()) or a writer (with :write put())\n" |
|
179
|
|
|
|
|
|
|
unless $is_reader || $is_writer; |
|
180
|
|
|
|
|
|
|
|
|
181
|
2
|
50
|
|
|
|
8
|
my $sax_processor_type = |
|
|
|
50
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
! $is_reader ? "XML::Generator::Essex" : |
|
183
|
|
|
|
|
|
|
! $is_writer ? "XML::Handler::Essex" : |
|
184
|
|
|
|
|
|
|
"XML::Filter::Essex"; |
|
185
|
|
|
|
|
|
|
|
|
186
|
2
|
|
|
|
|
2
|
my $state = 0; # 0=init; 1=code; 2=pod; 3=EOF |
|
187
|
|
|
|
|
|
|
filter_add( |
|
188
|
|
|
|
|
|
|
sub { |
|
189
|
83
|
100
|
|
83
|
|
173
|
if ( $state == 0 ) { |
|
190
|
2
|
|
|
|
|
6
|
$_ = join '', |
|
191
|
|
|
|
|
|
|
"XML::Essex::_init '", |
|
192
|
|
|
|
|
|
|
$sax_processor_type, |
|
193
|
|
|
|
|
|
|
"'; XML::Essex::_cleanup eval {"; |
|
194
|
2
|
|
|
|
|
3
|
++$state; |
|
195
|
2
|
|
|
|
|
10
|
return 1; |
|
196
|
|
|
|
|
|
|
} |
|
197
|
|
|
|
|
|
|
|
|
198
|
81
|
100
|
|
|
|
1788
|
return 0 if $state > 2; |
|
199
|
79
|
|
|
|
|
193
|
my $status = filter_read; |
|
200
|
|
|
|
|
|
|
|
|
201
|
79
|
50
|
66
|
|
|
317
|
if ( $status > 0 && substr( $_, 0, 1 ) eq "=" ) { |
|
202
|
0
|
0
|
|
|
|
0
|
if ( $state == 1 ) { $state = 2 } |
|
|
0
|
0
|
|
|
|
0
|
|
|
203
|
0
|
|
|
|
|
0
|
elsif ( substr( $_, 0, 4 ) eq "=cut" ) { $state = 1 } |
|
204
|
|
|
|
|
|
|
} |
|
205
|
|
|
|
|
|
|
|
|
206
|
79
|
100
|
|
|
|
863
|
return $status if $status != 0; |
|
207
|
|
|
|
|
|
|
|
|
208
|
2
|
50
|
|
|
|
8
|
$_ .= "\n\n=cut\n" if $state == 2; |
|
209
|
2
|
|
|
|
|
3
|
$_ .= "\n;1};"; |
|
210
|
|
|
|
|
|
|
|
|
211
|
2
|
|
|
|
|
5
|
$state = 3; |
|
212
|
|
|
|
|
|
|
|
|
213
|
2
|
|
|
|
|
8
|
return 1; |
|
214
|
|
|
|
|
|
|
}, |
|
215
|
2
|
|
|
|
|
15
|
); |
|
216
|
|
|
|
|
|
|
|
|
217
|
2
|
|
|
|
|
334
|
goto \&Exporter::import; |
|
218
|
|
|
|
|
|
|
} |
|
219
|
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
my @self_stack; |
|
221
|
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
sub _init_new { |
|
223
|
0
|
|
|
0
|
|
0
|
my ( $sax_processor_type ) = @_; |
|
224
|
|
|
|
|
|
|
|
|
225
|
0
|
|
|
|
|
0
|
push @self_stack, $XML::Essex::Base::self; |
|
226
|
0
|
|
|
|
|
0
|
my $self = $XML::Essex::Base::self = $sax_processor_type->new; |
|
227
|
0
|
|
|
|
|
0
|
$self->{NoExecute} = 1; |
|
228
|
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
## The first part of XML::Essex::Base::execute(); |
|
230
|
0
|
|
|
|
|
0
|
$self->reset; |
|
231
|
|
|
|
|
|
|
} |
|
232
|
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
sub _init { |
|
234
|
1
|
|
|
1
|
|
8
|
my ( $sax_processor_type ) = @_; |
|
235
|
1
|
50
|
|
|
|
87
|
eval "require $sax_processor_type" or croak $@; |
|
236
|
0
|
|
|
|
|
|
_init_new $sax_processor_type; |
|
237
|
|
|
|
|
|
|
}; |
|
238
|
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
sub _cleanup { |
|
241
|
0
|
|
|
0
|
|
|
my ( $ok ) = @_; |
|
242
|
0
|
|
|
|
|
|
my $self = $XML::Essex::Base::self; |
|
243
|
|
|
|
|
|
|
|
|
244
|
0
|
|
|
|
|
|
my $x = $@; |
|
245
|
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
## The last part of XML::Essex::Base::execute(); |
|
247
|
0
|
|
|
|
|
|
my ( $ok2, $result, $result_set ) = eval { |
|
248
|
0
|
|
|
|
|
|
( 1, $self->finish( $ok, $x ) ); |
|
249
|
|
|
|
|
|
|
}; |
|
250
|
0
|
|
|
|
|
|
$XML::Essex::Base::self = pop @self_stack; |
|
251
|
|
|
|
|
|
|
|
|
252
|
0
|
0
|
|
|
|
|
die $@ unless $ok2; |
|
253
|
0
|
0
|
|
|
|
|
return $result if $result_set; |
|
254
|
0
|
|
|
|
|
|
return 1; |
|
255
|
|
|
|
|
|
|
} |
|
256
|
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
sub _reinit { |
|
258
|
0
|
|
|
0
|
|
|
my $type = ref $XML::Essex::Base::self; |
|
259
|
0
|
|
|
|
|
|
_cleanup 1; |
|
260
|
0
|
|
|
|
|
|
_init_new $type; |
|
261
|
|
|
|
|
|
|
} |
|
262
|
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
=back |
|
264
|
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
=head1 Exported Functions |
|
266
|
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
These are exported by default, use the C |
|
268
|
|
|
|
|
|
|
avoid exporting any of these or export only the ones you want. |
|
269
|
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
The following export tags are also defined: |
|
271
|
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
:read get read_from parse_doc isa next_event path type xeof |
|
273
|
|
|
|
|
|
|
:rules on |
|
274
|
|
|
|
|
|
|
:write put write_to start_doc end_doc start_elt chars ... |
|
275
|
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
so you can |
|
277
|
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
use XML::Essex qw( :read :rules ); |
|
279
|
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
for an Essex script that just handles input and uses some rules, or |
|
281
|
|
|
|
|
|
|
even: |
|
282
|
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
use XML::Essex qw( parse_doc :rules ); |
|
284
|
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
for a purely rule-based script. |
|
286
|
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
Importing only what you need is a little quicker and more memory |
|
288
|
|
|
|
|
|
|
efficient, but it cal also allow XML::Essex to run more efficiently. If |
|
289
|
|
|
|
|
|
|
you don't import any output functions (see C<:write> above), it will not |
|
290
|
|
|
|
|
|
|
load the output routines. Same for the input and rule based APIs. |
|
291
|
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=over |
|
293
|
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
=item get |
|
295
|
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
my $e = get; |
|
297
|
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
Returns the next SAX event. Sets $_ as an EXPERIMENTAL feature. |
|
299
|
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
Throws an exception (which is silently caught outside the main code) |
|
301
|
|
|
|
|
|
|
on end of input. |
|
302
|
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
See C and C functions and method (in |
|
304
|
|
|
|
|
|
|
L) for how to test what was just gotten. |
|
305
|
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=cut |
|
307
|
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
sub get { |
|
309
|
0
|
|
|
0
|
1
|
|
my $self = $XML::Essex::Base::self; |
|
310
|
|
|
|
|
|
|
|
|
311
|
0
|
0
|
|
|
|
|
$self->_read_from_default unless $self->{Reader}; |
|
312
|
|
|
|
|
|
|
|
|
313
|
0
|
|
|
|
|
|
$XML::Essex::Base::self->get( @_ ); |
|
314
|
|
|
|
|
|
|
} |
|
315
|
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
=item read_from |
|
317
|
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
read_from \*STDIN; ## From a filehandle |
|
319
|
|
|
|
|
|
|
read_from "-"; ## From \*STDIN |
|
320
|
|
|
|
|
|
|
read_from "foo.xml"; ## From a file or URI (URI support is parser dependant) |
|
321
|
|
|
|
|
|
|
read_from \$xml_string; ## From a string. |
|
322
|
|
|
|
|
|
|
read_from undef; ## STDIN or files named in @ARGV, as appropriate |
|
323
|
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
Tells the next get() or parse_doc() to read from the indicated source. |
|
325
|
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
Calling read_from automatically disassembles the current processing chain |
|
327
|
|
|
|
|
|
|
and builds a new one (just like Perl's open() closes an already open |
|
328
|
|
|
|
|
|
|
filehandle). |
|
329
|
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
=cut |
|
331
|
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
sub XML::Essex::Base::_read_from_default { |
|
333
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
334
|
|
|
|
|
|
|
|
|
335
|
0
|
0
|
0
|
|
|
|
if ( @ARGV || $self->{FromARGV} ) { |
|
336
|
0
|
|
|
|
|
|
$self->{FromARGV} = 1; |
|
337
|
0
|
0
|
|
|
|
|
die EOL."\n" unless @ARGV; |
|
338
|
0
|
|
|
|
|
|
read_from( shift @ARGV ); |
|
339
|
|
|
|
|
|
|
} |
|
340
|
|
|
|
|
|
|
else { |
|
341
|
0
|
|
|
|
|
|
read_from( \*STDIN ); |
|
342
|
|
|
|
|
|
|
} |
|
343
|
|
|
|
|
|
|
} |
|
344
|
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
## TODO: move this in to XML::Handler::Essex as a set of standard |
|
346
|
|
|
|
|
|
|
## SAX parse_foo() APIs. |
|
347
|
|
|
|
|
|
|
sub read_from { |
|
348
|
|
|
|
|
|
|
## Shut down the old processing chain if it a Reader was already |
|
349
|
|
|
|
|
|
|
## created. |
|
350
|
|
|
|
|
|
|
## NOTE: This ASSumes that there is only one instance of the Essex |
|
351
|
|
|
|
|
|
|
## scripting env. in play at once. This is ok for now, but it does |
|
352
|
|
|
|
|
|
|
## contradict the idea of @self_stack. Perhaps having the source |
|
353
|
|
|
|
|
|
|
## filter set a secretly named global to point us to the right |
|
354
|
|
|
|
|
|
|
## $self would help. The goal is to enable handling of multiple |
|
355
|
|
|
|
|
|
|
## inputs at the same time: get from this, get from that. |
|
356
|
0
|
0
|
|
0
|
1
|
|
_reinit if $XML::Essex::Base::self->{Reader}; |
|
357
|
|
|
|
|
|
|
|
|
358
|
0
|
|
|
|
|
|
my $self = $XML::Essex::Base::self; |
|
359
|
0
|
|
|
|
|
|
my ( $what ) = @_; |
|
360
|
|
|
|
|
|
|
|
|
361
|
0
|
0
|
|
|
|
|
if ( ! defined $what ) { |
|
362
|
0
|
|
|
|
|
|
return delete $self->{Reader}; |
|
363
|
|
|
|
|
|
|
} |
|
364
|
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
$self->{Reader} = sub { |
|
366
|
0
|
|
|
0
|
|
|
require XML::SAX::PurePerl; ## ugh. need XML::LibXMl to support SAX2 |
|
367
|
0
|
|
|
|
|
|
my $p = XML::SAX::PurePerl->new( Handler => $self ); |
|
368
|
|
|
|
|
|
|
|
|
369
|
0
|
|
|
|
|
|
my $type = ref $what; |
|
370
|
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
## This is purely a non-threading implementation. |
|
372
|
|
|
|
|
|
|
## TODO: build the parser and save the reference to be parsed, then |
|
373
|
|
|
|
|
|
|
## use an appropriate driver for the parser that is called when |
|
374
|
|
|
|
|
|
|
## there are no more events in @{$self->{Events}}. |
|
375
|
0
|
0
|
0
|
|
|
|
if ( ! $type ) { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
376
|
0
|
0
|
|
|
|
|
$what eq "-" |
|
377
|
|
|
|
|
|
|
? $p->parse_file( \*STDIN ) |
|
378
|
|
|
|
|
|
|
: $p->parse_uri( $what ); |
|
379
|
|
|
|
|
|
|
} |
|
380
|
|
|
|
|
|
|
elsif ( $type eq "GLOB" || UNIVERSAL::isa( $what, "IO::Handle" ) ) { |
|
381
|
0
|
|
|
|
|
|
$p->parse_file( $what ); |
|
382
|
|
|
|
|
|
|
} |
|
383
|
|
|
|
|
|
|
elsif ( $type eq "SCALAR" ) { |
|
384
|
0
|
|
|
|
|
|
$p->parse_string( $$what ); |
|
385
|
|
|
|
|
|
|
} |
|
386
|
|
|
|
|
|
|
else { |
|
387
|
0
|
|
|
|
|
|
croak "Don't know how to read from a $type"; |
|
388
|
|
|
|
|
|
|
} |
|
389
|
0
|
|
|
|
|
|
}; |
|
390
|
|
|
|
|
|
|
} |
|
391
|
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
=item push_output_filters |
|
393
|
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
Adds an output filter to the end of the current list (and before the |
|
395
|
|
|
|
|
|
|
eventual writer). Can be a class name (which will be Ced |
|
396
|
|
|
|
|
|
|
unless the class can already new()) or a reference to a filter. |
|
397
|
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
=cut |
|
399
|
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
sub push_output_filters { |
|
401
|
0
|
|
|
0
|
1
|
|
my $self = $XML::Essex::Base::self; |
|
402
|
|
|
|
|
|
|
|
|
403
|
0
|
|
|
|
|
|
push @{$self->{OutputFilters}}, @_; |
|
|
0
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
} |
|
405
|
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
=item parse_doc |
|
407
|
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
Parses a single document from the current input. Morally equivalent to C
|
|
409
|
|
|
|
|
|
|
while 1;> but exits normally (as opposed to throwing an exception) when the |
|
410
|
|
|
|
|
|
|
end of document is reached. Also slightly faster now and hopefully moreso |
|
411
|
|
|
|
|
|
|
when optimizations can be made. |
|
412
|
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
Used to read to the end of a document, primarily in rule-based processing |
|
414
|
|
|
|
|
|
|
(L). |
|
415
|
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
TODO: Allow parse_doc to take rules. |
|
417
|
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
=cut |
|
419
|
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
sub parse_doc { |
|
421
|
0
|
|
|
0
|
1
|
|
my $self = $XML::Essex::Base::self; |
|
422
|
|
|
|
|
|
|
|
|
423
|
0
|
0
|
|
|
|
|
$self->_read_from_default unless $self->{Reader}; |
|
424
|
|
|
|
|
|
|
|
|
425
|
0
|
0
|
|
|
|
|
write_to( \*STDOUT ) unless $self->{Writer}; |
|
426
|
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
## The result is undocumented; what should be returned is the |
|
428
|
|
|
|
|
|
|
## normal XML::Filter::Dispatcher |
|
429
|
0
|
|
|
|
|
|
my $result; |
|
430
|
0
|
|
|
|
|
|
eval { |
|
431
|
0
|
|
|
|
|
|
$result = $self->get while 1; ## I did say I ;) |
|
432
|
|
|
|
|
|
|
}; |
|
433
|
|
|
|
|
|
|
|
|
434
|
0
|
0
|
|
|
|
|
die $@ unless $@ eq EOD . "\n"; |
|
435
|
|
|
|
|
|
|
|
|
436
|
0
|
|
|
|
|
|
return $result; |
|
437
|
|
|
|
|
|
|
} |
|
438
|
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
=item put |
|
440
|
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
Output one or more events. Usually these events are created by |
|
442
|
|
|
|
|
|
|
constructors like C (see |
|
443
|
|
|
|
|
|
|
L for details) or |
|
444
|
|
|
|
|
|
|
are objects returned C method. |
|
445
|
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
=cut |
|
447
|
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
sub put { |
|
449
|
0
|
|
|
0
|
1
|
|
my $self = $XML::Essex::Base::self; |
|
450
|
|
|
|
|
|
|
|
|
451
|
0
|
0
|
|
|
|
|
write_to( \*STDOUT ) unless $self->{Writer}; |
|
452
|
0
|
|
|
|
|
|
$self->put( @_ ); |
|
453
|
|
|
|
|
|
|
} |
|
454
|
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
=item write_to |
|
456
|
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
write_to \*STDOUT; ## To a filehandle |
|
458
|
|
|
|
|
|
|
write_to "-"; ## To \*STDOUT |
|
459
|
|
|
|
|
|
|
write_to "foo.xml"; ## To a file or URI (URI support is parser dependant) |
|
460
|
|
|
|
|
|
|
write_to \$xml_string; ## To a string. |
|
461
|
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
Tells the next put() to write the indicated source. |
|
463
|
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
=cut |
|
465
|
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
sub write_to { |
|
467
|
0
|
|
|
0
|
1
|
|
my $self = $XML::Essex::Base::self; |
|
468
|
0
|
|
|
|
|
|
my ( $what ) = @_; |
|
469
|
|
|
|
|
|
|
|
|
470
|
0
|
0
|
|
|
|
|
croak "Can't write to an undefined output" unless defined $what; |
|
471
|
|
|
|
|
|
|
|
|
472
|
0
|
|
|
|
|
|
require XML::SAX::Writer; |
|
473
|
|
|
|
|
|
|
$self->{Writer} = sub { |
|
474
|
0
|
|
|
0
|
|
|
my $h = XML::SAX::Writer->new( Output => $what ); |
|
475
|
0
|
0
|
|
|
|
|
for ( reverse @{$self->{OutputFilters} || [] } ) { |
|
|
0
|
|
|
|
|
|
|
|
476
|
0
|
0
|
|
|
|
|
unless ( ref $_ ) { |
|
477
|
0
|
0
|
0
|
|
|
|
eval "require $_" or die $@ unless $_->can( "new" ); |
|
478
|
0
|
|
|
|
|
|
$_ = $_->new( Handler => $h ); |
|
479
|
|
|
|
|
|
|
} |
|
480
|
|
|
|
|
|
|
else { |
|
481
|
0
|
|
|
|
|
|
$_->set_handler( $h ); |
|
482
|
|
|
|
|
|
|
} |
|
483
|
0
|
|
|
|
|
|
$h = $_; |
|
484
|
|
|
|
|
|
|
} |
|
485
|
0
|
|
|
|
|
|
return $h; |
|
486
|
0
|
|
|
|
|
|
}; |
|
487
|
|
|
|
|
|
|
} |
|
488
|
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
=back |
|
490
|
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
=head2 Miscellaneous |
|
492
|
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
=over |
|
494
|
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
=item isa |
|
496
|
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
get until isa "start_elt" and $_->name eq "foo"; |
|
498
|
|
|
|
|
|
|
$r = get until isa $r, "start_elt" and $_->name eq "foo"; |
|
499
|
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
Returns true if the parameter is of the indicated object type. Tests $_ |
|
501
|
|
|
|
|
|
|
unless more than one parameter is passed. |
|
502
|
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
=cut |
|
504
|
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
sub isa($) { |
|
506
|
0
|
0
|
|
0
|
1
|
|
local $_ = shift if @_ >= 2; |
|
507
|
0
|
0
|
|
|
|
|
UNIVERSAL::can( $_, "isa" ) |
|
508
|
|
|
|
|
|
|
? $_->isa( @_ ) |
|
509
|
|
|
|
|
|
|
: UNIVERSAL::isa( $_, @_ ); |
|
510
|
|
|
|
|
|
|
} |
|
511
|
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
=item next_event |
|
513
|
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
Like C (see L), but does not remove the next event |
|
515
|
|
|
|
|
|
|
from the input stream. |
|
516
|
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
get "start_document::*"; |
|
518
|
|
|
|
|
|
|
get if next_event->isa( "xml_decl" ); |
|
519
|
|
|
|
|
|
|
...process remainder of document... |
|
520
|
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
=cut |
|
522
|
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
sub next_event { |
|
524
|
0
|
|
|
0
|
1
|
|
my $self = $XML::Essex::Base::self; |
|
525
|
0
|
0
|
|
|
|
|
die "No XML input defined\n" unless $self->{Reader}; |
|
526
|
0
|
|
|
|
|
|
$self->{Reader}->peek; |
|
527
|
|
|
|
|
|
|
} |
|
528
|
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
=item path |
|
530
|
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
get "start_element::*" until path eq "/path/to/foo:bar" |
|
532
|
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
Returns the path to the current element as a string. |
|
534
|
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
=cut |
|
536
|
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
sub path { |
|
538
|
0
|
|
|
0
|
1
|
|
my $self = $XML::Essex::Base::self; |
|
539
|
0
|
|
|
|
|
|
return join "/", "", map $_->name, @{$self->{Stack}}; |
|
|
0
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
} |
|
541
|
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
=for import XML::Generator::Essex/put |
|
543
|
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
=item type |
|
545
|
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
get until type eq "start_document"; |
|
547
|
|
|
|
|
|
|
$r = get until type $r eq "start_document"; |
|
548
|
|
|
|
|
|
|
|
|
549
|
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
Return the type name of the object. This is the class name with a |
|
551
|
|
|
|
|
|
|
leading XML::Essex:: stripped off. This is a wrapper around the |
|
552
|
|
|
|
|
|
|
event's C method. |
|
553
|
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
=cut |
|
555
|
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
sub type { |
|
557
|
0
|
|
|
0
|
1
|
|
my $self = $XML::Essex::Base::self; |
|
558
|
0
|
|
|
|
|
|
$self->type( @_ ); |
|
559
|
|
|
|
|
|
|
} |
|
560
|
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
=item xeof |
|
562
|
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
Return TRUE if the last event has been read. |
|
564
|
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
=cut |
|
566
|
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
sub xeof { |
|
568
|
0
|
|
|
0
|
1
|
|
my $self = $XML::Essex::Base::self; |
|
569
|
0
|
0
|
|
|
|
|
die "No XML input defined\n" unless $self->{Reader}; |
|
570
|
0
|
|
|
|
|
|
$self->{Reader}->eof; |
|
571
|
|
|
|
|
|
|
} |
|
572
|
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
=back |
|
574
|
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
=head2 Namespaces |
|
576
|
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
If this section doesn't make any sense, see |
|
578
|
|
|
|
|
|
|
L |
|
579
|
|
|
|
|
|
|
for your next dose of XML koolaid. If it still doesn't make any sense |
|
580
|
|
|
|
|
|
|
then ding me for writing gibberish. |
|
581
|
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
Element names, attribute names, and PI targets returned by Essex are |
|
583
|
|
|
|
|
|
|
generated in one of three forms, depending on whether the named item |
|
584
|
|
|
|
|
|
|
has a namespace URI associated with it and whether the filter program |
|
585
|
|
|
|
|
|
|
has mapped that namespace URI to a prefix. You may also use any of |
|
586
|
|
|
|
|
|
|
these three forms when passing a name to Essex: |
|
587
|
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
=over |
|
589
|
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
=item "id" |
|
591
|
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
If an attribute has no NamespaceURI or an empty string for a |
|
593
|
|
|
|
|
|
|
NamespaceURI, it will be returned as a simple string. |
|
594
|
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
TODO: Add an option to enable this for the default namespace or |
|
596
|
|
|
|
|
|
|
for attrs in the element's namespace. |
|
597
|
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
=item "foo:id" |
|
599
|
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
If the attribute is in a namespace and there is a namespace -> prefix |
|
601
|
|
|
|
|
|
|
mapping has been declared by the filter |
|
602
|
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
=item "{http://foo/}id" |
|
604
|
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
If the attribute is in a namespace with no prefix mapped to it by |
|
606
|
|
|
|
|
|
|
the filter. |
|
607
|
|
|
|
|
|
|
|
|
608
|
|
|
|
|
|
|
=back |
|
609
|
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
Namespace prefixes from the source document are ignored; there's no |
|
611
|
|
|
|
|
|
|
telling what prefix somebody might have used. Intercept the |
|
612
|
|
|
|
|
|
|
start_prefix_mapping and end_prefix_mapping events to follow the weave |
|
613
|
|
|
|
|
|
|
of source document namespace mappings. |
|
614
|
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
When outputting events that belong to a namespace not in the source |
|
616
|
|
|
|
|
|
|
document, you need to C the start_prefix_mapping and |
|
617
|
|
|
|
|
|
|
end_prefix_mapping events manually, and be careful avoid existing |
|
618
|
|
|
|
|
|
|
prefixes from the document if need be while doing so. Future additions |
|
619
|
|
|
|
|
|
|
to Essex should make this easier and perhaps automatic. |
|
620
|
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
Essex lets you manage namespace mappings by mapping, hiding, and |
|
622
|
|
|
|
|
|
|
destroying ( $namespace => $prefix ) pairs using the functions: |
|
623
|
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
=over |
|
625
|
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
=cut |
|
627
|
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
=item namespace_map |
|
629
|
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
aka: ns_map |
|
631
|
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
my $map = ns_map( |
|
633
|
|
|
|
|
|
|
$ns1 => $prefix1, |
|
634
|
|
|
|
|
|
|
$ns2 => $prefix2, |
|
635
|
|
|
|
|
|
|
... |
|
636
|
|
|
|
|
|
|
); |
|
637
|
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
Creates a new set of mappings in addition to any that are already in |
|
639
|
|
|
|
|
|
|
effect. If a namespace is mapped to multiple prefixes, the last one |
|
640
|
|
|
|
|
|
|
created is used. The mappings stay in effect until the map objected |
|
641
|
|
|
|
|
|
|
referred to by C<$map> is destroyed. |
|
642
|
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
=cut |
|
644
|
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
sub ns_map { |
|
646
|
0
|
|
|
0
|
0
|
|
my $self = $XML::Essex::Base::self; |
|
647
|
0
|
|
|
|
|
|
return $self->new( @_ ); |
|
648
|
|
|
|
|
|
|
} |
|
649
|
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
=back |
|
652
|
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
=head2 Rule Based Processing |
|
654
|
|
|
|
|
|
|
|
|
655
|
|
|
|
|
|
|
It is often advantageous to declare exceptional events that should |
|
656
|
|
|
|
|
|
|
be processed as they occur in the stream rather than testing for them |
|
657
|
|
|
|
|
|
|
explicitly everywhere they might occur in the script. This is done |
|
658
|
|
|
|
|
|
|
using the "on" function. |
|
659
|
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
=cut |
|
661
|
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
=over |
|
663
|
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
=item on |
|
665
|
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
on( |
|
667
|
|
|
|
|
|
|
"start_document::*" => sub { warn "start of document reached" }, |
|
668
|
|
|
|
|
|
|
"end_document::*" => sub { warn "end of document reached" }, |
|
669
|
|
|
|
|
|
|
); |
|
670
|
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
=for TODO |
|
672
|
|
|
|
|
|
|
my $rule = on $pat1 => sub { ... }, ...; |
|
673
|
|
|
|
|
|
|
...time passes with rules in effect... |
|
674
|
|
|
|
|
|
|
disable_rule $rule; |
|
675
|
|
|
|
|
|
|
...time passes with rules I in effect... |
|
676
|
|
|
|
|
|
|
enable_rule $rule; |
|
677
|
|
|
|
|
|
|
...time passes with rules in effect again... |
|
678
|
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
This declares that a rule should be in effect until the end of the |
|
680
|
|
|
|
|
|
|
document |
|
681
|
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
=for TODO or it is disabled. |
|
683
|
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
=for TODO Returns a handle that may be used to enable or disable all |
|
685
|
|
|
|
|
|
|
rules passed in. |
|
686
|
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
For now, this must be called before the first get() for predictable |
|
688
|
|
|
|
|
|
|
results. |
|
689
|
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
Rules remain in effect after the main() routine has exited to facilitate |
|
691
|
|
|
|
|
|
|
pure rule based processing. |
|
692
|
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
=cut |
|
694
|
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
sub on { |
|
696
|
0
|
|
|
0
|
1
|
|
my $self = $XML::Essex::Base::self; |
|
697
|
0
|
|
|
|
|
|
$self->on( @_ ); |
|
698
|
|
|
|
|
|
|
} |
|
699
|
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
=item xvalue |
|
701
|
|
|
|
|
|
|
|
|
702
|
|
|
|
|
|
|
Returns the result of the expression that fired an action. Valid only |
|
703
|
|
|
|
|
|
|
within rules. |
|
704
|
|
|
|
|
|
|
|
|
705
|
|
|
|
|
|
|
=cut |
|
706
|
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
sub xvalue { |
|
708
|
0
|
|
|
0
|
1
|
|
my $self = $XML::Essex::Base::self; |
|
709
|
0
|
|
|
|
|
|
$self->xvalue; |
|
710
|
|
|
|
|
|
|
} |
|
711
|
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
=item xpush |
|
713
|
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
Returns the result of the expression that fired an action. Valid only |
|
715
|
|
|
|
|
|
|
within rules. |
|
716
|
|
|
|
|
|
|
|
|
717
|
|
|
|
|
|
|
=item xpop |
|
718
|
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
Returns the result of the expression that fired an action. Valid only |
|
720
|
|
|
|
|
|
|
within rules. |
|
721
|
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
=item xset |
|
723
|
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
Returns the result of the expression that fired an action. Valid only |
|
725
|
|
|
|
|
|
|
within rules. |
|
726
|
|
|
|
|
|
|
|
|
727
|
|
|
|
|
|
|
=item xadd |
|
728
|
|
|
|
|
|
|
|
|
729
|
|
|
|
|
|
|
Returns the result of the expression that fired an action. Valid only |
|
730
|
|
|
|
|
|
|
within rules. |
|
731
|
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
=cut |
|
733
|
|
|
|
|
|
|
|
|
734
|
0
|
|
|
0
|
1
|
|
sub xpush { XML::Filter::Dispatcher::xpush( @_ ) } |
|
735
|
0
|
|
|
0
|
1
|
|
sub xpop { XML::Filter::Dispatcher::xpop( @_ ) } |
|
736
|
0
|
|
|
0
|
1
|
|
sub xadd { XML::Filter::Dispatcher::xadd( @_ ) } |
|
737
|
0
|
|
|
0
|
1
|
|
sub xset { XML::Filter::Dispatcher::xset( @_ ) } |
|
738
|
|
|
|
|
|
|
|
|
739
|
|
|
|
|
|
|
=back |
|
740
|
|
|
|
|
|
|
|
|
741
|
|
|
|
|
|
|
=head2 Event Constructors |
|
742
|
|
|
|
|
|
|
|
|
743
|
|
|
|
|
|
|
These are exported by :write (in addition to being available individually). |
|
744
|
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
=over |
|
746
|
|
|
|
|
|
|
|
|
747
|
|
|
|
|
|
|
=cut |
|
748
|
|
|
|
|
|
|
|
|
749
|
2
|
|
|
2
|
|
15
|
no warnings "once"; |
|
|
2
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
714
|
|
|
750
|
|
|
|
|
|
|
|
|
751
|
|
|
|
|
|
|
=item chars |
|
752
|
|
|
|
|
|
|
|
|
753
|
|
|
|
|
|
|
aka: characters |
|
754
|
|
|
|
|
|
|
|
|
755
|
|
|
|
|
|
|
=cut |
|
756
|
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
sub characters { |
|
758
|
0
|
|
|
0
|
0
|
|
XML::Essex::Event::characters->new( @_ ); |
|
759
|
|
|
|
|
|
|
} |
|
760
|
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
*chars = \&characters; |
|
762
|
|
|
|
|
|
|
|
|
763
|
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
=item end_doc |
|
765
|
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
aka: end_document |
|
767
|
|
|
|
|
|
|
|
|
768
|
|
|
|
|
|
|
=cut |
|
769
|
|
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
sub end_document { |
|
771
|
0
|
|
|
0
|
0
|
|
XML::Essex::Event::end_doc->new( @_ ); |
|
772
|
|
|
|
|
|
|
} |
|
773
|
|
|
|
|
|
|
|
|
774
|
|
|
|
|
|
|
*end_doc = \&end_document; |
|
775
|
|
|
|
|
|
|
|
|
776
|
|
|
|
|
|
|
=item end_elt |
|
777
|
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
aka: end_element |
|
779
|
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
=cut |
|
781
|
|
|
|
|
|
|
|
|
782
|
|
|
|
|
|
|
sub end_element { |
|
783
|
0
|
|
|
0
|
0
|
|
XML::Essex::Event::end_element->new( @_ ); |
|
784
|
|
|
|
|
|
|
} |
|
785
|
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
*end_elt = \&end_element; |
|
787
|
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
|
|
789
|
|
|
|
|
|
|
=item start_doc |
|
790
|
|
|
|
|
|
|
|
|
791
|
|
|
|
|
|
|
aka: start_document |
|
792
|
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
=cut |
|
794
|
|
|
|
|
|
|
|
|
795
|
|
|
|
|
|
|
sub start_document { |
|
796
|
0
|
|
|
0
|
0
|
|
XML::Essex::Event::start_document->new( @_ ); |
|
797
|
|
|
|
|
|
|
} |
|
798
|
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
*start_doc = \&start_document; |
|
801
|
|
|
|
|
|
|
|
|
802
|
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
=item start_elt |
|
804
|
|
|
|
|
|
|
|
|
805
|
|
|
|
|
|
|
aka: start_element |
|
806
|
|
|
|
|
|
|
|
|
807
|
|
|
|
|
|
|
=cut |
|
808
|
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
sub start_element { |
|
810
|
0
|
|
|
0
|
0
|
|
XML::Essex::Event::start_element->new( @_ ); |
|
811
|
|
|
|
|
|
|
} |
|
812
|
|
|
|
|
|
|
|
|
813
|
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
*start_elt = \&start_element; |
|
815
|
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
=item xml_decl |
|
817
|
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
=cut |
|
819
|
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
sub xml_decl { |
|
821
|
0
|
|
|
0
|
1
|
|
XML::Essex::Event::xml_decl->new( @_ ); |
|
822
|
|
|
|
|
|
|
} |
|
823
|
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
|
|
825
|
|
|
|
|
|
|
=back |
|
826
|
|
|
|
|
|
|
|
|
827
|
|
|
|
|
|
|
=head1 IMPLEMENTATION NOTES |
|
828
|
|
|
|
|
|
|
|
|
829
|
|
|
|
|
|
|
XML::Essex is a source filter that wraps from the C |
|
830
|
|
|
|
|
|
|
end of the file in an eval { ... } block. |
|
831
|
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
=head1 LIMITATIONS |
|
833
|
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
Stay tuned. |
|
835
|
|
|
|
|
|
|
|
|
836
|
|
|
|
|
|
|
=head1 COPYRIGHT |
|
837
|
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
Copyright 2002, R. Barrie Slaymaker, Jr., All Rights Reserved |
|
839
|
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
=head1 LICENSE |
|
841
|
|
|
|
|
|
|
|
|
842
|
|
|
|
|
|
|
You may use this module under the terms of the BSD, Artistic, oir GPL licenses, |
|
843
|
|
|
|
|
|
|
any version. |
|
844
|
|
|
|
|
|
|
|
|
845
|
|
|
|
|
|
|
=head1 AUTHOR |
|
846
|
|
|
|
|
|
|
|
|
847
|
|
|
|
|
|
|
Barrie Slaymaker |
|
848
|
|
|
|
|
|
|
|
|
849
|
|
|
|
|
|
|
=cut |
|
850
|
|
|
|
|
|
|
|
|
851
|
|
|
|
|
|
|
1; |