rubysl-rexml 1.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,17 +1,17 @@
|
|
1
1
|
require "rexml/child"
|
2
2
|
module REXML
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
module DTD
|
4
|
+
class ElementDecl < Child
|
5
|
+
START = "<!ELEMENT"
|
6
|
+
START_RE = /^\s*#{START}/um
|
7
|
+
PATTERN_RE = /^\s*(#{START}.*?)>/um
|
8
|
+
PATTERN_RE = /^\s*#{START}\s+((?:[:\w_][-\.\w_]*:)?[-!\*\.\w_]*)(.*?)>/
|
9
|
+
#\s*((((["']).*?\5)|[^\/'">]*)*?)(\/)?>/um, true)
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
def initialize match
|
12
|
+
@name = match[1]
|
13
|
+
@rest = match[2]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
17
|
end
|
data/lib/rexml/dtd/entitydecl.rb
CHANGED
@@ -1,56 +1,56 @@
|
|
1
1
|
require "rexml/child"
|
2
2
|
module REXML
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
3
|
+
module DTD
|
4
|
+
class EntityDecl < Child
|
5
|
+
START = "<!ENTITY"
|
6
|
+
START_RE = /^\s*#{START}/um
|
7
|
+
PUBLIC = /^\s*#{START}\s+(?:%\s+)?(\w+)\s+PUBLIC\s+((["']).*?\3)\s+((["']).*?\5)\s*>/um
|
8
|
+
SYSTEM = /^\s*#{START}\s+(?:%\s+)?(\w+)\s+SYSTEM\s+((["']).*?\3)(?:\s+NDATA\s+\w+)?\s*>/um
|
9
|
+
PLAIN = /^\s*#{START}\s+(\w+)\s+((["']).*?\3)\s*>/um
|
10
|
+
PERCENT = /^\s*#{START}\s+%\s+(\w+)\s+((["']).*?\3)\s*>/um
|
11
|
+
# <!ENTITY name SYSTEM "...">
|
12
|
+
# <!ENTITY name "...">
|
13
|
+
def initialize src
|
14
|
+
super()
|
15
|
+
md = nil
|
16
|
+
if src.match( PUBLIC )
|
17
|
+
md = src.match( PUBLIC, true )
|
18
|
+
@middle = "PUBLIC"
|
19
|
+
@content = "#{md[2]} #{md[4]}"
|
20
|
+
elsif src.match( SYSTEM )
|
21
|
+
md = src.match( SYSTEM, true )
|
22
|
+
@middle = "SYSTEM"
|
23
|
+
@content = md[2]
|
24
|
+
elsif src.match( PLAIN )
|
25
|
+
md = src.match( PLAIN, true )
|
26
|
+
@middle = ""
|
27
|
+
@content = md[2]
|
28
|
+
elsif src.match( PERCENT )
|
29
|
+
md = src.match( PERCENT, true )
|
30
|
+
@middle = ""
|
31
|
+
@content = md[2]
|
32
|
+
end
|
33
|
+
raise ParseException.new("failed Entity match", src) if md.nil?
|
34
|
+
@name = md[1]
|
35
|
+
end
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
37
|
+
def to_s
|
38
|
+
rv = "<!ENTITY #@name "
|
39
|
+
rv << "#@middle " if @middle.size > 0
|
40
|
+
rv << @content
|
41
|
+
rv
|
42
|
+
end
|
43
43
|
|
44
|
-
|
44
|
+
def write( output, indent )
|
45
45
|
indent( output, indent )
|
46
|
-
|
47
|
-
|
46
|
+
output << to_s
|
47
|
+
end
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
49
|
+
def EntityDecl.parse_source source, listener
|
50
|
+
md = source.match( PATTERN_RE, true )
|
51
|
+
thing = md[0].squeeze(" \t\n\r")
|
52
|
+
listener.send inspect.downcase, thing
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
56
|
end
|
@@ -1,39 +1,39 @@
|
|
1
1
|
require "rexml/child"
|
2
2
|
module REXML
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
3
|
+
module DTD
|
4
|
+
class NotationDecl < Child
|
5
|
+
START = "<!NOTATION"
|
6
|
+
START_RE = /^\s*#{START}/um
|
7
|
+
PUBLIC = /^\s*#{START}\s+(\w[\w-]*)\s+(PUBLIC)\s+((["']).*?\4)\s*>/um
|
8
|
+
SYSTEM = /^\s*#{START}\s+(\w[\w-]*)\s+(SYSTEM)\s+((["']).*?\4)\s*>/um
|
9
|
+
def initialize src
|
10
|
+
super()
|
11
|
+
if src.match( PUBLIC )
|
12
|
+
md = src.match( PUBLIC, true )
|
13
|
+
elsif src.match( SYSTEM )
|
14
|
+
md = src.match( SYSTEM, true )
|
15
|
+
else
|
16
|
+
raise ParseException.new( "error parsing notation: no matching pattern", src )
|
17
|
+
end
|
18
|
+
@name = md[1]
|
19
|
+
@middle = md[2]
|
20
|
+
@rest = md[3]
|
21
|
+
end
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
def to_s
|
24
|
+
"<!NOTATION #@name #@middle #@rest>"
|
25
|
+
end
|
26
26
|
|
27
|
-
|
27
|
+
def write( output, indent )
|
28
28
|
indent( output, indent )
|
29
|
-
|
30
|
-
|
29
|
+
output << to_s
|
30
|
+
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
32
|
+
def NotationDecl.parse_source source, listener
|
33
|
+
md = source.match( PATTERN_RE, true )
|
34
|
+
thing = md[0].squeeze(" \t\n\r")
|
35
|
+
listener.send inspect.downcase, thing
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
39
|
end
|
data/lib/rexml/element.rb
CHANGED
@@ -20,7 +20,7 @@ module REXML
|
|
20
20
|
class Element < Parent
|
21
21
|
include Namespace
|
22
22
|
|
23
|
-
UNDEFINED = "UNDEFINED";
|
23
|
+
UNDEFINED = "UNDEFINED"; # The default name
|
24
24
|
|
25
25
|
# Mechanisms for accessing attributes and child elements of this
|
26
26
|
# element.
|
@@ -30,18 +30,18 @@ module REXML
|
|
30
30
|
attr_accessor :context
|
31
31
|
|
32
32
|
# Constructor
|
33
|
-
# arg::
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
# parent::
|
40
|
-
#
|
41
|
-
#
|
33
|
+
# arg::
|
34
|
+
# if not supplied, will be set to the default value.
|
35
|
+
# If a String, the name of this object will be set to the argument.
|
36
|
+
# If an Element, the object will be shallowly cloned; name,
|
37
|
+
# attributes, and namespaces will be copied. Children will +not+ be
|
38
|
+
# copied.
|
39
|
+
# parent::
|
40
|
+
# if supplied, must be a Parent, and will be used as
|
41
|
+
# the parent of this object.
|
42
42
|
# context::
|
43
|
-
#
|
44
|
-
#
|
43
|
+
# If supplied, must be a hash containing context items. Context items
|
44
|
+
# include:
|
45
45
|
# * <tt>:respect_whitespace</tt> the value of this is :+all+ or an array of
|
46
46
|
# strings being the names of the elements to respect
|
47
47
|
# whitespace for. Defaults to :+all+.
|
@@ -97,7 +97,7 @@ module REXML
|
|
97
97
|
self.class.new self
|
98
98
|
end
|
99
99
|
|
100
|
-
# Evaluates to the root node of the document that this element
|
100
|
+
# Evaluates to the root node of the document that this element
|
101
101
|
# belongs to. If this element doesn't belong to a document, but does
|
102
102
|
# belong to another Element, the parent's root will be returned, until the
|
103
103
|
# earliest ancestor is found.
|
@@ -137,8 +137,8 @@ module REXML
|
|
137
137
|
# is the case if:
|
138
138
|
# 1. Neither :+respect_whitespace+ nor :+compress_whitespace+ has any value
|
139
139
|
# 2. The context has :+respect_whitespace+ set to :+all+ or
|
140
|
-
# an array containing the name of this element, and
|
141
|
-
# :+compress_whitespace+ isn't set to :+all+ or an array containing the
|
140
|
+
# an array containing the name of this element, and
|
141
|
+
# :+compress_whitespace+ isn't set to :+all+ or an array containing the
|
142
142
|
# name of this element.
|
143
143
|
# The evaluation is tested against +expanded_name+, and so is namespace
|
144
144
|
# sensitive.
|
@@ -162,7 +162,7 @@ module REXML
|
|
162
162
|
@ignore_whitespace_nodes = false
|
163
163
|
if @context
|
164
164
|
if @context[:ignore_whitespace_nodes]
|
165
|
-
@ignore_whitespace_nodes =
|
165
|
+
@ignore_whitespace_nodes =
|
166
166
|
(@context[:ignore_whitespace_nodes] == :all or
|
167
167
|
@context[:ignore_whitespace_nodes].include? expanded_name)
|
168
168
|
end
|
@@ -206,13 +206,13 @@ module REXML
|
|
206
206
|
return namespaces
|
207
207
|
end
|
208
208
|
|
209
|
-
# Evalutas to the URI for a prefix, or the empty string if no such
|
209
|
+
# Evalutas to the URI for a prefix, or the empty string if no such
|
210
210
|
# namespace is declared for this element. Evaluates recursively for
|
211
211
|
# ancestors. Returns the default namespace, if there is one.
|
212
|
-
# prefix::
|
212
|
+
# prefix::
|
213
213
|
# the prefix to search for. If not supplied, returns the default
|
214
214
|
# namespace if one exists
|
215
|
-
# Returns::
|
215
|
+
# Returns::
|
216
216
|
# the namespace URI as a String, or nil if no such namespace
|
217
217
|
# exists. If the namespace is undefined, returns an empty string
|
218
218
|
# doc = Document.new("<a xmlns='1' xmlns:y='2'><b/><c xmlns:z='3'/></a>")
|
@@ -235,10 +235,10 @@ module REXML
|
|
235
235
|
end
|
236
236
|
|
237
237
|
# Adds a namespace to this element.
|
238
|
-
# prefix::
|
238
|
+
# prefix::
|
239
239
|
# the prefix string, or the namespace URI if +uri+ is not
|
240
240
|
# supplied
|
241
|
-
# uri::
|
241
|
+
# uri::
|
242
242
|
# the namespace URI. May be nil, in which +prefix+ is used as
|
243
243
|
# the URI
|
244
244
|
# Evaluates to: this Element
|
@@ -280,12 +280,12 @@ module REXML
|
|
280
280
|
|
281
281
|
# Adds a child to this element, optionally setting attributes in
|
282
282
|
# the element.
|
283
|
-
# element::
|
283
|
+
# element::
|
284
284
|
# optional. If Element, the element is added.
|
285
285
|
# Otherwise, a new Element is constructed with the argument (see
|
286
286
|
# Element.initialize).
|
287
|
-
# attrs::
|
288
|
-
# If supplied, must be a Hash containing String name,value
|
287
|
+
# attrs::
|
288
|
+
# If supplied, must be a Hash containing String name,value
|
289
289
|
# pairs, which will be used to set the attributes of the new Element.
|
290
290
|
# Returns:: the Element that was added
|
291
291
|
# el = doc.add_element 'my-tag'
|
@@ -296,15 +296,15 @@ module REXML
|
|
296
296
|
raise "First argument must be either an element name, or an Element object" if element.nil?
|
297
297
|
el = @elements.add(element)
|
298
298
|
attrs.each do |key, value|
|
299
|
-
el.attributes[key]=
|
300
|
-
end
|
299
|
+
el.attributes[key]=value
|
300
|
+
end if attrs.kind_of? Hash
|
301
301
|
el
|
302
302
|
end
|
303
303
|
|
304
304
|
# Deletes a child element.
|
305
|
-
# element::
|
306
|
-
# Must be an +Element+, +String+, or +Integer+. If Element,
|
307
|
-
# the element is removed. If String, the element is found (via XPath)
|
305
|
+
# element::
|
306
|
+
# Must be an +Element+, +String+, or +Integer+. If Element,
|
307
|
+
# the element is removed. If String, the element is found (via XPath)
|
308
308
|
# and removed. <em>This means that any parent can remove any
|
309
309
|
# descendant.<em> If Integer, the Element indexed by that number will be
|
310
310
|
# removed.
|
@@ -327,14 +327,14 @@ module REXML
|
|
327
327
|
|
328
328
|
# Iterates through the child elements, yielding for each Element that
|
329
329
|
# has a particular attribute set.
|
330
|
-
# key::
|
330
|
+
# key::
|
331
331
|
# the name of the attribute to search for
|
332
|
-
# value::
|
332
|
+
# value::
|
333
333
|
# the value of the attribute
|
334
|
-
# max::
|
335
|
-
# (optional) causes this method to return after yielding
|
334
|
+
# max::
|
335
|
+
# (optional) causes this method to return after yielding
|
336
336
|
# for this number of matching children
|
337
|
-
# name::
|
337
|
+
# name::
|
338
338
|
# (optional) if supplied, this is an XPath that filters
|
339
339
|
# the children to check.
|
340
340
|
#
|
@@ -348,7 +348,7 @@ module REXML
|
|
348
348
|
# # Yields d
|
349
349
|
# doc.root.each_element_with_attribute( 'id', '1', 0, 'd' ) {|e| p e}
|
350
350
|
def each_element_with_attribute( key, value=nil, max=0, name=nil, &block ) # :yields: Element
|
351
|
-
each_with_something( proc {|child|
|
351
|
+
each_with_something( proc {|child|
|
352
352
|
if value.nil?
|
353
353
|
child.attributes[key] != nil
|
354
354
|
else
|
@@ -359,13 +359,13 @@ module REXML
|
|
359
359
|
|
360
360
|
# Iterates through the children, yielding for each Element that
|
361
361
|
# has a particular text set.
|
362
|
-
# text::
|
362
|
+
# text::
|
363
363
|
# the text to search for. If nil, or not supplied, will iterate
|
364
364
|
# over all +Element+ children that contain at least one +Text+ node.
|
365
|
-
# max::
|
365
|
+
# max::
|
366
366
|
# (optional) causes this method to return after yielding
|
367
367
|
# for this number of matching children
|
368
|
-
# name::
|
368
|
+
# name::
|
369
369
|
# (optional) if supplied, this is an XPath that filters
|
370
370
|
# the children to check.
|
371
371
|
#
|
@@ -379,7 +379,7 @@ module REXML
|
|
379
379
|
# # Yields d
|
380
380
|
# doc.each_element_with_text(nil, 0, 'd'){|e|p e}
|
381
381
|
def each_element_with_text( text=nil, max=0, name=nil, &block ) # :yields: Element
|
382
|
-
each_with_something( proc {|child|
|
382
|
+
each_with_something( proc {|child|
|
383
383
|
if text.nil?
|
384
384
|
child.has_text?
|
385
385
|
else
|
@@ -408,7 +408,7 @@ module REXML
|
|
408
408
|
# doc.root.elements['c'].next_element #-> nil
|
409
409
|
def next_element
|
410
410
|
element = next_sibling
|
411
|
-
element = element.next_sibling until element.nil? or element.kind_of? Element
|
411
|
+
element = element.next_sibling until element.nil? or element.kind_of? Element
|
412
412
|
return element
|
413
413
|
end
|
414
414
|
|
@@ -477,7 +477,7 @@ module REXML
|
|
477
477
|
# this method with a nil argument. In this case, the next Text
|
478
478
|
# child becomes the first Text child. In no case is the order of
|
479
479
|
# any siblings disturbed.
|
480
|
-
# text::
|
480
|
+
# text::
|
481
481
|
# If a String, a new Text child is created and added to
|
482
482
|
# this Element as the first Text child. If Text, the text is set
|
483
483
|
# as the first Child element. If nil, then any existing first Text
|
@@ -520,7 +520,7 @@ module REXML
|
|
520
520
|
# Note that at the end of this example, the branch has <b>3</b> nodes; the 'e'
|
521
521
|
# element and <b>2</b> Text node children.
|
522
522
|
def add_text( text )
|
523
|
-
if text.kind_of? String
|
523
|
+
if text.kind_of? String
|
524
524
|
if @children[-1].kind_of? Text
|
525
525
|
@children[-1] << text
|
526
526
|
return
|
@@ -552,9 +552,25 @@ module REXML
|
|
552
552
|
|
553
553
|
def attribute( name, namespace=nil )
|
554
554
|
prefix = nil
|
555
|
-
|
555
|
+
if namespaces.respond_to? :key
|
556
|
+
prefix = namespaces.key(namespace) if namespace
|
557
|
+
else
|
558
|
+
prefix = namespaces.index(namespace) if namespace
|
559
|
+
end
|
556
560
|
prefix = nil if prefix == 'xmlns'
|
557
|
-
|
561
|
+
|
562
|
+
ret_val =
|
563
|
+
attributes.get_attribute( "#{prefix ? prefix + ':' : ''}#{name}" )
|
564
|
+
|
565
|
+
return ret_val unless ret_val.nil?
|
566
|
+
return nil if prefix.nil?
|
567
|
+
|
568
|
+
# now check that prefix'es namespace is not the same as the
|
569
|
+
# default namespace
|
570
|
+
return nil unless ( namespaces[ prefix ] == namespaces[ 'xmlns' ] )
|
571
|
+
|
572
|
+
attributes.get_attribute( name )
|
573
|
+
|
558
574
|
end
|
559
575
|
|
560
576
|
# Evaluates to +true+ if this element has any attributes set, false
|
@@ -570,7 +586,7 @@ module REXML
|
|
570
586
|
# the attribute is added to the list of Element attributes. If String,
|
571
587
|
# the argument is used as the name of the new attribute, and the value
|
572
588
|
# parameter must be supplied.
|
573
|
-
# value::
|
589
|
+
# value::
|
574
590
|
# Required if +key+ is a String, and ignored if the first argument is
|
575
591
|
# an Attribute. This is a String, and is used as the value
|
576
592
|
# of the new Attribute. This should be the unnormalized value of the
|
@@ -605,7 +621,7 @@ module REXML
|
|
605
621
|
# either an Attribute or a String. In either case, the
|
606
622
|
# attribute is found by matching the attribute name to the argument,
|
607
623
|
# and then removed. If no attribute is found, no action is taken.
|
608
|
-
# Returns::
|
624
|
+
# Returns::
|
609
625
|
# the attribute removed, or nil if this Element did not contain
|
610
626
|
# a matching attribute
|
611
627
|
# e = Element.new('E')
|
@@ -622,7 +638,7 @@ module REXML
|
|
622
638
|
# Other Utilities #
|
623
639
|
#################################################
|
624
640
|
|
625
|
-
# Get an array of all CData children.
|
641
|
+
# Get an array of all CData children.
|
626
642
|
# IMMUTABLE
|
627
643
|
def cdatas
|
628
644
|
find_all { |child| child.kind_of? CData }.freeze
|
@@ -651,7 +667,7 @@ module REXML
|
|
651
667
|
#
|
652
668
|
# Writes out this element, and recursively, all children.
|
653
669
|
# output::
|
654
|
-
#
|
670
|
+
# output an object which supports '<< string'; this is where the
|
655
671
|
# document will be written.
|
656
672
|
# indent::
|
657
673
|
# An integer. If -1, no indenting will be used; otherwise, the
|
@@ -662,19 +678,17 @@ module REXML
|
|
662
678
|
# pretty-printed in such a way that the added whitespace does not affect
|
663
679
|
# the parse tree of the document
|
664
680
|
# ie_hack::
|
665
|
-
#
|
666
|
-
#
|
667
|
-
# unable to parse proper XML, we have to provide a hack to generate XML
|
668
|
-
# that IE's limited abilities can handle. This hack inserts a space
|
669
|
-
# before the /> on empty tags. Defaults to false
|
681
|
+
# This hack inserts a space before the /> on empty tags to address
|
682
|
+
# a limitation of Internet Explorer. Defaults to false
|
670
683
|
#
|
671
684
|
# out = ''
|
672
685
|
# doc.write( out ) #-> doc is written to the string 'out'
|
673
686
|
# doc.write( $stdout ) #-> doc written to the console
|
674
|
-
def write(
|
687
|
+
def write(output=$stdout, indent=-1, transitive=false, ie_hack=false)
|
675
688
|
Kernel.warn("#{self.class.name}.write is deprecated. See REXML::Formatters")
|
676
689
|
formatter = if indent > -1
|
677
690
|
if transitive
|
691
|
+
require "rexml/formatters/transitive"
|
678
692
|
REXML::Formatters::Transitive.new( indent, ie_hack )
|
679
693
|
else
|
680
694
|
REXML::Formatters::Pretty.new( indent, ie_hack )
|
@@ -690,8 +704,8 @@ module REXML
|
|
690
704
|
def __to_xpath_helper node
|
691
705
|
rv = node.expanded_name.clone
|
692
706
|
if node.parent
|
693
|
-
results = node.parent.find_all {|n|
|
694
|
-
n.kind_of?(REXML::Element) and n.expanded_name == node.expanded_name
|
707
|
+
results = node.parent.find_all {|n|
|
708
|
+
n.kind_of?(REXML::Element) and n.expanded_name == node.expanded_name
|
695
709
|
}
|
696
710
|
if results.length > 1
|
697
711
|
idx = results.index( node )
|
@@ -704,7 +718,6 @@ module REXML
|
|
704
718
|
# A private helper method
|
705
719
|
def each_with_something( test, max=0, name=nil )
|
706
720
|
num = 0
|
707
|
-
child=nil
|
708
721
|
@elements.each( name ){ |child|
|
709
722
|
yield child if test.call(child) and num += 1
|
710
723
|
return if max>0 and num == max
|
@@ -718,7 +731,7 @@ module REXML
|
|
718
731
|
|
719
732
|
# A class which provides filtering of children for Elements, and
|
720
733
|
# XPath search support. You are expected to only encounter this class as
|
721
|
-
# the <tt>element.elements</tt> object. Therefore, you are
|
734
|
+
# the <tt>element.elements</tt> object. Therefore, you are
|
722
735
|
# _not_ expected to instantiate this yourself.
|
723
736
|
class Elements
|
724
737
|
include Enumerable
|
@@ -730,7 +743,7 @@ module REXML
|
|
730
743
|
|
731
744
|
# Fetches a child element. Filters only Element children, regardless of
|
732
745
|
# the XPath match.
|
733
|
-
# index::
|
746
|
+
# index::
|
734
747
|
# the search parameter. This is either an Integer, which
|
735
748
|
# will be used to find the index'th child Element, or an XPath,
|
736
749
|
# which will be used to search for the Element. <em>Because
|
@@ -740,7 +753,7 @@ module REXML
|
|
740
753
|
# child element is at index 1, not 0, and the +n+th element is at index
|
741
754
|
# +n+, not <tt>n-1</tt>. This is because XPath indexes element children
|
742
755
|
# starting from 1, not 0, and the indexes should be the same.
|
743
|
-
# name::
|
756
|
+
# name::
|
744
757
|
# optional, and only used in the first argument is an
|
745
758
|
# Integer. In that case, the index'th child Element that has the
|
746
759
|
# supplied name will be returned. Note again that the indexes start at 1.
|
@@ -754,16 +767,15 @@ module REXML
|
|
754
767
|
raise "index (#{index}) must be >= 1" if index < 1
|
755
768
|
name = literalize(name) if name
|
756
769
|
num = 0
|
757
|
-
child = nil
|
758
770
|
@element.find { |child|
|
759
771
|
child.kind_of? Element and
|
760
|
-
(name.nil? ? true : child.has_name?( name )) and
|
772
|
+
(name.nil? ? true : child.has_name?( name )) and
|
761
773
|
(num += 1) == index
|
762
774
|
}
|
763
775
|
else
|
764
776
|
return XPath::first( @element, index )
|
765
|
-
#{ |element|
|
766
|
-
#
|
777
|
+
#{ |element|
|
778
|
+
# return element if element.kind_of? Element
|
767
779
|
#}
|
768
780
|
#return nil
|
769
781
|
end
|
@@ -772,7 +784,7 @@ module REXML
|
|
772
784
|
# Sets an element, replacing any previous matching element. If no
|
773
785
|
# existing element is found ,the element is added.
|
774
786
|
# index:: Used to find a matching element to replace. See []().
|
775
|
-
# element::
|
787
|
+
# element::
|
776
788
|
# The element to replace the existing element with
|
777
789
|
# the previous element
|
778
790
|
# Returns:: nil if no previous element was found.
|
@@ -797,12 +809,12 @@ module REXML
|
|
797
809
|
@element.find{ |child| child.kind_of? Element}.nil?
|
798
810
|
end
|
799
811
|
|
800
|
-
# Returns the index of the supplied child (starting at 1), or -1 if
|
812
|
+
# Returns the index of the supplied child (starting at 1), or -1 if
|
801
813
|
# the element is not a child
|
802
814
|
# element:: an +Element+ child
|
803
815
|
def index element
|
804
816
|
rv = 0
|
805
|
-
found = @element.find do |child|
|
817
|
+
found = @element.find do |child|
|
806
818
|
child.kind_of? Element and
|
807
819
|
(rv += 1) and
|
808
820
|
child == element
|
@@ -812,7 +824,7 @@ module REXML
|
|
812
824
|
end
|
813
825
|
|
814
826
|
# Deletes a child Element
|
815
|
-
# element::
|
827
|
+
# element::
|
816
828
|
# Either an Element, which is removed directly; an
|
817
829
|
# xpath, where the first matching child is removed; or an Integer,
|
818
830
|
# where the n'th Element is removed.
|
@@ -839,7 +851,7 @@ module REXML
|
|
839
851
|
# deleted = doc.elements.delete_all 'a/c' #-> [<c/>, <c/>, <c/>, <c/>]
|
840
852
|
def delete_all( xpath )
|
841
853
|
rv = []
|
842
|
-
XPath::each( @element, xpath) {|element|
|
854
|
+
XPath::each( @element, xpath) {|element|
|
843
855
|
rv << element if element.kind_of? Element
|
844
856
|
}
|
845
857
|
rv.each do |element|
|
@@ -850,7 +862,7 @@ module REXML
|
|
850
862
|
end
|
851
863
|
|
852
864
|
# Adds an element
|
853
|
-
# element::
|
865
|
+
# element::
|
854
866
|
# if supplied, is either an Element, String, or
|
855
867
|
# Source (see Element.initialize). If not supplied or nil, a
|
856
868
|
# new, default Element will be constructed
|
@@ -859,7 +871,6 @@ module REXML
|
|
859
871
|
# a.elements.add(Element.new('b')) #-> <a><b/></a>
|
860
872
|
# a.elements.add('c') #-> <a><b/><c/></a>
|
861
873
|
def add element=nil
|
862
|
-
rv = nil
|
863
874
|
if element.nil?
|
864
875
|
Element.new("", self, @element.context)
|
865
876
|
elsif not element.kind_of?(Element)
|
@@ -875,31 +886,31 @@ module REXML
|
|
875
886
|
|
876
887
|
# Iterates through all of the child Elements, optionally filtering
|
877
888
|
# them by a given XPath
|
878
|
-
# xpath::
|
879
|
-
# optional. If supplied, this is a String XPath, and is used to
|
889
|
+
# xpath::
|
890
|
+
# optional. If supplied, this is a String XPath, and is used to
|
880
891
|
# filter the children, so that only matching children are yielded. Note
|
881
892
|
# that XPaths are automatically filtered for Elements, so that
|
882
893
|
# non-Element children will not be yielded
|
883
894
|
# doc = Document.new '<a><b/><c/><d/>sean<b/><c/><d/></a>'
|
884
|
-
# doc.root.each {|e|p e} #-> Yields b, c, d, b, c, d elements
|
885
|
-
# doc.root.each('b') {|e|p e} #-> Yields b, b elements
|
886
|
-
# doc.root.each('child::node()') {|e|p e}
|
895
|
+
# doc.root.elements.each {|e|p e} #-> Yields b, c, d, b, c, d elements
|
896
|
+
# doc.root.elements.each('b') {|e|p e} #-> Yields b, b elements
|
897
|
+
# doc.root.elements.each('child::node()') {|e|p e}
|
887
898
|
# #-> Yields <b/>, <c/>, <d/>, <b/>, <c/>, <d/>
|
888
899
|
# XPath.each(doc.root, 'child::node()', &block)
|
889
900
|
# #-> Yields <b/>, <c/>, <d/>, sean, <b/>, <c/>, <d/>
|
890
|
-
def each( xpath=nil
|
901
|
+
def each( xpath=nil )
|
891
902
|
XPath::each( @element, xpath ) {|e| yield e if e.kind_of? Element }
|
892
903
|
end
|
893
904
|
|
894
|
-
def collect( xpath=nil
|
905
|
+
def collect( xpath=nil )
|
895
906
|
collection = []
|
896
|
-
XPath::each( @element, xpath ) {|e|
|
897
|
-
collection << yield(e) if e.kind_of?(Element)
|
907
|
+
XPath::each( @element, xpath ) {|e|
|
908
|
+
collection << yield(e) if e.kind_of?(Element)
|
898
909
|
}
|
899
910
|
collection
|
900
911
|
end
|
901
912
|
|
902
|
-
def inject( xpath=nil, initial=nil
|
913
|
+
def inject( xpath=nil, initial=nil )
|
903
914
|
first = true
|
904
915
|
XPath::each( @element, xpath ) {|e|
|
905
916
|
if (e.kind_of? Element)
|
@@ -929,7 +940,7 @@ module REXML
|
|
929
940
|
# supplied XPath matches non-Element children.
|
930
941
|
# doc = Document.new '<a>sean<b/>elliott<c/></a>'
|
931
942
|
# doc.root.elements.to_a #-> [ <b/>, <c/> ]
|
932
|
-
# doc.root.elements.to_a("child::node()") #-> [ <b/>, <c/> ]
|
943
|
+
# doc.root.elements.to_a("child::node()") #-> [ <b/>, <c/> ]
|
933
944
|
# XPath.match(doc.root, "child::node()") #-> [ sean, <b/>, elliott, <c/> ]
|
934
945
|
def to_a( xpath=nil )
|
935
946
|
rv = XPath.match( @element, xpath )
|
@@ -949,7 +960,7 @@ module REXML
|
|
949
960
|
# ATTRIBUTES #
|
950
961
|
########################################################################
|
951
962
|
|
952
|
-
# A class that defines the set of Attributes of an Element and provides
|
963
|
+
# A class that defines the set of Attributes of an Element and provides
|
953
964
|
# operations for accessing elements in that set.
|
954
965
|
class Attributes < Hash
|
955
966
|
# Constructor
|
@@ -961,11 +972,11 @@ module REXML
|
|
961
972
|
# Fetches an attribute value. If you want to get the Attribute itself,
|
962
973
|
# use get_attribute()
|
963
974
|
# name:: an XPath attribute name. Namespaces are relevant here.
|
964
|
-
# Returns::
|
975
|
+
# Returns::
|
965
976
|
# the String value of the matching attribute, or +nil+ if no
|
966
977
|
# matching attribute was found. This is the unnormalized value
|
967
978
|
# (with entities expanded).
|
968
|
-
#
|
979
|
+
#
|
969
980
|
# doc = Document.new "<a foo:att='1' bar:att='2' att='<'/>"
|
970
981
|
# doc.root.attributes['att'] #-> '<'
|
971
982
|
# doc.root.attributes['bar:att'] #-> '2'
|
@@ -976,7 +987,7 @@ module REXML
|
|
976
987
|
end
|
977
988
|
|
978
989
|
def to_a
|
979
|
-
|
990
|
+
enum_for(:each_attribute).to_a
|
980
991
|
end
|
981
992
|
|
982
993
|
# Returns the number of attributes the owning Element contains.
|
@@ -991,7 +1002,7 @@ module REXML
|
|
991
1002
|
|
992
1003
|
# Iterates over the attributes of an Element. Yields actual Attribute
|
993
1004
|
# nodes, not String values.
|
994
|
-
#
|
1005
|
+
#
|
995
1006
|
# doc = Document.new '<a x="1" y="2"/>'
|
996
1007
|
# doc.root.attributes.each_attribute {|attr|
|
997
1008
|
# p attr.expanded_name+" => "+attr.value
|
@@ -1013,12 +1024,12 @@ module REXML
|
|
1013
1024
|
# doc.root.attributes.each {|name, value| p name+" => "+value }
|
1014
1025
|
def each
|
1015
1026
|
each_attribute do |attr|
|
1016
|
-
yield attr.expanded_name, attr.value
|
1027
|
+
yield [attr.expanded_name, attr.value]
|
1017
1028
|
end
|
1018
1029
|
end
|
1019
1030
|
|
1020
1031
|
# Fetches an attribute
|
1021
|
-
# name::
|
1032
|
+
# name::
|
1022
1033
|
# the name by which to search for the attribute. Can be a
|
1023
1034
|
# <tt>prefix:name</tt> namespace name.
|
1024
1035
|
# Returns:: The first matching attribute, or nil if there was none. This
|
@@ -1062,22 +1073,22 @@ module REXML
|
|
1062
1073
|
# Sets an attribute, overwriting any existing attribute value by the
|
1063
1074
|
# same name. Namespace is significant.
|
1064
1075
|
# name:: the name of the attribute
|
1065
|
-
# value::
|
1076
|
+
# value::
|
1066
1077
|
# (optional) If supplied, the value of the attribute. If
|
1067
1078
|
# nil, any existing matching attribute is deleted.
|
1068
|
-
# Returns::
|
1079
|
+
# Returns::
|
1069
1080
|
# Owning element
|
1070
1081
|
# doc = Document.new "<a x:foo='1' foo='3'/>"
|
1071
1082
|
# doc.root.attributes['y:foo'] = '2'
|
1072
1083
|
# doc.root.attributes['foo'] = '4'
|
1073
1084
|
# doc.root.attributes['x:foo'] = nil
|
1074
1085
|
def []=( name, value )
|
1075
|
-
if value.nil?
|
1086
|
+
if value.nil? # Delete the named attribute
|
1076
1087
|
attr = get_attribute(name)
|
1077
1088
|
delete attr
|
1078
1089
|
return
|
1079
1090
|
end
|
1080
|
-
|
1091
|
+
|
1081
1092
|
unless value.kind_of? Attribute
|
1082
1093
|
if @element.document and @element.document.doctype
|
1083
1094
|
value = Text::normalize( value, @element.document.doctype )
|
@@ -1094,23 +1105,23 @@ module REXML
|
|
1094
1105
|
old_attr[value.prefix] = value
|
1095
1106
|
elsif old_attr.prefix != value.prefix
|
1096
1107
|
# Check for conflicting namespaces
|
1097
|
-
raise ParseException.new(
|
1108
|
+
raise ParseException.new(
|
1098
1109
|
"Namespace conflict in adding attribute \"#{value.name}\": "+
|
1099
1110
|
"Prefix \"#{old_attr.prefix}\" = "+
|
1100
1111
|
"\"#{@element.namespace(old_attr.prefix)}\" and prefix "+
|
1101
|
-
"\"#{value.prefix}\" = \"#{@element.namespace(value.prefix)}\"") if
|
1112
|
+
"\"#{value.prefix}\" = \"#{@element.namespace(value.prefix)}\"") if
|
1102
1113
|
value.prefix != "xmlns" and old_attr.prefix != "xmlns" and
|
1103
|
-
@element.namespace( old_attr.prefix ) ==
|
1114
|
+
@element.namespace( old_attr.prefix ) ==
|
1104
1115
|
@element.namespace( value.prefix )
|
1105
|
-
store value.name, { old_attr.prefix
|
1106
|
-
value.prefix
|
1116
|
+
store value.name, { old_attr.prefix => old_attr,
|
1117
|
+
value.prefix => value }
|
1107
1118
|
else
|
1108
1119
|
store value.name, value
|
1109
1120
|
end
|
1110
1121
|
return @element
|
1111
1122
|
end
|
1112
1123
|
|
1113
|
-
# Returns an array of Strings containing all of the prefixes declared
|
1124
|
+
# Returns an array of Strings containing all of the prefixes declared
|
1114
1125
|
# by this set of # attributes. The array does not include the default
|
1115
1126
|
# namespace declaration, if one exists.
|
1116
1127
|
# doc = Document.new("<a xmlns='foo' xmlns:x='bar' xmlns:y='twee' "+
|
@@ -1149,7 +1160,7 @@ module REXML
|
|
1149
1160
|
end
|
1150
1161
|
|
1151
1162
|
# Removes an attribute
|
1152
|
-
# attribute::
|
1163
|
+
# attribute::
|
1153
1164
|
# either a String, which is the name of the attribute to remove --
|
1154
1165
|
# namespaces are significant here -- or the attribute to remove.
|
1155
1166
|
# Returns:: the owning element
|
@@ -1182,7 +1193,7 @@ module REXML
|
|
1182
1193
|
return @element
|
1183
1194
|
else # the supplied attribute is a top-level one
|
1184
1195
|
attr = old
|
1185
|
-
|
1196
|
+
super(name)
|
1186
1197
|
end
|
1187
1198
|
@element
|
1188
1199
|
end
|
@@ -1197,12 +1208,12 @@ module REXML
|
|
1197
1208
|
alias :<< :add
|
1198
1209
|
|
1199
1210
|
# Deletes all attributes matching a name. Namespaces are significant.
|
1200
|
-
# name::
|
1211
|
+
# name::
|
1201
1212
|
# A String; all attributes that match this path will be removed
|
1202
1213
|
# Returns:: an Array of the Attributes that were removed
|
1203
1214
|
def delete_all( name )
|
1204
1215
|
rv = []
|
1205
|
-
each_attribute { |attribute|
|
1216
|
+
each_attribute { |attribute|
|
1206
1217
|
rv << attribute if attribute.expanded_name == name
|
1207
1218
|
}
|
1208
1219
|
rv.each{ |attr| attr.remove }
|
@@ -1212,16 +1223,20 @@ module REXML
|
|
1212
1223
|
# The +get_attribute_ns+ method retrieves a method by its namespace
|
1213
1224
|
# and name. Thus it is possible to reliably identify an attribute
|
1214
1225
|
# even if an XML processor has changed the prefix.
|
1215
|
-
#
|
1226
|
+
#
|
1216
1227
|
# Method contributed by Henrik Martensson
|
1217
1228
|
def get_attribute_ns(namespace, name)
|
1229
|
+
result = nil
|
1218
1230
|
each_attribute() { |attribute|
|
1219
1231
|
if name == attribute.name &&
|
1220
|
-
namespace == attribute.namespace()
|
1221
|
-
|
1232
|
+
namespace == attribute.namespace() &&
|
1233
|
+
( !namespace.empty? || !attribute.fully_expanded_name.index(':') )
|
1234
|
+
# foo will match xmlns:foo, but only if foo isn't also an attribute
|
1235
|
+
result = attribute if !result or !namespace.empty? or
|
1236
|
+
!attribute.fully_expanded_name.index(':')
|
1222
1237
|
end
|
1223
1238
|
}
|
1224
|
-
|
1239
|
+
result
|
1225
1240
|
end
|
1226
1241
|
end
|
1227
1242
|
end
|