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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -2
  3. data/lib/rexml/attlistdecl.rb +56 -56
  4. data/lib/rexml/attribute.rb +155 -149
  5. data/lib/rexml/cdata.rb +48 -48
  6. data/lib/rexml/child.rb +82 -82
  7. data/lib/rexml/comment.rb +59 -59
  8. data/lib/rexml/doctype.rb +22 -24
  9. data/lib/rexml/document.rb +185 -129
  10. data/lib/rexml/dtd/attlistdecl.rb +7 -7
  11. data/lib/rexml/dtd/dtd.rb +41 -41
  12. data/lib/rexml/dtd/elementdecl.rb +13 -13
  13. data/lib/rexml/dtd/entitydecl.rb +49 -49
  14. data/lib/rexml/dtd/notationdecl.rb +32 -32
  15. data/lib/rexml/element.rb +122 -107
  16. data/lib/rexml/encoding.rb +37 -58
  17. data/lib/rexml/entity.rb +144 -144
  18. data/lib/rexml/formatters/default.rb +6 -4
  19. data/lib/rexml/formatters/pretty.rb +11 -8
  20. data/lib/rexml/formatters/transitive.rb +4 -3
  21. data/lib/rexml/functions.rb +33 -21
  22. data/lib/rexml/instruction.rb +49 -49
  23. data/lib/rexml/light/node.rb +190 -191
  24. data/lib/rexml/namespace.rb +39 -39
  25. data/lib/rexml/node.rb +38 -38
  26. data/lib/rexml/output.rb +17 -12
  27. data/lib/rexml/parent.rb +26 -25
  28. data/lib/rexml/parseexception.rb +4 -4
  29. data/lib/rexml/parsers/baseparser.rb +90 -61
  30. data/lib/rexml/parsers/lightparser.rb +41 -43
  31. data/lib/rexml/parsers/pullparser.rb +1 -1
  32. data/lib/rexml/parsers/sax2parser.rb +233 -198
  33. data/lib/rexml/parsers/streamparser.rb +6 -2
  34. data/lib/rexml/parsers/treeparser.rb +9 -6
  35. data/lib/rexml/parsers/ultralightparser.rb +40 -40
  36. data/lib/rexml/parsers/xpathparser.rb +51 -52
  37. data/lib/rexml/quickpath.rb +247 -248
  38. data/lib/rexml/rexml.rb +9 -10
  39. data/lib/rexml/sax2listener.rb +92 -92
  40. data/lib/rexml/security.rb +27 -0
  41. data/lib/rexml/source.rb +95 -50
  42. data/lib/rexml/streamlistener.rb +90 -90
  43. data/lib/rexml/syncenumerator.rb +3 -4
  44. data/lib/rexml/text.rb +157 -76
  45. data/lib/rexml/validation/relaxng.rb +18 -18
  46. data/lib/rexml/validation/validation.rb +5 -5
  47. data/lib/rexml/xmldecl.rb +59 -63
  48. data/lib/rexml/xmltokens.rb +14 -14
  49. data/lib/rexml/xpath.rb +67 -53
  50. data/lib/rexml/xpath_parser.rb +49 -38
  51. data/lib/rubysl/rexml.rb +1 -0
  52. data/lib/rubysl/rexml/version.rb +1 -1
  53. data/rubysl-rexml.gemspec +3 -1
  54. metadata +19 -28
  55. data/lib/rexml/encodings/CP-1252.rb +0 -103
  56. data/lib/rexml/encodings/EUC-JP.rb +0 -35
  57. data/lib/rexml/encodings/ICONV.rb +0 -22
  58. data/lib/rexml/encodings/ISO-8859-1.rb +0 -7
  59. data/lib/rexml/encodings/ISO-8859-15.rb +0 -72
  60. data/lib/rexml/encodings/SHIFT-JIS.rb +0 -37
  61. data/lib/rexml/encodings/SHIFT_JIS.rb +0 -1
  62. data/lib/rexml/encodings/UNILE.rb +0 -34
  63. data/lib/rexml/encodings/US-ASCII.rb +0 -30
  64. data/lib/rexml/encodings/UTF-16.rb +0 -35
  65. data/lib/rexml/encodings/UTF-8.rb +0 -18
@@ -12,9 +12,10 @@ module REXML
12
12
  # formatted. Since this formatter does not alter whitespace nodes, the
13
13
  # results of formatting already formatted XML will be odd.
14
14
  class Transitive < Default
15
- def initialize( indentation=2 )
15
+ def initialize( indentation=2, ie_hack=false )
16
16
  @indentation = indentation
17
17
  @level = 0
18
+ @ie_hack = ie_hack
18
19
  end
19
20
 
20
21
  protected
@@ -29,13 +30,13 @@ module REXML
29
30
  output << "\n"
30
31
  output << ' '*@level
31
32
  if node.children.empty?
32
- output << "/"
33
+ output << " " if @ie_hack
34
+ output << "/"
33
35
  else
34
36
  output << ">"
35
37
  # If compact and all children are text, and if the formatted output
36
38
  # is less than the specified width, then try to print everything on
37
39
  # one line
38
- skip = false
39
40
  @level += @indentation
40
41
  node.children.each { |child|
41
42
  write( child, output )
@@ -28,6 +28,7 @@ module REXML
28
28
  end
29
29
  end
30
30
 
31
+ # Returns the last node of the given list of nodes.
31
32
  def Functions::last( )
32
33
  @@context[:size]
33
34
  end
@@ -36,6 +37,7 @@ module REXML
36
37
  @@context[:index]
37
38
  end
38
39
 
40
+ # Returns the size of the given list of nodes.
39
41
  def Functions::count( node_set )
40
42
  node_set.size
41
43
  end
@@ -48,7 +50,7 @@ module REXML
48
50
  # UNTESTED
49
51
  def Functions::local_name( node_set=nil )
50
52
  get_namespace( node_set ) do |node|
51
- return node.local_name
53
+ return node.local_name
52
54
  end
53
55
  end
54
56
 
@@ -57,7 +59,7 @@ module REXML
57
59
  end
58
60
 
59
61
  def Functions::name( node_set=nil )
60
- get_namespace( node_set ) do |node|
62
+ get_namespace( node_set ) do |node|
61
63
  node.expanded_name
62
64
  end
63
65
  end
@@ -66,7 +68,7 @@ module REXML
66
68
  def Functions::get_namespace( node_set = nil )
67
69
  if node_set == nil
68
70
  yield @@context[:node] if defined? @@context[:node].namespace
69
- else
71
+ else
70
72
  if node_set.respond_to? :each
71
73
  node_set.each { |node| yield node if defined? node.namespace }
72
74
  elsif node_set.respond_to? :namespace
@@ -81,15 +83,15 @@ module REXML
81
83
  #
82
84
  # A number is converted to a string as follows
83
85
  #
84
- # NaN is converted to the string NaN
86
+ # NaN is converted to the string NaN
85
87
  #
86
- # positive zero is converted to the string 0
88
+ # positive zero is converted to the string 0
87
89
  #
88
- # negative zero is converted to the string 0
90
+ # negative zero is converted to the string 0
89
91
  #
90
- # positive infinity is converted to the string Infinity
92
+ # positive infinity is converted to the string Infinity
91
93
  #
92
- # negative infinity is converted to the string -Infinity
94
+ # negative infinity is converted to the string -Infinity
93
95
  #
94
96
  # if the number is an integer, the number is represented in decimal form
95
97
  # as a Number with no decimal point and no leading zeros, preceded by a
@@ -129,6 +131,11 @@ module REXML
129
131
  end
130
132
  end
131
133
 
134
+ # A node-set is converted to a string by
135
+ # returning the concatenation of the string-value
136
+ # of each of the children of the node in the
137
+ # node-set that is first in document order.
138
+ # If the node-set is empty, an empty string is returned.
132
139
  def Functions::string_value( o )
133
140
  rv = ""
134
141
  o.children.each { |e|
@@ -156,7 +163,7 @@ module REXML
156
163
  string(string).include?(string(test))
157
164
  end
158
165
 
159
- # Kouhei fixed this
166
+ # Kouhei fixed this
160
167
  def Functions::substring_before( string, test )
161
168
  ruby_string = string(string)
162
169
  ruby_index = ruby_string.index(string(test))
@@ -166,20 +173,19 @@ module REXML
166
173
  ruby_string[ 0...ruby_index ]
167
174
  end
168
175
  end
169
-
176
+
170
177
  # Kouhei fixed this too
171
178
  def Functions::substring_after( string, test )
172
179
  ruby_string = string(string)
173
- test_string = string(test)
174
180
  return $1 if ruby_string =~ /#{test}(.*)/
175
181
  ""
176
182
  end
177
183
 
178
- # Take equal portions of Mike Stok and Sean Russell; mix
184
+ # Take equal portions of Mike Stok and Sean Russell; mix
179
185
  # vigorously, and pour into a tall, chilled glass. Serves 10,000.
180
186
  def Functions::substring( string, start, length=nil )
181
187
  ruby_string = string(string)
182
- ruby_length = if length.nil?
188
+ ruby_length = if length.nil?
183
189
  ruby_string.length.to_f
184
190
  else
185
191
  number(length)
@@ -188,15 +194,15 @@ module REXML
188
194
 
189
195
  # Handle the special cases
190
196
  return '' if (
191
- ruby_length.nan? or
197
+ ruby_length.nan? or
192
198
  ruby_start.nan? or
193
199
  ruby_start.infinite?
194
200
  )
195
201
 
196
202
  infinite_length = ruby_length.infinite? == 1
197
203
  ruby_length = ruby_string.length if infinite_length
198
-
199
- # Now, get the bounds. The XPath bounds are 1..length; the ruby bounds
204
+
205
+ # Now, get the bounds. The XPath bounds are 1..length; the ruby bounds
200
206
  # are 0..length. Therefore, we have to offset the bounds by one.
201
207
  ruby_start = ruby_start.round - 1
202
208
  ruby_length = ruby_length.round
@@ -247,7 +253,7 @@ module REXML
247
253
  0.upto(from.length - 1) { |pos|
248
254
  from_char = from[pos]
249
255
  unless map.has_key? from_char
250
- map[from_char] =
256
+ map[from_char] =
251
257
  if pos < to.length
252
258
  to[pos]
253
259
  else
@@ -256,9 +262,15 @@ module REXML
256
262
  end
257
263
  }
258
264
 
259
- string(string).unpack('U*').collect { |c|
260
- if map.has_key? c then map[c] else c end
261
- }.compact.pack('U*')
265
+ if ''.respond_to? :chars
266
+ string(string).chars.collect { |c|
267
+ if map.has_key? c then map[c] else c end
268
+ }.compact.join
269
+ else
270
+ string(string).unpack('U*').collect { |c|
271
+ if map.has_key? c then map[c] else c end
272
+ }.compact.pack('U*')
273
+ end
262
274
  end
263
275
 
264
276
  # UNTESTED
@@ -353,7 +365,7 @@ module REXML
353
365
  nodes = [nodes] unless nodes.kind_of? Array
354
366
  nodes.inject(0) { |r,n| r += number(string(n)) }
355
367
  end
356
-
368
+
357
369
  def Functions::floor( number )
358
370
  number(number).floor
359
371
  end
@@ -2,62 +2,62 @@ require "rexml/child"
2
2
  require "rexml/source"
3
3
 
4
4
  module REXML
5
- # Represents an XML Instruction; IE, <? ... ?>
6
- # TODO: Add parent arg (3rd arg) to constructor
7
- class Instruction < Child
8
- START = '<\?'
9
- STOP = '\?>'
5
+ # Represents an XML Instruction; IE, <? ... ?>
6
+ # TODO: Add parent arg (3rd arg) to constructor
7
+ class Instruction < Child
8
+ START = '<\?'
9
+ STOP = '\?>'
10
10
 
11
- # target is the "name" of the Instruction; IE, the "tag" in <?tag ...?>
12
- # content is everything else.
13
- attr_accessor :target, :content
11
+ # target is the "name" of the Instruction; IE, the "tag" in <?tag ...?>
12
+ # content is everything else.
13
+ attr_accessor :target, :content
14
14
 
15
- # Constructs a new Instruction
16
- # @param target can be one of a number of things. If String, then
17
- # the target of this instruction is set to this. If an Instruction,
18
- # then the Instruction is shallowly cloned (target and content are
19
- # copied). If a Source, then the source is scanned and parsed for
20
- # an Instruction declaration.
21
- # @param content Must be either a String, or a Parent. Can only
22
- # be a Parent if the target argument is a Source. Otherwise, this
23
- # String is set as the content of this instruction.
24
- def initialize(target, content=nil)
25
- if target.kind_of? String
26
- super()
27
- @target = target
28
- @content = content
29
- elsif target.kind_of? Instruction
30
- super(content)
31
- @target = target.target
32
- @content = target.content
33
- end
34
- @content.strip! if @content
35
- end
15
+ # Constructs a new Instruction
16
+ # @param target can be one of a number of things. If String, then
17
+ # the target of this instruction is set to this. If an Instruction,
18
+ # then the Instruction is shallowly cloned (target and content are
19
+ # copied). If a Source, then the source is scanned and parsed for
20
+ # an Instruction declaration.
21
+ # @param content Must be either a String, or a Parent. Can only
22
+ # be a Parent if the target argument is a Source. Otherwise, this
23
+ # String is set as the content of this instruction.
24
+ def initialize(target, content=nil)
25
+ if target.kind_of? String
26
+ super()
27
+ @target = target
28
+ @content = content
29
+ elsif target.kind_of? Instruction
30
+ super(content)
31
+ @target = target.target
32
+ @content = target.content
33
+ end
34
+ @content.strip! if @content
35
+ end
36
+
37
+ def clone
38
+ Instruction.new self
39
+ end
36
40
 
37
- def clone
38
- Instruction.new self
39
- end
40
-
41
41
  # == DEPRECATED
42
42
  # See the rexml/formatters package
43
43
  #
44
- def write writer, indent=-1, transitive=false, ie_hack=false
44
+ def write writer, indent=-1, transitive=false, ie_hack=false
45
45
  Kernel.warn( "#{self.class.name}.write is deprecated" )
46
- indent(writer, indent)
47
- writer << START.sub(/\\/u, '')
48
- writer << @target
49
- writer << ' '
50
- writer << @content
51
- writer << STOP.sub(/\\/u, '')
52
- end
46
+ indent(writer, indent)
47
+ writer << START.sub(/\\/u, '')
48
+ writer << @target
49
+ writer << ' '
50
+ writer << @content
51
+ writer << STOP.sub(/\\/u, '')
52
+ end
53
53
 
54
- # @return true if other is an Instruction, and the content and target
55
- # of the other matches the target and content of this object.
56
- def ==( other )
57
- other.kind_of? Instruction and
58
- other.target == @target and
59
- other.content == @content
60
- end
54
+ # @return true if other is an Instruction, and the content and target
55
+ # of the other matches the target and content of this object.
56
+ def ==( other )
57
+ other.kind_of? Instruction and
58
+ other.target == @target and
59
+ other.content == @content
60
+ end
61
61
 
62
62
  def node_type
63
63
  :processing_instruction
@@ -66,5 +66,5 @@ module REXML
66
66
  def inspect
67
67
  "<?p-i #{target} ...?>"
68
68
  end
69
- end
69
+ end
70
70
  end
@@ -1,196 +1,195 @@
1
1
  require 'rexml/xmltokens'
2
- require 'rexml/light/node'
3
2
 
4
3
  # [ :element, parent, name, attributes, children* ]
5
- # a = Node.new
6
- # a << "B" # => <a>B</a>
7
- # a.b # => <a>B<b/></a>
8
- # a.b[1] # => <a>B<b/><b/><a>
9
- # a.b[1]["x"] = "y" # => <a>B<b/><b x="y"/></a>
10
- # a.b[0].c # => <a>B<b><c/></b><b x="y"/></a>
11
- # a.b.c << "D" # => <a>B<b><c>D</c></b><b x="y"/></a>
4
+ # a = Node.new
5
+ # a << "B" # => <a>B</a>
6
+ # a.b # => <a>B<b/></a>
7
+ # a.b[1] # => <a>B<b/><b/><a>
8
+ # a.b[1]["x"] = "y" # => <a>B<b/><b x="y"/></a>
9
+ # a.b[0].c # => <a>B<b><c/></b><b x="y"/></a>
10
+ # a.b.c << "D" # => <a>B<b><c>D</c></b><b x="y"/></a>
12
11
  module REXML
13
- module Light
14
- # Represents a tagged XML element. Elements are characterized by
15
- # having children, attributes, and names, and can themselves be
16
- # children.
17
- class Node
18
- NAMESPLIT = /^(?:(#{XMLTokens::NCNAME_STR}):)?(#{XMLTokens::NCNAME_STR})/u
19
- PARENTS = [ :element, :document, :doctype ]
20
- # Create a new element.
21
- def initialize node=nil
22
- @node = node
23
- if node.kind_of? String
24
- node = [ :text, node ]
25
- elsif node.nil?
26
- node = [ :document, nil, nil ]
27
- elsif node[0] == :start_element
28
- node[0] = :element
29
- elsif node[0] == :start_doctype
30
- node[0] = :doctype
31
- elsif node[0] == :start_document
32
- node[0] = :document
33
- end
34
- end
35
-
36
- def size
37
- if PARENTS.include? @node[0]
38
- @node[-1].size
39
- else
40
- 0
41
- end
42
- end
43
-
44
- def each( &block )
45
- size.times { |x| yield( at(x+4) ) }
46
- end
47
-
48
- def name
49
- at(2)
50
- end
51
-
52
- def name=( name_str, ns=nil )
53
- pfx = ''
54
- pfx = "#{prefix(ns)}:" if ns
55
- _old_put(2, "#{pfx}#{name_str}")
56
- end
57
-
58
- def parent=( node )
59
- _old_put(1,node)
60
- end
61
-
62
- def local_name
63
- namesplit
64
- @name
65
- end
66
-
67
- def local_name=( name_str )
68
- _old_put( 1, "#@prefix:#{name_str}" )
69
- end
70
-
71
- def prefix( namespace=nil )
72
- prefix_of( self, namespace )
73
- end
74
-
75
- def namespace( prefix=prefix() )
76
- namespace_of( self, prefix )
77
- end
78
-
79
- def namespace=( namespace )
80
- @prefix = prefix( namespace )
81
- pfx = ''
82
- pfx = "#@prefix:" if @prefix.size > 0
83
- _old_put(1, "#{pfx}#@name")
84
- end
85
-
86
- def []( reference, ns=nil )
87
- if reference.kind_of? String
88
- pfx = ''
89
- pfx = "#{prefix(ns)}:" if ns
90
- at(3)["#{pfx}#{reference}"]
91
- elsif reference.kind_of? Range
92
- _old_get( Range.new(4+reference.begin, reference.end, reference.exclude_end?) )
93
- else
94
- _old_get( 4+reference )
95
- end
96
- end
97
-
98
- def =~( path )
99
- XPath.match( self, path )
100
- end
101
-
102
- # Doesn't handle namespaces yet
103
- def []=( reference, ns, value=nil )
104
- if reference.kind_of? String
105
- value = ns unless value
106
- at( 3 )[reference] = value
107
- elsif reference.kind_of? Range
108
- _old_put( Range.new(3+reference.begin, reference.end, reference.exclude_end?), ns )
109
- else
110
- if value
111
- _old_put( 4+reference, ns, value )
112
- else
113
- _old_put( 4+reference, ns )
114
- end
115
- end
116
- end
117
-
118
- # Append a child to this element, optionally under a provided namespace.
119
- # The namespace argument is ignored if the element argument is an Element
120
- # object. Otherwise, the element argument is a string, the namespace (if
121
- # provided) is the namespace the element is created in.
122
- def << element
123
- if node_type() == :text
124
- at(-1) << element
125
- else
126
- newnode = Node.new( element )
127
- newnode.parent = self
128
- self.push( newnode )
129
- end
130
- at(-1)
131
- end
132
-
133
- def node_type
134
- _old_get(0)
135
- end
136
-
137
- def text=( foo )
138
- replace = at(4).kind_of?(String)? 1 : 0
139
- self._old_put(4,replace, normalizefoo)
140
- end
141
-
142
- def root
143
- context = self
144
- context = context.at(1) while context.at(1)
145
- end
146
-
147
- def has_name?( name, namespace = '' )
148
- at(3) == name and namespace() == namespace
149
- end
150
-
151
- def children
152
- self
153
- end
154
-
155
- def parent
156
- at(1)
157
- end
158
-
159
- def to_s
160
-
161
- end
162
-
163
- private
164
-
165
- def namesplit
166
- return if @name.defined?
167
- at(2) =~ NAMESPLIT
168
- @prefix = '' || $1
169
- @name = $2
170
- end
171
-
172
- def namespace_of( node, prefix=nil )
173
- if not prefix
174
- name = at(2)
175
- name =~ NAMESPLIT
176
- prefix = $1
177
- end
178
- to_find = 'xmlns'
179
- to_find = "xmlns:#{prefix}" if not prefix.nil?
180
- ns = at(3)[ to_find ]
181
- ns ? ns : namespace_of( @node[0], prefix )
182
- end
183
-
184
- def prefix_of( node, namespace=nil )
185
- if not namespace
186
- name = node.name
187
- name =~ NAMESPLIT
188
- $1
189
- else
190
- ns = at(3).find { |k,v| v == namespace }
191
- ns ? ns : prefix_of( node.parent, namespace )
192
- end
193
- end
194
- end
195
- end
12
+ module Light
13
+ # Represents a tagged XML element. Elements are characterized by
14
+ # having children, attributes, and names, and can themselves be
15
+ # children.
16
+ class Node
17
+ NAMESPLIT = /^(?:(#{XMLTokens::NCNAME_STR}):)?(#{XMLTokens::NCNAME_STR})/u
18
+ PARENTS = [ :element, :document, :doctype ]
19
+ # Create a new element.
20
+ def initialize node=nil
21
+ @node = node
22
+ if node.kind_of? String
23
+ node = [ :text, node ]
24
+ elsif node.nil?
25
+ node = [ :document, nil, nil ]
26
+ elsif node[0] == :start_element
27
+ node[0] = :element
28
+ elsif node[0] == :start_doctype
29
+ node[0] = :doctype
30
+ elsif node[0] == :start_document
31
+ node[0] = :document
32
+ end
33
+ end
34
+
35
+ def size
36
+ if PARENTS.include? @node[0]
37
+ @node[-1].size
38
+ else
39
+ 0
40
+ end
41
+ end
42
+
43
+ def each
44
+ size.times { |x| yield( at(x+4) ) }
45
+ end
46
+
47
+ def name
48
+ at(2)
49
+ end
50
+
51
+ def name=( name_str, ns=nil )
52
+ pfx = ''
53
+ pfx = "#{prefix(ns)}:" if ns
54
+ _old_put(2, "#{pfx}#{name_str}")
55
+ end
56
+
57
+ def parent=( node )
58
+ _old_put(1,node)
59
+ end
60
+
61
+ def local_name
62
+ namesplit
63
+ @name
64
+ end
65
+
66
+ def local_name=( name_str )
67
+ _old_put( 1, "#@prefix:#{name_str}" )
68
+ end
69
+
70
+ def prefix( namespace=nil )
71
+ prefix_of( self, namespace )
72
+ end
73
+
74
+ def namespace( prefix=prefix() )
75
+ namespace_of( self, prefix )
76
+ end
77
+
78
+ def namespace=( namespace )
79
+ @prefix = prefix( namespace )
80
+ pfx = ''
81
+ pfx = "#@prefix:" if @prefix.size > 0
82
+ _old_put(1, "#{pfx}#@name")
83
+ end
84
+
85
+ def []( reference, ns=nil )
86
+ if reference.kind_of? String
87
+ pfx = ''
88
+ pfx = "#{prefix(ns)}:" if ns
89
+ at(3)["#{pfx}#{reference}"]
90
+ elsif reference.kind_of? Range
91
+ _old_get( Range.new(4+reference.begin, reference.end, reference.exclude_end?) )
92
+ else
93
+ _old_get( 4+reference )
94
+ end
95
+ end
96
+
97
+ def =~( path )
98
+ XPath.match( self, path )
99
+ end
100
+
101
+ # Doesn't handle namespaces yet
102
+ def []=( reference, ns, value=nil )
103
+ if reference.kind_of? String
104
+ value = ns unless value
105
+ at( 3 )[reference] = value
106
+ elsif reference.kind_of? Range
107
+ _old_put( Range.new(3+reference.begin, reference.end, reference.exclude_end?), ns )
108
+ else
109
+ if value
110
+ _old_put( 4+reference, ns, value )
111
+ else
112
+ _old_put( 4+reference, ns )
113
+ end
114
+ end
115
+ end
116
+
117
+ # Append a child to this element, optionally under a provided namespace.
118
+ # The namespace argument is ignored if the element argument is an Element
119
+ # object. Otherwise, the element argument is a string, the namespace (if
120
+ # provided) is the namespace the element is created in.
121
+ def << element
122
+ if node_type() == :text
123
+ at(-1) << element
124
+ else
125
+ newnode = Node.new( element )
126
+ newnode.parent = self
127
+ self.push( newnode )
128
+ end
129
+ at(-1)
130
+ end
131
+
132
+ def node_type
133
+ _old_get(0)
134
+ end
135
+
136
+ def text=( foo )
137
+ replace = at(4).kind_of?(String)? 1 : 0
138
+ self._old_put(4,replace, normalizefoo)
139
+ end
140
+
141
+ def root
142
+ context = self
143
+ context = context.at(1) while context.at(1)
144
+ end
145
+
146
+ def has_name?( name, namespace = '' )
147
+ at(3) == name and namespace() == namespace
148
+ end
149
+
150
+ def children
151
+ self
152
+ end
153
+
154
+ def parent
155
+ at(1)
156
+ end
157
+
158
+ def to_s
159
+
160
+ end
161
+
162
+ private
163
+
164
+ def namesplit
165
+ return if @name.defined?
166
+ at(2) =~ NAMESPLIT
167
+ @prefix = '' || $1
168
+ @name = $2
169
+ end
170
+
171
+ def namespace_of( node, prefix=nil )
172
+ if not prefix
173
+ name = at(2)
174
+ name =~ NAMESPLIT
175
+ prefix = $1
176
+ end
177
+ to_find = 'xmlns'
178
+ to_find = "xmlns:#{prefix}" if not prefix.nil?
179
+ ns = at(3)[ to_find ]
180
+ ns ? ns : namespace_of( @node[0], prefix )
181
+ end
182
+
183
+ def prefix_of( node, namespace=nil )
184
+ if not namespace
185
+ name = node.name
186
+ name =~ NAMESPLIT
187
+ $1
188
+ else
189
+ ns = at(3).find { |k,v| v == namespace }
190
+ ns ? ns : prefix_of( node.parent, namespace )
191
+ end
192
+ end
193
+ end
194
+ end
196
195
  end