rexml 3.1.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rexml might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +10 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +60 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/rexml/attlistdecl.rb +63 -0
- data/lib/rexml/attribute.rb +192 -0
- data/lib/rexml/cdata.rb +68 -0
- data/lib/rexml/child.rb +97 -0
- data/lib/rexml/comment.rb +80 -0
- data/lib/rexml/doctype.rb +270 -0
- data/lib/rexml/document.rb +291 -0
- data/lib/rexml/dtd/attlistdecl.rb +11 -0
- data/lib/rexml/dtd/dtd.rb +47 -0
- data/lib/rexml/dtd/elementdecl.rb +18 -0
- data/lib/rexml/dtd/entitydecl.rb +57 -0
- data/lib/rexml/dtd/notationdecl.rb +40 -0
- data/lib/rexml/element.rb +1267 -0
- data/lib/rexml/encoding.rb +51 -0
- data/lib/rexml/entity.rb +171 -0
- data/lib/rexml/formatters/default.rb +112 -0
- data/lib/rexml/formatters/pretty.rb +142 -0
- data/lib/rexml/formatters/transitive.rb +58 -0
- data/lib/rexml/functions.rb +447 -0
- data/lib/rexml/instruction.rb +71 -0
- data/lib/rexml/light/node.rb +196 -0
- data/lib/rexml/namespace.rb +48 -0
- data/lib/rexml/node.rb +76 -0
- data/lib/rexml/output.rb +30 -0
- data/lib/rexml/parent.rb +166 -0
- data/lib/rexml/parseexception.rb +52 -0
- data/lib/rexml/parsers/baseparser.rb +586 -0
- data/lib/rexml/parsers/lightparser.rb +59 -0
- data/lib/rexml/parsers/pullparser.rb +197 -0
- data/lib/rexml/parsers/sax2parser.rb +273 -0
- data/lib/rexml/parsers/streamparser.rb +61 -0
- data/lib/rexml/parsers/treeparser.rb +101 -0
- data/lib/rexml/parsers/ultralightparser.rb +57 -0
- data/lib/rexml/parsers/xpathparser.rb +675 -0
- data/lib/rexml/quickpath.rb +266 -0
- data/lib/rexml/rexml.rb +32 -0
- data/lib/rexml/sax2listener.rb +98 -0
- data/lib/rexml/security.rb +28 -0
- data/lib/rexml/source.rb +298 -0
- data/lib/rexml/streamlistener.rb +93 -0
- data/lib/rexml/syncenumerator.rb +33 -0
- data/lib/rexml/text.rb +424 -0
- data/lib/rexml/undefinednamespaceexception.rb +9 -0
- data/lib/rexml/validation/relaxng.rb +539 -0
- data/lib/rexml/validation/validation.rb +144 -0
- data/lib/rexml/validation/validationexception.rb +10 -0
- data/lib/rexml/xmldecl.rb +116 -0
- data/lib/rexml/xmltokens.rb +85 -0
- data/lib/rexml/xpath.rb +81 -0
- data/lib/rexml/xpath_parser.rb +934 -0
- data/rexml.gemspec +42 -0
- metadata +131 -0
@@ -0,0 +1,539 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
require_relative "validation"
|
3
|
+
require_relative "../parsers/baseparser"
|
4
|
+
|
5
|
+
module REXML
|
6
|
+
module Validation
|
7
|
+
# Implemented:
|
8
|
+
# * empty
|
9
|
+
# * element
|
10
|
+
# * attribute
|
11
|
+
# * text
|
12
|
+
# * optional
|
13
|
+
# * choice
|
14
|
+
# * oneOrMore
|
15
|
+
# * zeroOrMore
|
16
|
+
# * group
|
17
|
+
# * value
|
18
|
+
# * interleave
|
19
|
+
# * mixed
|
20
|
+
# * ref
|
21
|
+
# * grammar
|
22
|
+
# * start
|
23
|
+
# * define
|
24
|
+
#
|
25
|
+
# Not implemented:
|
26
|
+
# * data
|
27
|
+
# * param
|
28
|
+
# * include
|
29
|
+
# * externalRef
|
30
|
+
# * notAllowed
|
31
|
+
# * anyName
|
32
|
+
# * nsName
|
33
|
+
# * except
|
34
|
+
# * name
|
35
|
+
class RelaxNG
|
36
|
+
include Validator
|
37
|
+
|
38
|
+
INFINITY = 1.0 / 0.0
|
39
|
+
EMPTY = Event.new( nil )
|
40
|
+
TEXT = [:start_element, "text"]
|
41
|
+
attr_accessor :current
|
42
|
+
attr_accessor :count
|
43
|
+
attr_reader :references
|
44
|
+
|
45
|
+
# FIXME: Namespaces
|
46
|
+
def initialize source
|
47
|
+
parser = REXML::Parsers::BaseParser.new( source )
|
48
|
+
|
49
|
+
@count = 0
|
50
|
+
@references = {}
|
51
|
+
@root = @current = Sequence.new(self)
|
52
|
+
@root.previous = true
|
53
|
+
states = [ @current ]
|
54
|
+
begin
|
55
|
+
event = parser.pull
|
56
|
+
case event[0]
|
57
|
+
when :start_element
|
58
|
+
case event[1]
|
59
|
+
when "empty"
|
60
|
+
when "element", "attribute", "text", "value"
|
61
|
+
states[-1] << event
|
62
|
+
when "optional"
|
63
|
+
states << Optional.new( self )
|
64
|
+
states[-2] << states[-1]
|
65
|
+
when "choice"
|
66
|
+
states << Choice.new( self )
|
67
|
+
states[-2] << states[-1]
|
68
|
+
when "oneOrMore"
|
69
|
+
states << OneOrMore.new( self )
|
70
|
+
states[-2] << states[-1]
|
71
|
+
when "zeroOrMore"
|
72
|
+
states << ZeroOrMore.new( self )
|
73
|
+
states[-2] << states[-1]
|
74
|
+
when "group"
|
75
|
+
states << Sequence.new( self )
|
76
|
+
states[-2] << states[-1]
|
77
|
+
when "interleave"
|
78
|
+
states << Interleave.new( self )
|
79
|
+
states[-2] << states[-1]
|
80
|
+
when "mixed"
|
81
|
+
states << Interleave.new( self )
|
82
|
+
states[-2] << states[-1]
|
83
|
+
states[-1] << TEXT
|
84
|
+
when "define"
|
85
|
+
states << [ event[2]["name"] ]
|
86
|
+
when "ref"
|
87
|
+
states[-1] << Ref.new( event[2]["name"] )
|
88
|
+
when "anyName"
|
89
|
+
states << AnyName.new( self )
|
90
|
+
states[-2] << states[-1]
|
91
|
+
when "nsName"
|
92
|
+
when "except"
|
93
|
+
when "name"
|
94
|
+
when "data"
|
95
|
+
when "param"
|
96
|
+
when "include"
|
97
|
+
when "grammar"
|
98
|
+
when "start"
|
99
|
+
when "externalRef"
|
100
|
+
when "notAllowed"
|
101
|
+
end
|
102
|
+
when :end_element
|
103
|
+
case event[1]
|
104
|
+
when "element", "attribute"
|
105
|
+
states[-1] << event
|
106
|
+
when "zeroOrMore", "oneOrMore", "choice", "optional",
|
107
|
+
"interleave", "group", "mixed"
|
108
|
+
states.pop
|
109
|
+
when "define"
|
110
|
+
ref = states.pop
|
111
|
+
@references[ ref.shift ] = ref
|
112
|
+
#when "empty"
|
113
|
+
end
|
114
|
+
when :end_document
|
115
|
+
states[-1] << event
|
116
|
+
when :text
|
117
|
+
states[-1] << event
|
118
|
+
end
|
119
|
+
end while event[0] != :end_document
|
120
|
+
end
|
121
|
+
|
122
|
+
def receive event
|
123
|
+
validate( event )
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
class State
|
128
|
+
def initialize( context )
|
129
|
+
@previous = []
|
130
|
+
@events = []
|
131
|
+
@current = 0
|
132
|
+
@count = context.count += 1
|
133
|
+
@references = context.references
|
134
|
+
@value = false
|
135
|
+
end
|
136
|
+
|
137
|
+
def reset
|
138
|
+
return if @current == 0
|
139
|
+
@current = 0
|
140
|
+
@events.each {|s| s.reset if s.kind_of? State }
|
141
|
+
end
|
142
|
+
|
143
|
+
def previous=( previous )
|
144
|
+
@previous << previous
|
145
|
+
end
|
146
|
+
|
147
|
+
def next( event )
|
148
|
+
#print "In next with #{event.inspect}. "
|
149
|
+
#p @previous
|
150
|
+
return @previous.pop.next( event ) if @events[@current].nil?
|
151
|
+
expand_ref_in( @events, @current ) if @events[@current].class == Ref
|
152
|
+
if ( @events[@current].kind_of? State )
|
153
|
+
@current += 1
|
154
|
+
@events[@current-1].previous = self
|
155
|
+
return @events[@current-1].next( event )
|
156
|
+
end
|
157
|
+
if ( @events[@current].matches?(event) )
|
158
|
+
@current += 1
|
159
|
+
if @events[@current].nil?
|
160
|
+
return @previous.pop
|
161
|
+
elsif @events[@current].kind_of? State
|
162
|
+
@current += 1
|
163
|
+
@events[@current-1].previous = self
|
164
|
+
return @events[@current-1]
|
165
|
+
else
|
166
|
+
return self
|
167
|
+
end
|
168
|
+
else
|
169
|
+
return nil
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def to_s
|
174
|
+
# Abbreviated:
|
175
|
+
self.class.name =~ /(?:::)(\w)\w+$/
|
176
|
+
# Full:
|
177
|
+
#self.class.name =~ /(?:::)(\w+)$/
|
178
|
+
"#$1.#@count"
|
179
|
+
end
|
180
|
+
|
181
|
+
def inspect
|
182
|
+
"< #{to_s} #{@events.collect{|e|
|
183
|
+
pre = e == @events[@current] ? '#' : ''
|
184
|
+
pre + e.inspect unless self == e
|
185
|
+
}.join(', ')} >"
|
186
|
+
end
|
187
|
+
|
188
|
+
def expected
|
189
|
+
return [@events[@current]]
|
190
|
+
end
|
191
|
+
|
192
|
+
def <<( event )
|
193
|
+
add_event_to_arry( @events, event )
|
194
|
+
end
|
195
|
+
|
196
|
+
|
197
|
+
protected
|
198
|
+
def expand_ref_in( arry, ind )
|
199
|
+
new_events = []
|
200
|
+
@references[ arry[ind].to_s ].each{ |evt|
|
201
|
+
add_event_to_arry(new_events,evt)
|
202
|
+
}
|
203
|
+
arry[ind,1] = new_events
|
204
|
+
end
|
205
|
+
|
206
|
+
def add_event_to_arry( arry, evt )
|
207
|
+
evt = generate_event( evt )
|
208
|
+
if evt.kind_of? String
|
209
|
+
arry[-1].event_arg = evt if arry[-1].kind_of? Event and @value
|
210
|
+
@value = false
|
211
|
+
else
|
212
|
+
arry << evt
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def generate_event( event )
|
217
|
+
return event if event.kind_of? State or event.class == Ref
|
218
|
+
evt = nil
|
219
|
+
arg = nil
|
220
|
+
case event[0]
|
221
|
+
when :start_element
|
222
|
+
case event[1]
|
223
|
+
when "element"
|
224
|
+
evt = :start_element
|
225
|
+
arg = event[2]["name"]
|
226
|
+
when "attribute"
|
227
|
+
evt = :start_attribute
|
228
|
+
arg = event[2]["name"]
|
229
|
+
when "text"
|
230
|
+
evt = :text
|
231
|
+
when "value"
|
232
|
+
evt = :text
|
233
|
+
@value = true
|
234
|
+
end
|
235
|
+
when :text
|
236
|
+
return event[1]
|
237
|
+
when :end_document
|
238
|
+
return Event.new( event[0] )
|
239
|
+
else # then :end_element
|
240
|
+
case event[1]
|
241
|
+
when "element"
|
242
|
+
evt = :end_element
|
243
|
+
when "attribute"
|
244
|
+
evt = :end_attribute
|
245
|
+
end
|
246
|
+
end
|
247
|
+
return Event.new( evt, arg )
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
|
252
|
+
class Sequence < State
|
253
|
+
def matches?(event)
|
254
|
+
@events[@current].matches?( event )
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
|
259
|
+
class Optional < State
|
260
|
+
def next( event )
|
261
|
+
if @current == 0
|
262
|
+
rv = super
|
263
|
+
return rv if rv
|
264
|
+
@prior = @previous.pop
|
265
|
+
return @prior.next( event )
|
266
|
+
end
|
267
|
+
super
|
268
|
+
end
|
269
|
+
|
270
|
+
def matches?(event)
|
271
|
+
@events[@current].matches?(event) ||
|
272
|
+
(@current == 0 and @previous[-1].matches?(event))
|
273
|
+
end
|
274
|
+
|
275
|
+
def expected
|
276
|
+
return [ @prior.expected, @events[0] ].flatten if @current == 0
|
277
|
+
return [@events[@current]]
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
|
282
|
+
class ZeroOrMore < Optional
|
283
|
+
def next( event )
|
284
|
+
expand_ref_in( @events, @current ) if @events[@current].class == Ref
|
285
|
+
if ( @events[@current].matches?(event) )
|
286
|
+
@current += 1
|
287
|
+
if @events[@current].nil?
|
288
|
+
@current = 0
|
289
|
+
return self
|
290
|
+
elsif @events[@current].kind_of? State
|
291
|
+
@current += 1
|
292
|
+
@events[@current-1].previous = self
|
293
|
+
return @events[@current-1]
|
294
|
+
else
|
295
|
+
return self
|
296
|
+
end
|
297
|
+
else
|
298
|
+
@prior = @previous.pop
|
299
|
+
return @prior.next( event ) if @current == 0
|
300
|
+
return nil
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
def expected
|
305
|
+
return [ @prior.expected, @events[0] ].flatten if @current == 0
|
306
|
+
return [@events[@current]]
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
|
311
|
+
class OneOrMore < State
|
312
|
+
def initialize context
|
313
|
+
super
|
314
|
+
@ord = 0
|
315
|
+
end
|
316
|
+
|
317
|
+
def reset
|
318
|
+
super
|
319
|
+
@ord = 0
|
320
|
+
end
|
321
|
+
|
322
|
+
def next( event )
|
323
|
+
expand_ref_in( @events, @current ) if @events[@current].class == Ref
|
324
|
+
if ( @events[@current].matches?(event) )
|
325
|
+
@current += 1
|
326
|
+
@ord += 1
|
327
|
+
if @events[@current].nil?
|
328
|
+
@current = 0
|
329
|
+
return self
|
330
|
+
elsif @events[@current].kind_of? State
|
331
|
+
@current += 1
|
332
|
+
@events[@current-1].previous = self
|
333
|
+
return @events[@current-1]
|
334
|
+
else
|
335
|
+
return self
|
336
|
+
end
|
337
|
+
else
|
338
|
+
return @previous.pop.next( event ) if @current == 0 and @ord > 0
|
339
|
+
return nil
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
def matches?( event )
|
344
|
+
@events[@current].matches?(event) ||
|
345
|
+
(@current == 0 and @ord > 0 and @previous[-1].matches?(event))
|
346
|
+
end
|
347
|
+
|
348
|
+
def expected
|
349
|
+
if @current == 0 and @ord > 0
|
350
|
+
return [@previous[-1].expected, @events[0]].flatten
|
351
|
+
else
|
352
|
+
return [@events[@current]]
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
|
358
|
+
class Choice < State
|
359
|
+
def initialize context
|
360
|
+
super
|
361
|
+
@choices = []
|
362
|
+
end
|
363
|
+
|
364
|
+
def reset
|
365
|
+
super
|
366
|
+
@events = []
|
367
|
+
@choices.each { |c| c.each { |s| s.reset if s.kind_of? State } }
|
368
|
+
end
|
369
|
+
|
370
|
+
def <<( event )
|
371
|
+
add_event_to_arry( @choices, event )
|
372
|
+
end
|
373
|
+
|
374
|
+
def next( event )
|
375
|
+
# Make the choice if we haven't
|
376
|
+
if @events.size == 0
|
377
|
+
c = 0 ; max = @choices.size
|
378
|
+
while c < max
|
379
|
+
if @choices[c][0].class == Ref
|
380
|
+
expand_ref_in( @choices[c], 0 )
|
381
|
+
@choices += @choices[c]
|
382
|
+
@choices.delete( @choices[c] )
|
383
|
+
max -= 1
|
384
|
+
else
|
385
|
+
c += 1
|
386
|
+
end
|
387
|
+
end
|
388
|
+
@events = @choices.find { |evt| evt[0].matches? event }
|
389
|
+
# Remove the references
|
390
|
+
# Find the events
|
391
|
+
end
|
392
|
+
unless @events
|
393
|
+
@events = []
|
394
|
+
return nil
|
395
|
+
end
|
396
|
+
super
|
397
|
+
end
|
398
|
+
|
399
|
+
def matches?( event )
|
400
|
+
return @events[@current].matches?( event ) if @events.size > 0
|
401
|
+
!@choices.find{|evt| evt[0].matches?(event)}.nil?
|
402
|
+
end
|
403
|
+
|
404
|
+
def expected
|
405
|
+
return [@events[@current]] if @events.size > 0
|
406
|
+
return @choices.collect do |x|
|
407
|
+
if x[0].kind_of? State
|
408
|
+
x[0].expected
|
409
|
+
else
|
410
|
+
x[0]
|
411
|
+
end
|
412
|
+
end.flatten
|
413
|
+
end
|
414
|
+
|
415
|
+
def inspect
|
416
|
+
"< #{to_s} #{@choices.collect{|e| e.collect{|f|f.to_s}.join(', ')}.join(' or ')} >"
|
417
|
+
end
|
418
|
+
|
419
|
+
protected
|
420
|
+
def add_event_to_arry( arry, evt )
|
421
|
+
if evt.kind_of? State or evt.class == Ref
|
422
|
+
arry << [evt]
|
423
|
+
elsif evt[0] == :text
|
424
|
+
if arry[-1] and
|
425
|
+
arry[-1][-1].kind_of?( Event ) and
|
426
|
+
arry[-1][-1].event_type == :text and @value
|
427
|
+
|
428
|
+
arry[-1][-1].event_arg = evt[1]
|
429
|
+
@value = false
|
430
|
+
end
|
431
|
+
else
|
432
|
+
arry << [] if evt[0] == :start_element
|
433
|
+
arry[-1] << generate_event( evt )
|
434
|
+
end
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
|
439
|
+
class Interleave < Choice
|
440
|
+
def initialize context
|
441
|
+
super
|
442
|
+
@choice = 0
|
443
|
+
end
|
444
|
+
|
445
|
+
def reset
|
446
|
+
@choice = 0
|
447
|
+
end
|
448
|
+
|
449
|
+
def next_current( event )
|
450
|
+
# Expand references
|
451
|
+
c = 0 ; max = @choices.size
|
452
|
+
while c < max
|
453
|
+
if @choices[c][0].class == Ref
|
454
|
+
expand_ref_in( @choices[c], 0 )
|
455
|
+
@choices += @choices[c]
|
456
|
+
@choices.delete( @choices[c] )
|
457
|
+
max -= 1
|
458
|
+
else
|
459
|
+
c += 1
|
460
|
+
end
|
461
|
+
end
|
462
|
+
@events = @choices[@choice..-1].find { |evt| evt[0].matches? event }
|
463
|
+
@current = 0
|
464
|
+
if @events
|
465
|
+
# reorder the choices
|
466
|
+
old = @choices[@choice]
|
467
|
+
idx = @choices.index( @events )
|
468
|
+
@choices[@choice] = @events
|
469
|
+
@choices[idx] = old
|
470
|
+
@choice += 1
|
471
|
+
end
|
472
|
+
|
473
|
+
@events = [] unless @events
|
474
|
+
end
|
475
|
+
|
476
|
+
|
477
|
+
def next( event )
|
478
|
+
# Find the next series
|
479
|
+
next_current(event) unless @events[@current]
|
480
|
+
return nil unless @events[@current]
|
481
|
+
|
482
|
+
expand_ref_in( @events, @current ) if @events[@current].class == Ref
|
483
|
+
if ( @events[@current].kind_of? State )
|
484
|
+
@current += 1
|
485
|
+
@events[@current-1].previous = self
|
486
|
+
return @events[@current-1].next( event )
|
487
|
+
end
|
488
|
+
return @previous.pop.next( event ) if @events[@current].nil?
|
489
|
+
if ( @events[@current].matches?(event) )
|
490
|
+
@current += 1
|
491
|
+
if @events[@current].nil?
|
492
|
+
return self unless @choices[@choice].nil?
|
493
|
+
return @previous.pop
|
494
|
+
elsif @events[@current].kind_of? State
|
495
|
+
@current += 1
|
496
|
+
@events[@current-1].previous = self
|
497
|
+
return @events[@current-1]
|
498
|
+
else
|
499
|
+
return self
|
500
|
+
end
|
501
|
+
else
|
502
|
+
return nil
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
def matches?( event )
|
507
|
+
return @events[@current].matches?( event ) if @events[@current]
|
508
|
+
!@choices[@choice..-1].find{|evt| evt[0].matches?(event)}.nil?
|
509
|
+
end
|
510
|
+
|
511
|
+
def expected
|
512
|
+
return [@events[@current]] if @events[@current]
|
513
|
+
return @choices[@choice..-1].collect do |x|
|
514
|
+
if x[0].kind_of? State
|
515
|
+
x[0].expected
|
516
|
+
else
|
517
|
+
x[0]
|
518
|
+
end
|
519
|
+
end.flatten
|
520
|
+
end
|
521
|
+
|
522
|
+
def inspect
|
523
|
+
"< #{to_s} #{@choices.collect{|e| e.collect{|f|f.to_s}.join(', ')}.join(' and ')} >"
|
524
|
+
end
|
525
|
+
end
|
526
|
+
|
527
|
+
class Ref
|
528
|
+
def initialize value
|
529
|
+
@value = value
|
530
|
+
end
|
531
|
+
def to_s
|
532
|
+
@value
|
533
|
+
end
|
534
|
+
def inspect
|
535
|
+
"{#{to_s}}"
|
536
|
+
end
|
537
|
+
end
|
538
|
+
end
|
539
|
+
end
|