rexml 3.2.5 → 3.4.4
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 +667 -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 +24 -19
- data/lib/rexml/cdata.rb +1 -1
- data/lib/rexml/child.rb +2 -3
- data/lib/rexml/comment.rb +1 -1
- data/lib/rexml/doctype.rb +3 -8
- data/lib/rexml/document.rb +27 -7
- data/lib/rexml/element.rb +66 -87
- data/lib/rexml/encoding.rb +3 -6
- data/lib/rexml/entity.rb +9 -38
- data/lib/rexml/formatters/pretty.rb +3 -3
- data/lib/rexml/functions.rb +4 -5
- data/lib/rexml/instruction.rb +1 -1
- data/lib/rexml/namespace.rb +12 -8
- data/lib/rexml/node.rb +10 -6
- data/lib/rexml/parseexception.rb +1 -0
- data/lib/rexml/parsers/baseparser.rb +543 -288
- data/lib/rexml/parsers/pullparser.rb +16 -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 +139 -89
- data/lib/rexml/quickpath.rb +19 -18
- data/lib/rexml/rexml.rb +3 -1
- data/lib/rexml/security.rb +2 -2
- data/lib/rexml/source.rb +190 -100
- data/lib/rexml/text.rb +74 -78
- data/lib/rexml/validation/relaxng.rb +27 -26
- data/lib/rexml/validation/validation.rb +8 -8
- data/lib/rexml/xpath.rb +2 -13
- data/lib/rexml/xpath_parser.rb +51 -45
- metadata +10 -52
data/lib/rexml/attribute.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# frozen_string_literal:
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
require_relative "namespace"
|
|
3
3
|
require_relative 'text'
|
|
4
4
|
|
|
@@ -13,9 +13,6 @@ module REXML
|
|
|
13
13
|
|
|
14
14
|
# The element to which this attribute belongs
|
|
15
15
|
attr_reader :element
|
|
16
|
-
# The normalized value of this attribute. That is, the attribute with
|
|
17
|
-
# entities intact.
|
|
18
|
-
attr_writer :normalized
|
|
19
16
|
PATTERN = /\s*(#{NAME_STR})\s*=\s*(["'])(.*?)\2/um
|
|
20
17
|
|
|
21
18
|
NEEDS_A_SECOND_CHECK = /(<|&((#{Entity::NAME});|(#0*((?:\d+)|(?:x[a-fA-F0-9]+)));)?)/um
|
|
@@ -122,18 +119,18 @@ module REXML
|
|
|
122
119
|
# b = Attribute.new( "ns:x", "y" )
|
|
123
120
|
# b.to_string # -> "ns:x='y'"
|
|
124
121
|
def to_string
|
|
122
|
+
value = to_s
|
|
125
123
|
if @element and @element.context and @element.context[:attribute_quote] == :quote
|
|
126
|
-
|
|
124
|
+
value = value.gsub('"', '"') if value.include?('"')
|
|
125
|
+
%Q^#@expanded_name="#{value}"^
|
|
127
126
|
else
|
|
128
|
-
|
|
127
|
+
value = value.gsub("'", ''') if value.include?("'")
|
|
128
|
+
"#@expanded_name='#{value}'"
|
|
129
129
|
end
|
|
130
130
|
end
|
|
131
131
|
|
|
132
132
|
def doctype
|
|
133
|
-
|
|
134
|
-
doc = @element.document
|
|
135
|
-
doc.doctype if doc
|
|
136
|
-
end
|
|
133
|
+
@element&.document&.doctype
|
|
137
134
|
end
|
|
138
135
|
|
|
139
136
|
# Returns the attribute value, with entities replaced
|
|
@@ -141,7 +138,6 @@ module REXML
|
|
|
141
138
|
return @normalized if @normalized
|
|
142
139
|
|
|
143
140
|
@normalized = Text::normalize( @unnormalized, doctype )
|
|
144
|
-
@unnormalized = nil
|
|
145
141
|
@normalized
|
|
146
142
|
end
|
|
147
143
|
|
|
@@ -149,9 +145,16 @@ module REXML
|
|
|
149
145
|
# have been expanded to their values
|
|
150
146
|
def value
|
|
151
147
|
return @unnormalized if @unnormalized
|
|
152
|
-
|
|
153
|
-
@
|
|
154
|
-
|
|
148
|
+
|
|
149
|
+
@unnormalized = Text::unnormalize(@normalized, doctype,
|
|
150
|
+
entity_expansion_text_limit: @element&.document&.entity_expansion_text_limit)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# The normalized value of this attribute. That is, the attribute with
|
|
154
|
+
# entities intact.
|
|
155
|
+
def normalized=(new_normalized)
|
|
156
|
+
@normalized = new_normalized
|
|
157
|
+
@unnormalized = nil
|
|
155
158
|
end
|
|
156
159
|
|
|
157
160
|
# Returns a copy of this attribute
|
|
@@ -167,7 +170,7 @@ module REXML
|
|
|
167
170
|
@element = element
|
|
168
171
|
|
|
169
172
|
if @normalized
|
|
170
|
-
Text.check( @normalized, NEEDS_A_SECOND_CHECK
|
|
173
|
+
Text.check( @normalized, NEEDS_A_SECOND_CHECK )
|
|
171
174
|
end
|
|
172
175
|
|
|
173
176
|
self
|
|
@@ -190,15 +193,17 @@ module REXML
|
|
|
190
193
|
end
|
|
191
194
|
|
|
192
195
|
def inspect
|
|
193
|
-
rv = ""
|
|
196
|
+
rv = +""
|
|
194
197
|
write( rv )
|
|
195
198
|
rv
|
|
196
199
|
end
|
|
197
200
|
|
|
198
201
|
def xpath
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
+
@element.xpath + "/@#{self.expanded_name}"
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def document
|
|
206
|
+
@element&.document
|
|
202
207
|
end
|
|
203
208
|
end
|
|
204
209
|
end
|
data/lib/rexml/cdata.rb
CHANGED
|
@@ -58,7 +58,7 @@ module REXML
|
|
|
58
58
|
# c = CData.new( " Some text " )
|
|
59
59
|
# c.write( $stdout ) #-> <![CDATA[ Some text ]]>
|
|
60
60
|
def write( output=$stdout, indent=-1, transitive=false, ie_hack=false )
|
|
61
|
-
Kernel.warn( "#{self.class.name}
|
|
61
|
+
Kernel.warn( "#{self.class.name}#write is deprecated", uplevel: 1)
|
|
62
62
|
indent( output, indent )
|
|
63
63
|
output << START
|
|
64
64
|
output << @string
|
data/lib/rexml/child.rb
CHANGED
|
@@ -83,13 +83,12 @@ module REXML
|
|
|
83
83
|
# Returns:: the document this child belongs to, or nil if this child
|
|
84
84
|
# belongs to no document
|
|
85
85
|
def document
|
|
86
|
-
|
|
87
|
-
nil
|
|
86
|
+
parent&.document
|
|
88
87
|
end
|
|
89
88
|
|
|
90
89
|
# This doesn't yet handle encodings
|
|
91
90
|
def bytes
|
|
92
|
-
document
|
|
91
|
+
document&.encoding
|
|
93
92
|
|
|
94
93
|
to_s
|
|
95
94
|
end
|
data/lib/rexml/comment.rb
CHANGED
|
@@ -48,7 +48,7 @@ module REXML
|
|
|
48
48
|
# ie_hack::
|
|
49
49
|
# Needed for conformity to the child API, but not used by this class.
|
|
50
50
|
def write( output, indent=-1, transitive=false, ie_hack=false )
|
|
51
|
-
Kernel.warn("
|
|
51
|
+
Kernel.warn("#{self.class.name}#write is deprecated. See REXML::Formatters", uplevel: 1)
|
|
52
52
|
indent( output, indent )
|
|
53
53
|
output << START
|
|
54
54
|
output << @string
|
data/lib/rexml/doctype.rb
CHANGED
|
@@ -171,15 +171,11 @@ module REXML
|
|
|
171
171
|
end
|
|
172
172
|
|
|
173
173
|
def context
|
|
174
|
-
|
|
175
|
-
@parent.context
|
|
176
|
-
else
|
|
177
|
-
nil
|
|
178
|
-
end
|
|
174
|
+
@parent&.context
|
|
179
175
|
end
|
|
180
176
|
|
|
181
177
|
def entity( name )
|
|
182
|
-
@entities[name]
|
|
178
|
+
@entities[name]&.unnormalized
|
|
183
179
|
end
|
|
184
180
|
|
|
185
181
|
def add child
|
|
@@ -288,8 +284,7 @@ module REXML
|
|
|
288
284
|
end
|
|
289
285
|
|
|
290
286
|
def to_s
|
|
291
|
-
context =
|
|
292
|
-
context = parent.context if parent
|
|
287
|
+
context = parent&.context
|
|
293
288
|
notation = "<!NOTATION #{@name}"
|
|
294
289
|
reference_writer = ReferenceWriter.new(@middle, @public, @system, context)
|
|
295
290
|
reference_writer.write(notation)
|
data/lib/rexml/document.rb
CHANGED
|
@@ -69,7 +69,7 @@ module REXML
|
|
|
69
69
|
# d.to_s # => "<root><foo>Foo</foo><bar>Bar</bar></root>"
|
|
70
70
|
#
|
|
71
71
|
# When argument +document+ is given, it must be an existing
|
|
72
|
-
# document object, whose context and attributes (but not
|
|
72
|
+
# document object, whose context and attributes (but not children)
|
|
73
73
|
# are cloned into the new document:
|
|
74
74
|
#
|
|
75
75
|
# d = REXML::Document.new(xml_string)
|
|
@@ -91,9 +91,13 @@ module REXML
|
|
|
91
91
|
#
|
|
92
92
|
def initialize( source = nil, context = {} )
|
|
93
93
|
@entity_expansion_count = 0
|
|
94
|
+
@entity_expansion_limit = Security.entity_expansion_limit
|
|
95
|
+
@entity_expansion_text_limit = Security.entity_expansion_text_limit
|
|
94
96
|
super()
|
|
95
97
|
@context = context
|
|
96
|
-
|
|
98
|
+
# `source = ""` is an invalid usage because no root element XML is an invalid XML.
|
|
99
|
+
# But we accept `""` for backward compatibility.
|
|
100
|
+
return if source.nil? or source == ""
|
|
97
101
|
if source.kind_of? Document
|
|
98
102
|
@context = source.context
|
|
99
103
|
super source
|
|
@@ -307,8 +311,8 @@ module REXML
|
|
|
307
311
|
end
|
|
308
312
|
|
|
309
313
|
# :call-seq:
|
|
310
|
-
# doc.write(output=$stdout, indent=-1,
|
|
311
|
-
# doc.write(options={:output => $stdout, :indent => -1, :
|
|
314
|
+
# doc.write(output=$stdout, indent=-1, transitive=false, ie_hack=false, encoding=nil)
|
|
315
|
+
# doc.write(options={:output => $stdout, :indent => -1, :transitive => false, :ie_hack => false, :encoding => nil})
|
|
312
316
|
#
|
|
313
317
|
# Write the XML tree out, optionally with indent. This writes out the
|
|
314
318
|
# entire XML document, including XML declarations, doctype declarations,
|
|
@@ -413,7 +417,7 @@ module REXML
|
|
|
413
417
|
#
|
|
414
418
|
# Deprecated. Use REXML::Security.entity_expansion_limit= instead.
|
|
415
419
|
def Document::entity_expansion_limit
|
|
416
|
-
|
|
420
|
+
Security.entity_expansion_limit
|
|
417
421
|
end
|
|
418
422
|
|
|
419
423
|
# Set the entity expansion limit. By default the limit is set to 10240.
|
|
@@ -427,14 +431,16 @@ module REXML
|
|
|
427
431
|
#
|
|
428
432
|
# Deprecated. Use REXML::Security.entity_expansion_text_limit instead.
|
|
429
433
|
def Document::entity_expansion_text_limit
|
|
430
|
-
|
|
434
|
+
Security.entity_expansion_text_limit
|
|
431
435
|
end
|
|
432
436
|
|
|
433
437
|
attr_reader :entity_expansion_count
|
|
438
|
+
attr_writer :entity_expansion_limit
|
|
439
|
+
attr_accessor :entity_expansion_text_limit
|
|
434
440
|
|
|
435
441
|
def record_entity_expansion
|
|
436
442
|
@entity_expansion_count += 1
|
|
437
|
-
if @entity_expansion_count >
|
|
443
|
+
if @entity_expansion_count > @entity_expansion_limit
|
|
438
444
|
raise "number of entity expansions exceeded, processing aborted."
|
|
439
445
|
end
|
|
440
446
|
end
|
|
@@ -444,6 +450,20 @@ module REXML
|
|
|
444
450
|
end
|
|
445
451
|
|
|
446
452
|
private
|
|
453
|
+
|
|
454
|
+
attr_accessor :namespaces_cache
|
|
455
|
+
|
|
456
|
+
# New document level cache is created and available in this block.
|
|
457
|
+
# This API is thread unsafe. Users can't change this document in this block.
|
|
458
|
+
def enable_cache
|
|
459
|
+
@namespaces_cache = {}
|
|
460
|
+
begin
|
|
461
|
+
yield
|
|
462
|
+
ensure
|
|
463
|
+
@namespaces_cache = nil
|
|
464
|
+
end
|
|
465
|
+
end
|
|
466
|
+
|
|
447
467
|
def build( source )
|
|
448
468
|
Parsers::TreeParser.new( source, self ).parse
|
|
449
469
|
end
|
data/lib/rexml/element.rb
CHANGED
|
@@ -7,14 +7,6 @@ require_relative "xpath"
|
|
|
7
7
|
require_relative "parseexception"
|
|
8
8
|
|
|
9
9
|
module REXML
|
|
10
|
-
# An implementation note about namespaces:
|
|
11
|
-
# As we parse, when we find namespaces we put them in a hash and assign
|
|
12
|
-
# them a unique ID. We then convert the namespace prefix for the node
|
|
13
|
-
# to the unique ID. This makes namespace lookup much faster for the
|
|
14
|
-
# cost of extra memory use. We save the namespace prefix for the
|
|
15
|
-
# context node and convert it back when we write it.
|
|
16
|
-
@@namespaces = {}
|
|
17
|
-
|
|
18
10
|
# An \REXML::Element object represents an XML element.
|
|
19
11
|
#
|
|
20
12
|
# An element:
|
|
@@ -449,9 +441,14 @@ module REXML
|
|
|
449
441
|
# Related: #root_node, #document.
|
|
450
442
|
#
|
|
451
443
|
def root
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
444
|
+
target = self
|
|
445
|
+
while target
|
|
446
|
+
return target.elements[1] if target.kind_of? Document
|
|
447
|
+
parent = target.parent
|
|
448
|
+
return target if parent.kind_of? Document or parent.nil?
|
|
449
|
+
target = parent
|
|
450
|
+
end
|
|
451
|
+
nil
|
|
455
452
|
end
|
|
456
453
|
|
|
457
454
|
# :call-seq:
|
|
@@ -476,8 +473,7 @@ module REXML
|
|
|
476
473
|
# Related: #root, #root_node.
|
|
477
474
|
#
|
|
478
475
|
def document
|
|
479
|
-
|
|
480
|
-
rt.parent if rt
|
|
476
|
+
root&.parent
|
|
481
477
|
end
|
|
482
478
|
|
|
483
479
|
# :call-seq:
|
|
@@ -569,7 +565,7 @@ module REXML
|
|
|
569
565
|
prefixes = []
|
|
570
566
|
prefixes = parent.prefixes if parent
|
|
571
567
|
prefixes |= attributes.prefixes
|
|
572
|
-
|
|
568
|
+
prefixes
|
|
573
569
|
end
|
|
574
570
|
|
|
575
571
|
# :call-seq:
|
|
@@ -592,10 +588,12 @@ module REXML
|
|
|
592
588
|
# d.elements['//c'].namespaces # => {"x"=>"1", "y"=>"2", "z"=>"3"}
|
|
593
589
|
#
|
|
594
590
|
def namespaces
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
591
|
+
namespaces_cache = document&.__send__(:namespaces_cache)
|
|
592
|
+
if namespaces_cache
|
|
593
|
+
namespaces_cache[self] ||= calculate_namespaces
|
|
594
|
+
else
|
|
595
|
+
calculate_namespaces
|
|
596
|
+
end
|
|
599
597
|
end
|
|
600
598
|
|
|
601
599
|
# :call-seq:
|
|
@@ -622,15 +620,11 @@ module REXML
|
|
|
622
620
|
if prefix.nil?
|
|
623
621
|
prefix = prefix()
|
|
624
622
|
end
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
prefix = "xmlns:#{prefix}" unless prefix[0,5] == 'xmlns'
|
|
629
|
-
end
|
|
630
|
-
ns = attributes[ prefix ]
|
|
631
|
-
ns = parent.namespace(prefix) if ns.nil? and parent
|
|
623
|
+
prefix = (prefix == '') ? 'xmlns' : prefix.delete_prefix("xmlns:")
|
|
624
|
+
ns = namespaces[prefix]
|
|
625
|
+
|
|
632
626
|
ns = '' if ns.nil? and prefix == 'xmlns'
|
|
633
|
-
|
|
627
|
+
ns
|
|
634
628
|
end
|
|
635
629
|
|
|
636
630
|
# :call-seq:
|
|
@@ -962,7 +956,7 @@ module REXML
|
|
|
962
956
|
def next_element
|
|
963
957
|
element = next_sibling
|
|
964
958
|
element = element.next_sibling until element.nil? or element.kind_of? Element
|
|
965
|
-
|
|
959
|
+
element
|
|
966
960
|
end
|
|
967
961
|
|
|
968
962
|
# :call-seq:
|
|
@@ -978,7 +972,7 @@ module REXML
|
|
|
978
972
|
def previous_element
|
|
979
973
|
element = previous_sibling
|
|
980
974
|
element = element.previous_sibling until element.nil? or element.kind_of? Element
|
|
981
|
-
|
|
975
|
+
element
|
|
982
976
|
end
|
|
983
977
|
|
|
984
978
|
|
|
@@ -989,7 +983,7 @@ module REXML
|
|
|
989
983
|
# :call-seq:
|
|
990
984
|
# has_text? -> true or false
|
|
991
985
|
#
|
|
992
|
-
# Returns +true if the element has one or more text noded,
|
|
986
|
+
# Returns +true+ if the element has one or more text noded,
|
|
993
987
|
# +false+ otherwise:
|
|
994
988
|
#
|
|
995
989
|
# d = REXML::Document.new '<a><b/>text<c/></a>'
|
|
@@ -1006,7 +1000,7 @@ module REXML
|
|
|
1006
1000
|
# text(xpath = nil) -> text_string or nil
|
|
1007
1001
|
#
|
|
1008
1002
|
# Returns the text string from the first text node child
|
|
1009
|
-
# in a specified element, if it exists,
|
|
1003
|
+
# in a specified element, if it exists, +nil+ otherwise.
|
|
1010
1004
|
#
|
|
1011
1005
|
# With no argument, returns the text from the first text node in +self+:
|
|
1012
1006
|
#
|
|
@@ -1014,7 +1008,7 @@ module REXML
|
|
|
1014
1008
|
# d.root.text.class # => String
|
|
1015
1009
|
# d.root.text # => "some text "
|
|
1016
1010
|
#
|
|
1017
|
-
# With argument +xpath+, returns text from the
|
|
1011
|
+
# With argument +xpath+, returns text from the first text node
|
|
1018
1012
|
# in the element that matches +xpath+:
|
|
1019
1013
|
#
|
|
1020
1014
|
# d.root.text(1) # => "this is bold!"
|
|
@@ -1028,8 +1022,7 @@ module REXML
|
|
|
1028
1022
|
#
|
|
1029
1023
|
def text( path = nil )
|
|
1030
1024
|
rv = get_text(path)
|
|
1031
|
-
|
|
1032
|
-
nil
|
|
1025
|
+
rv&.value
|
|
1033
1026
|
end
|
|
1034
1027
|
|
|
1035
1028
|
# :call-seq:
|
|
@@ -1057,7 +1050,7 @@ module REXML
|
|
|
1057
1050
|
else
|
|
1058
1051
|
rv = @children.find { |node| node.kind_of? Text }
|
|
1059
1052
|
end
|
|
1060
|
-
|
|
1053
|
+
rv
|
|
1061
1054
|
end
|
|
1062
1055
|
|
|
1063
1056
|
# :call-seq:
|
|
@@ -1101,7 +1094,7 @@ module REXML
|
|
|
1101
1094
|
old_text.replace_with( text )
|
|
1102
1095
|
end
|
|
1103
1096
|
end
|
|
1104
|
-
|
|
1097
|
+
self
|
|
1105
1098
|
end
|
|
1106
1099
|
|
|
1107
1100
|
# :call-seq:
|
|
@@ -1152,7 +1145,7 @@ module REXML
|
|
|
1152
1145
|
text = Text.new( text, whitespace(), nil, raw() )
|
|
1153
1146
|
end
|
|
1154
1147
|
self << text unless text.nil?
|
|
1155
|
-
|
|
1148
|
+
self
|
|
1156
1149
|
end
|
|
1157
1150
|
|
|
1158
1151
|
# :call-seq:
|
|
@@ -1196,7 +1189,7 @@ module REXML
|
|
|
1196
1189
|
cur = cur.parent
|
|
1197
1190
|
path_elements << __to_xpath_helper( cur )
|
|
1198
1191
|
end
|
|
1199
|
-
|
|
1192
|
+
path_elements.reverse.join( "/" )
|
|
1200
1193
|
end
|
|
1201
1194
|
|
|
1202
1195
|
#################################################
|
|
@@ -1284,16 +1277,11 @@ module REXML
|
|
|
1284
1277
|
# document.root.attribute("x", "a") # => a:x='a:x'
|
|
1285
1278
|
#
|
|
1286
1279
|
def attribute( name, namespace=nil )
|
|
1287
|
-
prefix =
|
|
1288
|
-
if namespaces.respond_to? :key
|
|
1289
|
-
prefix = namespaces.key(namespace) if namespace
|
|
1290
|
-
else
|
|
1291
|
-
prefix = namespaces.index(namespace) if namespace
|
|
1292
|
-
end
|
|
1280
|
+
prefix = namespaces.key(namespace) if namespace
|
|
1293
1281
|
prefix = nil if prefix == 'xmlns'
|
|
1294
1282
|
|
|
1295
1283
|
ret_val =
|
|
1296
|
-
attributes.get_attribute(
|
|
1284
|
+
attributes.get_attribute( prefix ? "#{prefix}:#{name}" : name )
|
|
1297
1285
|
|
|
1298
1286
|
return ret_val unless ret_val.nil?
|
|
1299
1287
|
return nil if prefix.nil?
|
|
@@ -1303,7 +1291,6 @@ module REXML
|
|
|
1303
1291
|
return nil unless ( namespaces[ prefix ] == namespaces[ 'xmlns' ] )
|
|
1304
1292
|
|
|
1305
1293
|
attributes.get_attribute( name )
|
|
1306
|
-
|
|
1307
1294
|
end
|
|
1308
1295
|
|
|
1309
1296
|
# :call-seq:
|
|
@@ -1317,7 +1304,7 @@ module REXML
|
|
|
1317
1304
|
# b.has_attributes? # => false
|
|
1318
1305
|
#
|
|
1319
1306
|
def has_attributes?
|
|
1320
|
-
|
|
1307
|
+
!@attributes.empty?
|
|
1321
1308
|
end
|
|
1322
1309
|
|
|
1323
1310
|
# :call-seq:
|
|
@@ -1506,7 +1493,7 @@ module REXML
|
|
|
1506
1493
|
# doc.write( out ) #-> doc is written to the string 'out'
|
|
1507
1494
|
# doc.write( $stdout ) #-> doc written to the console
|
|
1508
1495
|
def write(output=$stdout, indent=-1, transitive=false, ie_hack=false)
|
|
1509
|
-
Kernel.warn("#{self.class.name}
|
|
1496
|
+
Kernel.warn("#{self.class.name}#write is deprecated. See REXML::Formatters", uplevel: 1)
|
|
1510
1497
|
formatter = if indent > -1
|
|
1511
1498
|
if transitive
|
|
1512
1499
|
require_relative "formatters/transitive"
|
|
@@ -1520,8 +1507,15 @@ module REXML
|
|
|
1520
1507
|
formatter.write( self, output )
|
|
1521
1508
|
end
|
|
1522
1509
|
|
|
1523
|
-
|
|
1524
1510
|
private
|
|
1511
|
+
def calculate_namespaces
|
|
1512
|
+
if parent
|
|
1513
|
+
parent.namespaces.merge(attributes.namespaces)
|
|
1514
|
+
else
|
|
1515
|
+
attributes.namespaces
|
|
1516
|
+
end
|
|
1517
|
+
end
|
|
1518
|
+
|
|
1525
1519
|
def __to_xpath_helper node
|
|
1526
1520
|
rv = node.expanded_name.clone
|
|
1527
1521
|
if node.parent
|
|
@@ -1688,11 +1682,7 @@ module REXML
|
|
|
1688
1682
|
(num += 1) == index
|
|
1689
1683
|
}
|
|
1690
1684
|
else
|
|
1691
|
-
|
|
1692
|
-
#{ |element|
|
|
1693
|
-
# return element if element.kind_of? Element
|
|
1694
|
-
#}
|
|
1695
|
-
#return nil
|
|
1685
|
+
XPath::first( @element, index )
|
|
1696
1686
|
end
|
|
1697
1687
|
end
|
|
1698
1688
|
|
|
@@ -1739,7 +1729,7 @@ module REXML
|
|
|
1739
1729
|
else
|
|
1740
1730
|
previous.replace_with element
|
|
1741
1731
|
end
|
|
1742
|
-
|
|
1732
|
+
previous
|
|
1743
1733
|
end
|
|
1744
1734
|
|
|
1745
1735
|
# :call-seq:
|
|
@@ -1778,7 +1768,7 @@ module REXML
|
|
|
1778
1768
|
child == element
|
|
1779
1769
|
end
|
|
1780
1770
|
return rv if found == element
|
|
1781
|
-
|
|
1771
|
+
-1
|
|
1782
1772
|
end
|
|
1783
1773
|
|
|
1784
1774
|
# :call-seq:
|
|
@@ -1857,7 +1847,7 @@ module REXML
|
|
|
1857
1847
|
@element.delete element
|
|
1858
1848
|
element.remove
|
|
1859
1849
|
end
|
|
1860
|
-
|
|
1850
|
+
rv
|
|
1861
1851
|
end
|
|
1862
1852
|
|
|
1863
1853
|
# :call-seq:
|
|
@@ -2184,8 +2174,7 @@ module REXML
|
|
|
2184
2174
|
#
|
|
2185
2175
|
def [](name)
|
|
2186
2176
|
attr = get_attribute(name)
|
|
2187
|
-
|
|
2188
|
-
return nil
|
|
2177
|
+
attr&.value
|
|
2189
2178
|
end
|
|
2190
2179
|
|
|
2191
2180
|
# :call-seq:
|
|
@@ -2328,11 +2317,11 @@ module REXML
|
|
|
2328
2317
|
return attr
|
|
2329
2318
|
end
|
|
2330
2319
|
end
|
|
2331
|
-
|
|
2332
|
-
if
|
|
2320
|
+
doctype = @element.document&.doctype
|
|
2321
|
+
if doctype
|
|
2333
2322
|
expn = @element.expanded_name
|
|
2334
|
-
expn =
|
|
2335
|
-
attr_val =
|
|
2323
|
+
expn = doctype.name if expn.size == 0
|
|
2324
|
+
attr_val = doctype.attribute_of(expn, name)
|
|
2336
2325
|
return Attribute.new( name, attr_val ) if attr_val
|
|
2337
2326
|
end
|
|
2338
2327
|
return nil
|
|
@@ -2340,7 +2329,7 @@ module REXML
|
|
|
2340
2329
|
if attr.kind_of? Hash
|
|
2341
2330
|
attr = attr[ @element.prefix ]
|
|
2342
2331
|
end
|
|
2343
|
-
|
|
2332
|
+
attr
|
|
2344
2333
|
end
|
|
2345
2334
|
|
|
2346
2335
|
# :call-seq:
|
|
@@ -2374,8 +2363,9 @@ module REXML
|
|
|
2374
2363
|
end
|
|
2375
2364
|
|
|
2376
2365
|
unless value.kind_of? Attribute
|
|
2377
|
-
|
|
2378
|
-
|
|
2366
|
+
doctype = @element.document&.doctype
|
|
2367
|
+
if doctype
|
|
2368
|
+
value = Text::normalize( value, doctype )
|
|
2379
2369
|
else
|
|
2380
2370
|
value = Text::normalize( value, nil )
|
|
2381
2371
|
end
|
|
@@ -2388,23 +2378,12 @@ module REXML
|
|
|
2388
2378
|
elsif old_attr.kind_of? Hash
|
|
2389
2379
|
old_attr[value.prefix] = value
|
|
2390
2380
|
elsif old_attr.prefix != value.prefix
|
|
2391
|
-
# Check for conflicting namespaces
|
|
2392
|
-
if value.prefix != "xmlns" and old_attr.prefix != "xmlns"
|
|
2393
|
-
old_namespace = old_attr.namespace
|
|
2394
|
-
new_namespace = value.namespace
|
|
2395
|
-
if old_namespace == new_namespace
|
|
2396
|
-
raise ParseException.new(
|
|
2397
|
-
"Namespace conflict in adding attribute \"#{value.name}\": "+
|
|
2398
|
-
"Prefix \"#{old_attr.prefix}\" = \"#{old_namespace}\" and "+
|
|
2399
|
-
"prefix \"#{value.prefix}\" = \"#{new_namespace}\"")
|
|
2400
|
-
end
|
|
2401
|
-
end
|
|
2402
2381
|
store value.name, {old_attr.prefix => old_attr,
|
|
2403
2382
|
value.prefix => value}
|
|
2404
2383
|
else
|
|
2405
2384
|
store value.name, value
|
|
2406
2385
|
end
|
|
2407
|
-
|
|
2386
|
+
@element
|
|
2408
2387
|
end
|
|
2409
2388
|
|
|
2410
2389
|
# :call-seq:
|
|
@@ -2423,10 +2402,11 @@ module REXML
|
|
|
2423
2402
|
each_attribute do |attribute|
|
|
2424
2403
|
ns << attribute.name if attribute.prefix == 'xmlns'
|
|
2425
2404
|
end
|
|
2426
|
-
|
|
2405
|
+
doctype = @element.document&.doctype
|
|
2406
|
+
if doctype
|
|
2427
2407
|
expn = @element.expanded_name
|
|
2428
|
-
expn =
|
|
2429
|
-
|
|
2408
|
+
expn = doctype.name if expn.size == 0
|
|
2409
|
+
doctype.attributes_of(expn).each {
|
|
2430
2410
|
|attribute|
|
|
2431
2411
|
ns << attribute.name if attribute.prefix == 'xmlns'
|
|
2432
2412
|
}
|
|
@@ -2448,10 +2428,11 @@ module REXML
|
|
|
2448
2428
|
each_attribute do |attribute|
|
|
2449
2429
|
namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
|
|
2450
2430
|
end
|
|
2451
|
-
|
|
2431
|
+
doctype = @element.document&.doctype
|
|
2432
|
+
if doctype
|
|
2452
2433
|
expn = @element.expanded_name
|
|
2453
|
-
expn =
|
|
2454
|
-
|
|
2434
|
+
expn = doctype.name if expn.size == 0
|
|
2435
|
+
doctype.attributes_of(expn).each {
|
|
2455
2436
|
|attribute|
|
|
2456
2437
|
namespaces[attribute.name] = attribute.value if attribute.prefix == 'xmlns' or attribute.name == 'xmlns'
|
|
2457
2438
|
}
|
|
@@ -2506,9 +2487,7 @@ module REXML
|
|
|
2506
2487
|
old.each_value{|v| repl = v}
|
|
2507
2488
|
store name, repl
|
|
2508
2489
|
end
|
|
2509
|
-
elsif old
|
|
2510
|
-
return @element
|
|
2511
|
-
else # the supplied attribute is a top-level one
|
|
2490
|
+
elsif old # the supplied attribute is a top-level one
|
|
2512
2491
|
super(name)
|
|
2513
2492
|
end
|
|
2514
2493
|
@element
|
|
@@ -2562,7 +2541,7 @@ module REXML
|
|
|
2562
2541
|
rv << attribute if attribute.expanded_name == name
|
|
2563
2542
|
}
|
|
2564
2543
|
rv.each{ |attr| attr.remove }
|
|
2565
|
-
|
|
2544
|
+
rv
|
|
2566
2545
|
end
|
|
2567
2546
|
|
|
2568
2547
|
# :call-seq:
|
data/lib/rexml/encoding.rb
CHANGED
|
@@ -5,7 +5,7 @@ module REXML
|
|
|
5
5
|
# ID ---> Encoding name
|
|
6
6
|
attr_reader :encoding
|
|
7
7
|
def encoding=(encoding)
|
|
8
|
-
encoding = encoding.name if encoding.is_a?(Encoding)
|
|
8
|
+
encoding = encoding.name if encoding.is_a?(::Encoding)
|
|
9
9
|
if encoding.is_a?(String)
|
|
10
10
|
original_encoding = encoding
|
|
11
11
|
encoding = find_encoding(encoding)
|
|
@@ -13,12 +13,9 @@ module REXML
|
|
|
13
13
|
raise ArgumentError, "Bad encoding name #{original_encoding}"
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
|
+
encoding = encoding.upcase if encoding
|
|
16
17
|
return false if defined?(@encoding) and encoding == @encoding
|
|
17
|
-
|
|
18
|
-
@encoding = encoding.upcase
|
|
19
|
-
else
|
|
20
|
-
@encoding = 'UTF-8'
|
|
21
|
-
end
|
|
18
|
+
@encoding = encoding || "UTF-8"
|
|
22
19
|
true
|
|
23
20
|
end
|
|
24
21
|
|