nokogiri 1.1.1-java

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nokogiri might be problematic. Click here for more details.

Files changed (142) hide show
  1. data/History.ja.txt +99 -0
  2. data/History.txt +99 -0
  3. data/Manifest.txt +141 -0
  4. data/README.ja.txt +100 -0
  5. data/README.txt +109 -0
  6. data/Rakefile +354 -0
  7. data/ext/nokogiri/extconf.rb +93 -0
  8. data/ext/nokogiri/html_document.c +86 -0
  9. data/ext/nokogiri/html_document.h +10 -0
  10. data/ext/nokogiri/html_sax_parser.c +36 -0
  11. data/ext/nokogiri/html_sax_parser.h +11 -0
  12. data/ext/nokogiri/native.c +41 -0
  13. data/ext/nokogiri/native.h +50 -0
  14. data/ext/nokogiri/xml_cdata.c +44 -0
  15. data/ext/nokogiri/xml_cdata.h +9 -0
  16. data/ext/nokogiri/xml_comment.c +42 -0
  17. data/ext/nokogiri/xml_comment.h +9 -0
  18. data/ext/nokogiri/xml_document.c +206 -0
  19. data/ext/nokogiri/xml_document.h +10 -0
  20. data/ext/nokogiri/xml_dtd.c +121 -0
  21. data/ext/nokogiri/xml_dtd.h +8 -0
  22. data/ext/nokogiri/xml_io.c +17 -0
  23. data/ext/nokogiri/xml_io.h +9 -0
  24. data/ext/nokogiri/xml_node.c +727 -0
  25. data/ext/nokogiri/xml_node.h +13 -0
  26. data/ext/nokogiri/xml_node_set.c +118 -0
  27. data/ext/nokogiri/xml_node_set.h +9 -0
  28. data/ext/nokogiri/xml_reader.c +465 -0
  29. data/ext/nokogiri/xml_reader.h +10 -0
  30. data/ext/nokogiri/xml_sax_parser.c +201 -0
  31. data/ext/nokogiri/xml_sax_parser.h +10 -0
  32. data/ext/nokogiri/xml_syntax_error.c +199 -0
  33. data/ext/nokogiri/xml_syntax_error.h +11 -0
  34. data/ext/nokogiri/xml_text.c +40 -0
  35. data/ext/nokogiri/xml_text.h +9 -0
  36. data/ext/nokogiri/xml_xpath.c +53 -0
  37. data/ext/nokogiri/xml_xpath.h +11 -0
  38. data/ext/nokogiri/xml_xpath_context.c +214 -0
  39. data/ext/nokogiri/xml_xpath_context.h +9 -0
  40. data/ext/nokogiri/xslt_stylesheet.c +123 -0
  41. data/ext/nokogiri/xslt_stylesheet.h +9 -0
  42. data/lib/action-nokogiri.rb +30 -0
  43. data/lib/nokogiri.rb +72 -0
  44. data/lib/nokogiri/css.rb +25 -0
  45. data/lib/nokogiri/css/generated_parser.rb +721 -0
  46. data/lib/nokogiri/css/generated_tokenizer.rb +159 -0
  47. data/lib/nokogiri/css/node.rb +97 -0
  48. data/lib/nokogiri/css/parser.rb +64 -0
  49. data/lib/nokogiri/css/parser.y +216 -0
  50. data/lib/nokogiri/css/syntax_error.rb +6 -0
  51. data/lib/nokogiri/css/tokenizer.rb +9 -0
  52. data/lib/nokogiri/css/tokenizer.rex +63 -0
  53. data/lib/nokogiri/css/xpath_visitor.rb +168 -0
  54. data/lib/nokogiri/decorators.rb +2 -0
  55. data/lib/nokogiri/decorators/hpricot.rb +3 -0
  56. data/lib/nokogiri/decorators/hpricot/node.rb +56 -0
  57. data/lib/nokogiri/decorators/hpricot/node_set.rb +54 -0
  58. data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +28 -0
  59. data/lib/nokogiri/decorators/slop.rb +31 -0
  60. data/lib/nokogiri/hpricot.rb +51 -0
  61. data/lib/nokogiri/html.rb +105 -0
  62. data/lib/nokogiri/html/builder.rb +9 -0
  63. data/lib/nokogiri/html/document.rb +9 -0
  64. data/lib/nokogiri/html/sax/parser.rb +21 -0
  65. data/lib/nokogiri/version.rb +3 -0
  66. data/lib/nokogiri/xml.rb +83 -0
  67. data/lib/nokogiri/xml/after_handler.rb +18 -0
  68. data/lib/nokogiri/xml/attr.rb +10 -0
  69. data/lib/nokogiri/xml/before_handler.rb +33 -0
  70. data/lib/nokogiri/xml/builder.rb +84 -0
  71. data/lib/nokogiri/xml/cdata.rb +9 -0
  72. data/lib/nokogiri/xml/comment.rb +6 -0
  73. data/lib/nokogiri/xml/document.rb +55 -0
  74. data/lib/nokogiri/xml/dtd.rb +6 -0
  75. data/lib/nokogiri/xml/element.rb +6 -0
  76. data/lib/nokogiri/xml/entity_declaration.rb +9 -0
  77. data/lib/nokogiri/xml/node.rb +333 -0
  78. data/lib/nokogiri/xml/node_set.rb +197 -0
  79. data/lib/nokogiri/xml/notation.rb +6 -0
  80. data/lib/nokogiri/xml/reader.rb +20 -0
  81. data/lib/nokogiri/xml/sax.rb +9 -0
  82. data/lib/nokogiri/xml/sax/document.rb +59 -0
  83. data/lib/nokogiri/xml/sax/parser.rb +37 -0
  84. data/lib/nokogiri/xml/syntax_error.rb +21 -0
  85. data/lib/nokogiri/xml/text.rb +6 -0
  86. data/lib/nokogiri/xml/xpath.rb +10 -0
  87. data/lib/nokogiri/xml/xpath/syntax_error.rb +8 -0
  88. data/lib/nokogiri/xml/xpath_context.rb +14 -0
  89. data/lib/nokogiri/xslt.rb +28 -0
  90. data/lib/nokogiri/xslt/stylesheet.rb +6 -0
  91. data/test/css/test_nthiness.rb +159 -0
  92. data/test/css/test_parser.rb +237 -0
  93. data/test/css/test_tokenizer.rb +162 -0
  94. data/test/css/test_xpath_visitor.rb +64 -0
  95. data/test/files/dont_hurt_em_why.xml +422 -0
  96. data/test/files/exslt.xml +8 -0
  97. data/test/files/exslt.xslt +35 -0
  98. data/test/files/staff.xml +59 -0
  99. data/test/files/staff.xslt +32 -0
  100. data/test/files/tlm.html +850 -0
  101. data/test/helper.rb +78 -0
  102. data/test/hpricot/files/basic.xhtml +17 -0
  103. data/test/hpricot/files/boingboing.html +2266 -0
  104. data/test/hpricot/files/cy0.html +3653 -0
  105. data/test/hpricot/files/immob.html +400 -0
  106. data/test/hpricot/files/pace_application.html +1320 -0
  107. data/test/hpricot/files/tenderlove.html +16 -0
  108. data/test/hpricot/files/uswebgen.html +220 -0
  109. data/test/hpricot/files/utf8.html +1054 -0
  110. data/test/hpricot/files/week9.html +1723 -0
  111. data/test/hpricot/files/why.xml +19 -0
  112. data/test/hpricot/load_files.rb +11 -0
  113. data/test/hpricot/test_alter.rb +67 -0
  114. data/test/hpricot/test_builder.rb +27 -0
  115. data/test/hpricot/test_parser.rb +426 -0
  116. data/test/hpricot/test_paths.rb +15 -0
  117. data/test/hpricot/test_preserved.rb +77 -0
  118. data/test/hpricot/test_xml.rb +30 -0
  119. data/test/html/sax/test_parser.rb +27 -0
  120. data/test/html/test_builder.rb +89 -0
  121. data/test/html/test_document.rb +150 -0
  122. data/test/html/test_node.rb +21 -0
  123. data/test/test_convert_xpath.rb +185 -0
  124. data/test/test_css_cache.rb +57 -0
  125. data/test/test_gc.rb +15 -0
  126. data/test/test_memory_leak.rb +38 -0
  127. data/test/test_nokogiri.rb +97 -0
  128. data/test/test_reader.rb +222 -0
  129. data/test/test_xslt_transforms.rb +93 -0
  130. data/test/xml/sax/test_parser.rb +95 -0
  131. data/test/xml/test_attr.rb +15 -0
  132. data/test/xml/test_builder.rb +16 -0
  133. data/test/xml/test_cdata.rb +18 -0
  134. data/test/xml/test_comment.rb +16 -0
  135. data/test/xml/test_document.rb +195 -0
  136. data/test/xml/test_dtd.rb +43 -0
  137. data/test/xml/test_node.rb +394 -0
  138. data/test/xml/test_node_set.rb +143 -0
  139. data/test/xml/test_text.rb +13 -0
  140. data/test/xml/test_xpath.rb +105 -0
  141. data/vendor/hoe.rb +1020 -0
  142. metadata +233 -0
@@ -0,0 +1,6 @@
1
+ module Nokogiri
2
+ module XML
3
+ class DTD < Node
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Nokogiri
2
+ module XML
3
+ class Element < Node
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ module Nokogiri
2
+ module XML
3
+ class EntityDeclaration < Node
4
+ def attributes
5
+ nil
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,333 @@
1
+ module Nokogiri
2
+ module XML
3
+ class Node
4
+ ELEMENT_NODE = 1
5
+ ATTRIBUTE_NODE = 2
6
+ TEXT_NODE = 3
7
+ CDATA_SECTION_NODE = 4
8
+ ENTITY_REF_NODE = 5
9
+ ENTITY_NODE = 6
10
+ PI_NODE = 7
11
+ COMMENT_NODE = 8
12
+ DOCUMENT_NODE = 9
13
+ DOCUMENT_TYPE_NODE = 10
14
+ DOCUMENT_FRAG_NODE = 11
15
+ NOTATION_NODE = 12
16
+ HTML_DOCUMENT_NODE = 13
17
+ DTD_NODE = 14
18
+ ELEMENT_DECL = 15
19
+ ATTRIBUTE_DECL = 16
20
+ ENTITY_DECL = 17
21
+ NAMESPACE_DECL = 18
22
+ XINCLUDE_START = 19
23
+ XINCLUDE_END = 20
24
+ DOCB_DOCUMENT_NODE = 21
25
+
26
+ attr_accessor :document
27
+
28
+ ###
29
+ # Decorate this node with the decorators set up in this node's Document
30
+ def decorate!
31
+ document.decorate(self) if document
32
+ end
33
+
34
+ ###
35
+ # Get the list of children for this node as a NodeSet
36
+ def children
37
+ list = NodeSet.new(document)
38
+ document.decorate(list)
39
+
40
+ first = self.child
41
+ return list unless first # Empty list
42
+
43
+ list << first
44
+ while first = first.next
45
+ list << first
46
+ end
47
+ list
48
+ end
49
+
50
+ ###
51
+ # Search this node for +paths+. +paths+ can be XPath or CSS, and an
52
+ # optional hash of namespaces may be appended.
53
+ # See Node#xpath and Node#css.
54
+ def search *paths
55
+ ns = paths.last.is_a?(Hash) ? paths.pop : {}
56
+ xpath(*(paths.map { |path|
57
+ path = path.to_s
58
+ path =~ /^(\.\/|\/)/ ? path : CSS.xpath_for(path, :prefix => ".//")
59
+ }.flatten.uniq) + [ns])
60
+ end
61
+ alias :/ :search
62
+
63
+ ###
64
+ # Search this node for XPath +paths+. +paths+ must be one or more XPath
65
+ # queries. A hash of namespaces may be appended. For example:
66
+ #
67
+ # node.xpath('.//title')
68
+ # node.xpath('.//foo:name', { 'foo' => 'http://example.org/' })
69
+ # node.xpath('.//xmlns:name', node.root.namespaces)
70
+ #
71
+ # Custom XPath functions may also be defined. To define custom functions
72
+ # create a class and implement the # function you want to define.
73
+ # For example:
74
+ #
75
+ # node.xpath('.//title[regex(., "\w+")]', Class.new {
76
+ # def regex node_set, regex
77
+ # node_set.find_all { |node| node['some_attribute'] =~ /#{regex}/ }
78
+ # end
79
+ # })
80
+ #
81
+ def xpath *paths
82
+ # Pop off our custom function handler if it exists
83
+ handler = ![
84
+ Hash, String, Symbol
85
+ ].include?(paths.last.class) ? paths.pop : nil
86
+
87
+ ns = paths.last.is_a?(Hash) ? paths.pop : {}
88
+
89
+ return NodeSet.new(document) unless document.root
90
+
91
+ sets = paths.map { |path|
92
+ ctx = XPathContext.new(self)
93
+ ctx.register_namespaces(ns)
94
+ set = ctx.evaluate(path, handler).node_set
95
+ set.document = document
96
+ document.decorate(set)
97
+ set
98
+ }
99
+ return sets.first if sets.length == 1
100
+
101
+ NodeSet.new(document) do |combined|
102
+ document.decorate(combined)
103
+ sets.each do |set|
104
+ set.each do |node|
105
+ combined << node
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ ###
112
+ # Search this node for CSS +rules+. +rules+ must be one or more CSS
113
+ # selectors. For example:
114
+ #
115
+ # node.css('title')
116
+ # node.css('body h1.bold')
117
+ # node.css('div + p.green', 'div#one')
118
+ #
119
+ # Custom CSS pseudo classes may also be defined. To define custom pseudo
120
+ # classes, create a class and implement the custom pseudo class you
121
+ # want defined. The first argument to the method will be the current
122
+ # matching NodeSet. Any other arguments are ones that you pass in.
123
+ # For example:
124
+ #
125
+ # node.css('title:regex("\w+")', Class.new {
126
+ # def regex node_set, regex
127
+ # node_set.find_all { |node| node['some_attribute'] =~ /#{regex}/ }
128
+ # end
129
+ # })
130
+ #
131
+ def css *rules
132
+ # Pop off our custom function handler if it exists
133
+ handler = ![
134
+ Hash, String, Symbol
135
+ ].include?(rules.last.class) ? rules.pop : nil
136
+
137
+ ns = rules.last.is_a?(Hash) ? rules.pop : {}
138
+
139
+ rules = rules.map { |rule|
140
+ CSS.xpath_for(rule, :prefix => ".//")
141
+ }.flatten.uniq + [ns, handler].compact
142
+
143
+ xpath(*rules)
144
+ end
145
+
146
+ def at path, ns = {}
147
+ search(path, ns).first
148
+ end
149
+
150
+ def [](property)
151
+ return nil unless key?(property)
152
+ get(property)
153
+ end
154
+
155
+ def next
156
+ next_sibling
157
+ end
158
+
159
+ def previous
160
+ previous_sibling
161
+ end
162
+
163
+ def remove
164
+ unlink
165
+ end
166
+
167
+ ####
168
+ # Returns a hash containing the node's attributes. The key is the
169
+ # attribute name, the value is the string value of the attribute.
170
+ def attributes
171
+ Hash[*(attribute_nodes.map { |node|
172
+ [node.name, node]
173
+ }.flatten)]
174
+ end
175
+
176
+ ###
177
+ # Remove the attribute named +name+
178
+ def remove_attribute name
179
+ attributes[name].remove if key? name
180
+ end
181
+ alias :delete :remove_attribute
182
+
183
+ ####
184
+ # Create nodes from +data+ and insert them before this node
185
+ # (as a sibling).
186
+ def before data
187
+ classes = document.class.name.split('::')
188
+ classes[-1] = 'SAX::Parser'
189
+
190
+ parser = eval(classes.join('::')).new(BeforeHandler.new(self, data))
191
+ parser.parse(data)
192
+ end
193
+
194
+ ####
195
+ # Create nodes from +data+ and insert them after this node
196
+ # (as a sibling).
197
+ def after data
198
+ classes = document.class.name.split('::')
199
+ classes[-1] = 'SAX::Parser'
200
+
201
+ handler = AfterHandler.new(self, data)
202
+ parser = eval(classes.join('::')).new(handler)
203
+ parser.parse(data)
204
+ handler.after_nodes.reverse.each do |sibling|
205
+ self.add_next_sibling sibling
206
+ end
207
+ end
208
+
209
+ def has_attribute?(property)
210
+ key? property
211
+ end
212
+
213
+ alias :get_attribute :[]
214
+ def set_attribute(name, value)
215
+ self[name] = value
216
+ end
217
+
218
+ def text
219
+ content
220
+ end
221
+ alias :inner_text :text
222
+
223
+ ####
224
+ # Set the content to +string+.
225
+ # If +encode+, encode any special characters first.
226
+ def content= string, encode = true
227
+ self.native_content = encode_special_chars(string)
228
+ end
229
+
230
+ ###
231
+ # Set the parent Node for this Node
232
+ def parent= parent_node
233
+ parent_node.add_child(self)
234
+ parent_node
235
+ end
236
+
237
+ def << child
238
+ add_child child
239
+ end
240
+
241
+ def comment?
242
+ type == COMMENT_NODE
243
+ end
244
+
245
+ def cdata?
246
+ type == CDATA_SECTION_NODE
247
+ end
248
+
249
+ def xml?
250
+ type == DOCUMENT_NODE
251
+ end
252
+
253
+ def html?
254
+ type == HTML_DOCUMENT_NODE
255
+ end
256
+
257
+ def text?
258
+ type == TEXT_NODE
259
+ end
260
+
261
+ def read_only?
262
+ # According to gdome2, these are read-only node types
263
+ [NOTATION_NODE, ENTITY_NODE, ENTITY_DECL].include?(type)
264
+ end
265
+
266
+ def element?
267
+ type == ELEMENT_NODE
268
+ end
269
+ alias :elem? :element?
270
+
271
+ def to_s
272
+ document.xml? ? to_xml : to_html
273
+ end
274
+
275
+ def inner_html
276
+ children.map { |x| x.to_html }.join
277
+ end
278
+
279
+ def css_path
280
+ path.split(/\//).map { |part|
281
+ part.length == 0 ? nil : part.gsub(/\[(\d+)\]/, ':nth-of-type(\1)')
282
+ }.compact.join(' > ')
283
+ end
284
+
285
+ # recursively get all namespaces from this node and its subtree
286
+ def collect_namespaces
287
+ # TODO: print warning message if a prefix refers to more than one URI in the document?
288
+ ns = {}
289
+ traverse {|j| ns.merge!(j.namespaces)}
290
+ ns
291
+ end
292
+
293
+ ###
294
+ # Get a list of ancestor Node for this Node
295
+ def ancestors
296
+ parents = []
297
+
298
+ this_parent = self.parent
299
+
300
+ while this_parent != nil
301
+ parents << this_parent
302
+ this_parent = this_parent.parent
303
+ end
304
+ parents
305
+ end
306
+
307
+ ####
308
+ # Yields self and all children to +block+ recursively.
309
+ def traverse(&block)
310
+ children.each{|j| j.traverse(&block) }
311
+ block.call(self)
312
+ end
313
+
314
+ ####
315
+ # replace node with the new node in the document.
316
+ def replace(new_node)
317
+ if new_node.is_a?(Document)
318
+ raise ArgumentError, <<-EOERR
319
+ Node.replace requires a Node argument, and cannot accept a Document.
320
+ (You probably want to select a node from the Document with at() or search(), or create a new Node via Node.new().)
321
+ EOERR
322
+ end
323
+ replace_with_node new_node
324
+ end
325
+
326
+ def == other
327
+ return false unless other
328
+ return false unless other.respond_to?(:pointer_id)
329
+ pointer_id == other.pointer_id
330
+ end
331
+ end
332
+ end
333
+ end
@@ -0,0 +1,197 @@
1
+ module Nokogiri
2
+ module XML
3
+ class NodeSet
4
+ include Enumerable
5
+
6
+ attr_accessor :document
7
+
8
+ def initialize document, list = []
9
+ @document = document
10
+ list.each { |x| self << x }
11
+ yield self if block_given?
12
+ end
13
+
14
+ ###
15
+ # Get the first element of the NodeSet.
16
+ def first
17
+ self[0]
18
+ end
19
+
20
+ ###
21
+ # Get the last element of the NodeSet.
22
+ def last
23
+ self[length - 1]
24
+ end
25
+
26
+ ###
27
+ # Is this NodeSet empty?
28
+ def empty?
29
+ length == 0
30
+ end
31
+
32
+ ###
33
+ # Insert +datum+ before the first Node in this NodeSet
34
+ def before datum
35
+ first.before datum
36
+ end
37
+
38
+ ###
39
+ # Insert +datum+ after the last Node in this NodeSet
40
+ def after datum
41
+ last.after datum
42
+ end
43
+
44
+ ###
45
+ # Append +node+ to the NodeSet.
46
+ def << node
47
+ push(node)
48
+ end
49
+
50
+ ###
51
+ # Unlink this NodeSet and all Node objects it contains from their
52
+ # current context.
53
+ def unlink
54
+ each { |node| node.unlink }
55
+ self
56
+ end
57
+ alias :remove :unlink
58
+
59
+ ###
60
+ # Search this document for +paths+
61
+ def search *paths
62
+ sub_set = NodeSet.new(document)
63
+ document.decorate(sub_set)
64
+ each do |node|
65
+ node.search(*paths).each do |sub_node|
66
+ sub_set << sub_node
67
+ end
68
+ end
69
+ sub_set
70
+ end
71
+ alias :/ :search
72
+ alias :xpath :search
73
+ alias :css :search
74
+
75
+ ###
76
+ # If path is a string, search this document for +path+ returning the
77
+ # first Node. Otherwise, index in to the array with +path+.
78
+ def at path, ns = {}
79
+ return self[path] if path.is_a?(Numeric)
80
+ search(path, ns).first
81
+ end
82
+
83
+ ###
84
+ # Append the class attribute +name+ to all Node objects in the NodeSet.
85
+ def add_class name
86
+ each do |el|
87
+ next unless el.respond_to? :get_attribute
88
+ classes = el.get_attribute('class').to_s.split(" ")
89
+ el.set_attribute('class', classes.push(name).uniq.join(" "))
90
+ end
91
+ self
92
+ end
93
+
94
+ ###
95
+ # Remove the class attribute +name+ from all Node objects in the NodeSet.
96
+ def remove_class name = nil
97
+ each do |el|
98
+ next unless el.respond_to? :get_attribute
99
+ if name
100
+ classes = el.get_attribute('class').to_s.split(" ")
101
+ el.set_attribute('class', (classes - [name]).uniq.join(" "))
102
+ else
103
+ el.remove_attribute("class")
104
+ end
105
+ end
106
+ self
107
+ end
108
+
109
+ ###
110
+ # Set the attribute +key+ to +value+ or the return value of +blk+
111
+ # on all Node objects in the NodeSet.
112
+ def attr key, value = nil, &blk
113
+ if value or blk
114
+ each do |el|
115
+ el.set_attribute(key, value || blk[el])
116
+ end
117
+ return self
118
+ end
119
+ if key.is_a? Hash
120
+ key.each { |k,v| self.attr(k,v) }
121
+ return self
122
+ else
123
+ return self[0].get_attribute(key)
124
+ end
125
+ end
126
+ alias_method :set, :attr
127
+
128
+ ###
129
+ # Remove the attributed named +name+ from all Node objects in the NodeSet
130
+ def remove_attr name
131
+ each do |el|
132
+ next unless el.respond_to? :remove_attribute
133
+ el.remove_attribute(name)
134
+ end
135
+ self
136
+ end
137
+
138
+ ###
139
+ # Iterate over each node, yielding to +block+
140
+ def each(&block)
141
+ x = 0
142
+ while x < length
143
+ yield self[x]
144
+ x += 1
145
+ end
146
+ end
147
+
148
+ ###
149
+ # Get the inner text of all contained Node objects
150
+ def inner_text
151
+ collect{|j| j.inner_text}.join('')
152
+ end
153
+ alias :text :inner_text
154
+
155
+ ###
156
+ # Get the inner html of all contained Node objects
157
+ def inner_html
158
+ collect{|j| j.inner_html}.join('')
159
+ end
160
+
161
+ ###
162
+ # Wrap this NodeSet with +html+ or the results of the builder in +blk+
163
+ def wrap(html, &blk)
164
+ each do |j|
165
+ new_parent = Nokogiri.make(html, &blk)
166
+ j.replace(new_parent)
167
+ nest = new_parent
168
+ if nest.child
169
+ nest = nest.child until nest.child.nil?
170
+ end
171
+ j.parent = nest
172
+ end
173
+ self
174
+ end
175
+
176
+ def to_s
177
+ map { |x| x.to_s }.join
178
+ end
179
+
180
+ def to_html
181
+ map { |x| x.to_html }.join('')
182
+ end
183
+
184
+ def to_xml *args
185
+ map { |x| x.to_xml(*args) }.join('')
186
+ end
187
+
188
+ def size
189
+ length
190
+ end
191
+
192
+ def to_ary
193
+ to_a
194
+ end
195
+ end
196
+ end
197
+ end