nokogiri 1.2.3-x86-mswin32-60 → 1.4.5-x86-mswin32-60

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 (319) hide show
  1. data/.autotest +18 -7
  2. data/.gemtest +0 -0
  3. data/CHANGELOG.ja.rdoc +297 -3
  4. data/CHANGELOG.rdoc +289 -0
  5. data/Manifest.txt +148 -37
  6. data/README.ja.rdoc +20 -20
  7. data/README.rdoc +53 -22
  8. data/Rakefile +127 -211
  9. data/bin/nokogiri +54 -0
  10. data/ext/nokogiri/depend +358 -0
  11. data/ext/nokogiri/extconf.rb +89 -54
  12. data/ext/nokogiri/html_document.c +34 -27
  13. data/ext/nokogiri/html_document.h +1 -1
  14. data/ext/nokogiri/html_element_description.c +276 -0
  15. data/ext/nokogiri/html_element_description.h +10 -0
  16. data/ext/nokogiri/html_entity_lookup.c +7 -5
  17. data/ext/nokogiri/html_entity_lookup.h +1 -1
  18. data/ext/nokogiri/html_sax_parser_context.c +94 -0
  19. data/ext/nokogiri/html_sax_parser_context.h +11 -0
  20. data/ext/nokogiri/{native.c → nokogiri.c} +31 -7
  21. data/ext/nokogiri/{native.h → nokogiri.h} +68 -41
  22. data/ext/nokogiri/xml_attr.c +20 -9
  23. data/ext/nokogiri/xml_attr.h +1 -1
  24. data/ext/nokogiri/xml_attribute_decl.c +70 -0
  25. data/ext/nokogiri/xml_attribute_decl.h +9 -0
  26. data/ext/nokogiri/xml_cdata.c +21 -9
  27. data/ext/nokogiri/xml_cdata.h +1 -1
  28. data/ext/nokogiri/xml_comment.c +18 -6
  29. data/ext/nokogiri/xml_comment.h +1 -1
  30. data/ext/nokogiri/xml_document.c +247 -68
  31. data/ext/nokogiri/xml_document.h +5 -3
  32. data/ext/nokogiri/xml_document_fragment.c +15 -7
  33. data/ext/nokogiri/xml_document_fragment.h +1 -1
  34. data/ext/nokogiri/xml_dtd.c +110 -10
  35. data/ext/nokogiri/xml_dtd.h +3 -1
  36. data/ext/nokogiri/xml_element_content.c +123 -0
  37. data/ext/nokogiri/xml_element_content.h +10 -0
  38. data/ext/nokogiri/xml_element_decl.c +69 -0
  39. data/ext/nokogiri/xml_element_decl.h +9 -0
  40. data/ext/nokogiri/xml_encoding_handler.c +79 -0
  41. data/ext/nokogiri/xml_encoding_handler.h +8 -0
  42. data/ext/nokogiri/xml_entity_decl.c +110 -0
  43. data/ext/nokogiri/xml_entity_decl.h +10 -0
  44. data/ext/nokogiri/xml_entity_reference.c +16 -5
  45. data/ext/nokogiri/xml_entity_reference.h +1 -1
  46. data/ext/nokogiri/xml_io.c +40 -8
  47. data/ext/nokogiri/xml_io.h +2 -1
  48. data/ext/nokogiri/xml_libxml2_hacks.c +112 -0
  49. data/ext/nokogiri/xml_libxml2_hacks.h +12 -0
  50. data/ext/nokogiri/xml_namespace.c +84 -0
  51. data/ext/nokogiri/xml_namespace.h +13 -0
  52. data/ext/nokogiri/xml_node.c +782 -225
  53. data/ext/nokogiri/xml_node.h +2 -4
  54. data/ext/nokogiri/xml_node_set.c +253 -34
  55. data/ext/nokogiri/xml_node_set.h +2 -2
  56. data/ext/nokogiri/xml_processing_instruction.c +17 -5
  57. data/ext/nokogiri/xml_processing_instruction.h +1 -1
  58. data/ext/nokogiri/xml_reader.c +277 -85
  59. data/ext/nokogiri/xml_reader.h +1 -1
  60. data/ext/nokogiri/xml_relax_ng.c +168 -0
  61. data/ext/nokogiri/xml_relax_ng.h +9 -0
  62. data/ext/nokogiri/xml_sax_parser.c +183 -111
  63. data/ext/nokogiri/xml_sax_parser.h +30 -1
  64. data/ext/nokogiri/xml_sax_parser_context.c +199 -0
  65. data/ext/nokogiri/xml_sax_parser_context.h +10 -0
  66. data/ext/nokogiri/xml_sax_push_parser.c +42 -12
  67. data/ext/nokogiri/xml_sax_push_parser.h +1 -1
  68. data/ext/nokogiri/xml_schema.c +205 -0
  69. data/ext/nokogiri/xml_schema.h +9 -0
  70. data/ext/nokogiri/xml_syntax_error.c +28 -173
  71. data/ext/nokogiri/xml_syntax_error.h +2 -1
  72. data/ext/nokogiri/xml_text.c +16 -6
  73. data/ext/nokogiri/xml_text.h +1 -1
  74. data/ext/nokogiri/xml_xpath_context.c +104 -47
  75. data/ext/nokogiri/xml_xpath_context.h +1 -1
  76. data/ext/nokogiri/xslt_stylesheet.c +161 -19
  77. data/ext/nokogiri/xslt_stylesheet.h +1 -1
  78. data/lib/nokogiri.rb +47 -8
  79. data/lib/nokogiri/1.8/nokogiri.so +0 -0
  80. data/lib/nokogiri/1.9/nokogiri.so +0 -0
  81. data/lib/nokogiri/css.rb +6 -3
  82. data/lib/nokogiri/css/node.rb +14 -12
  83. data/lib/nokogiri/css/parser.rb +665 -62
  84. data/lib/nokogiri/css/parser.y +20 -10
  85. data/lib/nokogiri/css/parser_extras.rb +91 -0
  86. data/lib/nokogiri/css/tokenizer.rb +148 -5
  87. data/lib/nokogiri/css/tokenizer.rex +10 -9
  88. data/lib/nokogiri/css/xpath_visitor.rb +47 -44
  89. data/lib/nokogiri/decorators/slop.rb +8 -4
  90. data/lib/nokogiri/ffi/encoding_handler.rb +42 -0
  91. data/lib/nokogiri/ffi/html/document.rb +28 -0
  92. data/lib/nokogiri/ffi/html/element_description.rb +81 -0
  93. data/lib/nokogiri/ffi/html/entity_lookup.rb +16 -0
  94. data/lib/nokogiri/ffi/html/sax/parser_context.rb +38 -0
  95. data/lib/nokogiri/ffi/io_callbacks.rb +42 -0
  96. data/lib/nokogiri/ffi/libxml.rb +420 -0
  97. data/lib/nokogiri/ffi/structs/common_node.rb +38 -0
  98. data/lib/nokogiri/ffi/structs/html_elem_desc.rb +24 -0
  99. data/lib/nokogiri/ffi/structs/html_entity_desc.rb +13 -0
  100. data/lib/nokogiri/ffi/structs/xml_alloc.rb +16 -0
  101. data/lib/nokogiri/ffi/structs/xml_attr.rb +20 -0
  102. data/lib/nokogiri/ffi/structs/xml_attribute.rb +27 -0
  103. data/lib/nokogiri/ffi/structs/xml_buffer.rb +16 -0
  104. data/lib/nokogiri/ffi/structs/xml_char_encoding_handler.rb +11 -0
  105. data/lib/nokogiri/ffi/structs/xml_document.rb +117 -0
  106. data/lib/nokogiri/ffi/structs/xml_dtd.rb +28 -0
  107. data/lib/nokogiri/ffi/structs/xml_element.rb +26 -0
  108. data/lib/nokogiri/ffi/structs/xml_element_content.rb +17 -0
  109. data/lib/nokogiri/ffi/structs/xml_entity.rb +32 -0
  110. data/lib/nokogiri/ffi/structs/xml_enumeration.rb +12 -0
  111. data/lib/nokogiri/ffi/structs/xml_node.rb +28 -0
  112. data/lib/nokogiri/ffi/structs/xml_node_set.rb +53 -0
  113. data/lib/nokogiri/ffi/structs/xml_notation.rb +11 -0
  114. data/lib/nokogiri/ffi/structs/xml_ns.rb +15 -0
  115. data/lib/nokogiri/ffi/structs/xml_parser_context.rb +20 -0
  116. data/lib/nokogiri/ffi/structs/xml_parser_input.rb +19 -0
  117. data/lib/nokogiri/ffi/structs/xml_relax_ng.rb +14 -0
  118. data/lib/nokogiri/ffi/structs/xml_sax_handler.rb +51 -0
  119. data/lib/nokogiri/ffi/structs/xml_sax_push_parser_context.rb +124 -0
  120. data/lib/nokogiri/ffi/structs/xml_schema.rb +13 -0
  121. data/lib/nokogiri/ffi/structs/xml_syntax_error.rb +31 -0
  122. data/lib/nokogiri/ffi/structs/xml_text_reader.rb +12 -0
  123. data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +38 -0
  124. data/lib/nokogiri/ffi/structs/xml_xpath_object.rb +35 -0
  125. data/lib/nokogiri/ffi/structs/xml_xpath_parser_context.rb +20 -0
  126. data/lib/nokogiri/ffi/structs/xslt_stylesheet.rb +13 -0
  127. data/lib/nokogiri/ffi/weak_bucket.rb +40 -0
  128. data/lib/nokogiri/ffi/xml/attr.rb +41 -0
  129. data/lib/nokogiri/ffi/xml/attribute_decl.rb +27 -0
  130. data/lib/nokogiri/ffi/xml/cdata.rb +19 -0
  131. data/lib/nokogiri/ffi/xml/comment.rb +18 -0
  132. data/lib/nokogiri/ffi/xml/document.rb +174 -0
  133. data/lib/nokogiri/ffi/xml/document_fragment.rb +21 -0
  134. data/lib/nokogiri/ffi/xml/dtd.rb +67 -0
  135. data/lib/nokogiri/ffi/xml/element_content.rb +43 -0
  136. data/lib/nokogiri/ffi/xml/element_decl.rb +19 -0
  137. data/lib/nokogiri/ffi/xml/entity_decl.rb +36 -0
  138. data/lib/nokogiri/ffi/xml/entity_reference.rb +19 -0
  139. data/lib/nokogiri/ffi/xml/namespace.rb +44 -0
  140. data/lib/nokogiri/ffi/xml/node.rb +559 -0
  141. data/lib/nokogiri/ffi/xml/node_set.rb +150 -0
  142. data/lib/nokogiri/ffi/xml/processing_instruction.rb +20 -0
  143. data/lib/nokogiri/ffi/xml/reader.rb +236 -0
  144. data/lib/nokogiri/ffi/xml/relax_ng.rb +85 -0
  145. data/lib/nokogiri/ffi/xml/sax/parser.rb +143 -0
  146. data/lib/nokogiri/ffi/xml/sax/parser_context.rb +79 -0
  147. data/lib/nokogiri/ffi/xml/sax/push_parser.rb +51 -0
  148. data/lib/nokogiri/ffi/xml/schema.rb +109 -0
  149. data/lib/nokogiri/ffi/xml/syntax_error.rb +98 -0
  150. data/lib/nokogiri/ffi/xml/text.rb +18 -0
  151. data/lib/nokogiri/ffi/xml/xpath.rb +9 -0
  152. data/lib/nokogiri/ffi/xml/xpath_context.rb +153 -0
  153. data/lib/nokogiri/ffi/xslt/stylesheet.rb +77 -0
  154. data/lib/nokogiri/html.rb +13 -47
  155. data/lib/nokogiri/html/builder.rb +27 -1
  156. data/lib/nokogiri/html/document.rb +201 -7
  157. data/lib/nokogiri/html/document_fragment.rb +41 -0
  158. data/lib/nokogiri/html/element_description.rb +23 -0
  159. data/lib/nokogiri/html/entity_lookup.rb +2 -0
  160. data/lib/nokogiri/html/sax/parser.rb +34 -3
  161. data/lib/nokogiri/html/sax/parser_context.rb +16 -0
  162. data/lib/nokogiri/nokogiri.rb +1 -0
  163. data/lib/nokogiri/version.rb +40 -1
  164. data/lib/nokogiri/version_warning.rb +14 -0
  165. data/lib/nokogiri/xml.rb +32 -53
  166. data/lib/nokogiri/xml/attr.rb +5 -0
  167. data/lib/nokogiri/xml/attribute_decl.rb +18 -0
  168. data/lib/nokogiri/xml/builder.rb +349 -29
  169. data/lib/nokogiri/xml/cdata.rb +3 -1
  170. data/lib/nokogiri/xml/character_data.rb +7 -0
  171. data/lib/nokogiri/xml/document.rb +166 -14
  172. data/lib/nokogiri/xml/document_fragment.rb +76 -1
  173. data/lib/nokogiri/xml/dtd.rb +16 -3
  174. data/lib/nokogiri/xml/element_content.rb +36 -0
  175. data/lib/nokogiri/xml/element_decl.rb +13 -0
  176. data/lib/nokogiri/xml/entity_decl.rb +19 -0
  177. data/lib/nokogiri/xml/namespace.rb +13 -0
  178. data/lib/nokogiri/xml/node.rb +561 -166
  179. data/lib/nokogiri/xml/node/save_options.rb +22 -2
  180. data/lib/nokogiri/xml/node_set.rb +202 -40
  181. data/lib/nokogiri/xml/parse_options.rb +93 -0
  182. data/lib/nokogiri/xml/pp.rb +2 -0
  183. data/lib/nokogiri/xml/pp/character_data.rb +18 -0
  184. data/lib/nokogiri/xml/pp/node.rb +56 -0
  185. data/lib/nokogiri/xml/processing_instruction.rb +2 -0
  186. data/lib/nokogiri/xml/reader.rb +93 -8
  187. data/lib/nokogiri/xml/relax_ng.rb +32 -0
  188. data/lib/nokogiri/xml/sax.rb +1 -7
  189. data/lib/nokogiri/xml/sax/document.rb +107 -2
  190. data/lib/nokogiri/xml/sax/parser.rb +57 -7
  191. data/lib/nokogiri/xml/sax/parser_context.rb +16 -0
  192. data/lib/nokogiri/xml/sax/push_parser.rb +13 -1
  193. data/lib/nokogiri/xml/schema.rb +63 -0
  194. data/lib/nokogiri/xml/syntax_error.rb +25 -1
  195. data/lib/nokogiri/xml/text.rb +4 -1
  196. data/lib/nokogiri/xml/xpath.rb +1 -1
  197. data/lib/nokogiri/xml/xpath/syntax_error.rb +3 -0
  198. data/lib/nokogiri/xml/xpath_context.rb +2 -0
  199. data/lib/nokogiri/xslt.rb +26 -2
  200. data/lib/nokogiri/xslt/stylesheet.rb +19 -0
  201. data/lib/xsd/xmlparser/nokogiri.rb +45 -9
  202. data/tasks/cross_compile.rb +173 -0
  203. data/tasks/test.rb +25 -69
  204. data/test/css/test_nthiness.rb +3 -4
  205. data/test/css/test_parser.rb +75 -20
  206. data/test/css/test_tokenizer.rb +23 -1
  207. data/test/css/test_xpath_visitor.rb +10 -1
  208. data/test/decorators/test_slop.rb +16 -0
  209. data/test/ffi/test_document.rb +35 -0
  210. data/test/files/2ch.html +108 -0
  211. data/test/files/address_book.rlx +12 -0
  212. data/test/files/address_book.xml +10 -0
  213. data/test/files/bar/bar.xsd +4 -0
  214. data/test/files/encoding.html +82 -0
  215. data/test/files/encoding.xhtml +84 -0
  216. data/test/files/foo/foo.xsd +4 -0
  217. data/test/files/po.xml +32 -0
  218. data/test/files/po.xsd +66 -0
  219. data/test/files/shift_jis.html +10 -0
  220. data/test/files/shift_jis.xml +5 -0
  221. data/test/files/snuggles.xml +3 -0
  222. data/test/files/staff.dtd +10 -0
  223. data/test/files/valid_bar.xml +2 -0
  224. data/test/helper.rb +101 -23
  225. data/test/html/sax/test_parser.rb +81 -2
  226. data/test/html/sax/test_parser_context.rb +48 -0
  227. data/test/html/test_builder.rb +39 -8
  228. data/test/html/test_document.rb +186 -23
  229. data/test/html/test_document_encoding.rb +78 -1
  230. data/test/html/test_document_fragment.rb +253 -0
  231. data/test/html/test_element_description.rb +98 -0
  232. data/test/html/test_named_characters.rb +1 -1
  233. data/test/html/test_node.rb +124 -36
  234. data/test/html/test_node_encoding.rb +27 -0
  235. data/test/test_convert_xpath.rb +1 -52
  236. data/test/test_css_cache.rb +2 -13
  237. data/test/test_encoding_handler.rb +46 -0
  238. data/test/test_memory_leak.rb +88 -19
  239. data/test/test_nokogiri.rb +38 -5
  240. data/test/test_reader.rb +188 -6
  241. data/test/test_soap4r_sax.rb +52 -0
  242. data/test/test_xslt_transforms.rb +183 -83
  243. data/test/xml/node/test_save_options.rb +1 -1
  244. data/test/xml/node/test_subclass.rb +44 -0
  245. data/test/xml/sax/test_parser.rb +175 -4
  246. data/test/xml/sax/test_parser_context.rb +113 -0
  247. data/test/xml/sax/test_push_parser.rb +90 -2
  248. data/test/xml/test_attr.rb +35 -1
  249. data/test/xml/test_attribute_decl.rb +82 -0
  250. data/test/xml/test_builder.rb +186 -1
  251. data/test/xml/test_cdata.rb +32 -1
  252. data/test/xml/test_comment.rb +13 -1
  253. data/test/xml/test_document.rb +415 -43
  254. data/test/xml/test_document_encoding.rb +1 -1
  255. data/test/xml/test_document_fragment.rb +173 -5
  256. data/test/xml/test_dtd.rb +61 -6
  257. data/test/xml/test_dtd_encoding.rb +3 -1
  258. data/test/xml/test_element_content.rb +56 -0
  259. data/test/xml/test_element_decl.rb +73 -0
  260. data/test/xml/test_entity_decl.rb +120 -0
  261. data/test/xml/test_entity_reference.rb +5 -1
  262. data/test/xml/test_namespace.rb +68 -0
  263. data/test/xml/test_node.rb +546 -201
  264. data/test/xml/test_node_attributes.rb +34 -0
  265. data/test/xml/test_node_encoding.rb +33 -3
  266. data/test/xml/test_node_reparenting.rb +321 -0
  267. data/test/xml/test_node_set.rb +538 -2
  268. data/test/xml/test_parse_options.rb +52 -0
  269. data/test/xml/test_processing_instruction.rb +6 -1
  270. data/test/xml/test_reader_encoding.rb +1 -1
  271. data/test/xml/test_relax_ng.rb +60 -0
  272. data/test/xml/test_schema.rb +94 -0
  273. data/test/xml/test_syntax_error.rb +12 -0
  274. data/test/xml/test_text.rb +35 -1
  275. data/test/xml/test_unparented_node.rb +5 -5
  276. data/test/xml/test_xpath.rb +142 -11
  277. data/test/xslt/test_custom_functions.rb +94 -0
  278. metadata +328 -92
  279. data/ext/nokogiri/html_sax_parser.c +0 -57
  280. data/ext/nokogiri/html_sax_parser.h +0 -11
  281. data/ext/nokogiri/iconv.dll +0 -0
  282. data/ext/nokogiri/libexslt.dll +0 -0
  283. data/ext/nokogiri/libxml2.dll +0 -0
  284. data/ext/nokogiri/libxslt.dll +0 -0
  285. data/ext/nokogiri/native.so +0 -0
  286. data/ext/nokogiri/xml_xpath.c +0 -53
  287. data/ext/nokogiri/xml_xpath.h +0 -11
  288. data/ext/nokogiri/zlib1.dll +0 -0
  289. data/lib/action-nokogiri.rb +0 -30
  290. data/lib/nokogiri/css/generated_parser.rb +0 -713
  291. data/lib/nokogiri/css/generated_tokenizer.rb +0 -144
  292. data/lib/nokogiri/decorators.rb +0 -2
  293. data/lib/nokogiri/decorators/hpricot.rb +0 -3
  294. data/lib/nokogiri/decorators/hpricot/node.rb +0 -56
  295. data/lib/nokogiri/decorators/hpricot/node_set.rb +0 -54
  296. data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +0 -28
  297. data/lib/nokogiri/hpricot.rb +0 -51
  298. data/lib/nokogiri/xml/comment.rb +0 -6
  299. data/lib/nokogiri/xml/element.rb +0 -6
  300. data/lib/nokogiri/xml/entity_declaration.rb +0 -9
  301. data/lib/nokogiri/xml/fragment_handler.rb +0 -34
  302. data/test/hpricot/files/basic.xhtml +0 -17
  303. data/test/hpricot/files/boingboing.html +0 -2266
  304. data/test/hpricot/files/cy0.html +0 -3653
  305. data/test/hpricot/files/immob.html +0 -400
  306. data/test/hpricot/files/pace_application.html +0 -1320
  307. data/test/hpricot/files/tenderlove.html +0 -16
  308. data/test/hpricot/files/uswebgen.html +0 -220
  309. data/test/hpricot/files/utf8.html +0 -1054
  310. data/test/hpricot/files/week9.html +0 -1723
  311. data/test/hpricot/files/why.xml +0 -19
  312. data/test/hpricot/load_files.rb +0 -11
  313. data/test/hpricot/test_alter.rb +0 -68
  314. data/test/hpricot/test_builder.rb +0 -20
  315. data/test/hpricot/test_parser.rb +0 -426
  316. data/test/hpricot/test_paths.rb +0 -15
  317. data/test/hpricot/test_preserved.rb +0 -77
  318. data/test/hpricot/test_xml.rb +0 -30
  319. data/test/test_gc.rb +0 -15
@@ -0,0 +1,41 @@
1
+ module Nokogiri
2
+ module HTML
3
+ class DocumentFragment < Nokogiri::XML::DocumentFragment
4
+ attr_accessor :errors
5
+
6
+ ####
7
+ # Create a Nokogiri::XML::DocumentFragment from +tags+, using +encoding+
8
+ def self.parse tags, encoding = nil
9
+ doc = HTML::Document.new
10
+
11
+ encoding ||= tags.respond_to?(:encoding) ? tags.encoding.name : 'UTF-8'
12
+ doc.encoding = encoding
13
+
14
+ new(doc, tags)
15
+ end
16
+
17
+ def initialize document, tags = nil, ctx = nil
18
+ return self unless tags
19
+
20
+ if ctx
21
+ preexisting_errors = document.errors.dup
22
+ node_set = ctx.parse("<div>#{tags}</div>")
23
+ node_set.first.children.each { |child| child.parent = self } unless node_set.empty?
24
+ self.errors = document.errors - preexisting_errors
25
+ else
26
+ # This is a horrible hack, but I don't care
27
+ if tags.strip =~ /^<body/i
28
+ path = "/html/body"
29
+ else
30
+ path = "/html/body/node()"
31
+ end
32
+
33
+ temp_doc = HTML::Document.parse "<html><body>#{tags}", nil, document.encoding
34
+ temp_doc.xpath(path).each { |child| child.parent = self }
35
+ self.errors = temp_doc.errors
36
+ end
37
+ children
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,23 @@
1
+ module Nokogiri
2
+ module HTML
3
+ class ElementDescription
4
+ ###
5
+ # Is this element a block element?
6
+ def block?
7
+ !inline?
8
+ end
9
+
10
+ ###
11
+ # Convert this description to a string
12
+ def to_s
13
+ "#{name}: #{description}"
14
+ end
15
+
16
+ ###
17
+ # Inspection information
18
+ def inspect
19
+ "#<#{self.class.name}: #{name} #{description}>"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -3,6 +3,8 @@ module Nokogiri
3
3
  class EntityDescription < Struct.new(:value, :name, :description); end
4
4
 
5
5
  class EntityLookup
6
+ ###
7
+ # Look up entity with +name+
6
8
  def [] name
7
9
  (val = get(name)) && val.value
8
10
  end
@@ -1,19 +1,50 @@
1
1
  module Nokogiri
2
2
  module HTML
3
+ ###
4
+ # Nokogiri lets you write a SAX parser to process HTML but get HTML
5
+ # correction features.
6
+ #
7
+ # See Nokogiri::HTML::SAX::Parser for a basic example of using a
8
+ # SAX parser with HTML.
9
+ #
10
+ # For more information on SAX parsers, see Nokogiri::XML::SAX
3
11
  module SAX
4
- class Parser < XML::SAX::Parser
12
+ ###
13
+ # This class lets you perform SAX style parsing on HTML with HTML
14
+ # error correction.
15
+ #
16
+ # Here is a basic usage example:
17
+ #
18
+ # class MyDoc < Nokogiri::XML::SAX::Document
19
+ # def start_element name, attributes = []
20
+ # puts "found a #{name}"
21
+ # end
22
+ # end
23
+ #
24
+ # parser = Nokogiri::HTML::SAX::Parser.new(MyDoc.new)
25
+ # parser.parse(File.read(ARGV[0], 'rb'))
26
+ #
27
+ # For more information on SAX parsers, see Nokogiri::XML::SAX
28
+ class Parser < Nokogiri::XML::SAX::Parser
5
29
  ###
6
30
  # Parse html stored in +data+ using +encoding+
7
31
  def parse_memory data, encoding = 'UTF-8'
8
- native_parse_memory(data, encoding)
32
+ raise ArgumentError unless data
33
+ return unless data.length > 0
34
+ ctx = ParserContext.memory(data, encoding)
35
+ yield ctx if block_given?
36
+ ctx.parse_with self
9
37
  end
10
38
 
11
39
  ###
12
40
  # Parse a file with +filename+
13
41
  def parse_file filename, encoding = 'UTF-8'
42
+ raise ArgumentError unless filename
14
43
  raise Errno::ENOENT unless File.exists?(filename)
15
44
  raise Errno::EISDIR if File.directory?(filename)
16
- native_parse_file filename, encoding
45
+ ctx = ParserContext.file(filename, encoding)
46
+ yield ctx if block_given?
47
+ ctx.parse_with self
17
48
  end
18
49
  end
19
50
  end
@@ -0,0 +1,16 @@
1
+ module Nokogiri
2
+ module HTML
3
+ module SAX
4
+ ###
5
+ # Context for HTML SAX parsers. This class is usually not instantiated
6
+ # by the user. Instead, you should be looking at
7
+ # Nokogiri::HTML::SAX::Parser
8
+ class ParserContext < Nokogiri::XML::SAX::ParserContext
9
+ def self.new thing, encoding = 'UTF-8'
10
+ [:read, :close].all? { |x| thing.respond_to?(x) } ? super :
11
+ memory(thing, encoding)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1 @@
1
+ require "nokogiri/#{RUBY_VERSION.sub(/\.\d+$/, '')}/nokogiri"
@@ -1,4 +1,43 @@
1
1
  module Nokogiri
2
2
  # The version of Nokogiri you are using
3
- VERSION = '1.2.3'
3
+ VERSION = '1.4.5'
4
+
5
+ # More complete version information about libxml
6
+ VERSION_INFO = {}
7
+ VERSION_INFO['warnings'] = []
8
+ VERSION_INFO['nokogiri'] = Nokogiri::VERSION
9
+ VERSION_INFO['ruby'] = {}
10
+ VERSION_INFO['ruby']['version'] = ::RUBY_VERSION
11
+ VERSION_INFO['ruby']['platform'] = ::RUBY_PLATFORM
12
+ VERSION_INFO['ruby']['description'] = ::RUBY_DESCRIPTION
13
+ VERSION_INFO['ruby']['engine'] = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'mri'
14
+ VERSION_INFO['ruby']['jruby'] = ::JRUBY_VERSION if RUBY_PLATFORM == "java"
15
+ if defined?(LIBXML_VERSION)
16
+ VERSION_INFO['libxml'] = {}
17
+ VERSION_INFO['libxml']['binding'] = 'extension'
18
+ VERSION_INFO['libxml']['compiled'] = LIBXML_VERSION
19
+ VERSION_INFO['libxml']['loaded'] = LIBXML_PARSER_VERSION.scan(/^(.*)(..)(..)$/).first.collect{|j|j.to_i}.join(".")
20
+
21
+ if VERSION_INFO['libxml']['compiled'] != VERSION_INFO['libxml']['loaded']
22
+ warning = "Nokogiri was built against LibXML version #{VERSION_INFO['libxml']['compiled']}, but has dynamically loaded #{VERSION_INFO['libxml']['loaded']}"
23
+ VERSION_INFO['warnings'] << warning
24
+ warn "WARNING: #{warning}"
25
+ end
26
+ end
27
+
28
+ def self.uses_libxml? # :nodoc:
29
+ !Nokogiri::VERSION_INFO['libxml'].nil?
30
+ end
31
+
32
+ def self.ffi? # :nodoc:
33
+ uses_libxml? && Nokogiri::VERSION_INFO['libxml']['binding'] == 'ffi'
34
+ end
35
+
36
+ def self.jruby?
37
+ false # for 1.5 compatibility
38
+ end
39
+
40
+ def self.is_2_6_16? # :nodoc:
41
+ Nokogiri::VERSION_INFO['libxml']['loaded'] <= '2.6.16'
42
+ end
4
43
  end
@@ -0,0 +1,14 @@
1
+ module Nokogiri
2
+ if self.is_2_6_16?
3
+ VERSION_INFO['warnings'] << "libxml 2.6.16 is old and buggy."
4
+ if !defined?(I_KNOW_I_AM_USING_AN_OLD_AND_BUGGY_VERSION_OF_LIBXML2)
5
+ warn <<-eom
6
+ HI. You're using libxml2 version 2.6.16 which is over 4 years old and has
7
+ plenty of bugs. We suggest that for maximum HTML/XML parsing pleasure, you
8
+ upgrade your version of libxml2 and re-install nokogiri. If you like using
9
+ libxml2 version 2.6.16, but don't like this warning, please define the constant
10
+ I_KNOW_I_AM_USING_AN_OLD_AND_BUGGY_VERSION_OF_LIBXML2 before requring nokogiri.
11
+ eom
12
+ end
13
+ end
14
+ end
data/lib/nokogiri/xml.rb CHANGED
@@ -1,14 +1,19 @@
1
+ require 'nokogiri/xml/pp'
2
+ require 'nokogiri/xml/parse_options'
1
3
  require 'nokogiri/xml/sax'
2
- require 'nokogiri/xml/fragment_handler'
3
4
  require 'nokogiri/xml/node'
5
+ require 'nokogiri/xml/attribute_decl'
6
+ require 'nokogiri/xml/element_decl'
7
+ require 'nokogiri/xml/element_content'
8
+ require 'nokogiri/xml/character_data'
9
+ require 'nokogiri/xml/namespace'
4
10
  require 'nokogiri/xml/attr'
5
11
  require 'nokogiri/xml/dtd'
6
- require 'nokogiri/xml/text'
7
12
  require 'nokogiri/xml/cdata'
8
- require 'nokogiri/xml/processing_instruction'
9
- require 'nokogiri/xml/comment'
13
+ require 'nokogiri/xml/text'
10
14
  require 'nokogiri/xml/document'
11
15
  require 'nokogiri/xml/document_fragment'
16
+ require 'nokogiri/xml/processing_instruction'
12
17
  require 'nokogiri/xml/node_set'
13
18
  require 'nokogiri/xml/syntax_error'
14
19
  require 'nokogiri/xml/xpath'
@@ -16,72 +21,46 @@ require 'nokogiri/xml/xpath_context'
16
21
  require 'nokogiri/xml/builder'
17
22
  require 'nokogiri/xml/reader'
18
23
  require 'nokogiri/xml/notation'
19
- require 'nokogiri/xml/element'
20
- require 'nokogiri/xml/entity_declaration'
24
+ require 'nokogiri/xml/entity_decl'
25
+ require 'nokogiri/xml/schema'
26
+ require 'nokogiri/xml/relax_ng'
21
27
 
22
28
  module Nokogiri
23
29
  class << self
24
30
  ###
25
- # Parse an XML file. +thing+ may be a String, or any object that
26
- # responds to _read_ and _close_ such as an IO, or StringIO.
27
- # +url+ is resource where this document is located. +encoding+ is the
28
- # encoding that should be used when processing the document. +options+
29
- # is a number that sets options in the parser, such as
30
- # Nokogiri::XML::PARSE_RECOVER. See the constants in
31
- # Nokogiri::XML.
32
- def XML thing, url = nil, encoding = nil, options = 1
33
- Nokogiri::XML.parse(thing, url, encoding, options)
31
+ # Parse XML. Convenience method for Nokogiri::XML::Document.parse
32
+ def XML thing, url = nil, encoding = nil, options = XML::ParseOptions::DEFAULT_XML, &block
33
+ Nokogiri::XML::Document.parse(thing, url, encoding, options, &block)
34
34
  end
35
35
  end
36
36
 
37
37
  module XML
38
- # Parser options
39
- PARSE_RECOVER = 1 << 0 # Recover from errors
40
- PARSE_NOENT = 1 << 1 # Substitute entities
41
- PARSE_DTDLOAD = 1 << 2 # Load external subsets
42
- PARSE_DTDATTR = 1 << 3 # Default DTD attributes
43
- PARSE_DTDVALID = 1 << 4 # validate with the DTD
44
- PARSE_NOERROR = 1 << 5 # suppress error reports
45
- PARSE_NOWARNING = 1 << 6 # suppress warning reports
46
- PARSE_PEDANTIC = 1 << 7 # pedantic error reporting
47
- PARSE_NOBLANKS = 1 << 8 # remove blank nodes
48
- PARSE_SAX1 = 1 << 9 # use the SAX1 interface internally
49
- PARSE_XINCLUDE = 1 << 10 # Implement XInclude substitition
50
- PARSE_NONET = 1 << 11 # Forbid network access
51
- PARSE_NODICT = 1 << 12 # Do not reuse the context dictionnary
52
- PARSE_NSCLEAN = 1 << 13 # remove redundant namespaces declarations
53
- PARSE_NOCDATA = 1 << 14 # merge CDATA as text nodes
54
- PARSE_NOXINCNODE = 1 << 15 # do not generate XINCLUDE START/END nodes
55
-
56
38
  class << self
57
- def Reader string, url = nil, encoding = nil, options = 0
58
- Reader.from_memory(string, url, encoding, options)
59
- end
60
-
61
39
  ###
62
- # Parse an XML document. See Nokogiri.XML.
63
- def parse string_or_io, url = nil, encoding = nil, options = 2159
64
- if string_or_io.respond_to?(:read)
65
- url ||= string_or_io.respond_to?(:path) ? string_or_io.path : nil
66
- return Document.read_io(string_or_io, url, encoding, options)
67
- end
40
+ # Parse an XML document using the Nokogiri::XML::Reader API. See
41
+ # Nokogiri::XML::Reader for mor information
42
+ def Reader string_or_io, url = nil, encoding = nil, options = ParseOptions::STRICT
68
43
 
69
- # read_memory pukes on empty docs
70
- return Document.new if string_or_io.nil? or string_or_io.empty?
44
+ options = Nokogiri::XML::ParseOptions.new(options) if Fixnum === options
45
+ # Give the options to the user
46
+ yield options if block_given?
71
47
 
72
- Document.read_memory(string_or_io, url, encoding, options)
48
+ if string_or_io.respond_to? :read
49
+ return Reader.from_io(string_or_io, url, encoding, options.to_i)
50
+ end
51
+ Reader.from_memory(string_or_io, url, encoding, options.to_i)
73
52
  end
74
53
 
75
54
  ###
76
- # Sets whether or not entities should be substituted.
77
- def substitute_entities=(value = true)
78
- Document.substitute_entities = value
55
+ # Parse XML. Convenience method for Nokogiri::XML::Document.parse
56
+ def parse thing, url = nil, encoding = nil, options = ParseOptions::DEFAULT_XML, &block
57
+ Document.parse(thing, url, encoding, options, &block)
79
58
  end
80
59
 
81
- ###
82
- # Sets whether or not external subsets should be loaded
83
- def load_external_subsets=(value = true)
84
- Document.load_external_subsets = value
60
+ ####
61
+ # Parse a fragment from +string+ in to a NodeSet.
62
+ def fragment string
63
+ XML::DocumentFragment.parse(string)
85
64
  end
86
65
  end
87
66
  end
@@ -4,6 +4,11 @@ module Nokogiri
4
4
  alias :value :content
5
5
  alias :to_s :content
6
6
  alias :content= :value=
7
+
8
+ private
9
+ def inspect_attributes
10
+ [:name, :namespace, :value]
11
+ end
7
12
  end
8
13
  end
9
14
  end
@@ -0,0 +1,18 @@
1
+ module Nokogiri
2
+ module XML
3
+ ###
4
+ # Represents an attribute declaration in a DTD
5
+ class AttributeDecl < Nokogiri::XML::Node
6
+ undef_method :attribute_nodes
7
+ undef_method :attributes
8
+ undef_method :content
9
+ undef_method :namespace
10
+ undef_method :namespace_definitions
11
+ undef_method :line
12
+
13
+ def inspect
14
+ "#<#{self.class.name}:#{sprintf("0x%x", object_id)} #{to_s.inspect}>"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,46 +1,350 @@
1
1
  module Nokogiri
2
2
  module XML
3
+ ###
4
+ # Nokogiri builder can be used for building XML and HTML documents.
5
+ #
6
+ # == Synopsis:
7
+ #
8
+ # builder = Nokogiri::XML::Builder.new do |xml|
9
+ # xml.root {
10
+ # xml.products {
11
+ # xml.widget {
12
+ # xml.id_ "10"
13
+ # xml.name "Awesome widget"
14
+ # }
15
+ # }
16
+ # }
17
+ # end
18
+ # puts builder.to_xml
19
+ #
20
+ # Will output:
21
+ #
22
+ # <?xml version="1.0"?>
23
+ # <root>
24
+ # <products>
25
+ # <widget>
26
+ # <id>10</id>
27
+ # <name>Awesome widget</name>
28
+ # </widget>
29
+ # </products>
30
+ # </root>
31
+ #
32
+ #
33
+ # === Builder scope
34
+ #
35
+ # The builder allows two forms. When the builder is supplied with a block
36
+ # that has a parameter, the outside scope is maintained. This means you
37
+ # can access variables that are outside your builder. If you don't need
38
+ # outside scope, you can use the builder without the "xml" prefix like
39
+ # this:
40
+ #
41
+ # builder = Nokogiri::XML::Builder.new do
42
+ # root {
43
+ # products {
44
+ # widget {
45
+ # id_ "10"
46
+ # name "Awesome widget"
47
+ # }
48
+ # }
49
+ # }
50
+ # end
51
+ #
52
+ # == Special Tags
53
+ #
54
+ # The builder works by taking advantage of method_missing. Unfortunately
55
+ # some methods are defined in ruby that are difficult or dangerous to
56
+ # remove. You may want to create tags with the name "type", "class", and
57
+ # "id" for example. In that case, you can use an underscore to
58
+ # disambiguate your tag name from the method call.
59
+ #
60
+ # Here is an example of using the underscore to disambiguate tag names from
61
+ # ruby methods:
62
+ #
63
+ # @objects = [Object.new, Object.new, Object.new]
64
+ #
65
+ # builder = Nokogiri::XML::Builder.new do |xml|
66
+ # xml.root {
67
+ # xml.objects {
68
+ # @objects.each do |o|
69
+ # xml.object {
70
+ # xml.type_ o.type
71
+ # xml.class_ o.class.name
72
+ # xml.id_ o.id
73
+ # }
74
+ # end
75
+ # }
76
+ # }
77
+ # end
78
+ # puts builder.to_xml
79
+ #
80
+ # The underscore may be used with any tag name, and the last underscore
81
+ # will just be removed. This code will output the following XML:
82
+ #
83
+ # <?xml version="1.0"?>
84
+ # <root>
85
+ # <objects>
86
+ # <object>
87
+ # <type>Object</type>
88
+ # <class>Object</class>
89
+ # <id>48390</id>
90
+ # </object>
91
+ # <object>
92
+ # <type>Object</type>
93
+ # <class>Object</class>
94
+ # <id>48380</id>
95
+ # </object>
96
+ # <object>
97
+ # <type>Object</type>
98
+ # <class>Object</class>
99
+ # <id>48370</id>
100
+ # </object>
101
+ # </objects>
102
+ # </root>
103
+ #
104
+ # == Tag Attributes
105
+ #
106
+ # Tag attributes may be supplied as method arguments. Here is our
107
+ # previous example, but using attributes rather than tags:
108
+ #
109
+ # @objects = [Object.new, Object.new, Object.new]
110
+ #
111
+ # builder = Nokogiri::XML::Builder.new do |xml|
112
+ # xml.root {
113
+ # xml.objects {
114
+ # @objects.each do |o|
115
+ # xml.object(:type => o.type, :class => o.class, :id => o.id)
116
+ # end
117
+ # }
118
+ # }
119
+ # end
120
+ # puts builder.to_xml
121
+ #
122
+ # === Tag Attribute Short Cuts
123
+ #
124
+ # A couple attribute short cuts are available when building tags. The
125
+ # short cuts are available by special method calls when building a tag.
126
+ #
127
+ # This example builds an "object" tag with the class attribute "classy"
128
+ # and the id of "thing":
129
+ #
130
+ # builder = Nokogiri::XML::Builder.new do |xml|
131
+ # xml.root {
132
+ # xml.objects {
133
+ # xml.object.classy.thing!
134
+ # }
135
+ # }
136
+ # end
137
+ # puts builder.to_xml
138
+ #
139
+ # Which will output:
140
+ #
141
+ # <?xml version="1.0"?>
142
+ # <root>
143
+ # <objects>
144
+ # <object class="classy" id="thing"/>
145
+ # </objects>
146
+ # </root>
147
+ #
148
+ # All other options are still supported with this syntax, including
149
+ # blocks and extra tag attributes.
150
+ #
151
+ # == Namespaces
152
+ #
153
+ # Namespaces are added similarly to attributes. Nokogiri::XML::Builder
154
+ # assumes that when an attribute starts with "xmlns", it is meant to be
155
+ # a namespace:
156
+ #
157
+ # builder = Nokogiri::XML::Builder.new { |xml|
158
+ # xml.root('xmlns' => 'default', 'xmlns:foo' => 'bar') do
159
+ # xml.tenderlove
160
+ # end
161
+ # }
162
+ # puts builder.to_xml
163
+ #
164
+ # Will output XML like this:
165
+ #
166
+ # <?xml version="1.0"?>
167
+ # <root xmlns:foo="bar" xmlns="default">
168
+ # <tenderlove/>
169
+ # </root>
170
+ #
171
+ # === Referencing declared namespaces
172
+ #
173
+ # Tags that reference non-default namespaces (i.e. a tag "foo:bar") can be
174
+ # built by using the Nokogiri::XML::Builder#[] method.
175
+ #
176
+ # For example:
177
+ #
178
+ # builder = Nokogiri::XML::Builder.new do |xml|
179
+ # xml.root('xmlns:foo' => 'bar') {
180
+ # xml.objects {
181
+ # xml['foo'].object.classy.thing!
182
+ # }
183
+ # }
184
+ # end
185
+ # puts builder.to_xml
186
+ #
187
+ # Will output this XML:
188
+ #
189
+ # <?xml version="1.0"?>
190
+ # <root xmlns:foo="bar">
191
+ # <objects>
192
+ # <foo:object class="classy" id="thing"/>
193
+ # </objects>
194
+ # </root>
195
+ #
196
+ # Note the "foo:object" tag.
197
+ #
198
+ # == Document Types
199
+ #
200
+ # To create a document type (DTD), access use the Builder#doc method to get
201
+ # the current context document. Then call Node#create_internal_subset to
202
+ # create the DTD node.
203
+ #
204
+ # For example, this Ruby:
205
+ #
206
+ # builder = Nokogiri::XML::Builder.new do |xml|
207
+ # xml.doc.create_internal_subset(
208
+ # 'html',
209
+ # "-//W3C//DTD HTML 4.01 Transitional//EN",
210
+ # "http://www.w3.org/TR/html4/loose.dtd"
211
+ # )
212
+ # xml.root do
213
+ # xml.foo
214
+ # end
215
+ # end
216
+ #
217
+ # puts builder.to_xml
218
+ #
219
+ # Will output this xml:
220
+ #
221
+ # <?xml version="1.0"?>
222
+ # <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
223
+ # <root>
224
+ # <foo/>
225
+ # </root>
226
+ #
3
227
  class Builder
4
- attr_accessor :doc, :parent, :context
5
- def initialize &block
6
- namespace = self.class.name.split('::')
7
- namespace[-1] = 'Document'
8
- @doc = eval(namespace.join('::')).new
9
- @parent = @doc
10
- @context = nil
11
- if block_given?
228
+ # The current Document object being built
229
+ attr_accessor :doc
230
+
231
+ # The parent of the current node being built
232
+ attr_accessor :parent
233
+
234
+ # A context object for use when the block has no arguments
235
+ attr_accessor :context
236
+
237
+ attr_accessor :arity # :nodoc:
238
+
239
+ ###
240
+ # Create a builder with an existing root object. This is for use when
241
+ # you have an existing document that you would like to augment with
242
+ # builder methods. The builder context created will start with the
243
+ # given +root+ node.
244
+ #
245
+ # For example:
246
+ #
247
+ # doc = Nokogiri::XML(open('somedoc.xml'))
248
+ # Nokogiri::XML::Builder.with(doc.at('some_tag')) do |xml|
249
+ # # ... Use normal builder methods here ...
250
+ # xml.awesome # add the "awesome" tag below "some_tag"
251
+ # end
252
+ #
253
+ def self.with root, &block
254
+ new({}, root, &block)
255
+ end
256
+
257
+ ###
258
+ # Create a new Builder object. +options+ are sent to the top level
259
+ # Document that is being built.
260
+ #
261
+ # Building a document with a particular encoding for example:
262
+ #
263
+ # Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
264
+ # ...
265
+ # end
266
+ def initialize options = {}, root = nil, &block
267
+
268
+ if root
269
+ @doc = root.document
270
+ @parent = root
271
+ else
272
+ namespace = self.class.name.split('::')
273
+ namespace[-1] = 'Document'
274
+ @doc = eval(namespace.join('::')).new
275
+ @parent = @doc
276
+ end
277
+
278
+ @context = nil
279
+ @arity = nil
280
+ @ns = nil
281
+
282
+ options.each do |k,v|
283
+ @doc.send(:"#{k}=", v)
284
+ end
285
+
286
+ return unless block_given?
287
+
288
+ @arity = block.arity
289
+ if @arity <= 0
12
290
  @context = eval('self', block.binding)
291
+ instance_eval(&block)
292
+ else
293
+ yield self
13
294
  end
14
- instance_eval(&block) if block_given?
295
+
15
296
  @parent = @doc
16
297
  end
17
298
 
299
+ ###
300
+ # Create a Text Node with content of +string+
18
301
  def text string
19
- node = Nokogiri::XML::Text.new(string.to_s, @doc)
20
- insert(node)
302
+ insert @doc.create_text_node(string)
21
303
  end
22
304
 
305
+ ###
306
+ # Create a CDATA Node with content of +string+
23
307
  def cdata string
24
- node = Nokogiri::XML::CDATA.new(@doc, string.to_s)
25
- insert(node)
308
+ insert(doc.create_cdata(string))
309
+ end
310
+
311
+ ###
312
+ # Build a tag that is associated with namespace +ns+. Raises an
313
+ # ArgumentError if +ns+ has not been defined higher in the tree.
314
+ def [] ns
315
+ @ns = @parent.namespace_definitions.find { |x| x.prefix == ns.to_s }
316
+ return self if @ns
317
+
318
+ @parent.ancestors.each do |a|
319
+ next if a == doc
320
+ @ns = a.namespace_definitions.find { |x| x.prefix == ns.to_s }
321
+ return self if @ns
322
+ end
323
+
324
+ raise ArgumentError, "Namespace #{ns} has not been defined"
325
+ end
326
+
327
+ ###
328
+ # Convert this Builder object to XML
329
+ def to_xml(*args)
330
+ @doc.to_xml(*args)
26
331
  end
27
332
 
28
- def to_xml
29
- @doc.to_xml
333
+ ###
334
+ # Append the given raw XML +string+ to the document
335
+ def << string
336
+ @doc.fragment(string).children.each { |x| insert(x) }
30
337
  end
31
338
 
32
- def method_missing method, *args, &block
339
+ def method_missing method, *args, &block # :nodoc:
33
340
  if @context && @context.respond_to?(method)
34
341
  @context.send(method, *args, &block)
35
342
  else
36
- node = Nokogiri::XML::Node.new(method.to_s, @doc) { |n|
37
- args.each do |arg|
38
- case arg
39
- when Hash
40
- arg.each { |k,v| n[k.to_s] = v.to_s }
41
- else
42
- n.content = arg
43
- end
343
+ node = @doc.create_element(method.to_s.sub(/[_!]$/, ''),*args) { |n|
344
+ # Set up the namespace
345
+ if @ns
346
+ n.namespace = @ns
347
+ @ns = nil
44
348
  end
45
349
  }
46
350
  insert(node, &block)
@@ -48,22 +352,38 @@ module Nokogiri
48
352
  end
49
353
 
50
354
  private
355
+ ###
356
+ # Insert +node+ as a child of the current Node
51
357
  def insert(node, &block)
52
358
  node.parent = @parent
53
359
  if block_given?
54
- @parent = node
55
- instance_eval(&block)
56
- @parent = node.parent
360
+ old_parent = @parent
361
+ @parent = node
362
+ @arity ||= block.arity
363
+ if @arity <= 0
364
+ instance_eval(&block)
365
+ else
366
+ block.call(self)
367
+ end
368
+ @parent = old_parent
57
369
  end
58
370
  NodeBuilder.new(node, self)
59
371
  end
60
372
 
61
373
  class NodeBuilder # :nodoc:
62
- def initialize(node, doc_builder)
374
+ def initialize node, doc_builder
63
375
  @node = node
64
376
  @doc_builder = doc_builder
65
377
  end
66
378
 
379
+ def []= k, v
380
+ @node[k] = v
381
+ end
382
+
383
+ def [] k
384
+ @node[k]
385
+ end
386
+
67
387
  def method_missing(method, *args, &block)
68
388
  opts = args.last.is_a?(Hash) ? args.pop : {}
69
389
  case method.to_s
@@ -73,7 +393,7 @@ module Nokogiri
73
393
  when /^(.*)=/
74
394
  @node[$1] = args.first
75
395
  else
76
- @node['class'] =
396
+ @node['class'] =
77
397
  ((@node['class'] || '').split(/\s/) + [method.to_s]).join(' ')
78
398
  @node.content = args.first if args.first
79
399
  end