rexml 3.2.5 → 3.3.9
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/NEWS.md +470 -2
- data/README.md +10 -1
- data/doc/rexml/tasks/rdoc/element.rdoc +2 -2
- data/doc/rexml/tutorial.rdoc +1358 -0
- data/lib/rexml/attribute.rb +17 -11
- data/lib/rexml/document.rb +6 -2
- data/lib/rexml/element.rb +19 -34
- data/lib/rexml/entity.rb +9 -38
- data/lib/rexml/formatters/pretty.rb +3 -3
- data/lib/rexml/functions.rb +1 -2
- data/lib/rexml/namespace.rb +8 -4
- data/lib/rexml/node.rb +8 -4
- data/lib/rexml/parseexception.rb +1 -0
- data/lib/rexml/parsers/baseparser.rb +433 -265
- data/lib/rexml/parsers/pullparser.rb +12 -0
- data/lib/rexml/parsers/sax2parser.rb +16 -19
- data/lib/rexml/parsers/streamparser.rb +16 -10
- data/lib/rexml/parsers/treeparser.rb +9 -21
- data/lib/rexml/parsers/xpathparser.rb +136 -86
- data/lib/rexml/rexml.rb +3 -1
- data/lib/rexml/source.rb +134 -98
- data/lib/rexml/text.rb +45 -21
- data/lib/rexml/xpath_parser.rb +7 -3
- metadata +10 -52
data/lib/rexml/source.rb
CHANGED
@@ -1,8 +1,28 @@
|
|
1
1
|
# coding: US-ASCII
|
2
2
|
# frozen_string_literal: false
|
3
|
+
|
4
|
+
require "strscan"
|
5
|
+
|
3
6
|
require_relative 'encoding'
|
4
7
|
|
5
8
|
module REXML
|
9
|
+
if StringScanner::Version < "1.0.0"
|
10
|
+
module StringScannerCheckScanString
|
11
|
+
refine StringScanner do
|
12
|
+
def check(pattern)
|
13
|
+
pattern = /#{Regexp.escape(pattern)}/ if pattern.is_a?(String)
|
14
|
+
super(pattern)
|
15
|
+
end
|
16
|
+
|
17
|
+
def scan(pattern)
|
18
|
+
pattern = /#{Regexp.escape(pattern)}/ if pattern.is_a?(String)
|
19
|
+
super(pattern)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
using StringScannerCheckScanString
|
24
|
+
end
|
25
|
+
|
6
26
|
# Generates Source-s. USE THIS CLASS.
|
7
27
|
class SourceFactory
|
8
28
|
# Generates a Source object
|
@@ -30,26 +50,50 @@ module REXML
|
|
30
50
|
# objects and provides consumption of text
|
31
51
|
class Source
|
32
52
|
include Encoding
|
33
|
-
# The current buffer (what we're going to read next)
|
34
|
-
attr_reader :buffer
|
35
53
|
# The line number of the last consumed text
|
36
54
|
attr_reader :line
|
37
55
|
attr_reader :encoding
|
38
56
|
|
57
|
+
module Private
|
58
|
+
SCANNER_RESET_SIZE = 100000
|
59
|
+
PRE_DEFINED_TERM_PATTERNS = {}
|
60
|
+
pre_defined_terms = ["'", '"', "<"]
|
61
|
+
pre_defined_terms.each do |term|
|
62
|
+
PRE_DEFINED_TERM_PATTERNS[term] = /#{Regexp.escape(term)}/
|
63
|
+
end
|
64
|
+
end
|
65
|
+
private_constant :Private
|
66
|
+
|
39
67
|
# Constructor
|
40
68
|
# @param arg must be a String, and should be a valid XML document
|
41
69
|
# @param encoding if non-null, sets the encoding of the source to this
|
42
70
|
# value, overriding all encoding detection
|
43
71
|
def initialize(arg, encoding=nil)
|
44
|
-
@orig =
|
72
|
+
@orig = arg
|
73
|
+
@scanner = StringScanner.new(@orig)
|
45
74
|
if encoding
|
46
75
|
self.encoding = encoding
|
47
76
|
else
|
48
77
|
detect_encoding
|
49
78
|
end
|
50
79
|
@line = 0
|
80
|
+
@term_encord = {}
|
51
81
|
end
|
52
82
|
|
83
|
+
# The current buffer (what we're going to read next)
|
84
|
+
def buffer
|
85
|
+
@scanner.rest
|
86
|
+
end
|
87
|
+
|
88
|
+
def drop_parsed_content
|
89
|
+
if @scanner.pos > Private::SCANNER_RESET_SIZE
|
90
|
+
@scanner.string = @scanner.rest
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def buffer_encoding=(encoding)
|
95
|
+
@scanner.string.force_encoding(encoding)
|
96
|
+
end
|
53
97
|
|
54
98
|
# Inherited from Encoding
|
55
99
|
# Overridden to support optimized en/decoding
|
@@ -58,98 +102,78 @@ module REXML
|
|
58
102
|
encoding_updated
|
59
103
|
end
|
60
104
|
|
61
|
-
|
62
|
-
# usual scan() method. For one thing, the pattern argument has some
|
63
|
-
# requirements; for another, the source can be consumed. You can easily
|
64
|
-
# confuse this method. Originally, the patterns were easier
|
65
|
-
# to construct and this method more robust, because this method
|
66
|
-
# generated search regexps on the fly; however, this was
|
67
|
-
# computationally expensive and slowed down the entire REXML package
|
68
|
-
# considerably, since this is by far the most commonly called method.
|
69
|
-
# @param pattern must be a Regexp, and must be in the form of
|
70
|
-
# /^\s*(#{your pattern, with no groups})(.*)/. The first group
|
71
|
-
# will be returned; the second group is used if the consume flag is
|
72
|
-
# set.
|
73
|
-
# @param consume if true, the pattern returned will be consumed, leaving
|
74
|
-
# everything after it in the Source.
|
75
|
-
# @return the pattern, if found, or nil if the Source is empty or the
|
76
|
-
# pattern is not found.
|
77
|
-
def scan(pattern, cons=false)
|
78
|
-
return nil if @buffer.nil?
|
79
|
-
rv = @buffer.scan(pattern)
|
80
|
-
@buffer = $' if cons and rv.size>0
|
81
|
-
rv
|
105
|
+
def read(term = nil)
|
82
106
|
end
|
83
107
|
|
84
|
-
def
|
108
|
+
def read_until(term)
|
109
|
+
pattern = Private::PRE_DEFINED_TERM_PATTERNS[term] || /#{Regexp.escape(term)}/
|
110
|
+
data = @scanner.scan_until(pattern)
|
111
|
+
unless data
|
112
|
+
data = @scanner.rest
|
113
|
+
@scanner.pos = @scanner.string.bytesize
|
114
|
+
end
|
115
|
+
data
|
85
116
|
end
|
86
117
|
|
87
|
-
def
|
88
|
-
@buffer = $' if pattern.match( @buffer )
|
118
|
+
def ensure_buffer
|
89
119
|
end
|
90
120
|
|
91
|
-
def
|
92
|
-
|
121
|
+
def match(pattern, cons=false)
|
122
|
+
if cons
|
123
|
+
@scanner.scan(pattern).nil? ? nil : @scanner
|
124
|
+
else
|
125
|
+
@scanner.check(pattern).nil? ? nil : @scanner
|
126
|
+
end
|
93
127
|
end
|
94
128
|
|
95
|
-
def
|
96
|
-
|
97
|
-
@buffer = $'
|
98
|
-
return md
|
129
|
+
def position
|
130
|
+
@scanner.pos
|
99
131
|
end
|
100
132
|
|
101
|
-
def
|
102
|
-
|
103
|
-
@buffer = $' if cons and md
|
104
|
-
return md
|
133
|
+
def position=(pos)
|
134
|
+
@scanner.pos = pos
|
105
135
|
end
|
106
136
|
|
107
137
|
# @return true if the Source is exhausted
|
108
138
|
def empty?
|
109
|
-
@
|
110
|
-
end
|
111
|
-
|
112
|
-
def position
|
113
|
-
@orig.index( @buffer )
|
139
|
+
@scanner.eos?
|
114
140
|
end
|
115
141
|
|
116
142
|
# @return the current line in the source
|
117
143
|
def current_line
|
118
144
|
lines = @orig.split
|
119
|
-
res = lines.grep @
|
145
|
+
res = lines.grep @scanner.rest[0..30]
|
120
146
|
res = res[-1] if res.kind_of? Array
|
121
147
|
lines.index( res ) if res
|
122
148
|
end
|
123
149
|
|
124
150
|
private
|
151
|
+
|
125
152
|
def detect_encoding
|
126
|
-
|
153
|
+
scanner_encoding = @scanner.rest.encoding
|
127
154
|
detected_encoding = "UTF-8"
|
128
155
|
begin
|
129
|
-
@
|
130
|
-
if @
|
131
|
-
@buffer[0, 2] = ""
|
156
|
+
@scanner.string.force_encoding("ASCII-8BIT")
|
157
|
+
if @scanner.scan(/\xfe\xff/n)
|
132
158
|
detected_encoding = "UTF-16BE"
|
133
|
-
elsif @
|
134
|
-
@buffer[0, 2] = ""
|
159
|
+
elsif @scanner.scan(/\xff\xfe/n)
|
135
160
|
detected_encoding = "UTF-16LE"
|
136
|
-
elsif @
|
137
|
-
@buffer[0, 3] = ""
|
161
|
+
elsif @scanner.scan(/\xef\xbb\xbf/n)
|
138
162
|
detected_encoding = "UTF-8"
|
139
163
|
end
|
140
164
|
ensure
|
141
|
-
@
|
165
|
+
@scanner.string.force_encoding(scanner_encoding)
|
142
166
|
end
|
143
167
|
self.encoding = detected_encoding
|
144
168
|
end
|
145
169
|
|
146
170
|
def encoding_updated
|
147
171
|
if @encoding != 'UTF-8'
|
148
|
-
@
|
172
|
+
@scanner.string = decode(@scanner.rest)
|
149
173
|
@to_utf = true
|
150
174
|
else
|
151
175
|
@to_utf = false
|
152
|
-
@
|
176
|
+
@scanner.string.force_encoding(::Encoding::UTF_8)
|
153
177
|
end
|
154
178
|
end
|
155
179
|
end
|
@@ -172,7 +196,7 @@ module REXML
|
|
172
196
|
end
|
173
197
|
|
174
198
|
if !@to_utf and
|
175
|
-
@
|
199
|
+
@orig.respond_to?(:force_encoding) and
|
176
200
|
@source.respond_to?(:external_encoding) and
|
177
201
|
@source.external_encoding != ::Encoding::UTF_8
|
178
202
|
@force_utf8 = true
|
@@ -181,65 +205,72 @@ module REXML
|
|
181
205
|
end
|
182
206
|
end
|
183
207
|
|
184
|
-
def
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
rescue Iconv::IllegalSequence
|
196
|
-
raise
|
197
|
-
rescue
|
198
|
-
@source = nil
|
208
|
+
def read(term = nil, min_bytes = 1)
|
209
|
+
term = encode(term) if term
|
210
|
+
begin
|
211
|
+
str = readline(term)
|
212
|
+
@scanner << str
|
213
|
+
read_bytes = str.bytesize
|
214
|
+
begin
|
215
|
+
while read_bytes < min_bytes
|
216
|
+
str = readline(term)
|
217
|
+
@scanner << str
|
218
|
+
read_bytes += str.bytesize
|
199
219
|
end
|
220
|
+
rescue IOError
|
200
221
|
end
|
201
|
-
|
222
|
+
true
|
223
|
+
rescue Exception, NameError
|
224
|
+
@source = nil
|
225
|
+
false
|
202
226
|
end
|
203
|
-
rv.taint if RUBY_VERSION < '2.7'
|
204
|
-
rv
|
205
227
|
end
|
206
228
|
|
207
|
-
def
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
@source
|
229
|
+
def read_until(term)
|
230
|
+
pattern = Private::PRE_DEFINED_TERM_PATTERNS[term] || /#{Regexp.escape(term)}/
|
231
|
+
term = @term_encord[term] ||= encode(term)
|
232
|
+
until str = @scanner.scan_until(pattern)
|
233
|
+
break if @source.nil?
|
234
|
+
break if @source.eof?
|
235
|
+
@scanner << readline(term)
|
236
|
+
end
|
237
|
+
if str
|
238
|
+
read if @scanner.eos? and !@source.eof?
|
239
|
+
str
|
240
|
+
else
|
241
|
+
rest = @scanner.rest
|
242
|
+
@scanner.pos = @scanner.string.bytesize
|
243
|
+
rest
|
212
244
|
end
|
213
245
|
end
|
214
246
|
|
215
|
-
def
|
216
|
-
|
247
|
+
def ensure_buffer
|
248
|
+
read if @scanner.eos? && @source
|
217
249
|
end
|
218
250
|
|
219
251
|
def match( pattern, cons=false )
|
220
|
-
|
221
|
-
|
222
|
-
while
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
rescue
|
228
|
-
@source = nil
|
252
|
+
# To avoid performance issue, we need to increase bytes to read per scan
|
253
|
+
min_bytes = 1
|
254
|
+
while true
|
255
|
+
if cons
|
256
|
+
md = @scanner.scan(pattern)
|
257
|
+
else
|
258
|
+
md = @scanner.check(pattern)
|
229
259
|
end
|
260
|
+
break if md
|
261
|
+
return nil if pattern.is_a?(String)
|
262
|
+
return nil if @source.nil?
|
263
|
+
return nil unless read(nil, min_bytes)
|
264
|
+
min_bytes *= 2
|
230
265
|
end
|
231
|
-
|
232
|
-
|
266
|
+
|
267
|
+
md.nil? ? nil : @scanner
|
233
268
|
end
|
234
269
|
|
235
270
|
def empty?
|
236
271
|
super and ( @source.nil? || @source.eof? )
|
237
272
|
end
|
238
273
|
|
239
|
-
def position
|
240
|
-
@er_source.pos rescue 0
|
241
|
-
end
|
242
|
-
|
243
274
|
# @return the current line in the source
|
244
275
|
def current_line
|
245
276
|
begin
|
@@ -263,15 +294,20 @@ module REXML
|
|
263
294
|
end
|
264
295
|
|
265
296
|
private
|
266
|
-
def readline
|
267
|
-
str = @source.readline(@line_break)
|
297
|
+
def readline(term = nil)
|
268
298
|
if @pending_buffer
|
299
|
+
begin
|
300
|
+
str = @source.readline(term || @line_break)
|
301
|
+
rescue IOError
|
302
|
+
end
|
269
303
|
if str.nil?
|
270
304
|
str = @pending_buffer
|
271
305
|
else
|
272
306
|
str = @pending_buffer + str
|
273
307
|
end
|
274
308
|
@pending_buffer = nil
|
309
|
+
else
|
310
|
+
str = @source.readline(term || @line_break)
|
275
311
|
end
|
276
312
|
return nil if str.nil?
|
277
313
|
|
@@ -290,7 +326,7 @@ module REXML
|
|
290
326
|
@source.set_encoding(@encoding, @encoding)
|
291
327
|
end
|
292
328
|
@line_break = encode(">")
|
293
|
-
@pending_buffer, @
|
329
|
+
@pending_buffer, @scanner.string = @scanner.rest, ""
|
294
330
|
@pending_buffer.force_encoding(@encoding)
|
295
331
|
super
|
296
332
|
end
|
data/lib/rexml/text.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# frozen_string_literal:
|
1
|
+
# frozen_string_literal: true
|
2
2
|
require_relative 'security'
|
3
3
|
require_relative 'entity'
|
4
4
|
require_relative 'doctype'
|
@@ -131,7 +131,7 @@ module REXML
|
|
131
131
|
def Text.check string, pattern, doctype
|
132
132
|
|
133
133
|
# illegal anywhere
|
134
|
-
if string
|
134
|
+
if !string.match?(VALID_XML_CHARS)
|
135
135
|
if String.method_defined? :encode
|
136
136
|
string.chars.each do |c|
|
137
137
|
case c.ord
|
@@ -151,25 +151,45 @@ module REXML
|
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
154
|
-
|
155
|
-
string.
|
156
|
-
if
|
157
|
-
raise "Illegal character #{
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
154
|
+
pos = 0
|
155
|
+
while (index = string.index(/<|&/, pos))
|
156
|
+
if string[index] == "<"
|
157
|
+
raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}"
|
158
|
+
end
|
159
|
+
|
160
|
+
unless (end_index = string.index(/[^\s];/, index + 1))
|
161
|
+
raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}"
|
162
|
+
end
|
163
|
+
|
164
|
+
value = string[(index + 1)..end_index]
|
165
|
+
if /\s/.match?(value)
|
166
|
+
raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}"
|
167
|
+
end
|
168
|
+
|
169
|
+
if value[0] == "#"
|
170
|
+
character_reference = value[1..-1]
|
171
|
+
|
172
|
+
unless (/\A(\d+|x[0-9a-fA-F]+)\z/.match?(character_reference))
|
173
|
+
if character_reference[0] == "x" || character_reference[-1] == "x"
|
174
|
+
raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}"
|
162
175
|
else
|
163
|
-
raise "Illegal character #{
|
176
|
+
raise "Illegal character #{string.inspect} in raw string #{string.inspect}"
|
164
177
|
end
|
165
|
-
# FIXME: below can't work but this needs API change.
|
166
|
-
# elsif @parent and $3 and !SUBSTITUTES.include?($1)
|
167
|
-
# if !doctype or !doctype.entities.has_key?($3)
|
168
|
-
# raise "Undeclared entity '#{$1}' in raw string \"#{string}\""
|
169
|
-
# end
|
170
178
|
end
|
179
|
+
|
180
|
+
case (character_reference[0] == "x" ? character_reference[1..-1].to_i(16) : character_reference[0..-1].to_i)
|
181
|
+
when *VALID_CHAR
|
182
|
+
else
|
183
|
+
raise "Illegal character #{string.inspect} in raw string #{string.inspect}"
|
184
|
+
end
|
185
|
+
elsif !(/\A#{Entity::NAME}\z/um.match?(value))
|
186
|
+
raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}"
|
171
187
|
end
|
188
|
+
|
189
|
+
pos = end_index + 1
|
172
190
|
end
|
191
|
+
|
192
|
+
string
|
173
193
|
end
|
174
194
|
|
175
195
|
def node_type
|
@@ -248,7 +268,8 @@ module REXML
|
|
248
268
|
# u = Text.new( "sean russell", false, nil, true )
|
249
269
|
# u.value #-> "sean russell"
|
250
270
|
def value
|
251
|
-
@unnormalized ||= Text::unnormalize(
|
271
|
+
@unnormalized ||= Text::unnormalize(@string, doctype,
|
272
|
+
entity_expansion_text_limit: document&.entity_expansion_text_limit)
|
252
273
|
end
|
253
274
|
|
254
275
|
# Sets the contents of this text node. This expects the text to be
|
@@ -371,7 +392,7 @@ module REXML
|
|
371
392
|
copy = input.to_s
|
372
393
|
# Doing it like this rather than in a loop improves the speed
|
373
394
|
#copy = copy.gsub( EREFERENCE, '&' )
|
374
|
-
copy = copy.gsub( "&", "&" )
|
395
|
+
copy = copy.gsub( "&", "&" ) if copy.include?("&")
|
375
396
|
if doctype
|
376
397
|
# Replace all ampersands that aren't part of an entity
|
377
398
|
doctype.entities.each_value do |entity|
|
@@ -382,18 +403,21 @@ module REXML
|
|
382
403
|
else
|
383
404
|
# Replace all ampersands that aren't part of an entity
|
384
405
|
DocType::DEFAULT_ENTITIES.each_value do |entity|
|
385
|
-
|
406
|
+
if copy.include?(entity.value)
|
407
|
+
copy = copy.gsub(entity.value, "&#{entity.name};" )
|
408
|
+
end
|
386
409
|
end
|
387
410
|
end
|
388
411
|
copy
|
389
412
|
end
|
390
413
|
|
391
414
|
# Unescapes all possible entities
|
392
|
-
def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil )
|
415
|
+
def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil, entity_expansion_text_limit: nil )
|
416
|
+
entity_expansion_text_limit ||= Security.entity_expansion_text_limit
|
393
417
|
sum = 0
|
394
418
|
string.gsub( /\r\n?/, "\n" ).gsub( REFERENCE ) {
|
395
419
|
s = Text.expand($&, doctype, filter)
|
396
|
-
if sum + s.bytesize >
|
420
|
+
if sum + s.bytesize > entity_expansion_text_limit
|
397
421
|
raise "entity expansion has grown too large"
|
398
422
|
else
|
399
423
|
sum += s.bytesize
|
data/lib/rexml/xpath_parser.rb
CHANGED
@@ -590,6 +590,7 @@ module REXML
|
|
590
590
|
|
591
591
|
def evaluate_predicate(expression, nodesets)
|
592
592
|
enter(:predicate, expression, nodesets) if @debug
|
593
|
+
new_nodeset_count = 0
|
593
594
|
new_nodesets = nodesets.collect do |nodeset|
|
594
595
|
new_nodeset = []
|
595
596
|
subcontext = { :size => nodeset.size }
|
@@ -606,17 +607,20 @@ module REXML
|
|
606
607
|
result = result[0] if result.kind_of? Array and result.length == 1
|
607
608
|
if result.kind_of? Numeric
|
608
609
|
if result == node.position
|
609
|
-
|
610
|
+
new_nodeset_count += 1
|
611
|
+
new_nodeset << XPathNode.new(node, position: new_nodeset_count)
|
610
612
|
end
|
611
613
|
elsif result.instance_of? Array
|
612
614
|
if result.size > 0 and result.inject(false) {|k,s| s or k}
|
613
615
|
if result.size > 0
|
614
|
-
|
616
|
+
new_nodeset_count += 1
|
617
|
+
new_nodeset << XPathNode.new(node, position: new_nodeset_count)
|
615
618
|
end
|
616
619
|
end
|
617
620
|
else
|
618
621
|
if result
|
619
|
-
|
622
|
+
new_nodeset_count += 1
|
623
|
+
new_nodeset << XPathNode.new(node, position: new_nodeset_count)
|
620
624
|
end
|
621
625
|
end
|
622
626
|
end
|
metadata
CHANGED
@@ -1,57 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rexml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.3.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kouhei Sutou
|
8
|
-
|
9
|
-
bindir: exe
|
8
|
+
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bundler
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rake
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: test-unit
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
10
|
+
date: 2024-10-24 00:00:00.000000000 Z
|
11
|
+
dependencies: []
|
55
12
|
description: An XML toolkit for Ruby
|
56
13
|
email:
|
57
14
|
- kou@cozmixng.org
|
@@ -73,6 +30,7 @@ extra_rdoc_files:
|
|
73
30
|
- doc/rexml/tasks/tocs/master_toc.rdoc
|
74
31
|
- doc/rexml/tasks/tocs/node_toc.rdoc
|
75
32
|
- doc/rexml/tasks/tocs/parent_toc.rdoc
|
33
|
+
- doc/rexml/tutorial.rdoc
|
76
34
|
files:
|
77
35
|
- LICENSE.txt
|
78
36
|
- NEWS.md
|
@@ -89,6 +47,7 @@ files:
|
|
89
47
|
- doc/rexml/tasks/tocs/master_toc.rdoc
|
90
48
|
- doc/rexml/tasks/tocs/node_toc.rdoc
|
91
49
|
- doc/rexml/tasks/tocs/parent_toc.rdoc
|
50
|
+
- doc/rexml/tutorial.rdoc
|
92
51
|
- lib/rexml.rb
|
93
52
|
- lib/rexml/attlistdecl.rb
|
94
53
|
- lib/rexml/attribute.rb
|
@@ -142,8 +101,8 @@ files:
|
|
142
101
|
homepage: https://github.com/ruby/rexml
|
143
102
|
licenses:
|
144
103
|
- BSD-2-Clause
|
145
|
-
metadata:
|
146
|
-
|
104
|
+
metadata:
|
105
|
+
changelog_uri: https://github.com/ruby/rexml/releases/tag/v3.3.9
|
147
106
|
rdoc_options:
|
148
107
|
- "--main"
|
149
108
|
- README.md
|
@@ -153,15 +112,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
153
112
|
requirements:
|
154
113
|
- - ">="
|
155
114
|
- !ruby/object:Gem::Version
|
156
|
-
version:
|
115
|
+
version: 2.5.0
|
157
116
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
117
|
requirements:
|
159
118
|
- - ">="
|
160
119
|
- !ruby/object:Gem::Version
|
161
120
|
version: '0'
|
162
121
|
requirements: []
|
163
|
-
rubygems_version: 3.
|
164
|
-
signing_key:
|
122
|
+
rubygems_version: 3.6.0.dev
|
165
123
|
specification_version: 4
|
166
124
|
summary: An XML toolkit for Ruby
|
167
125
|
test_files: []
|