nokogiri 1.4.3.1-java → 1.5.0-java

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.
Files changed (231) hide show
  1. data/.gemtest +0 -0
  2. data/CHANGELOG.ja.rdoc +113 -0
  3. data/CHANGELOG.rdoc +113 -1
  4. data/Manifest.txt +72 -68
  5. data/README.ja.rdoc +4 -4
  6. data/README.rdoc +31 -7
  7. data/Rakefile +110 -132
  8. data/bin/nokogiri +7 -3
  9. data/ext/java/nokogiri/EncodingHandler.java +124 -0
  10. data/ext/java/nokogiri/HtmlDocument.java +119 -0
  11. data/ext/java/nokogiri/HtmlElementDescription.java +145 -0
  12. data/ext/java/nokogiri/HtmlEntityLookup.java +79 -0
  13. data/ext/java/nokogiri/HtmlSaxParserContext.java +259 -0
  14. data/ext/java/nokogiri/NokogiriService.java +590 -0
  15. data/ext/java/nokogiri/XmlAttr.java +180 -0
  16. data/ext/java/nokogiri/XmlAttributeDecl.java +130 -0
  17. data/ext/java/nokogiri/XmlCdata.java +84 -0
  18. data/ext/java/nokogiri/XmlComment.java +86 -0
  19. data/ext/java/nokogiri/XmlDocument.java +519 -0
  20. data/ext/java/nokogiri/XmlDocumentFragment.java +223 -0
  21. data/ext/java/nokogiri/XmlDtd.java +469 -0
  22. data/ext/java/nokogiri/XmlElement.java +195 -0
  23. data/ext/java/nokogiri/XmlElementContent.java +382 -0
  24. data/ext/java/nokogiri/XmlElementDecl.java +152 -0
  25. data/ext/java/nokogiri/XmlEntityDecl.java +162 -0
  26. data/ext/java/nokogiri/XmlEntityReference.java +97 -0
  27. data/ext/java/nokogiri/XmlNamespace.java +183 -0
  28. data/ext/java/nokogiri/XmlNode.java +1378 -0
  29. data/ext/java/nokogiri/XmlNodeSet.java +267 -0
  30. data/ext/java/nokogiri/XmlProcessingInstruction.java +99 -0
  31. data/ext/java/nokogiri/XmlReader.java +408 -0
  32. data/ext/java/nokogiri/XmlRelaxng.java +144 -0
  33. data/ext/java/nokogiri/XmlSaxParserContext.java +367 -0
  34. data/ext/java/nokogiri/XmlSaxPushParser.java +184 -0
  35. data/ext/java/nokogiri/XmlSchema.java +324 -0
  36. data/ext/java/nokogiri/XmlSyntaxError.java +119 -0
  37. data/ext/java/nokogiri/XmlText.java +119 -0
  38. data/ext/java/nokogiri/XmlXpathContext.java +199 -0
  39. data/ext/java/nokogiri/XsltStylesheet.java +197 -0
  40. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +204 -0
  41. data/ext/java/nokogiri/internals/NokogiriDocumentCache.java +73 -0
  42. data/ext/java/nokogiri/internals/NokogiriErrorHandler.java +86 -0
  43. data/ext/java/nokogiri/internals/NokogiriHandler.java +327 -0
  44. data/ext/java/nokogiri/internals/NokogiriHelpers.java +639 -0
  45. data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +167 -0
  46. data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +130 -0
  47. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler.java +74 -0
  48. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler4NekoHtml.java +121 -0
  49. data/ext/java/nokogiri/internals/NokogiriStrictErrorHandler.java +79 -0
  50. data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +141 -0
  51. data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +73 -0
  52. data/ext/java/nokogiri/internals/NokogiriXPathVariableResolver.java +67 -0
  53. data/ext/java/nokogiri/internals/NokogiriXsltErrorListener.java +86 -0
  54. data/ext/java/nokogiri/internals/ParserContext.java +276 -0
  55. data/ext/java/nokogiri/internals/PushInputStream.java +411 -0
  56. data/ext/java/nokogiri/internals/ReaderNode.java +531 -0
  57. data/ext/java/nokogiri/internals/SaveContextVisitor.java +567 -0
  58. data/ext/java/nokogiri/internals/SchemaErrorHandler.java +76 -0
  59. data/ext/java/nokogiri/internals/XmlDeclHandler.java +42 -0
  60. data/ext/java/nokogiri/internals/XmlDomParser.java +76 -0
  61. data/ext/java/nokogiri/internals/XmlDomParserContext.java +244 -0
  62. data/ext/java/nokogiri/internals/XmlSaxParser.java +65 -0
  63. data/ext/java/nokogiri/internals/XsltExtensionFunction.java +72 -0
  64. data/ext/nokogiri/depend +358 -32
  65. data/ext/nokogiri/extconf.rb +10 -6
  66. data/ext/nokogiri/nokogiri.c +23 -3
  67. data/ext/nokogiri/nokogiri.h +7 -2
  68. data/ext/nokogiri/xml_document.c +9 -0
  69. data/ext/nokogiri/xml_dtd.c +2 -2
  70. data/ext/nokogiri/xml_io.c +32 -7
  71. data/ext/nokogiri/xml_node.c +45 -25
  72. data/ext/nokogiri/xml_node_set.c +1 -1
  73. data/ext/nokogiri/xml_relax_ng.c +0 -7
  74. data/ext/nokogiri/xml_sax_parser.c +14 -7
  75. data/ext/nokogiri/xml_sax_parser_context.c +40 -0
  76. data/ext/nokogiri/xml_xpath_context.c +33 -2
  77. data/ext/nokogiri/xslt_stylesheet.c +128 -6
  78. data/lib/isorelax.jar +0 -0
  79. data/lib/jing.jar +0 -0
  80. data/lib/nekodtd.jar +0 -0
  81. data/lib/nekohtml.jar +0 -0
  82. data/lib/nokogiri/css/parser.rb +665 -70
  83. data/lib/nokogiri/css/parser.y +3 -1
  84. data/lib/nokogiri/css/parser_extras.rb +91 -0
  85. data/lib/nokogiri/css/tokenizer.rb +148 -3
  86. data/lib/nokogiri/css/tokenizer.rex +1 -1
  87. data/lib/nokogiri/css/xpath_visitor.rb +15 -7
  88. data/lib/nokogiri/css.rb +5 -3
  89. data/lib/nokogiri/decorators/slop.rb +5 -3
  90. data/lib/nokogiri/html/document.rb +142 -19
  91. data/lib/nokogiri/html/document_fragment.rb +19 -17
  92. data/lib/nokogiri/html/element_description_defaults.rb +671 -0
  93. data/lib/nokogiri/html/sax/parser.rb +6 -2
  94. data/lib/nokogiri/html.rb +1 -0
  95. data/lib/nokogiri/nokogiri.jar +0 -0
  96. data/lib/nokogiri/version.rb +76 -26
  97. data/lib/nokogiri/xml/attribute_decl.rb +1 -1
  98. data/lib/nokogiri/xml/builder.rb +7 -0
  99. data/lib/nokogiri/xml/document.rb +43 -2
  100. data/lib/nokogiri/xml/document_fragment.rb +16 -2
  101. data/lib/nokogiri/xml/dtd.rb +12 -1
  102. data/lib/nokogiri/xml/element_decl.rb +1 -1
  103. data/lib/nokogiri/xml/entity_decl.rb +1 -1
  104. data/lib/nokogiri/xml/node/save_options.rb +20 -1
  105. data/lib/nokogiri/xml/node.rb +198 -78
  106. data/lib/nokogiri/xml/node_set.rb +10 -3
  107. data/lib/nokogiri/xml/parse_options.rb +8 -0
  108. data/lib/nokogiri/xml/reader.rb +42 -6
  109. data/lib/nokogiri/xml/sax/document.rb +4 -2
  110. data/lib/nokogiri/xml/schema.rb +7 -1
  111. data/lib/nokogiri/xslt/stylesheet.rb +1 -1
  112. data/lib/nokogiri/xslt.rb +9 -5
  113. data/lib/nokogiri.rb +19 -25
  114. data/lib/xercesImpl.jar +0 -0
  115. data/nokogiri_help_responses.md +40 -0
  116. data/tasks/cross_compile.rb +130 -136
  117. data/tasks/nokogiri.org.rb +18 -0
  118. data/tasks/test.rb +2 -2
  119. data/test/css/test_parser.rb +29 -18
  120. data/test/css/test_tokenizer.rb +8 -0
  121. data/test/decorators/test_slop.rb +16 -0
  122. data/test/files/encoding.html +82 -0
  123. data/test/files/encoding.xhtml +84 -0
  124. data/test/files/metacharset.html +10 -0
  125. data/test/files/noencoding.html +47 -0
  126. data/test/helper.rb +5 -1
  127. data/test/html/sax/test_parser.rb +65 -3
  128. data/test/html/test_document.rb +75 -1
  129. data/test/html/test_document_encoding.rb +61 -0
  130. data/test/html/test_document_fragment.rb +50 -5
  131. data/test/html/test_element_description.rb +4 -2
  132. data/test/html/test_node.rb +9 -0
  133. data/test/test_memory_leak.rb +20 -35
  134. data/test/test_nokogiri.rb +14 -20
  135. data/test/test_reader.rb +23 -6
  136. data/test/test_xslt_transforms.rb +6 -2
  137. data/test/xml/node/test_save_options.rb +10 -2
  138. data/test/xml/sax/test_parser.rb +39 -8
  139. data/test/xml/sax/test_parser_context.rb +50 -0
  140. data/test/xml/sax/test_push_parser.rb +18 -1
  141. data/test/xml/test_attribute_decl.rb +7 -3
  142. data/test/xml/test_builder.rb +17 -0
  143. data/test/xml/test_document.rb +34 -5
  144. data/test/xml/test_document_fragment.rb +14 -2
  145. data/test/xml/test_dtd.rb +28 -3
  146. data/test/xml/test_element_content.rb +1 -1
  147. data/test/xml/test_element_decl.rb +1 -1
  148. data/test/xml/test_entity_decl.rb +12 -10
  149. data/test/xml/test_namespace.rb +7 -5
  150. data/test/xml/test_node.rb +65 -13
  151. data/test/xml/test_node_reparenting.rb +72 -31
  152. data/test/xml/test_node_set.rb +57 -0
  153. data/test/xml/test_schema.rb +5 -0
  154. data/test/xml/test_xpath.rb +32 -0
  155. data/test/xslt/test_custom_functions.rb +94 -0
  156. data/test/xslt/test_exception_handling.rb +37 -0
  157. metadata +512 -517
  158. data/deps.rip +0 -5
  159. data/ext/nokogiri/libcharset-1.dll +0 -0
  160. data/ext/nokogiri/libexslt.dll +0 -0
  161. data/ext/nokogiri/libiconv-2.dll +0 -0
  162. data/ext/nokogiri/libxml2.dll +0 -0
  163. data/ext/nokogiri/libxslt.dll +0 -0
  164. data/ext/nokogiri/zlib1.dll +0 -0
  165. data/lib/nokogiri/css/generated_parser.rb +0 -676
  166. data/lib/nokogiri/css/generated_tokenizer.rb +0 -146
  167. data/lib/nokogiri/ffi/encoding_handler.rb +0 -42
  168. data/lib/nokogiri/ffi/html/document.rb +0 -28
  169. data/lib/nokogiri/ffi/html/element_description.rb +0 -81
  170. data/lib/nokogiri/ffi/html/entity_lookup.rb +0 -16
  171. data/lib/nokogiri/ffi/html/sax/parser_context.rb +0 -38
  172. data/lib/nokogiri/ffi/io_callbacks.rb +0 -42
  173. data/lib/nokogiri/ffi/libxml.rb +0 -411
  174. data/lib/nokogiri/ffi/structs/common_node.rb +0 -38
  175. data/lib/nokogiri/ffi/structs/html_elem_desc.rb +0 -24
  176. data/lib/nokogiri/ffi/structs/html_entity_desc.rb +0 -13
  177. data/lib/nokogiri/ffi/structs/xml_alloc.rb +0 -16
  178. data/lib/nokogiri/ffi/structs/xml_attr.rb +0 -19
  179. data/lib/nokogiri/ffi/structs/xml_attribute.rb +0 -27
  180. data/lib/nokogiri/ffi/structs/xml_buffer.rb +0 -16
  181. data/lib/nokogiri/ffi/structs/xml_char_encoding_handler.rb +0 -11
  182. data/lib/nokogiri/ffi/structs/xml_document.rb +0 -117
  183. data/lib/nokogiri/ffi/structs/xml_dtd.rb +0 -28
  184. data/lib/nokogiri/ffi/structs/xml_element.rb +0 -26
  185. data/lib/nokogiri/ffi/structs/xml_element_content.rb +0 -17
  186. data/lib/nokogiri/ffi/structs/xml_entity.rb +0 -32
  187. data/lib/nokogiri/ffi/structs/xml_enumeration.rb +0 -12
  188. data/lib/nokogiri/ffi/structs/xml_node.rb +0 -28
  189. data/lib/nokogiri/ffi/structs/xml_node_set.rb +0 -53
  190. data/lib/nokogiri/ffi/structs/xml_notation.rb +0 -11
  191. data/lib/nokogiri/ffi/structs/xml_ns.rb +0 -15
  192. data/lib/nokogiri/ffi/structs/xml_parser_context.rb +0 -19
  193. data/lib/nokogiri/ffi/structs/xml_relax_ng.rb +0 -14
  194. data/lib/nokogiri/ffi/structs/xml_sax_handler.rb +0 -51
  195. data/lib/nokogiri/ffi/structs/xml_sax_push_parser_context.rb +0 -124
  196. data/lib/nokogiri/ffi/structs/xml_schema.rb +0 -13
  197. data/lib/nokogiri/ffi/structs/xml_syntax_error.rb +0 -31
  198. data/lib/nokogiri/ffi/structs/xml_text_reader.rb +0 -12
  199. data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +0 -38
  200. data/lib/nokogiri/ffi/structs/xml_xpath_object.rb +0 -35
  201. data/lib/nokogiri/ffi/structs/xml_xpath_parser_context.rb +0 -20
  202. data/lib/nokogiri/ffi/structs/xslt_stylesheet.rb +0 -13
  203. data/lib/nokogiri/ffi/weak_bucket.rb +0 -40
  204. data/lib/nokogiri/ffi/xml/attr.rb +0 -41
  205. data/lib/nokogiri/ffi/xml/attribute_decl.rb +0 -27
  206. data/lib/nokogiri/ffi/xml/cdata.rb +0 -19
  207. data/lib/nokogiri/ffi/xml/comment.rb +0 -18
  208. data/lib/nokogiri/ffi/xml/document.rb +0 -166
  209. data/lib/nokogiri/ffi/xml/document_fragment.rb +0 -21
  210. data/lib/nokogiri/ffi/xml/dtd.rb +0 -67
  211. data/lib/nokogiri/ffi/xml/element_content.rb +0 -43
  212. data/lib/nokogiri/ffi/xml/element_decl.rb +0 -19
  213. data/lib/nokogiri/ffi/xml/entity_decl.rb +0 -36
  214. data/lib/nokogiri/ffi/xml/entity_reference.rb +0 -19
  215. data/lib/nokogiri/ffi/xml/namespace.rb +0 -44
  216. data/lib/nokogiri/ffi/xml/node.rb +0 -554
  217. data/lib/nokogiri/ffi/xml/node_set.rb +0 -149
  218. data/lib/nokogiri/ffi/xml/processing_instruction.rb +0 -20
  219. data/lib/nokogiri/ffi/xml/reader.rb +0 -236
  220. data/lib/nokogiri/ffi/xml/relax_ng.rb +0 -85
  221. data/lib/nokogiri/ffi/xml/sax/parser.rb +0 -135
  222. data/lib/nokogiri/ffi/xml/sax/parser_context.rb +0 -67
  223. data/lib/nokogiri/ffi/xml/sax/push_parser.rb +0 -51
  224. data/lib/nokogiri/ffi/xml/schema.rb +0 -109
  225. data/lib/nokogiri/ffi/xml/syntax_error.rb +0 -98
  226. data/lib/nokogiri/ffi/xml/text.rb +0 -18
  227. data/lib/nokogiri/ffi/xml/xpath.rb +0 -9
  228. data/lib/nokogiri/ffi/xml/xpath_context.rb +0 -148
  229. data/lib/nokogiri/ffi/xslt/stylesheet.rb +0 -53
  230. data/lib/nokogiri/version_warning.rb +0 -14
  231. data/test/ffi/test_document.rb +0 -35
@@ -95,13 +95,17 @@ module Nokogiri
95
95
  # optional hash of namespaces may be appended.
96
96
  # See Node#xpath and Node#css.
97
97
  def search *paths
98
+ # TODO use paths, handler, ns, binds = extract_params(paths)
98
99
  ns = paths.last.is_a?(Hash) ? paths.pop :
99
100
  (document.root ? document.root.namespaces : {})
101
+
102
+ prefix = "#{implied_xpath_context}/"
103
+
100
104
  xpath(*(paths.map { |path|
101
105
  path = path.to_s
102
- path =~ /^(\.\/|\/)/ ? path : CSS.xpath_for(
106
+ path =~ /^(\.\/|\/|\.\.)/ ? path : CSS.xpath_for(
103
107
  path,
104
- :prefix => ".//",
108
+ :prefix => prefix,
105
109
  :ns => ns
106
110
  )
107
111
  }.flatten.uniq) + [ns])
@@ -109,16 +113,28 @@ module Nokogiri
109
113
  alias :/ :search
110
114
 
111
115
  ###
116
+ # call-seq: xpath *paths, [namespace-bindings, variable-bindings, custom-handler-class]
117
+ #
112
118
  # Search this node for XPath +paths+. +paths+ must be one or more XPath
113
- # queries. A hash of namespaces may be appended. For example:
119
+ # queries.
114
120
  #
115
121
  # node.xpath('.//title')
116
- # node.xpath('.//foo:name', { 'foo' => 'http://example.org/' })
122
+ #
123
+ # A hash of namespace bindings may be appended. For example:
124
+ #
125
+ # node.xpath('.//foo:name', {'foo' => 'http://example.org/'})
117
126
  # node.xpath('.//xmlns:name', node.root.namespaces)
118
127
  #
119
- # Custom XPath functions may also be defined. To define custom functions
120
- # create a class and implement the # function you want to define.
121
- # For example:
128
+ # A hash of variable bindings may also be appended to the namespace bindings. For example:
129
+ #
130
+ # node.xpath('.//address[@domestic=$value]', nil, {:value => 'Yes'})
131
+ #
132
+ # Custom XPath functions may also be defined. To define custom
133
+ # functions create a class and implement the function you want
134
+ # to define. The first argument to the method will be the
135
+ # current matching NodeSet. Any other arguments are ones that
136
+ # you pass in. Note that this class may appear anywhere in the
137
+ # argument list. For example:
122
138
  #
123
139
  # node.xpath('.//title[regex(., "\w+")]', Class.new {
124
140
  # def regex node_set, regex
@@ -127,19 +143,19 @@ module Nokogiri
127
143
  # }.new)
128
144
  #
129
145
  def xpath *paths
130
- # Pop off our custom function handler if it exists
131
- handler = ![
132
- Hash, String, Symbol
133
- ].include?(paths.last.class) ? paths.pop : nil
134
-
135
- ns = paths.last.is_a?(Hash) ? paths.pop :
136
- (document.root ? document.root.namespaces : {})
137
-
138
146
  return NodeSet.new(document) unless document
139
147
 
148
+ paths, handler, ns, binds = extract_params(paths)
149
+
140
150
  sets = paths.map { |path|
141
151
  ctx = XPathContext.new(self)
142
152
  ctx.register_namespaces(ns)
153
+ path = path.gsub(/\/xmlns:/,'/:') unless Nokogiri.uses_libxml?
154
+
155
+ binds.each do |key,value|
156
+ ctx.register_variable key.to_s, value
157
+ end if binds
158
+
143
159
  ctx.evaluate(path, handler)
144
160
  }
145
161
  return sets.first if sets.length == 1
@@ -154,18 +170,24 @@ module Nokogiri
154
170
  end
155
171
 
156
172
  ###
173
+ # call-seq: css *rules, [namespace-bindings, custom-pseudo-class]
174
+ #
157
175
  # Search this node for CSS +rules+. +rules+ must be one or more CSS
158
- # selectors. For example:
176
+ # selectors. For example:
159
177
  #
160
178
  # node.css('title')
161
179
  # node.css('body h1.bold')
162
180
  # node.css('div + p.green', 'div#one')
163
181
  #
164
- # Custom CSS pseudo classes may also be defined. To define custom pseudo
165
- # classes, create a class and implement the custom pseudo class you
166
- # want defined. The first argument to the method will be the current
167
- # matching NodeSet. Any other arguments are ones that you pass in.
168
- # For example:
182
+ # A hash of namespace bindings may be appended. For example:
183
+ #
184
+ # node.css('bike|tire', {'bike' => 'http://schwinn.com/'})
185
+ #
186
+ # Custom CSS pseudo classes may also be defined. To define
187
+ # custom pseudo classes, create a class and implement the custom
188
+ # pseudo class you want defined. The first argument to the
189
+ # method will be the current matching NodeSet. Any other
190
+ # arguments are ones that you pass in. For example:
169
191
  #
170
192
  # node.css('title:regex("\w+")', Class.new {
171
193
  # def regex node_set, regex
@@ -173,18 +195,21 @@ module Nokogiri
173
195
  # end
174
196
  # }.new)
175
197
  #
198
+ # Note that the CSS query string is case-sensitive with regards
199
+ # to your document type. That is, if you're looking for "H1" in
200
+ # an HTML document, you'll never find anything, since HTML tags
201
+ # will match only lowercase CSS queries. However, "H1" might be
202
+ # found in an XML document, where tags names are case-sensitive
203
+ # (e.g., "H1" is distinct from "h1").
204
+ #
176
205
  def css *rules
177
- # Pop off our custom function handler if it exists
178
- handler = ![
179
- Hash, String, Symbol
180
- ].include?(rules.last.class) ? rules.pop : nil
206
+ rules, handler, ns, binds = extract_params(rules)
181
207
 
182
- ns = rules.last.is_a?(Hash) ? rules.pop :
183
- (document.root ? document.root.namespaces : {})
208
+ prefix = "#{implied_xpath_context}/"
184
209
 
185
210
  rules = rules.map { |rule|
186
- CSS.xpath_for(rule, :prefix => ".//", :ns => ns)
187
- }.flatten.uniq + [ns, handler].compact
211
+ CSS.xpath_for(rule, :prefix => prefix, :ns => ns)
212
+ }.flatten.uniq + [ns, handler, binds].compact
188
213
 
189
214
  xpath(*rules)
190
215
  end
@@ -234,7 +259,9 @@ module Nokogiri
234
259
  # Add +node_or_tags+ as a child of this Node.
235
260
  # +node_or_tags+ can be a Nokogiri::XML::Node, a ::DocumentFragment, a ::NodeSet, or a string containing markup.
236
261
  #
237
- # Returns the new child node.
262
+ # Returns the reparented node (if +node_or_tags+ is a Node), or NodeSet (if +node_or_tags+ is a DocumentFragment, NodeSet, or string).
263
+ #
264
+ # Also see related method +<<+.
238
265
  def add_child node_or_tags
239
266
  node_or_tags = coerce(node_or_tags)
240
267
  if node_or_tags.is_a?(XML::NodeSet)
@@ -242,42 +269,66 @@ module Nokogiri
242
269
  else
243
270
  add_child_node node_or_tags
244
271
  end
272
+ node_or_tags
245
273
  end
246
274
 
275
+ ###
276
+ # Add +node_or_tags+ as a child of this Node.
277
+ # +node_or_tags+ can be a Nokogiri::XML::Node, a ::DocumentFragment, a ::NodeSet, or a string containing markup.
278
+ #
279
+ # Returns self, to support chaining of calls (e.g., root << child1 << child2)
280
+ #
281
+ # Also see related method +add_child+.
282
+ def << node_or_tags
283
+ add_child node_or_tags
284
+ self
285
+ end
247
286
  ###
248
287
  # Insert +node_or_tags+ before this Node (as a sibling).
249
288
  # +node_or_tags+ can be a Nokogiri::XML::Node, a ::DocumentFragment, a ::NodeSet, or a string containing markup.
250
289
  #
251
- # Returns the new sibling node.
290
+ # Returns the reparented node (if +node_or_tags+ is a Node), or NodeSet (if +node_or_tags+ is a DocumentFragment, NodeSet, or string).
252
291
  #
253
292
  # Also see related method +before+.
254
293
  def add_previous_sibling node_or_tags
255
294
  node_or_tags = coerce(node_or_tags)
256
295
  if node_or_tags.is_a?(XML::NodeSet)
257
- node_or_tags.each { |n| add_previous_sibling_node n }
296
+ if text?
297
+ pivot = Nokogiri::XML::Node.new 'dummy', document
298
+ add_previous_sibling_node pivot
299
+ else
300
+ pivot = self
301
+ end
302
+ node_or_tags.each { |n| pivot.send :add_previous_sibling_node, n }
303
+ pivot.unlink if text?
258
304
  else
259
305
  add_previous_sibling_node node_or_tags
260
306
  end
307
+ node_or_tags
261
308
  end
262
309
 
263
310
  ###
264
311
  # Insert +node_or_tags+ after this Node (as a sibling).
265
312
  # +node_or_tags+ can be a Nokogiri::XML::Node, a ::DocumentFragment, a ::NodeSet, or a string containing markup.
266
313
  #
267
- # Returns the new sibling node.
314
+ # Returns the reparented node (if +node_or_tags+ is a Node), or NodeSet (if +node_or_tags+ is a DocumentFragment, NodeSet, or string).
268
315
  #
269
316
  # Also see related method +after+.
270
317
  def add_next_sibling node_or_tags
271
318
  node_or_tags = coerce(node_or_tags)
272
319
  if node_or_tags.is_a?(XML::NodeSet)
273
- if '1.8.6' == RUBY_VERSION
274
- node_or_tags.reverse.each { |n| add_next_sibling_node n }
320
+ if text?
321
+ pivot = Nokogiri::XML::Node.new 'dummy', document
322
+ add_next_sibling_node pivot
275
323
  else
276
- node_or_tags.reverse_each { |n| add_next_sibling_node n }
324
+ pivot = self
277
325
  end
326
+ node_or_tags.reverse_each { |n| pivot.send :add_next_sibling_node, n }
327
+ pivot.unlink if text?
278
328
  else
279
329
  add_next_sibling_node node_or_tags
280
330
  end
331
+ node_or_tags
281
332
  end
282
333
 
283
334
  ####
@@ -305,36 +356,58 @@ module Nokogiri
305
356
  end
306
357
 
307
358
  ####
308
- # Set the inner_html for this Node to +node_or_tags+
359
+ # Set the inner html for this Node to +node_or_tags+
309
360
  # +node_or_tags+ can be a Nokogiri::XML::Node, a Nokogiri::XML::DocumentFragment, or a string containing markup.
310
361
  #
311
362
  # Returns self.
363
+ #
364
+ # Also see related method +children=+
312
365
  def inner_html= node_or_tags
366
+ self.children = node_or_tags
367
+ self
368
+ end
369
+
370
+ ####
371
+ # Set the inner html for this Node +node_or_tags+
372
+ # +node_or_tags+ can be a Nokogiri::XML::Node, a Nokogiri::XML::DocumentFragment, or a string containing markup.
373
+ #
374
+ # Returns the reparented node (if +node_or_tags+ is a Node), or NodeSet (if +node_or_tags+ is a DocumentFragment, NodeSet, or string).
375
+ #
376
+ # Also see related method +inner_html=+
377
+ def children= node_or_tags
313
378
  node_or_tags = coerce(node_or_tags)
314
379
  children.unlink
315
380
  if node_or_tags.is_a?(XML::NodeSet)
316
381
  node_or_tags.each { |n| add_child_node n }
317
382
  else
318
- add_child node_or_tags
383
+ add_child_node node_or_tags
319
384
  end
320
- self
385
+ node_or_tags
321
386
  end
322
387
 
323
388
  ####
324
389
  # Replace this Node with +node_or_tags+.
325
390
  # +node_or_tags+ can be a Nokogiri::XML::Node, a ::DocumentFragment, a ::NodeSet, or a string containing markup.
326
391
  #
327
- # Returns the new child node.
392
+ # Returns the reparented node (if +node_or_tags+ is a Node), or NodeSet (if +node_or_tags+ is a DocumentFragment, NodeSet, or string).
328
393
  #
329
394
  # Also see related method +swap+.
330
395
  def replace node_or_tags
331
396
  node_or_tags = coerce(node_or_tags)
332
397
  if node_or_tags.is_a?(XML::NodeSet)
333
- node_or_tags.each { |n| add_previous_sibling n }
334
- unlink
398
+ if text?
399
+ replacee = Nokogiri::XML::Node.new 'dummy', document
400
+ add_previous_sibling_node replacee
401
+ unlink
402
+ else
403
+ replacee = self
404
+ end
405
+ node_or_tags.each { |n| replacee.add_previous_sibling n }
406
+ replacee.unlink
335
407
  else
336
408
  replace_node node_or_tags
337
409
  end
410
+ node_or_tags
338
411
  end
339
412
 
340
413
  ####
@@ -365,7 +438,6 @@ module Nokogiri
365
438
  alias :text :content
366
439
  alias :inner_text :content
367
440
  alias :has_attribute? :key?
368
- alias :<< :add_child
369
441
  alias :name :node_name
370
442
  alias :name= :node_name=
371
443
  alias :type :node_type
@@ -430,7 +502,8 @@ module Nokogiri
430
502
  # Parse +string_or_io+ as a document fragment within the context of
431
503
  # *this* node. Returns a XML::NodeSet containing the nodes parsed from
432
504
  # +string_or_io+.
433
- def parse string_or_io, options = ParseOptions::DEFAULT_XML
505
+ def parse string_or_io, options = nil
506
+ options ||= (document.html? ? ParseOptions::DEFAULT_HTML : ParseOptions::DEFAULT_XML)
434
507
  if Fixnum === options
435
508
  options = Nokogiri::XML::ParseOptions.new(options)
436
509
  end
@@ -442,7 +515,16 @@ module Nokogiri
442
515
  string_or_io
443
516
 
444
517
  return Nokogiri::XML::NodeSet.new(document) if contents.empty?
445
- in_context(contents, options.to_i)
518
+
519
+ ##
520
+ # This is a horrible hack, but I don't care. See #313 for background.
521
+ error_count = document.errors.length
522
+ node_set = in_context(contents, options.to_i)
523
+ if node_set.empty? and document.errors.length > error_count and options.recover?
524
+ fragment = Nokogiri::HTML::DocumentFragment.parse contents
525
+ node_set = fragment.children
526
+ end
527
+ node_set
446
528
  end
447
529
 
448
530
  ####
@@ -459,7 +541,19 @@ module Nokogiri
459
541
  end
460
542
 
461
543
  ###
462
- # Get a hash containing the Namespace definitions for this Node
544
+ # Returns a Hash of {prefix => value} for all namespaces on this
545
+ # node and its ancestors.
546
+ #
547
+ # This method returns the same namespaces as #namespace_scopes.
548
+ #
549
+ # Returns namespaces in scope for self -- those defined on self
550
+ # element directly or any ancestor node -- as a Hash of
551
+ # attribute-name/value pairs. Note that the keys in this hash
552
+ # XML attributes that would be used to define this namespace,
553
+ # such as "xmlns:prefix", not just the prefix. Default namespace
554
+ # set on self will be included with key "xmlns". However,
555
+ # default namespaces set on ancestor will NOT be, even if self
556
+ # has no explicit default namespace.
463
557
  def namespaces
464
558
  Hash[*namespace_scopes.map { |nd|
465
559
  key = ['xmlns', nd.prefix].compact.join(':')
@@ -567,14 +661,22 @@ module Nokogiri
567
661
  end
568
662
 
569
663
  ###
570
- # Set the default namespace for this node to +url+
664
+ # Adds a default namespace supplied as a string +url+ href, to self.
665
+ # The consequence is as an xmlns attribute with supplied argument were
666
+ # present in parsed XML. A default namespace set with this method will
667
+ # now show up in #attributes, but when this node is serialized to XML an
668
+ # "xmlns" attribute will appear. See also #namespace and #namespace=
571
669
  def default_namespace= url
572
670
  add_namespace_definition(nil, url)
573
671
  end
574
672
  alias :add_namespace :add_namespace_definition
575
673
 
576
674
  ###
577
- # Set the namespace for this node to +ns+
675
+ # Set the default namespace on this node (as would be defined with an
676
+ # "xmlns=" attribute in XML source), as a Namespace object +ns+. Note that
677
+ # a Namespace added this way will NOT be serialized as an xmlns attribute
678
+ # for this node. You probably want #default_namespace= instead, or perhaps
679
+ # #add_namespace_definition with a nil prefix argument.
578
680
  def namespace= ns
579
681
  return set_namespace(ns) unless ns
580
682
 
@@ -626,10 +728,11 @@ module Nokogiri
626
728
  def serialize *args, &block
627
729
  options = args.first.is_a?(Hash) ? args.shift : {
628
730
  :encoding => args[0],
629
- :save_with => args[1] || SaveOptions::FORMAT
731
+ :save_with => args[1]
630
732
  }
631
733
 
632
734
  encoding = options[:encoding] || document.encoding
735
+ options[:encoding] = encoding
633
736
 
634
737
  outstring = ""
635
738
  if encoding && outstring.respond_to?(:force_encoding)
@@ -649,13 +752,10 @@ module Nokogiri
649
752
  # use Node#to_xhtml instead.
650
753
  def to_html options = {}
651
754
  # FIXME: this is a hack around broken libxml versions
652
- return dump_html if %w[2 6] === LIBXML_VERSION.split('.')[0..1]
653
-
654
- options[:save_with] ||= SaveOptions::FORMAT |
655
- SaveOptions::NO_DECLARATION |
656
- SaveOptions::NO_EMPTY_TAGS |
657
- SaveOptions::AS_HTML
755
+ return dump_html if Nokogiri.uses_libxml? && %w[2 6] === LIBXML_VERSION.split('.')[0..1]
658
756
 
757
+ options[:save_with] |= SaveOptions::DEFAULT_HTML if options[:save_with]
758
+ options[:save_with] = SaveOptions::DEFAULT_HTML unless options[:save_with]
659
759
  serialize(options)
660
760
  end
661
761
 
@@ -666,8 +766,8 @@ module Nokogiri
666
766
  #
667
767
  # See Node#write_to for a list of +options+
668
768
  def to_xml options = {}
669
- options[:save_with] ||= SaveOptions::FORMAT | SaveOptions::AS_XML
670
-
769
+ options[:save_with] |= SaveOptions::DEFAULT_XML if options[:save_with]
770
+ options[:save_with] = SaveOptions::DEFAULT_XML unless options[:save_with]
671
771
  serialize(options)
672
772
  end
673
773
 
@@ -679,13 +779,10 @@ module Nokogiri
679
779
  # See Node#write_to for a list of +options+
680
780
  def to_xhtml options = {}
681
781
  # FIXME: this is a hack around broken libxml versions
682
- return dump_html if %w[2 6] === LIBXML_VERSION.split('.')[0..1]
683
-
684
- options[:save_with] ||= SaveOptions::FORMAT |
685
- SaveOptions::NO_DECLARATION |
686
- SaveOptions::NO_EMPTY_TAGS |
687
- SaveOptions::AS_XHTML
782
+ return dump_html if Nokogiri.uses_libxml? && %w[2 6] === LIBXML_VERSION.split('.')[0..1]
688
783
 
784
+ options[:save_with] |= SaveOptions::DEFAULT_XHTML if options[:save_with]
785
+ options[:save_with] = SaveOptions::DEFAULT_XHTML unless options[:save_with]
689
786
  serialize(options)
690
787
  end
691
788
 
@@ -709,12 +806,16 @@ module Nokogiri
709
806
  def write_to io, *options
710
807
  options = options.first.is_a?(Hash) ? options.shift : {}
711
808
  encoding = options[:encoding] || options[0]
712
- save_options = options[:save_with] || options[1] || SaveOptions::FORMAT
809
+ if Nokogiri.jruby?
810
+ save_options = options[:save_with] || options[1]
811
+ indent_times = options[:indent] || 0
812
+ else
813
+ save_options = options[:save_with] || options[1] || SaveOptions::FORMAT
814
+ indent_times = options[:indent] || 2
815
+ end
713
816
  indent_text = options[:indent_text] || ' '
714
- indent_times = options[:indent] || 2
715
-
716
817
 
717
- config = SaveOptions.new(save_options)
818
+ config = SaveOptions.new(save_options.to_i)
718
819
  yield config if block_given?
719
820
 
720
821
  native_write_to(io, encoding, indent_text * indent_times, config.options)
@@ -726,12 +827,9 @@ module Nokogiri
726
827
  # See Node#write_to for a list of +options+
727
828
  def write_html_to io, options = {}
728
829
  # FIXME: this is a hack around broken libxml versions
729
- return (io << dump_html) if %w[2 6] === LIBXML_VERSION.split('.')[0..1]
830
+ return (io << dump_html) if Nokogiri.uses_libxml? && %w[2 6] === LIBXML_VERSION.split('.')[0..1]
730
831
 
731
- options[:save_with] ||= SaveOptions::FORMAT |
732
- SaveOptions::NO_DECLARATION |
733
- SaveOptions::NO_EMPTY_TAGS |
734
- SaveOptions::AS_HTML
832
+ options[:save_with] ||= SaveOptions::DEFAULT_HTML
735
833
  write_to io, options
736
834
  end
737
835
 
@@ -741,12 +839,9 @@ module Nokogiri
741
839
  # See Node#write_to for a list of +options+
742
840
  def write_xhtml_to io, options = {}
743
841
  # FIXME: this is a hack around broken libxml versions
744
- return (io << dump_html) if %w[2 6] === LIBXML_VERSION.split('.')[0..1]
842
+ return (io << dump_html) if Nokogiri.uses_libxml? && %w[2 6] === LIBXML_VERSION.split('.')[0..1]
745
843
 
746
- options[:save_with] ||= SaveOptions::FORMAT |
747
- SaveOptions::NO_DECLARATION |
748
- SaveOptions::NO_EMPTY_TAGS |
749
- SaveOptions::AS_XHTML
844
+ options[:save_with] ||= SaveOptions::DEFAULT_XHTML
750
845
  write_to io, options
751
846
  end
752
847
 
@@ -757,7 +852,7 @@ module Nokogiri
757
852
  #
758
853
  # See Node#write_to for a list of options
759
854
  def write_xml_to io, options = {}
760
- options[:save_with] ||= SaveOptions::FORMAT | SaveOptions::AS_XML
855
+ options[:save_with] ||= SaveOptions::DEFAULT_XML
761
856
  write_to io, options
762
857
  end
763
858
 
@@ -772,6 +867,27 @@ module Nokogiri
772
867
 
773
868
  private
774
869
 
870
+ def extract_params params # :nodoc:
871
+ # Pop off our custom function handler if it exists
872
+ handler = params.find { |param|
873
+ ![Hash, String, Symbol].include?(param.class)
874
+ }
875
+
876
+ params -= [handler] if handler
877
+
878
+ hashes = []
879
+ while Hash === params.last || params.last.nil?
880
+ hashes << params.pop
881
+ break if params.empty?
882
+ end
883
+
884
+ ns, binds = hashes.reverse
885
+
886
+ ns ||= document.root ? document.root.namespaces : {}
887
+
888
+ [params, handler, ns, binds]
889
+ end
890
+
775
891
  def coerce data # :nodoc:
776
892
  return data if data.is_a?(XML::NodeSet)
777
893
  return data.children if data.is_a?(XML::DocumentFragment)
@@ -787,6 +903,10 @@ Requires a Node, NodeSet or String argument, and cannot accept a #{data.class}.
787
903
  data
788
904
  end
789
905
 
906
+ def implied_xpath_context
907
+ "./"
908
+ end
909
+
790
910
  def inspect_attributes
791
911
  [:name, :namespace, :attribute_nodes, :children]
792
912
  end
@@ -42,7 +42,7 @@ module Nokogiri
42
42
  end
43
43
 
44
44
  ###
45
- # Returns the index of the first node in self that is == to +node+. Returns nil if no match is found.
45
+ # Returns the index of the first node in self that is == to +node+. Returns nil if no match is found.
46
46
  def index(node)
47
47
  each_with_index { |member, j| return j if member == node }
48
48
  nil
@@ -104,7 +104,7 @@ module Nokogiri
104
104
 
105
105
  each do |node|
106
106
  doc = node.document
107
- search_ns = ns || doc.root ? doc.root.namespaces : {}
107
+ search_ns = ns || (doc.root ? doc.root.namespaces : {})
108
108
 
109
109
  xpaths = paths.map { |rule|
110
110
  [
@@ -257,7 +257,7 @@ module Nokogiri
257
257
  # Wrap this NodeSet with +html+ or the results of the builder in +blk+
258
258
  def wrap(html, &blk)
259
259
  each do |j|
260
- new_parent = document.root.parse(html).first
260
+ new_parent = document.parse(html).first
261
261
  j.add_next_sibling(new_parent)
262
262
  new_parent.add_child(j)
263
263
  end
@@ -273,6 +273,13 @@ module Nokogiri
273
273
  ###
274
274
  # Convert this NodeSet to HTML
275
275
  def to_html *args
276
+ if Nokogiri.jruby?
277
+ options = args.first.is_a?(Hash) ? args.shift : {}
278
+ if !options[:save_with]
279
+ options[:save_with] = Node::SaveOptions::NO_DECLARATION | Node::SaveOptions::NO_EMPTY_TAGS | Node::SaveOptions::AS_HTML
280
+ end
281
+ args.insert(0, options)
282
+ end
276
283
  map { |x| x.to_html(*args) }.join
277
284
  end
278
285
 
@@ -37,6 +37,14 @@ module Nokogiri
37
37
  NOCDATA = 1 << 14
38
38
  # do not generate XINCLUDE START/END nodes
39
39
  NOXINCNODE = 1 << 15
40
+ # compact small text nodes; no modification of the tree allowed afterwards (will possibly crash if you try to modify the tree)
41
+ COMPACT = 1 << 16
42
+ # parse using XML-1.0 before update 5
43
+ OLD10 = 1 << 17
44
+ # do not fixup XINCLUDE xml:base uris
45
+ NOBASEFIX = 1 << 18
46
+ # relax any hardcoded limit from the parser
47
+ HUGE = 1 << 19
40
48
 
41
49
  # the default options used for parsing XML documents
42
50
  DEFAULT_XML = RECOVER
@@ -30,6 +30,42 @@ module Nokogiri
30
30
  class Reader
31
31
  include Enumerable
32
32
 
33
+ TYPE_NONE = 0
34
+ # Element node type
35
+ TYPE_ELEMENT = 1
36
+ # Attribute node type
37
+ TYPE_ATTRIBUTE = 2
38
+ # Text node type
39
+ TYPE_TEXT = 3
40
+ # CDATA node type
41
+ TYPE_CDATA = 4
42
+ # Entity Reference node type
43
+ TYPE_ENTITY_REFERENCE = 5
44
+ # Entity node type
45
+ TYPE_ENTITY = 6
46
+ # PI node type
47
+ TYPE_PROCESSING_INSTRUCTION = 7
48
+ # Comment node type
49
+ TYPE_COMMENT = 8
50
+ # Document node type
51
+ TYPE_DOCUMENT = 9
52
+ # Document Type node type
53
+ TYPE_DOCUMENT_TYPE = 10
54
+ # Document Fragment node type
55
+ TYPE_DOCUMENT_FRAGMENT = 11
56
+ # Notation node type
57
+ TYPE_NOTATION = 12
58
+ # Whitespace node type
59
+ TYPE_WHITESPACE = 13
60
+ # Significant Whitespace node type
61
+ TYPE_SIGNIFICANT_WHITESPACE = 14
62
+ # Element end node type
63
+ TYPE_END_ELEMENT = 15
64
+ # Entity end node type
65
+ TYPE_END_ENTITY = 16
66
+ # XML Declaration node type
67
+ TYPE_XML_DECLARATION = 17
68
+
33
69
  # A list of errors encountered while parsing
34
70
  attr_accessor :errors
35
71
 
@@ -51,9 +87,9 @@ module Nokogiri
51
87
  ###
52
88
  # Get a list of attributes for the current node.
53
89
  def attributes
54
- Hash[*(attribute_nodes.map { |node|
90
+ Hash[attribute_nodes.map { |node|
55
91
  [node.name, node.to_s]
56
- }.flatten)].merge(namespaces || {})
92
+ }].merge(namespaces || {})
57
93
  end
58
94
 
59
95
  ###
@@ -65,10 +101,10 @@ module Nokogiri
65
101
  end
66
102
 
67
103
  ###
68
- # Move the cursor through the document yielding each node to the block
69
- def each(&block)
70
- while node = self.read
71
- block.call(node)
104
+ # Move the cursor through the document yielding the cursor to the block
105
+ def each
106
+ while cursor = self.read
107
+ yield cursor
72
108
  end
73
109
  end
74
110
  end
@@ -85,7 +85,9 @@ module Nokogiri
85
85
 
86
86
  ###
87
87
  # Called at the beginning of an element
88
- # +name+ is the name of the tag with +attrs+ as attributes
88
+ # * +name+ is the name of the tag
89
+ # * +attrs+ are an assoc list of namespaces and attributes, e.g.:
90
+ # [ ["xmlns:foo", "http://sample.net"], ["size", "large"] ]
89
91
  def start_element name, attrs = []
90
92
  end
91
93
 
@@ -110,7 +112,7 @@ module Nokogiri
110
112
  [['xmlns', ns_prefix].compact.join(':'), ns_uri]
111
113
  } + attrs.map { |attr|
112
114
  [[attr.prefix, attr.localname].compact.join(':'), attr.value]
113
- }.flatten
115
+ }
114
116
  start_element name, attributes
115
117
  end
116
118
 
@@ -43,7 +43,13 @@ module Nokogiri
43
43
  # Nokogiri::XML::SyntaxError objects found while validating the
44
44
  # +thing+ is returned.
45
45
  def validate thing
46
- thing.is_a?(Nokogiri::XML::Document) ? validate_document(thing) : validate_file(thing)
46
+ if thing.is_a?(Nokogiri::XML::Document)
47
+ validate_document(thing)
48
+ elsif File.file?(thing)
49
+ validate_file(thing)
50
+ else
51
+ raise ArgumentError, "Must provide Nokogiri::Xml::Document or the name of an existing file"
52
+ end
47
53
  end
48
54
 
49
55
  ###