rubysl-rexml 1.0.0 → 2.0.1
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.
- checksums.yaml +4 -4
- data/.travis.yml +3 -2
- data/lib/rexml/attlistdecl.rb +56 -56
- data/lib/rexml/attribute.rb +155 -149
- data/lib/rexml/cdata.rb +48 -48
- data/lib/rexml/child.rb +82 -82
- data/lib/rexml/comment.rb +59 -59
- data/lib/rexml/doctype.rb +22 -24
- data/lib/rexml/document.rb +185 -129
- data/lib/rexml/dtd/attlistdecl.rb +7 -7
- data/lib/rexml/dtd/dtd.rb +41 -41
- data/lib/rexml/dtd/elementdecl.rb +13 -13
- data/lib/rexml/dtd/entitydecl.rb +49 -49
- data/lib/rexml/dtd/notationdecl.rb +32 -32
- data/lib/rexml/element.rb +122 -107
- data/lib/rexml/encoding.rb +37 -58
- data/lib/rexml/entity.rb +144 -144
- data/lib/rexml/formatters/default.rb +6 -4
- data/lib/rexml/formatters/pretty.rb +11 -8
- data/lib/rexml/formatters/transitive.rb +4 -3
- data/lib/rexml/functions.rb +33 -21
- data/lib/rexml/instruction.rb +49 -49
- data/lib/rexml/light/node.rb +190 -191
- data/lib/rexml/namespace.rb +39 -39
- data/lib/rexml/node.rb +38 -38
- data/lib/rexml/output.rb +17 -12
- data/lib/rexml/parent.rb +26 -25
- data/lib/rexml/parseexception.rb +4 -4
- data/lib/rexml/parsers/baseparser.rb +90 -61
- data/lib/rexml/parsers/lightparser.rb +41 -43
- data/lib/rexml/parsers/pullparser.rb +1 -1
- data/lib/rexml/parsers/sax2parser.rb +233 -198
- data/lib/rexml/parsers/streamparser.rb +6 -2
- data/lib/rexml/parsers/treeparser.rb +9 -6
- data/lib/rexml/parsers/ultralightparser.rb +40 -40
- data/lib/rexml/parsers/xpathparser.rb +51 -52
- data/lib/rexml/quickpath.rb +247 -248
- data/lib/rexml/rexml.rb +9 -10
- data/lib/rexml/sax2listener.rb +92 -92
- data/lib/rexml/security.rb +27 -0
- data/lib/rexml/source.rb +95 -50
- data/lib/rexml/streamlistener.rb +90 -90
- data/lib/rexml/syncenumerator.rb +3 -4
- data/lib/rexml/text.rb +157 -76
- data/lib/rexml/validation/relaxng.rb +18 -18
- data/lib/rexml/validation/validation.rb +5 -5
- data/lib/rexml/xmldecl.rb +59 -63
- data/lib/rexml/xmltokens.rb +14 -14
- data/lib/rexml/xpath.rb +67 -53
- data/lib/rexml/xpath_parser.rb +49 -38
- data/lib/rubysl/rexml.rb +1 -0
- data/lib/rubysl/rexml/version.rb +1 -1
- data/rubysl-rexml.gemspec +3 -1
- metadata +19 -28
- data/lib/rexml/encodings/CP-1252.rb +0 -103
- data/lib/rexml/encodings/EUC-JP.rb +0 -35
- data/lib/rexml/encodings/ICONV.rb +0 -22
- data/lib/rexml/encodings/ISO-8859-1.rb +0 -7
- data/lib/rexml/encodings/ISO-8859-15.rb +0 -72
- data/lib/rexml/encodings/SHIFT-JIS.rb +0 -37
- data/lib/rexml/encodings/SHIFT_JIS.rb +0 -1
- data/lib/rexml/encodings/UNILE.rb +0 -34
- data/lib/rexml/encodings/US-ASCII.rb +0 -30
- data/lib/rexml/encodings/UTF-16.rb +0 -35
- data/lib/rexml/encodings/UTF-8.rb +0 -18
@@ -79,7 +79,7 @@ module REXML
|
|
79
79
|
when "mixed"
|
80
80
|
states << Interleave.new( self )
|
81
81
|
states[-2] << states[-1]
|
82
|
-
states[-1] << TEXT
|
82
|
+
states[-1] << TEXT
|
83
83
|
when "define"
|
84
84
|
states << [ event[2]["name"] ]
|
85
85
|
when "ref"
|
@@ -102,7 +102,7 @@ module REXML
|
|
102
102
|
case event[1]
|
103
103
|
when "element", "attribute"
|
104
104
|
states[-1] << event
|
105
|
-
when "zeroOrMore", "oneOrMore", "choice", "optional",
|
105
|
+
when "zeroOrMore", "oneOrMore", "choice", "optional",
|
106
106
|
"interleave", "group", "mixed"
|
107
107
|
states.pop
|
108
108
|
when "define"
|
@@ -139,7 +139,7 @@ module REXML
|
|
139
139
|
@events.each {|s| s.reset if s.kind_of? State }
|
140
140
|
end
|
141
141
|
|
142
|
-
def previous=( previous )
|
142
|
+
def previous=( previous )
|
143
143
|
@previous << previous
|
144
144
|
end
|
145
145
|
|
@@ -183,7 +183,7 @@ module REXML
|
|
183
183
|
end
|
184
184
|
|
185
185
|
def inspect
|
186
|
-
"< #{to_s} #{@events.collect{|e|
|
186
|
+
"< #{to_s} #{@events.collect{|e|
|
187
187
|
pre = e == @events[@current] ? '#' : ''
|
188
188
|
pre + e.inspect unless self == e
|
189
189
|
}.join(', ')} >"
|
@@ -201,15 +201,15 @@ module REXML
|
|
201
201
|
protected
|
202
202
|
def expand_ref_in( arry, ind )
|
203
203
|
new_events = []
|
204
|
-
@references[ arry[ind].to_s ].each{ |evt|
|
204
|
+
@references[ arry[ind].to_s ].each{ |evt|
|
205
205
|
add_event_to_arry(new_events,evt)
|
206
206
|
}
|
207
207
|
arry[ind,1] = new_events
|
208
208
|
end
|
209
209
|
|
210
|
-
def add_event_to_arry( arry, evt )
|
210
|
+
def add_event_to_arry( arry, evt )
|
211
211
|
evt = generate_event( evt )
|
212
|
-
if evt.kind_of? String
|
212
|
+
if evt.kind_of? String
|
213
213
|
arry[-1].event_arg = evt if arry[-1].kind_of? Event and @value
|
214
214
|
@value = false
|
215
215
|
else
|
@@ -272,7 +272,7 @@ module REXML
|
|
272
272
|
end
|
273
273
|
|
274
274
|
def matches?(event)
|
275
|
-
@events[@current].matches?(event) ||
|
275
|
+
@events[@current].matches?(event) ||
|
276
276
|
(@current == 0 and @previous[-1].matches?(event))
|
277
277
|
end
|
278
278
|
|
@@ -319,7 +319,7 @@ module REXML
|
|
319
319
|
end
|
320
320
|
|
321
321
|
def reset
|
322
|
-
super
|
322
|
+
super
|
323
323
|
@ord = 0
|
324
324
|
end
|
325
325
|
|
@@ -345,7 +345,7 @@ module REXML
|
|
345
345
|
end
|
346
346
|
|
347
347
|
def matches?( event )
|
348
|
-
@events[@current].matches?(event) ||
|
348
|
+
@events[@current].matches?(event) ||
|
349
349
|
(@current == 0 and @ord > 0 and @previous[-1].matches?(event))
|
350
350
|
end
|
351
351
|
|
@@ -412,7 +412,7 @@ module REXML
|
|
412
412
|
#puts "IN CHOICE EXPECTED"
|
413
413
|
#puts "EVENTS = #{@events.inspect}"
|
414
414
|
return [@events[@current]] if @events.size > 0
|
415
|
-
return @choices.collect do |x|
|
415
|
+
return @choices.collect do |x|
|
416
416
|
if x[0].kind_of? State
|
417
417
|
x[0].expected
|
418
418
|
else
|
@@ -426,17 +426,17 @@ module REXML
|
|
426
426
|
end
|
427
427
|
|
428
428
|
protected
|
429
|
-
def add_event_to_arry( arry, evt )
|
429
|
+
def add_event_to_arry( arry, evt )
|
430
430
|
if evt.kind_of? State or evt.class == Ref
|
431
431
|
arry << [evt]
|
432
|
-
elsif evt[0] == :text
|
432
|
+
elsif evt[0] == :text
|
433
433
|
if arry[-1] and
|
434
|
-
arry[-1][-1].kind_of?( Event ) and
|
434
|
+
arry[-1][-1].kind_of?( Event ) and
|
435
435
|
arry[-1][-1].event_type == :text and @value
|
436
436
|
|
437
437
|
arry[-1][-1].event_arg = evt[1]
|
438
438
|
@value = false
|
439
|
-
|
439
|
+
end
|
440
440
|
else
|
441
441
|
arry << [] if evt[0] == :start_element
|
442
442
|
arry[-1] << generate_event( evt )
|
@@ -478,7 +478,7 @@ module REXML
|
|
478
478
|
@choices[idx] = old
|
479
479
|
@choice += 1
|
480
480
|
end
|
481
|
-
|
481
|
+
|
482
482
|
#puts "In next with #{event.inspect}."
|
483
483
|
#puts "events is #{@events.inspect}"
|
484
484
|
@events = [] unless @events
|
@@ -490,7 +490,7 @@ module REXML
|
|
490
490
|
next_current(event) unless @events[@current]
|
491
491
|
return nil unless @events[@current]
|
492
492
|
|
493
|
-
expand_ref_in( @events, @current ) if @events[@current].class == Ref
|
493
|
+
expand_ref_in( @events, @current ) if @events[@current].class == Ref
|
494
494
|
#puts "In next with #{event.inspect}."
|
495
495
|
#puts "Next (#@current) is #{@events[@current]}"
|
496
496
|
if ( @events[@current].kind_of? State )
|
@@ -530,7 +530,7 @@ module REXML
|
|
530
530
|
#puts "IN CHOICE EXPECTED"
|
531
531
|
#puts "EVENTS = #{@events.inspect}"
|
532
532
|
return [@events[@current]] if @events[@current]
|
533
|
-
return @choices[@choice..-1].collect do |x|
|
533
|
+
return @choices[@choice..-1].collect do |x|
|
534
534
|
if x[0].kind_of? State
|
535
535
|
x[0].expected
|
536
536
|
else
|
@@ -14,7 +14,7 @@ module REXML
|
|
14
14
|
def dump
|
15
15
|
puts @root.inspect
|
16
16
|
end
|
17
|
-
def validate( event )
|
17
|
+
def validate( event )
|
18
18
|
#puts "Current: #@current"
|
19
19
|
#puts "Event: #{event.inspect}"
|
20
20
|
@attr_stack = [] unless defined? @attr_stack
|
@@ -33,12 +33,12 @@ module REXML
|
|
33
33
|
sattr = [:start_attribute, nil]
|
34
34
|
eattr = [:end_attribute]
|
35
35
|
text = [:text, nil]
|
36
|
-
k,
|
37
|
-
sattr[1] =
|
36
|
+
k, = event[2].find { |key,value|
|
37
|
+
sattr[1] = key
|
38
38
|
#puts "Looking for #{sattr.inspect}"
|
39
39
|
m = @current.next( sattr )
|
40
40
|
#puts "Got #{m.inspect}"
|
41
|
-
if m
|
41
|
+
if m
|
42
42
|
# If the state has text children...
|
43
43
|
#puts "Looking for #{eattr.inspect}"
|
44
44
|
#puts "Expect #{m.expected}"
|
@@ -47,7 +47,7 @@ module REXML
|
|
47
47
|
@current = m
|
48
48
|
else
|
49
49
|
#puts "Didn't get end"
|
50
|
-
text[1] =
|
50
|
+
text[1] = value
|
51
51
|
#puts "Looking for #{text.inspect}"
|
52
52
|
m = m.next( text )
|
53
53
|
#puts "Got #{m.inspect}"
|
data/lib/rexml/xmldecl.rb
CHANGED
@@ -2,40 +2,40 @@ require 'rexml/encoding'
|
|
2
2
|
require 'rexml/source'
|
3
3
|
|
4
4
|
module REXML
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
# NEEDS DOCUMENTATION
|
6
|
+
class XMLDecl < Child
|
7
|
+
include Encoding
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
DEFAULT_VERSION = "1.0";
|
10
|
+
DEFAULT_ENCODING = "UTF-8";
|
11
|
+
DEFAULT_STANDALONE = "no";
|
12
|
+
START = '<\?xml';
|
13
|
+
STOP = '\?>';
|
14
14
|
|
15
|
-
|
15
|
+
attr_accessor :version, :standalone
|
16
16
|
attr_reader :writeencoding, :writethis
|
17
17
|
|
18
|
-
|
18
|
+
def initialize(version=DEFAULT_VERSION, encoding=nil, standalone=nil)
|
19
19
|
@writethis = true
|
20
20
|
@writeencoding = !encoding.nil?
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
if version.kind_of? XMLDecl
|
22
|
+
super()
|
23
|
+
@version = version.version
|
24
|
+
self.encoding = version.encoding
|
25
25
|
@writeencoding = version.writeencoding
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
26
|
+
@standalone = version.standalone
|
27
|
+
else
|
28
|
+
super()
|
29
|
+
@version = version
|
30
|
+
self.encoding = encoding
|
31
|
+
@standalone = standalone
|
32
|
+
end
|
33
|
+
@version = DEFAULT_VERSION if @version.nil?
|
34
|
+
end
|
35
|
+
|
36
|
+
def clone
|
37
|
+
XMLDecl.new(self)
|
38
|
+
end
|
39
39
|
|
40
40
|
# indent::
|
41
41
|
# Ignored. There must be no whitespace before an XML declaration
|
@@ -43,35 +43,31 @@ module REXML
|
|
43
43
|
# Ignored
|
44
44
|
# ie_hack::
|
45
45
|
# Ignored
|
46
|
-
|
46
|
+
def write(writer, indent=-1, transitive=false, ie_hack=false)
|
47
47
|
return nil unless @writethis or writer.kind_of? Output
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
:xmldecl
|
72
|
-
end
|
73
|
-
|
74
|
-
alias :stand_alone? :standalone
|
48
|
+
writer << START.sub(/\\/u, '')
|
49
|
+
writer << " #{content encoding}"
|
50
|
+
writer << STOP.sub(/\\/u, '')
|
51
|
+
end
|
52
|
+
|
53
|
+
def ==( other )
|
54
|
+
other.kind_of?(XMLDecl) and
|
55
|
+
other.version == @version and
|
56
|
+
other.encoding == self.encoding and
|
57
|
+
other.standalone == @standalone
|
58
|
+
end
|
59
|
+
|
60
|
+
def xmldecl version, encoding, standalone
|
61
|
+
@version = version
|
62
|
+
self.encoding = encoding
|
63
|
+
@standalone = standalone
|
64
|
+
end
|
65
|
+
|
66
|
+
def node_type
|
67
|
+
:xmldecl
|
68
|
+
end
|
69
|
+
|
70
|
+
alias :stand_alone? :standalone
|
75
71
|
alias :old_enc= :encoding=
|
76
72
|
|
77
73
|
def encoding=( enc )
|
@@ -108,12 +104,12 @@ module REXML
|
|
108
104
|
START.sub(/\\/u, '') + " ... " + STOP.sub(/\\/u, '')
|
109
105
|
end
|
110
106
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
107
|
+
private
|
108
|
+
def content(enc)
|
109
|
+
rv = "version='#@version'"
|
110
|
+
rv << " encoding='#{enc}'" if @writeencoding || enc !~ /\Autf-8\z/i
|
111
|
+
rv << " standalone='#@standalone'" if @standalone
|
112
|
+
rv
|
113
|
+
end
|
114
|
+
end
|
119
115
|
end
|
data/lib/rexml/xmltokens.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
module REXML
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
# Defines a number of tokens used for parsing XML. Not for general
|
3
|
+
# consumption.
|
4
|
+
module XMLTokens
|
5
|
+
NCNAME_STR= '[\w:][\-\w.]*'
|
6
|
+
NAME_STR= "(?:#{NCNAME_STR}:)?#{NCNAME_STR}"
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
NAMECHAR = '[\-\w\.:]'
|
9
|
+
NAME = "([\\w:]#{NAMECHAR}*)"
|
10
|
+
NMTOKEN = "(?:#{NAMECHAR})+"
|
11
|
+
NMTOKENS = "#{NMTOKEN}(\\s+#{NMTOKEN})*"
|
12
|
+
REFERENCE = "(?:&#{NAME};|&#\\d+;|&#x[0-9a-fA-F]+;)"
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
#REFERENCE = "(?:#{ENTITYREF}|#{CHARREF})"
|
15
|
+
#ENTITYREF = "&#{NAME};"
|
16
|
+
#CHARREF = "&#\\d+;|&#x[0-9a-fA-F]+;"
|
17
|
+
end
|
18
18
|
end
|
data/lib/rexml/xpath.rb
CHANGED
@@ -2,65 +2,79 @@ require 'rexml/functions'
|
|
2
2
|
require 'rexml/xpath_parser'
|
3
3
|
|
4
4
|
module REXML
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
# Wrapper class. Use this class to access the XPath functions.
|
6
|
+
class XPath
|
7
|
+
include Functions
|
8
|
+
# A base Hash object, supposing to be used when initializing a
|
9
|
+
# default empty namespaces set, but is currently unused.
|
10
|
+
# TODO: either set the namespaces=EMPTY_HASH, or deprecate this.
|
11
|
+
EMPTY_HASH = {}
|
9
12
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
13
|
+
# Finds and returns the first node that matches the supplied xpath.
|
14
|
+
# element::
|
15
|
+
# The context element
|
16
|
+
# path::
|
17
|
+
# The xpath to search for. If not supplied or nil, returns the first
|
18
|
+
# node matching '*'.
|
19
|
+
# namespaces::
|
20
|
+
# If supplied, a Hash which defines a namespace mapping.
|
21
|
+
# variables::
|
22
|
+
# If supplied, a Hash which maps $variables in the query
|
23
|
+
# to values. This can be used to avoid XPath injection attacks
|
24
|
+
# or to automatically handle escaping string values.
|
25
|
+
#
|
26
|
+
# XPath.first( node )
|
27
|
+
# XPath.first( doc, "//b"} )
|
28
|
+
# XPath.first( node, "a/x:b", { "x"=>"http://doofus" } )
|
29
|
+
# XPath.first( node, '/book/publisher/text()=$publisher', {}, {"publisher"=>"O'Reilly"})
|
22
30
|
def XPath::first element, path=nil, namespaces=nil, variables={}
|
23
31
|
raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
|
24
32
|
raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
33
|
+
parser = XPathParser.new
|
34
|
+
parser.namespaces = namespaces
|
35
|
+
parser.variables = variables
|
36
|
+
path = "*" unless path
|
37
|
+
element = [element] unless element.kind_of? Array
|
38
|
+
parser.parse(path, element).flatten[0]
|
39
|
+
end
|
32
40
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
# Iterates over nodes that match the given path, calling the supplied
|
42
|
+
# block with the match.
|
43
|
+
# element::
|
44
|
+
# The context element
|
45
|
+
# path::
|
46
|
+
# The xpath to search for. If not supplied or nil, defaults to '*'
|
47
|
+
# namespaces::
|
48
|
+
# If supplied, a Hash which defines a namespace mapping
|
49
|
+
# variables::
|
50
|
+
# If supplied, a Hash which maps $variables in the query
|
51
|
+
# to values. This can be used to avoid XPath injection attacks
|
52
|
+
# or to automatically handle escaping string values.
|
53
|
+
#
|
54
|
+
# XPath.each( node ) { |el| ... }
|
55
|
+
# XPath.each( node, '/*[@attr='v']' ) { |el| ... }
|
56
|
+
# XPath.each( node, 'ancestor::x' ) { |el| ... }
|
57
|
+
# XPath.each( node, '/book/publisher/text()=$publisher', {}, {"publisher"=>"O'Reilly"}) \
|
58
|
+
# {|el| ... }
|
59
|
+
def XPath::each element, path=nil, namespaces=nil, variables={}, &block
|
46
60
|
raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
|
47
61
|
raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
62
|
+
parser = XPathParser.new
|
63
|
+
parser.namespaces = namespaces
|
64
|
+
parser.variables = variables
|
65
|
+
path = "*" unless path
|
66
|
+
element = [element] unless element.kind_of? Array
|
67
|
+
parser.parse(path, element).each( &block )
|
68
|
+
end
|
55
69
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
70
|
+
# Returns an array of nodes matching a given XPath.
|
71
|
+
def XPath::match element, path=nil, namespaces=nil, variables={}
|
72
|
+
parser = XPathParser.new
|
73
|
+
parser.namespaces = namespaces
|
74
|
+
parser.variables = variables
|
75
|
+
path = "*" unless path
|
76
|
+
element = [element] unless element.kind_of? Array
|
77
|
+
parser.parse(path,element)
|
78
|
+
end
|
79
|
+
end
|
66
80
|
end
|