rubyjedi-nokogiri_java 1.4.0.20100513161003-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (285) hide show
  1. data/.autotest +26 -0
  2. data/CHANGELOG.ja.rdoc +330 -0
  3. data/CHANGELOG.rdoc +341 -0
  4. data/Manifest.txt +277 -0
  5. data/README.ja.rdoc +105 -0
  6. data/README.rdoc +125 -0
  7. data/Rakefile +307 -0
  8. data/bin/nokogiri +49 -0
  9. data/deps.rip +5 -0
  10. data/ext/nokogiri/extconf.rb +149 -0
  11. data/ext/nokogiri/html_document.c +145 -0
  12. data/ext/nokogiri/html_document.h +10 -0
  13. data/ext/nokogiri/html_element_description.c +272 -0
  14. data/ext/nokogiri/html_element_description.h +10 -0
  15. data/ext/nokogiri/html_entity_lookup.c +32 -0
  16. data/ext/nokogiri/html_entity_lookup.h +8 -0
  17. data/ext/nokogiri/html_sax_parser_context.c +92 -0
  18. data/ext/nokogiri/html_sax_parser_context.h +11 -0
  19. data/ext/nokogiri/nokogiri.c +96 -0
  20. data/ext/nokogiri/nokogiri.h +148 -0
  21. data/ext/nokogiri/xml_attr.c +92 -0
  22. data/ext/nokogiri/xml_attr.h +9 -0
  23. data/ext/nokogiri/xml_attribute_decl.c +67 -0
  24. data/ext/nokogiri/xml_attribute_decl.h +9 -0
  25. data/ext/nokogiri/xml_cdata.c +54 -0
  26. data/ext/nokogiri/xml_cdata.h +9 -0
  27. data/ext/nokogiri/xml_comment.c +52 -0
  28. data/ext/nokogiri/xml_comment.h +9 -0
  29. data/ext/nokogiri/xml_document.c +386 -0
  30. data/ext/nokogiri/xml_document.h +24 -0
  31. data/ext/nokogiri/xml_document_fragment.c +46 -0
  32. data/ext/nokogiri/xml_document_fragment.h +10 -0
  33. data/ext/nokogiri/xml_dtd.c +192 -0
  34. data/ext/nokogiri/xml_dtd.h +10 -0
  35. data/ext/nokogiri/xml_element_content.c +123 -0
  36. data/ext/nokogiri/xml_element_content.h +10 -0
  37. data/ext/nokogiri/xml_element_decl.c +69 -0
  38. data/ext/nokogiri/xml_element_decl.h +9 -0
  39. data/ext/nokogiri/xml_encoding_handler.c +79 -0
  40. data/ext/nokogiri/xml_encoding_handler.h +8 -0
  41. data/ext/nokogiri/xml_entity_decl.c +97 -0
  42. data/ext/nokogiri/xml_entity_decl.h +10 -0
  43. data/ext/nokogiri/xml_entity_reference.c +50 -0
  44. data/ext/nokogiri/xml_entity_reference.h +9 -0
  45. data/ext/nokogiri/xml_io.c +31 -0
  46. data/ext/nokogiri/xml_io.h +11 -0
  47. data/ext/nokogiri/xml_namespace.c +82 -0
  48. data/ext/nokogiri/xml_namespace.h +13 -0
  49. data/ext/nokogiri/xml_node.c +1080 -0
  50. data/ext/nokogiri/xml_node.h +13 -0
  51. data/ext/nokogiri/xml_node_set.c +405 -0
  52. data/ext/nokogiri/xml_node_set.h +9 -0
  53. data/ext/nokogiri/xml_processing_instruction.c +54 -0
  54. data/ext/nokogiri/xml_processing_instruction.h +9 -0
  55. data/ext/nokogiri/xml_reader.c +593 -0
  56. data/ext/nokogiri/xml_reader.h +10 -0
  57. data/ext/nokogiri/xml_relax_ng.c +159 -0
  58. data/ext/nokogiri/xml_relax_ng.h +9 -0
  59. data/ext/nokogiri/xml_sax_parser.c +283 -0
  60. data/ext/nokogiri/xml_sax_parser.h +43 -0
  61. data/ext/nokogiri/xml_sax_parser_context.c +157 -0
  62. data/ext/nokogiri/xml_sax_parser_context.h +10 -0
  63. data/ext/nokogiri/xml_sax_push_parser.c +114 -0
  64. data/ext/nokogiri/xml_sax_push_parser.h +9 -0
  65. data/ext/nokogiri/xml_schema.c +156 -0
  66. data/ext/nokogiri/xml_schema.h +9 -0
  67. data/ext/nokogiri/xml_syntax_error.c +52 -0
  68. data/ext/nokogiri/xml_syntax_error.h +13 -0
  69. data/ext/nokogiri/xml_text.c +48 -0
  70. data/ext/nokogiri/xml_text.h +9 -0
  71. data/ext/nokogiri/xml_xpath.c +53 -0
  72. data/ext/nokogiri/xml_xpath.h +11 -0
  73. data/ext/nokogiri/xml_xpath_context.c +239 -0
  74. data/ext/nokogiri/xml_xpath_context.h +9 -0
  75. data/ext/nokogiri/xslt_stylesheet.c +131 -0
  76. data/ext/nokogiri/xslt_stylesheet.h +9 -0
  77. data/lib/isorelax.jar +0 -0
  78. data/lib/jing.jar +0 -0
  79. data/lib/nekodtd.jar +0 -0
  80. data/lib/nekohtml.jar +0 -0
  81. data/lib/nokogiri.rb +123 -0
  82. data/lib/nokogiri/css.rb +25 -0
  83. data/lib/nokogiri/css/generated_parser.rb +659 -0
  84. data/lib/nokogiri/css/generated_tokenizer.rb +145 -0
  85. data/lib/nokogiri/css/node.rb +99 -0
  86. data/lib/nokogiri/css/parser.rb +82 -0
  87. data/lib/nokogiri/css/parser.y +230 -0
  88. data/lib/nokogiri/css/syntax_error.rb +7 -0
  89. data/lib/nokogiri/css/tokenizer.rb +7 -0
  90. data/lib/nokogiri/css/tokenizer.rex +55 -0
  91. data/lib/nokogiri/css/xpath_visitor.rb +164 -0
  92. data/lib/nokogiri/decorators/slop.rb +33 -0
  93. data/lib/nokogiri/ffi/encoding_handler.rb +42 -0
  94. data/lib/nokogiri/ffi/html/document.rb +28 -0
  95. data/lib/nokogiri/ffi/html/element_description.rb +81 -0
  96. data/lib/nokogiri/ffi/html/entity_lookup.rb +16 -0
  97. data/lib/nokogiri/ffi/html/sax/parser_context.rb +38 -0
  98. data/lib/nokogiri/ffi/io_callbacks.rb +42 -0
  99. data/lib/nokogiri/ffi/libxml.rb +372 -0
  100. data/lib/nokogiri/ffi/structs/common_node.rb +26 -0
  101. data/lib/nokogiri/ffi/structs/html_elem_desc.rb +24 -0
  102. data/lib/nokogiri/ffi/structs/html_entity_desc.rb +13 -0
  103. data/lib/nokogiri/ffi/structs/xml_alloc.rb +16 -0
  104. data/lib/nokogiri/ffi/structs/xml_attr.rb +19 -0
  105. data/lib/nokogiri/ffi/structs/xml_attribute.rb +27 -0
  106. data/lib/nokogiri/ffi/structs/xml_buffer.rb +16 -0
  107. data/lib/nokogiri/ffi/structs/xml_char_encoding_handler.rb +11 -0
  108. data/lib/nokogiri/ffi/structs/xml_document.rb +108 -0
  109. data/lib/nokogiri/ffi/structs/xml_dtd.rb +28 -0
  110. data/lib/nokogiri/ffi/structs/xml_element.rb +26 -0
  111. data/lib/nokogiri/ffi/structs/xml_element_content.rb +17 -0
  112. data/lib/nokogiri/ffi/structs/xml_entity.rb +32 -0
  113. data/lib/nokogiri/ffi/structs/xml_enumeration.rb +12 -0
  114. data/lib/nokogiri/ffi/structs/xml_node.rb +28 -0
  115. data/lib/nokogiri/ffi/structs/xml_node_set.rb +53 -0
  116. data/lib/nokogiri/ffi/structs/xml_notation.rb +11 -0
  117. data/lib/nokogiri/ffi/structs/xml_ns.rb +15 -0
  118. data/lib/nokogiri/ffi/structs/xml_parser_context.rb +19 -0
  119. data/lib/nokogiri/ffi/structs/xml_relax_ng.rb +14 -0
  120. data/lib/nokogiri/ffi/structs/xml_sax_handler.rb +51 -0
  121. data/lib/nokogiri/ffi/structs/xml_sax_push_parser_context.rb +124 -0
  122. data/lib/nokogiri/ffi/structs/xml_schema.rb +13 -0
  123. data/lib/nokogiri/ffi/structs/xml_syntax_error.rb +31 -0
  124. data/lib/nokogiri/ffi/structs/xml_text_reader.rb +12 -0
  125. data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +37 -0
  126. data/lib/nokogiri/ffi/structs/xml_xpath_object.rb +35 -0
  127. data/lib/nokogiri/ffi/structs/xml_xpath_parser_context.rb +20 -0
  128. data/lib/nokogiri/ffi/structs/xslt_stylesheet.rb +13 -0
  129. data/lib/nokogiri/ffi/xml/attr.rb +41 -0
  130. data/lib/nokogiri/ffi/xml/attribute_decl.rb +27 -0
  131. data/lib/nokogiri/ffi/xml/cdata.rb +19 -0
  132. data/lib/nokogiri/ffi/xml/comment.rb +18 -0
  133. data/lib/nokogiri/ffi/xml/document.rb +135 -0
  134. data/lib/nokogiri/ffi/xml/document_fragment.rb +21 -0
  135. data/lib/nokogiri/ffi/xml/dtd.rb +67 -0
  136. data/lib/nokogiri/ffi/xml/element_content.rb +43 -0
  137. data/lib/nokogiri/ffi/xml/element_decl.rb +19 -0
  138. data/lib/nokogiri/ffi/xml/entity_decl.rb +27 -0
  139. data/lib/nokogiri/ffi/xml/entity_reference.rb +19 -0
  140. data/lib/nokogiri/ffi/xml/namespace.rb +44 -0
  141. data/lib/nokogiri/ffi/xml/node.rb +465 -0
  142. data/lib/nokogiri/ffi/xml/node_set.rb +146 -0
  143. data/lib/nokogiri/ffi/xml/processing_instruction.rb +20 -0
  144. data/lib/nokogiri/ffi/xml/reader.rb +227 -0
  145. data/lib/nokogiri/ffi/xml/relax_ng.rb +85 -0
  146. data/lib/nokogiri/ffi/xml/sax/parser.rb +135 -0
  147. data/lib/nokogiri/ffi/xml/sax/parser_context.rb +67 -0
  148. data/lib/nokogiri/ffi/xml/sax/push_parser.rb +55 -0
  149. data/lib/nokogiri/ffi/xml/schema.rb +92 -0
  150. data/lib/nokogiri/ffi/xml/syntax_error.rb +98 -0
  151. data/lib/nokogiri/ffi/xml/text.rb +18 -0
  152. data/lib/nokogiri/ffi/xml/xpath.rb +19 -0
  153. data/lib/nokogiri/ffi/xml/xpath_context.rb +135 -0
  154. data/lib/nokogiri/ffi/xslt/stylesheet.rb +50 -0
  155. data/lib/nokogiri/html.rb +36 -0
  156. data/lib/nokogiri/html/builder.rb +35 -0
  157. data/lib/nokogiri/html/document.rb +88 -0
  158. data/lib/nokogiri/html/document_fragment.rb +15 -0
  159. data/lib/nokogiri/html/element_description.rb +23 -0
  160. data/lib/nokogiri/html/element_description_defaults.rb +671 -0
  161. data/lib/nokogiri/html/entity_lookup.rb +13 -0
  162. data/lib/nokogiri/html/sax/parser.rb +48 -0
  163. data/lib/nokogiri/html/sax/parser_context.rb +16 -0
  164. data/lib/nokogiri/nokogiri.jar +0 -0
  165. data/lib/nokogiri/syntax_error.rb +4 -0
  166. data/lib/nokogiri/version.rb +33 -0
  167. data/lib/nokogiri/version_warning.rb +11 -0
  168. data/lib/nokogiri/xml.rb +67 -0
  169. data/lib/nokogiri/xml/attr.rb +14 -0
  170. data/lib/nokogiri/xml/attribute_decl.rb +18 -0
  171. data/lib/nokogiri/xml/builder.rb +405 -0
  172. data/lib/nokogiri/xml/cdata.rb +11 -0
  173. data/lib/nokogiri/xml/character_data.rb +7 -0
  174. data/lib/nokogiri/xml/document.rb +163 -0
  175. data/lib/nokogiri/xml/document_fragment.rb +73 -0
  176. data/lib/nokogiri/xml/dtd.rb +11 -0
  177. data/lib/nokogiri/xml/element_content.rb +36 -0
  178. data/lib/nokogiri/xml/element_decl.rb +13 -0
  179. data/lib/nokogiri/xml/entity_decl.rb +15 -0
  180. data/lib/nokogiri/xml/fragment_handler.rb +73 -0
  181. data/lib/nokogiri/xml/namespace.rb +13 -0
  182. data/lib/nokogiri/xml/node.rb +730 -0
  183. data/lib/nokogiri/xml/node/save_options.rb +42 -0
  184. data/lib/nokogiri/xml/node_set.rb +318 -0
  185. data/lib/nokogiri/xml/notation.rb +6 -0
  186. data/lib/nokogiri/xml/parse_options.rb +85 -0
  187. data/lib/nokogiri/xml/pp.rb +2 -0
  188. data/lib/nokogiri/xml/pp/character_data.rb +18 -0
  189. data/lib/nokogiri/xml/pp/node.rb +56 -0
  190. data/lib/nokogiri/xml/processing_instruction.rb +8 -0
  191. data/lib/nokogiri/xml/reader.rb +74 -0
  192. data/lib/nokogiri/xml/relax_ng.rb +32 -0
  193. data/lib/nokogiri/xml/sax.rb +4 -0
  194. data/lib/nokogiri/xml/sax/document.rb +160 -0
  195. data/lib/nokogiri/xml/sax/parser.rb +115 -0
  196. data/lib/nokogiri/xml/sax/parser_context.rb +16 -0
  197. data/lib/nokogiri/xml/sax/push_parser.rb +60 -0
  198. data/lib/nokogiri/xml/schema.rb +61 -0
  199. data/lib/nokogiri/xml/syntax_error.rb +43 -0
  200. data/lib/nokogiri/xml/xpath.rb +10 -0
  201. data/lib/nokogiri/xml/xpath/syntax_error.rb +8 -0
  202. data/lib/nokogiri/xml/xpath_context.rb +16 -0
  203. data/lib/nokogiri/xslt.rb +48 -0
  204. data/lib/nokogiri/xslt/stylesheet.rb +25 -0
  205. data/lib/xercesImpl.jar +0 -0
  206. data/lib/xsd/xmlparser/nokogiri.rb +90 -0
  207. data/tasks/test.rb +100 -0
  208. data/test/css/test_nthiness.rb +159 -0
  209. data/test/css/test_parser.rb +282 -0
  210. data/test/css/test_tokenizer.rb +190 -0
  211. data/test/css/test_xpath_visitor.rb +76 -0
  212. data/test/ffi/test_document.rb +35 -0
  213. data/test/files/2ch.html +108 -0
  214. data/test/files/address_book.rlx +12 -0
  215. data/test/files/address_book.xml +10 -0
  216. data/test/files/bar/bar.xsd +4 -0
  217. data/test/files/dont_hurt_em_why.xml +422 -0
  218. data/test/files/exslt.xml +8 -0
  219. data/test/files/exslt.xslt +35 -0
  220. data/test/files/foo/foo.xsd +4 -0
  221. data/test/files/po.xml +32 -0
  222. data/test/files/po.xsd +66 -0
  223. data/test/files/shift_jis.html +10 -0
  224. data/test/files/shift_jis.xml +5 -0
  225. data/test/files/snuggles.xml +3 -0
  226. data/test/files/staff.dtd +10 -0
  227. data/test/files/staff.xml +59 -0
  228. data/test/files/staff.xslt +32 -0
  229. data/test/files/tlm.html +850 -0
  230. data/test/files/valid_bar.xml +2 -0
  231. data/test/helper.rb +137 -0
  232. data/test/html/sax/test_parser.rb +83 -0
  233. data/test/html/sax/test_parser_context.rb +48 -0
  234. data/test/html/test_builder.rb +164 -0
  235. data/test/html/test_document.rb +385 -0
  236. data/test/html/test_document_encoding.rb +77 -0
  237. data/test/html/test_document_fragment.rb +157 -0
  238. data/test/html/test_element_description.rb +98 -0
  239. data/test/html/test_named_characters.rb +14 -0
  240. data/test/html/test_node.rb +242 -0
  241. data/test/html/test_node_encoding.rb +27 -0
  242. data/test/test_convert_xpath.rb +135 -0
  243. data/test/test_css_cache.rb +45 -0
  244. data/test/test_encoding_handler.rb +46 -0
  245. data/test/test_jruby.rb +40 -0
  246. data/test/test_memory_leak.rb +87 -0
  247. data/test/test_nokogiri.rb +140 -0
  248. data/test/test_reader.rb +358 -0
  249. data/test/test_soap4r_sax.rb +52 -0
  250. data/test/test_xslt_transforms.rb +150 -0
  251. data/test/xml/node/test_save_options.rb +20 -0
  252. data/test/xml/node/test_subclass.rb +44 -0
  253. data/test/xml/sax/test_parser.rb +314 -0
  254. data/test/xml/sax/test_parser_context.rb +63 -0
  255. data/test/xml/sax/test_push_parser.rb +135 -0
  256. data/test/xml/test_attr.rb +38 -0
  257. data/test/xml/test_attribute_decl.rb +90 -0
  258. data/test/xml/test_builder.rb +167 -0
  259. data/test/xml/test_cdata.rb +38 -0
  260. data/test/xml/test_comment.rb +29 -0
  261. data/test/xml/test_document.rb +638 -0
  262. data/test/xml/test_document_encoding.rb +26 -0
  263. data/test/xml/test_document_fragment.rb +149 -0
  264. data/test/xml/test_dtd.rb +92 -0
  265. data/test/xml/test_dtd_encoding.rb +33 -0
  266. data/test/xml/test_element_content.rb +56 -0
  267. data/test/xml/test_element_decl.rb +73 -0
  268. data/test/xml/test_entity_decl.rb +83 -0
  269. data/test/xml/test_entity_reference.rb +21 -0
  270. data/test/xml/test_namespace.rb +70 -0
  271. data/test/xml/test_node.rb +740 -0
  272. data/test/xml/test_node_attributes.rb +34 -0
  273. data/test/xml/test_node_encoding.rb +107 -0
  274. data/test/xml/test_node_reparenting.rb +279 -0
  275. data/test/xml/test_node_set.rb +577 -0
  276. data/test/xml/test_parse_options.rb +52 -0
  277. data/test/xml/test_processing_instruction.rb +30 -0
  278. data/test/xml/test_reader_encoding.rb +126 -0
  279. data/test/xml/test_relax_ng.rb +60 -0
  280. data/test/xml/test_schema.rb +89 -0
  281. data/test/xml/test_syntax_error.rb +12 -0
  282. data/test/xml/test_text.rb +30 -0
  283. data/test/xml/test_unparented_node.rb +381 -0
  284. data/test/xml/test_xpath.rb +169 -0
  285. metadata +477 -0
@@ -0,0 +1,9 @@
1
+ #ifndef NOKOGIRI_XML_ELEMENT_DECL
2
+ #define NOKOGIRI_XML_ELEMENT_DECL
3
+
4
+ #include <nokogiri.h>
5
+
6
+ void init_xml_element_decl();
7
+
8
+ extern VALUE cNokogiriXmlElementDecl;
9
+ #endif
@@ -0,0 +1,79 @@
1
+ #include <xml_encoding_handler.h>
2
+
3
+ /*
4
+ * call-seq: Nokogiri::EncodingHandler.[](name)
5
+ *
6
+ * Get the encoding handler for +name+
7
+ */
8
+ static VALUE get(VALUE klass, VALUE key)
9
+ {
10
+ xmlCharEncodingHandlerPtr handler;
11
+
12
+ handler = xmlFindCharEncodingHandler(StringValuePtr(key));
13
+ if(handler)
14
+ return Data_Wrap_Struct(klass, NULL, NULL, handler);
15
+
16
+ return Qnil;
17
+ }
18
+
19
+ /*
20
+ * call-seq: Nokogiri::EncodingHandler.delete(name)
21
+ *
22
+ * Delete the encoding alias named +name+
23
+ */
24
+ static VALUE delete(VALUE klass, VALUE name)
25
+ {
26
+ if(xmlDelEncodingAlias(StringValuePtr(name))) return Qnil;
27
+
28
+ return Qtrue;
29
+ }
30
+
31
+ /*
32
+ * call-seq: Nokogiri::EncodingHandler.alias(from, to)
33
+ *
34
+ * Alias encoding handler with name +from+ to name +to+
35
+ */
36
+ static VALUE alias(VALUE klass, VALUE from, VALUE to)
37
+ {
38
+ xmlAddEncodingAlias(StringValuePtr(from), StringValuePtr(to));
39
+
40
+ return to;
41
+ }
42
+
43
+ /*
44
+ * call-seq: Nokogiri::EncodingHandler.clear_aliases!
45
+ *
46
+ * Remove all encoding aliases.
47
+ */
48
+ static VALUE clear_aliases(VALUE klass)
49
+ {
50
+ xmlCleanupEncodingAliases();
51
+
52
+ return klass;
53
+ }
54
+
55
+ /*
56
+ * call-seq: name
57
+ *
58
+ * Get the name of this EncodingHandler
59
+ */
60
+ static VALUE name(VALUE self)
61
+ {
62
+ xmlCharEncodingHandlerPtr handler;
63
+
64
+ Data_Get_Struct(self, xmlCharEncodingHandler, handler);
65
+
66
+ return NOKOGIRI_STR_NEW2(handler->name);
67
+ }
68
+
69
+ void init_xml_encoding_handler()
70
+ {
71
+ VALUE nokogiri = rb_define_module("Nokogiri");
72
+ VALUE klass = rb_define_class_under(nokogiri, "EncodingHandler", rb_cObject);
73
+
74
+ rb_define_singleton_method(klass, "[]", get, 1);
75
+ rb_define_singleton_method(klass, "delete", delete, 1);
76
+ rb_define_singleton_method(klass, "alias", alias, 2);
77
+ rb_define_singleton_method(klass, "clear_aliases!", clear_aliases, 0);
78
+ rb_define_method(klass, "name", name, 0);
79
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef NOKOGIRI_XML_ENCODING_HANDLER
2
+ #define NOKOGIRI_XML_ENCODING_HANDLER
3
+
4
+ #include <nokogiri.h>
5
+
6
+ void init_xml_encoding_handler();
7
+
8
+ #endif
@@ -0,0 +1,97 @@
1
+ #include <xml_entity_decl.h>
2
+
3
+ /*
4
+ * call-seq:
5
+ * original_content
6
+ *
7
+ * Get the original_content before ref substitution
8
+ */
9
+ static VALUE original_content(VALUE self)
10
+ {
11
+ xmlEntityPtr node;
12
+ Data_Get_Struct(self, xmlEntity, node);
13
+
14
+ if(!node->orig) return Qnil;
15
+
16
+ return NOKOGIRI_STR_NEW2(node->orig);
17
+ }
18
+
19
+ /*
20
+ * call-seq:
21
+ * content
22
+ *
23
+ * Get the content
24
+ */
25
+ static VALUE get_content(VALUE self)
26
+ {
27
+ xmlEntityPtr node;
28
+ Data_Get_Struct(self, xmlEntity, node);
29
+
30
+ if(!node->content) return Qnil;
31
+
32
+ return NOKOGIRI_STR_NEW(node->content, node->length);
33
+ }
34
+
35
+ /*
36
+ * call-seq:
37
+ * content
38
+ *
39
+ * Get the entity type
40
+ */
41
+ static VALUE entity_type(VALUE self)
42
+ {
43
+ xmlEntityPtr node;
44
+ Data_Get_Struct(self, xmlEntity, node);
45
+
46
+ return INT2NUM((int)node->etype);
47
+ }
48
+
49
+ /*
50
+ * call-seq:
51
+ * external_id
52
+ *
53
+ * Get the external identifier for PUBLIC
54
+ */
55
+ static VALUE external_id(VALUE self)
56
+ {
57
+ xmlEntityPtr node;
58
+ Data_Get_Struct(self, xmlEntity, node);
59
+
60
+ if(!node->ExternalID) return Qnil;
61
+
62
+ return NOKOGIRI_STR_NEW2(node->ExternalID);
63
+ }
64
+
65
+ /*
66
+ * call-seq:
67
+ * system_id
68
+ *
69
+ * Get the URI for a SYSTEM or PUBLIC Entity
70
+ */
71
+ static VALUE system_id(VALUE self)
72
+ {
73
+ xmlEntityPtr node;
74
+ Data_Get_Struct(self, xmlEntity, node);
75
+
76
+ if(!node->SystemID) return Qnil;
77
+
78
+ return NOKOGIRI_STR_NEW2(node->SystemID);
79
+ }
80
+
81
+ VALUE cNokogiriXmlEntityDecl;
82
+
83
+ void init_xml_entity_decl()
84
+ {
85
+ VALUE nokogiri = rb_define_module("Nokogiri");
86
+ VALUE xml = rb_define_module_under(nokogiri, "XML");
87
+ VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
88
+ VALUE klass = rb_define_class_under(xml, "EntityDecl", node);
89
+
90
+ cNokogiriXmlEntityDecl = klass;
91
+
92
+ rb_define_method(klass, "original_content", original_content, 0);
93
+ rb_define_method(klass, "content", get_content, 0);
94
+ rb_define_method(klass, "entity_type", entity_type, 0);
95
+ rb_define_method(klass, "external_id", external_id, 0);
96
+ rb_define_method(klass, "system_id", system_id, 0);
97
+ }
@@ -0,0 +1,10 @@
1
+ #ifndef NOKOGIRI_XML_ENTITY_DECL
2
+ #define NOKOGIRI_XML_ENTITY_DECL
3
+
4
+ #include <nokogiri.h>
5
+
6
+ void init_xml_entity_decl();
7
+
8
+ extern VALUE cNokogiriXmlEntityDecl;
9
+ #endif
10
+
@@ -0,0 +1,50 @@
1
+ #include <xml_entity_reference.h>
2
+
3
+ /*
4
+ * call-seq:
5
+ * new(document, content)
6
+ *
7
+ * Create a new EntityReference element on the +document+ with +name+
8
+ */
9
+ static VALUE new(int argc, VALUE *argv, VALUE klass)
10
+ {
11
+ xmlDocPtr xml_doc;
12
+ VALUE document;
13
+ VALUE name;
14
+ VALUE rest;
15
+
16
+ rb_scan_args(argc, argv, "2*", &document, &name, &rest);
17
+
18
+ Data_Get_Struct(document, xmlDoc, xml_doc);
19
+
20
+ xmlNodePtr node = xmlNewReference(
21
+ xml_doc,
22
+ (const xmlChar *)StringValuePtr(name)
23
+ );
24
+
25
+ NOKOGIRI_ROOT_NODE(node);
26
+
27
+ VALUE rb_node = Nokogiri_wrap_xml_node(klass, node);
28
+ rb_obj_call_init(rb_node, argc, argv);
29
+
30
+ if(rb_block_given_p()) rb_yield(rb_node);
31
+
32
+ return rb_node;
33
+ }
34
+
35
+ VALUE cNokogiriXmlEntityReference;
36
+ void init_xml_entity_reference()
37
+ {
38
+ VALUE nokogiri = rb_define_module("Nokogiri");
39
+ VALUE xml = rb_define_module_under(nokogiri, "XML");
40
+ VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
41
+
42
+ /*
43
+ * EntityReference represents an EntityReference node in an xml document.
44
+ */
45
+ VALUE klass = rb_define_class_under(xml, "EntityReference", node);
46
+
47
+ cNokogiriXmlEntityReference = klass;
48
+
49
+ rb_define_singleton_method(klass, "new", new, -1);
50
+ }
@@ -0,0 +1,9 @@
1
+ #ifndef NOKOGIRI_XML_ENTITY_REFERENCE
2
+ #define NOKOGIRI_XML_ENTITY_REFERENCE
3
+
4
+ #include <nokogiri.h>
5
+
6
+ void init_xml_entity_reference();
7
+
8
+ extern VALUE cNokogiriXmlEntityReference;
9
+ #endif
@@ -0,0 +1,31 @@
1
+ #include <xml_io.h>
2
+
3
+ static ID id_read, id_write;
4
+
5
+ int io_read_callback(void * ctx, char * buffer, int len) {
6
+ VALUE io = (VALUE)ctx;
7
+ VALUE string = rb_funcall(io, id_read, 1, INT2NUM(len));
8
+
9
+ if(NIL_P(string)) return 0;
10
+
11
+ memcpy(buffer, StringValuePtr(string), (unsigned int)RSTRING_LEN(string));
12
+
13
+ return RSTRING_LEN(string);
14
+ }
15
+
16
+ int io_write_callback(void * ctx, char * buffer, int len) {
17
+ VALUE io = (VALUE)ctx;
18
+ VALUE string = rb_str_new(buffer, len);
19
+
20
+ rb_funcall(io, id_write, 1, string);
21
+ return len;
22
+ }
23
+
24
+ int io_close_callback(void * ctx) {
25
+ return 0;
26
+ }
27
+
28
+ void init_nokogiri_io() {
29
+ id_read = rb_intern("read");
30
+ id_write = rb_intern("write");
31
+ }
@@ -0,0 +1,11 @@
1
+ #ifndef NOKOGIRI_XML_IO
2
+ #define NOKOGIRI_XML_IO
3
+
4
+ #include <nokogiri.h>
5
+
6
+ int io_read_callback(void * ctx, char * buffer, int len);
7
+ int io_write_callback(void * ctx, char * buffer, int len);
8
+ int io_close_callback(void * ctx);
9
+ void init_nokogiri_io();
10
+
11
+ #endif
@@ -0,0 +1,82 @@
1
+ #include <xml_namespace.h>
2
+
3
+ VALUE cNokogiriXmlNamespace ;
4
+
5
+ /*
6
+ * call-seq:
7
+ * prefix
8
+ *
9
+ * Get the prefix for this namespace. Returns +nil+ if there is no prefix.
10
+ */
11
+ static VALUE prefix(VALUE self)
12
+ {
13
+ xmlNsPtr ns;
14
+ xmlDocPtr doc;
15
+
16
+ Data_Get_Struct(self, xmlNs, ns);
17
+ if(!ns->prefix) return Qnil;
18
+
19
+ Data_Get_Struct(rb_iv_get(self, "@document"), xmlDoc, doc);
20
+
21
+ return NOKOGIRI_STR_NEW2(ns->prefix);
22
+ }
23
+
24
+ /*
25
+ * call-seq:
26
+ * href
27
+ *
28
+ * Get the href for this namespace
29
+ */
30
+ static VALUE href(VALUE self)
31
+ {
32
+ xmlNsPtr ns;
33
+ xmlDocPtr doc;
34
+
35
+ Data_Get_Struct(self, xmlNs, ns);
36
+ if(!ns->href) return Qnil;
37
+
38
+ Data_Get_Struct(rb_iv_get(self, "@document"), xmlDoc, doc);
39
+
40
+ return NOKOGIRI_STR_NEW2(ns->href);
41
+ }
42
+
43
+ VALUE Nokogiri_wrap_xml_namespace(xmlDocPtr doc, xmlNsPtr node)
44
+ {
45
+ assert(doc->_private);
46
+
47
+ if(node->_private)
48
+ return (VALUE)node->_private;
49
+
50
+ VALUE ns = Data_Wrap_Struct(cNokogiriXmlNamespace, 0, 0, node);
51
+
52
+ VALUE document = DOC_RUBY_OBJECT(doc);
53
+
54
+ VALUE node_cache = rb_iv_get(document, "@node_cache");
55
+ rb_ary_push(node_cache, ns);
56
+
57
+ rb_iv_set(ns, "@document", DOC_RUBY_OBJECT(doc));
58
+
59
+ node->_private = (void *)ns;
60
+
61
+ return ns;
62
+ }
63
+
64
+ VALUE Nokogiri_wrap_xml_namespace2(VALUE document, xmlNsPtr node)
65
+ {
66
+ xmlDocPtr doc;
67
+ Data_Get_Struct(document, xmlDoc, doc) ;
68
+ return Nokogiri_wrap_xml_namespace(doc, node);
69
+ }
70
+
71
+
72
+ void init_xml_namespace()
73
+ {
74
+ VALUE nokogiri = rb_define_module("Nokogiri");
75
+ VALUE xml = rb_define_module_under(nokogiri, "XML");
76
+ VALUE klass = rb_define_class_under(xml, "Namespace", rb_cObject);
77
+
78
+ cNokogiriXmlNamespace = klass;
79
+
80
+ rb_define_method(klass, "prefix", prefix, 0);
81
+ rb_define_method(klass, "href", href, 0);
82
+ }
@@ -0,0 +1,13 @@
1
+ #ifndef NOKOGIRI_XML_NAMESPACE
2
+ #define NOKOGIRI_XML_NAMESPACE
3
+
4
+ #include <nokogiri.h>
5
+
6
+ void init_xml_namespace();
7
+
8
+ extern VALUE cNokogiriXmlNamespace ;
9
+
10
+ VALUE Nokogiri_wrap_xml_namespace(xmlDocPtr doc, xmlNsPtr node) ;
11
+ VALUE Nokogiri_wrap_xml_namespace2(VALUE document, xmlNsPtr node) ;
12
+
13
+ #endif
@@ -0,0 +1,1080 @@
1
+ #include <xml_node.h>
2
+
3
+ static ID decorate, decorate_bang;
4
+
5
+ #ifdef DEBUG
6
+ static void debug_node_dealloc(xmlNodePtr x)
7
+ {
8
+ NOKOGIRI_DEBUG_START(x)
9
+ NOKOGIRI_DEBUG_END(x)
10
+ }
11
+ #else
12
+ # define debug_node_dealloc 0
13
+ #endif
14
+
15
+ static void mark(xmlNodePtr node)
16
+ {
17
+ // it's OK if the document isn't fully realized (as in XML::Reader).
18
+ // see http://github.com/tenderlove/nokogiri/issues/closed/#issue/95
19
+ if (DOC_RUBY_OBJECT_TEST(node->doc) && DOC_RUBY_OBJECT(node->doc))
20
+ rb_gc_mark(DOC_RUBY_OBJECT(node->doc));
21
+ }
22
+
23
+ /* :nodoc: */
24
+ typedef xmlNodePtr (*node_other_func)(xmlNodePtr, xmlNodePtr);
25
+
26
+ /* :nodoc: */
27
+ static void relink_namespace(xmlNodePtr reparented)
28
+ {
29
+ // Avoid segv when relinking against unlinked nodes.
30
+ if(!reparented->parent) return;
31
+
32
+ // Make sure that our reparented node has the correct namespaces
33
+ if(!reparented->ns && reparented->doc != (xmlDocPtr)reparented->parent)
34
+ xmlSetNs(reparented, reparented->parent->ns);
35
+
36
+ // Search our parents for an existing definition
37
+ if(reparented->nsDef) {
38
+ xmlNsPtr ns = xmlSearchNsByHref(
39
+ reparented->doc,
40
+ reparented->parent,
41
+ reparented->nsDef->href
42
+ );
43
+ if(ns && ns != reparented->nsDef) reparented->nsDef = NULL;
44
+ }
45
+
46
+ // Only walk all children if there actually is a namespace we need to
47
+ // reparent.
48
+ if(NULL == reparented->ns) return;
49
+
50
+ // When a node gets reparented, walk it's children to make sure that
51
+ // their namespaces are reparented as well.
52
+ xmlNodePtr child = reparented->children;
53
+ while(NULL != child) {
54
+ relink_namespace(child);
55
+ child = child->next;
56
+ }
57
+ }
58
+
59
+ /* :nodoc: */
60
+ static xmlNodePtr xmlReplaceNodeWrapper(xmlNodePtr old, xmlNodePtr cur)
61
+ {
62
+ xmlNodePtr retval ;
63
+ retval = xmlReplaceNode(old, cur) ;
64
+ if (retval == old) {
65
+ return cur ; // return semantics for reparent_node_with
66
+ }
67
+ return retval ;
68
+ }
69
+
70
+ /* :nodoc: */
71
+ static VALUE reparent_node_with(VALUE node_obj, VALUE other_obj, node_other_func func)
72
+ {
73
+ VALUE reparented_obj ;
74
+ xmlNodePtr node, other, reparented ;
75
+
76
+ if(!rb_obj_is_kind_of(node_obj, cNokogiriXmlNode))
77
+ rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node");
78
+
79
+ Data_Get_Struct(node_obj, xmlNode, node);
80
+ Data_Get_Struct(other_obj, xmlNode, other);
81
+
82
+ if(XML_DOCUMENT_NODE == node->type || XML_HTML_DOCUMENT_NODE == node->type)
83
+ rb_raise(rb_eArgError, "cannot reparent a document node");
84
+
85
+ if(node->type == XML_TEXT_NODE) {
86
+ NOKOGIRI_ROOT_NODE(node);
87
+ node = xmlDocCopyNode(node, other->doc, 1);
88
+ }
89
+
90
+ if (node->doc == other->doc) {
91
+ xmlUnlinkNode(node) ;
92
+
93
+ // TODO: I really want to remove this. We shouldn't support 2.6.16 anymore
94
+ if ( node->type == XML_TEXT_NODE
95
+ && other->type == XML_TEXT_NODE
96
+ && is_2_6_16() ) {
97
+
98
+ // we'd rather leak than segfault.
99
+ other->content = xmlStrdup(other->content);
100
+
101
+ }
102
+
103
+ if(!(reparented = (*func)(other, node))) {
104
+ rb_raise(rb_eRuntimeError, "Could not reparent node (1)");
105
+ }
106
+ } else {
107
+ xmlNodePtr duped_node ;
108
+ // recursively copy to the new document
109
+ if (!(duped_node = xmlDocCopyNode(node, other->doc, 1))) {
110
+ rb_raise(rb_eRuntimeError, "Could not reparent node (xmlDocCopyNode)");
111
+ }
112
+ if(!(reparented = (*func)(other, duped_node))) {
113
+ rb_raise(rb_eRuntimeError, "Could not reparent node (2)");
114
+ }
115
+ xmlUnlinkNode(node);
116
+ NOKOGIRI_ROOT_NODE(node);
117
+ }
118
+
119
+ // the child was a text node that was coalesced. we need to have the object
120
+ // point at SOMETHING, or we'll totally bomb out.
121
+ if (reparented != node) {
122
+ DATA_PTR(node_obj) = reparented ;
123
+ }
124
+
125
+ // Appropriately link in namespaces
126
+ relink_namespace(reparented);
127
+
128
+ reparented_obj = Nokogiri_wrap_xml_node(Qnil, reparented);
129
+
130
+ rb_funcall(reparented_obj, decorate_bang, 0);
131
+
132
+ return reparented_obj ;
133
+ }
134
+
135
+
136
+ /*
137
+ * call-seq:
138
+ * document
139
+ *
140
+ * Get the document for this Node
141
+ */
142
+ static VALUE document(VALUE self)
143
+ {
144
+ xmlNodePtr node;
145
+ Data_Get_Struct(self, xmlNode, node);
146
+ return DOC_RUBY_OBJECT(node->doc);
147
+ }
148
+
149
+ /*
150
+ * call-seq:
151
+ * pointer_id
152
+ *
153
+ * Get the internal pointer number
154
+ */
155
+ static VALUE pointer_id(VALUE self)
156
+ {
157
+ xmlNodePtr node;
158
+ Data_Get_Struct(self, xmlNode, node);
159
+
160
+ return INT2NUM((long)(node));
161
+ }
162
+
163
+ /*
164
+ * call-seq:
165
+ * encode_special_chars(string)
166
+ *
167
+ * Encode any special characters in +string+
168
+ */
169
+ static VALUE encode_special_chars(VALUE self, VALUE string)
170
+ {
171
+ xmlNodePtr node;
172
+ Data_Get_Struct(self, xmlNode, node);
173
+ xmlChar * encoded = xmlEncodeSpecialChars(
174
+ node->doc,
175
+ (const xmlChar *)StringValuePtr(string)
176
+ );
177
+
178
+ VALUE encoded_str = NOKOGIRI_STR_NEW2(encoded);
179
+ xmlFree(encoded);
180
+
181
+ return encoded_str;
182
+ }
183
+
184
+ /*
185
+ * call-seq:
186
+ * create_internal_subset(name, external_id, system_id)
187
+ *
188
+ * Create an internal subset
189
+ */
190
+ static VALUE create_internal_subset(VALUE self, VALUE name, VALUE external_id, VALUE system_id)
191
+ {
192
+ xmlNodePtr node;
193
+ xmlDocPtr doc;
194
+ Data_Get_Struct(self, xmlNode, node);
195
+
196
+ doc = node->doc;
197
+
198
+ if(xmlGetIntSubset(doc))
199
+ rb_raise(rb_eRuntimeError, "Document already has an internal subset");
200
+
201
+ xmlDtdPtr dtd = xmlCreateIntSubset(
202
+ doc,
203
+ NIL_P(name) ? NULL : (const xmlChar *)StringValuePtr(name),
204
+ NIL_P(external_id) ? NULL : (const xmlChar *)StringValuePtr(external_id),
205
+ NIL_P(system_id) ? NULL : (const xmlChar *)StringValuePtr(system_id)
206
+ );
207
+
208
+ if(!dtd) return Qnil;
209
+
210
+ return Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)dtd);
211
+ }
212
+
213
+ /*
214
+ * call-seq:
215
+ * create_external_subset(name, external_id, system_id)
216
+ *
217
+ * Create an external subset
218
+ */
219
+ static VALUE create_external_subset(VALUE self, VALUE name, VALUE external_id, VALUE system_id)
220
+ {
221
+ xmlNodePtr node;
222
+ xmlDocPtr doc;
223
+ Data_Get_Struct(self, xmlNode, node);
224
+
225
+ doc = node->doc;
226
+
227
+ if(doc->extSubset)
228
+ rb_raise(rb_eRuntimeError, "Document already has an external subset");
229
+
230
+ xmlDtdPtr dtd = xmlNewDtd(
231
+ doc,
232
+ NIL_P(name) ? NULL : (const xmlChar *)StringValuePtr(name),
233
+ NIL_P(external_id) ? NULL : (const xmlChar *)StringValuePtr(external_id),
234
+ NIL_P(system_id) ? NULL : (const xmlChar *)StringValuePtr(system_id)
235
+ );
236
+
237
+ if(!dtd) return Qnil;
238
+
239
+ return Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)dtd);
240
+ }
241
+
242
+ /*
243
+ * call-seq:
244
+ * external_subset
245
+ *
246
+ * Get the external subset
247
+ */
248
+ static VALUE external_subset(VALUE self)
249
+ {
250
+ xmlNodePtr node;
251
+ xmlDocPtr doc;
252
+ Data_Get_Struct(self, xmlNode, node);
253
+
254
+ if(!node->doc) return Qnil;
255
+
256
+ doc = node->doc;
257
+ xmlDtdPtr dtd = doc->extSubset;
258
+
259
+ if(!dtd) return Qnil;
260
+
261
+ return Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)dtd);
262
+ }
263
+
264
+ /*
265
+ * call-seq:
266
+ * internal_subset
267
+ *
268
+ * Get the internal subset
269
+ */
270
+ static VALUE internal_subset(VALUE self)
271
+ {
272
+ xmlNodePtr node;
273
+ xmlDocPtr doc;
274
+ Data_Get_Struct(self, xmlNode, node);
275
+
276
+ if(!node->doc) return Qnil;
277
+
278
+ doc = node->doc;
279
+ xmlDtdPtr dtd = xmlGetIntSubset(doc);
280
+
281
+ if(!dtd) return Qnil;
282
+
283
+ return Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)dtd);
284
+ }
285
+
286
+ /*
287
+ * call-seq:
288
+ * dup
289
+ *
290
+ * Copy this node. An optional depth may be passed in, but it defaults
291
+ * to a deep copy. 0 is a shallow copy, 1 is a deep copy.
292
+ */
293
+ static VALUE duplicate_node(int argc, VALUE *argv, VALUE self)
294
+ {
295
+ VALUE level;
296
+
297
+ if(rb_scan_args(argc, argv, "01", &level) == 0)
298
+ level = INT2NUM((long)1);
299
+
300
+ xmlNodePtr node, dup;
301
+ Data_Get_Struct(self, xmlNode, node);
302
+
303
+ dup = xmlDocCopyNode(node, node->doc, (int)NUM2INT(level));
304
+ if(dup == NULL) return Qnil;
305
+
306
+ return Nokogiri_wrap_xml_node(rb_obj_class(self), dup);
307
+ }
308
+
309
+ /*
310
+ * call-seq:
311
+ * unlink
312
+ *
313
+ * Unlink this node from its current context.
314
+ */
315
+ static VALUE unlink_node(VALUE self)
316
+ {
317
+ xmlNodePtr node;
318
+ Data_Get_Struct(self, xmlNode, node);
319
+ xmlUnlinkNode(node);
320
+ NOKOGIRI_ROOT_NODE(node);
321
+ return self;
322
+ }
323
+
324
+ /*
325
+ * call-seq:
326
+ * blank?
327
+ *
328
+ * Is this node blank?
329
+ */
330
+ static VALUE blank_eh(VALUE self)
331
+ {
332
+ xmlNodePtr node;
333
+ Data_Get_Struct(self, xmlNode, node);
334
+ if(1 == xmlIsBlankNode(node))
335
+ return Qtrue;
336
+ return Qfalse;
337
+ }
338
+
339
+ /*
340
+ * call-seq:
341
+ * next_sibling
342
+ *
343
+ * Returns the next sibling node
344
+ */
345
+ static VALUE next_sibling(VALUE self)
346
+ {
347
+ xmlNodePtr node, sibling;
348
+ Data_Get_Struct(self, xmlNode, node);
349
+
350
+ sibling = node->next;
351
+ if(!sibling) return Qnil;
352
+
353
+ return Nokogiri_wrap_xml_node(Qnil, sibling) ;
354
+ }
355
+
356
+ /*
357
+ * call-seq:
358
+ * previous_sibling
359
+ *
360
+ * Returns the previous sibling node
361
+ */
362
+ static VALUE previous_sibling(VALUE self)
363
+ {
364
+ xmlNodePtr node, sibling;
365
+ Data_Get_Struct(self, xmlNode, node);
366
+
367
+ sibling = node->prev;
368
+ if(!sibling) return Qnil;
369
+
370
+ return Nokogiri_wrap_xml_node(Qnil, sibling);
371
+ }
372
+
373
+ /*
374
+ * call-seq:
375
+ * next_element
376
+ *
377
+ * Returns the next Nokogiri::XML::Element type sibling node.
378
+ */
379
+ static VALUE next_element(VALUE self)
380
+ {
381
+ xmlNodePtr node, sibling;
382
+ Data_Get_Struct(self, xmlNode, node);
383
+
384
+ sibling = node->next;
385
+ if(!sibling) return Qnil;
386
+
387
+ while(sibling && sibling->type != XML_ELEMENT_NODE)
388
+ sibling = sibling->next;
389
+
390
+ return sibling ? Nokogiri_wrap_xml_node(Qnil, sibling) : Qnil ;
391
+ }
392
+
393
+ /*
394
+ * call-seq:
395
+ * previous_element
396
+ *
397
+ * Returns the previous Nokogiri::XML::Element type sibling node.
398
+ */
399
+ static VALUE previous_element(VALUE self)
400
+ {
401
+ xmlNodePtr node, sibling;
402
+ Data_Get_Struct(self, xmlNode, node);
403
+
404
+ sibling = node->prev;
405
+ if(!sibling) return Qnil;
406
+
407
+ while(sibling && sibling->type != XML_ELEMENT_NODE)
408
+ sibling = sibling->prev;
409
+
410
+ return sibling ? Nokogiri_wrap_xml_node(Qnil, sibling) : Qnil ;
411
+ }
412
+
413
+ /* :nodoc: */
414
+ static VALUE replace(VALUE self, VALUE _new_node)
415
+ {
416
+ reparent_node_with(_new_node, self, xmlReplaceNodeWrapper) ;
417
+ return self ;
418
+ }
419
+
420
+ /*
421
+ * call-seq:
422
+ * children
423
+ *
424
+ * Get the list of children for this node as a NodeSet
425
+ */
426
+ static VALUE children(VALUE self)
427
+ {
428
+ xmlNodePtr node;
429
+ Data_Get_Struct(self, xmlNode, node);
430
+
431
+ xmlNodePtr child = node->children;
432
+ xmlNodeSetPtr set = xmlXPathNodeSetCreate(child);
433
+
434
+ if(!child) return Nokogiri_wrap_xml_node_set(set);
435
+
436
+ child = child->next;
437
+ while(NULL != child) {
438
+ xmlXPathNodeSetAdd(set, child);
439
+ child = child->next;
440
+ }
441
+
442
+ VALUE node_set = Nokogiri_wrap_xml_node_set(set);
443
+ rb_iv_set(node_set, "@document", DOC_RUBY_OBJECT(node->doc));
444
+
445
+ return node_set;
446
+ }
447
+
448
+ /*
449
+ * call-seq:
450
+ * child
451
+ *
452
+ * Returns the child node
453
+ */
454
+ static VALUE child(VALUE self)
455
+ {
456
+ xmlNodePtr node, child;
457
+ Data_Get_Struct(self, xmlNode, node);
458
+
459
+ child = node->children;
460
+ if(!child) return Qnil;
461
+
462
+ return Nokogiri_wrap_xml_node(Qnil, child);
463
+ }
464
+
465
+ /*
466
+ * call-seq:
467
+ * key?(attribute)
468
+ *
469
+ * Returns true if +attribute+ is set
470
+ */
471
+ static VALUE key_eh(VALUE self, VALUE attribute)
472
+ {
473
+ xmlNodePtr node;
474
+ Data_Get_Struct(self, xmlNode, node);
475
+ if(xmlHasProp(node, (xmlChar *)StringValuePtr(attribute)))
476
+ return Qtrue;
477
+ return Qfalse;
478
+ }
479
+
480
+ /*
481
+ * call-seq:
482
+ * namespaced_key?(attribute, namespace)
483
+ *
484
+ * Returns true if +attribute+ is set with +namespace+
485
+ */
486
+ static VALUE namespaced_key_eh(VALUE self, VALUE attribute, VALUE namespace)
487
+ {
488
+ xmlNodePtr node;
489
+ Data_Get_Struct(self, xmlNode, node);
490
+ if(xmlHasNsProp(node, (xmlChar *)StringValuePtr(attribute),
491
+ NIL_P(namespace) ? NULL : (xmlChar *)StringValuePtr(namespace)))
492
+ return Qtrue;
493
+ return Qfalse;
494
+ }
495
+
496
+ /*
497
+ * call-seq:
498
+ * []=(property, value)
499
+ *
500
+ * Set the +property+ to +value+
501
+ */
502
+ static VALUE set(VALUE self, VALUE property, VALUE value)
503
+ {
504
+ xmlNodePtr node;
505
+ Data_Get_Struct(self, xmlNode, node);
506
+
507
+ xmlSetProp(node, (xmlChar *)StringValuePtr(property),
508
+ (xmlChar *)StringValuePtr(value));
509
+
510
+ return value;
511
+ }
512
+
513
+ /*
514
+ * call-seq:
515
+ * get(attribute)
516
+ *
517
+ * Get the value for +attribute+
518
+ */
519
+ static VALUE get(VALUE self, VALUE attribute)
520
+ {
521
+ xmlNodePtr node;
522
+ xmlChar* propstr ;
523
+ VALUE rval ;
524
+ Data_Get_Struct(self, xmlNode, node);
525
+
526
+ if(NIL_P(attribute)) return Qnil;
527
+
528
+ propstr = xmlGetProp(node, (xmlChar *)StringValuePtr(attribute));
529
+
530
+ if(!propstr) return Qnil;
531
+
532
+ rval = NOKOGIRI_STR_NEW2(propstr);
533
+
534
+ xmlFree(propstr);
535
+ return rval ;
536
+ }
537
+
538
+ /*
539
+ * call-seq:
540
+ * set_namespace(namespace)
541
+ *
542
+ * Set the namespace to +namespace+
543
+ */
544
+ static VALUE set_namespace(VALUE self, VALUE namespace)
545
+ {
546
+ xmlNodePtr node;
547
+ xmlNsPtr ns;
548
+
549
+ Data_Get_Struct(self, xmlNode, node);
550
+ Data_Get_Struct(namespace, xmlNs, ns);
551
+
552
+ xmlSetNs(node, ns);
553
+
554
+ return self;
555
+ }
556
+
557
+ /*
558
+ * call-seq:
559
+ * attribute(name)
560
+ *
561
+ * Get the attribute node with +name+
562
+ */
563
+ static VALUE attr(VALUE self, VALUE name)
564
+ {
565
+ xmlNodePtr node;
566
+ xmlAttrPtr prop;
567
+ Data_Get_Struct(self, xmlNode, node);
568
+ prop = xmlHasProp(node, (xmlChar *)StringValuePtr(name));
569
+
570
+ if(! prop) return Qnil;
571
+ return Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)prop);
572
+ }
573
+
574
+ /*
575
+ * call-seq:
576
+ * attribute_with_ns(name, namespace)
577
+ *
578
+ * Get the attribute node with +name+ and +namespace+
579
+ */
580
+ static VALUE attribute_with_ns(VALUE self, VALUE name, VALUE namespace)
581
+ {
582
+ xmlNodePtr node;
583
+ xmlAttrPtr prop;
584
+ Data_Get_Struct(self, xmlNode, node);
585
+ prop = xmlHasNsProp(node, (xmlChar *)StringValuePtr(name),
586
+ NIL_P(namespace) ? NULL : (xmlChar *)StringValuePtr(namespace));
587
+
588
+ if(! prop) return Qnil;
589
+ return Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)prop);
590
+ }
591
+
592
+ /*
593
+ * call-seq:
594
+ * attribute_nodes()
595
+ *
596
+ * returns a list containing the Node attributes.
597
+ */
598
+ static VALUE attribute_nodes(VALUE self)
599
+ {
600
+ /* this code in the mode of xmlHasProp() */
601
+ xmlNodePtr node;
602
+
603
+ Data_Get_Struct(self, xmlNode, node);
604
+
605
+ VALUE attr = rb_ary_new();
606
+ Nokogiri_xml_node_properties(node, attr);
607
+
608
+ return attr ;
609
+ }
610
+
611
+
612
+ /*
613
+ * call-seq:
614
+ * namespace()
615
+ *
616
+ * returns the Nokogiri::XML::Namespace for the node, if one exists.
617
+ */
618
+ static VALUE namespace(VALUE self)
619
+ {
620
+ xmlNodePtr node ;
621
+ Data_Get_Struct(self, xmlNode, node);
622
+
623
+ if (node->ns)
624
+ return Nokogiri_wrap_xml_namespace(node->doc, node->ns);
625
+
626
+ return Qnil ;
627
+ }
628
+
629
+ /*
630
+ * call-seq:
631
+ * namespace_definitions()
632
+ *
633
+ * returns a list of Namespace nodes defined on _self_
634
+ */
635
+ static VALUE namespace_definitions(VALUE self)
636
+ {
637
+ /* this code in the mode of xmlHasProp() */
638
+ xmlNodePtr node ;
639
+
640
+ Data_Get_Struct(self, xmlNode, node);
641
+
642
+ VALUE list = rb_ary_new();
643
+
644
+ xmlNsPtr ns = node->nsDef;
645
+
646
+ if(!ns) return list;
647
+
648
+ while(NULL != ns) {
649
+ rb_ary_push(list, Nokogiri_wrap_xml_namespace(node->doc, ns));
650
+ ns = ns->next;
651
+ }
652
+
653
+ return list;
654
+ }
655
+
656
+ /*
657
+ * call-seq:
658
+ * node_type
659
+ *
660
+ * Get the type for this Node
661
+ */
662
+ static VALUE node_type(VALUE self)
663
+ {
664
+ xmlNodePtr node;
665
+ Data_Get_Struct(self, xmlNode, node);
666
+ return INT2NUM((long)node->type);
667
+ }
668
+
669
+ /*
670
+ * call-seq:
671
+ * content=
672
+ *
673
+ * Set the content for this Node
674
+ */
675
+ static VALUE set_content(VALUE self, VALUE content)
676
+ {
677
+ xmlNodePtr node;
678
+ Data_Get_Struct(self, xmlNode, node);
679
+ xmlNodeSetContent(node, (xmlChar *)StringValuePtr(content));
680
+ return content;
681
+ }
682
+
683
+ /*
684
+ * call-seq:
685
+ * content
686
+ *
687
+ * Returns the content for this Node
688
+ */
689
+ static VALUE get_content(VALUE self)
690
+ {
691
+ xmlNodePtr node;
692
+ Data_Get_Struct(self, xmlNode, node);
693
+
694
+ xmlChar * content = xmlNodeGetContent(node);
695
+ if(content) {
696
+ VALUE rval = NOKOGIRI_STR_NEW2(content);
697
+ xmlFree(content);
698
+ return rval;
699
+ }
700
+ return Qnil;
701
+ }
702
+
703
+ /* :nodoc: */
704
+ static VALUE add_child(VALUE self, VALUE child)
705
+ {
706
+ return reparent_node_with(child, self, xmlAddChild);
707
+ }
708
+
709
+ /*
710
+ * call-seq:
711
+ * parent
712
+ *
713
+ * Get the parent Node for this Node
714
+ */
715
+ static VALUE get_parent(VALUE self)
716
+ {
717
+ xmlNodePtr node, parent;
718
+ Data_Get_Struct(self, xmlNode, node);
719
+
720
+ parent = node->parent;
721
+ if(!parent) return Qnil;
722
+
723
+ return Nokogiri_wrap_xml_node(Qnil, parent) ;
724
+ }
725
+
726
+ /*
727
+ * call-seq:
728
+ * name=(new_name)
729
+ *
730
+ * Set the name for this Node
731
+ */
732
+ static VALUE set_name(VALUE self, VALUE new_name)
733
+ {
734
+ xmlNodePtr node;
735
+ Data_Get_Struct(self, xmlNode, node);
736
+ xmlNodeSetName(node, (xmlChar*)StringValuePtr(new_name));
737
+ return new_name;
738
+ }
739
+
740
+ /*
741
+ * call-seq:
742
+ * name
743
+ *
744
+ * Returns the name for this Node
745
+ */
746
+ static VALUE get_name(VALUE self)
747
+ {
748
+ xmlNodePtr node;
749
+ Data_Get_Struct(self, xmlNode, node);
750
+ if(node->name)
751
+ return NOKOGIRI_STR_NEW2(node->name);
752
+ return Qnil;
753
+ }
754
+
755
+ /*
756
+ * call-seq:
757
+ * path
758
+ *
759
+ * Returns the path associated with this Node
760
+ */
761
+ static VALUE path(VALUE self)
762
+ {
763
+ xmlNodePtr node;
764
+ xmlChar *path ;
765
+ Data_Get_Struct(self, xmlNode, node);
766
+
767
+ path = xmlGetNodePath(node);
768
+ VALUE rval = NOKOGIRI_STR_NEW2(path);
769
+ xmlFree(path);
770
+ return rval ;
771
+ }
772
+
773
+ /* :nodoc: */
774
+ static VALUE add_next_sibling(VALUE self, VALUE rb_node)
775
+ {
776
+ return reparent_node_with(rb_node, self, xmlAddNextSibling) ;
777
+ }
778
+
779
+ /* :nodoc: */
780
+ static VALUE add_previous_sibling(VALUE self, VALUE rb_node)
781
+ {
782
+ return reparent_node_with(rb_node, self, xmlAddPrevSibling) ;
783
+ }
784
+
785
+ /*
786
+ * call-seq:
787
+ * native_write_to(io, encoding, options)
788
+ *
789
+ * Write this Node to +io+ with +encoding+ and +options+
790
+ */
791
+ static VALUE native_write_to(
792
+ VALUE self,
793
+ VALUE io,
794
+ VALUE encoding,
795
+ VALUE indent_string,
796
+ VALUE options
797
+ ) {
798
+ xmlNodePtr node;
799
+
800
+ Data_Get_Struct(self, xmlNode, node);
801
+
802
+ xmlIndentTreeOutput = 1;
803
+
804
+ const char * before_indent = xmlTreeIndentString;
805
+
806
+ xmlTreeIndentString = StringValuePtr(indent_string);
807
+
808
+ xmlSaveCtxtPtr savectx = xmlSaveToIO(
809
+ (xmlOutputWriteCallback)io_write_callback,
810
+ (xmlOutputCloseCallback)io_close_callback,
811
+ (void *)io,
812
+ RTEST(encoding) ? StringValuePtr(encoding) : NULL,
813
+ (int)NUM2INT(options)
814
+ );
815
+
816
+ xmlSaveTree(savectx, node);
817
+ xmlSaveClose(savectx);
818
+
819
+ xmlTreeIndentString = before_indent;
820
+ return io;
821
+ }
822
+
823
+ /*
824
+ * call-seq:
825
+ * line
826
+ *
827
+ * Returns the line for this Node
828
+ */
829
+ static VALUE line(VALUE self)
830
+ {
831
+ xmlNodePtr node;
832
+ Data_Get_Struct(self, xmlNode, node);
833
+
834
+ return INT2NUM(xmlGetLineNo(node));
835
+ }
836
+
837
+ /*
838
+ * call-seq:
839
+ * add_namespace_definition(prefix, href)
840
+ *
841
+ * Adds a namespace definition with +prefix+ using +href+
842
+ */
843
+ static VALUE add_namespace_definition(VALUE self, VALUE prefix, VALUE href)
844
+ {
845
+ xmlNodePtr node;
846
+ Data_Get_Struct(self, xmlNode, node);
847
+
848
+
849
+ xmlNsPtr ns = xmlNewNs(
850
+ node,
851
+ (const xmlChar *)StringValuePtr(href),
852
+ (const xmlChar *)(NIL_P(prefix) ? NULL : StringValuePtr(prefix))
853
+ );
854
+
855
+ if(!ns) {
856
+ ns = xmlSearchNs(
857
+ node->doc,
858
+ node,
859
+ (const xmlChar *)(NIL_P(prefix) ? NULL : StringValuePtr(prefix))
860
+ );
861
+ }
862
+
863
+ if(NIL_P(prefix)) xmlSetNs(node, ns);
864
+
865
+ return Nokogiri_wrap_xml_namespace(node->doc, ns);
866
+ }
867
+
868
+ /*
869
+ * call-seq:
870
+ * new(name, document)
871
+ *
872
+ * Create a new node with +name+ sharing GC lifecycle with +document+
873
+ */
874
+ static VALUE new(int argc, VALUE *argv, VALUE klass)
875
+ {
876
+ xmlDocPtr doc;
877
+ VALUE name;
878
+ VALUE document;
879
+ VALUE rest;
880
+
881
+ rb_scan_args(argc, argv, "2*", &name, &document, &rest);
882
+
883
+ Data_Get_Struct(document, xmlDoc, doc);
884
+
885
+ xmlNodePtr node = xmlNewNode(NULL, (xmlChar *)StringValuePtr(name));
886
+ node->doc = doc->doc;
887
+ NOKOGIRI_ROOT_NODE(node);
888
+
889
+ VALUE rb_node = Nokogiri_wrap_xml_node(
890
+ klass == cNokogiriXmlNode ? (VALUE)NULL : klass,
891
+ node
892
+ );
893
+ rb_obj_call_init(rb_node, argc, argv);
894
+
895
+ if(rb_block_given_p()) rb_yield(rb_node);
896
+
897
+ return rb_node;
898
+ }
899
+
900
+ /*
901
+ * call-seq:
902
+ * dump_html
903
+ *
904
+ * Returns the Node as html.
905
+ */
906
+ static VALUE dump_html(VALUE self)
907
+ {
908
+ xmlBufferPtr buf ;
909
+ xmlNodePtr node ;
910
+ Data_Get_Struct(self, xmlNode, node);
911
+
912
+ buf = xmlBufferCreate() ;
913
+ htmlNodeDump(buf, node->doc, node);
914
+ VALUE html = NOKOGIRI_STR_NEW2(buf->content);
915
+ xmlBufferFree(buf);
916
+ return html ;
917
+ }
918
+
919
+ /*
920
+ * call-seq:
921
+ * compare(other)
922
+ *
923
+ * Compare this Node to +other+ with respect to their Document
924
+ */
925
+ static VALUE compare(VALUE self, VALUE _other)
926
+ {
927
+ xmlNodePtr node, other;
928
+ Data_Get_Struct(self, xmlNode, node);
929
+ Data_Get_Struct(_other, xmlNode, other);
930
+
931
+ return INT2NUM((long)xmlXPathCmpNodes(other, node));
932
+ }
933
+
934
+ VALUE Nokogiri_wrap_xml_node(VALUE klass, xmlNodePtr node)
935
+ {
936
+ assert(node);
937
+
938
+ VALUE document = Qnil ;
939
+ VALUE node_cache = Qnil ;
940
+ VALUE rb_node = Qnil ;
941
+
942
+ if(node->type == XML_DOCUMENT_NODE || node->type == XML_HTML_DOCUMENT_NODE)
943
+ return DOC_RUBY_OBJECT(node->doc);
944
+
945
+ if(NULL != node->_private) return (VALUE)node->_private;
946
+
947
+ if(RTEST(klass))
948
+ rb_node = Data_Wrap_Struct(klass, mark, debug_node_dealloc, node) ;
949
+
950
+ else switch(node->type)
951
+ {
952
+ case XML_ELEMENT_NODE:
953
+ klass = cNokogiriXmlElement;
954
+ break;
955
+ case XML_TEXT_NODE:
956
+ klass = cNokogiriXmlText;
957
+ break;
958
+ case XML_ATTRIBUTE_NODE:
959
+ klass = cNokogiriXmlAttr;
960
+ break;
961
+ case XML_ENTITY_REF_NODE:
962
+ klass = cNokogiriXmlEntityReference;
963
+ break;
964
+ case XML_COMMENT_NODE:
965
+ klass = cNokogiriXmlComment;
966
+ break;
967
+ case XML_DOCUMENT_FRAG_NODE:
968
+ klass = cNokogiriXmlDocumentFragment;
969
+ break;
970
+ case XML_PI_NODE:
971
+ klass = cNokogiriXmlProcessingInstruction;
972
+ break;
973
+ case XML_ENTITY_DECL:
974
+ klass = cNokogiriXmlEntityDecl;
975
+ break;
976
+ case XML_CDATA_SECTION_NODE:
977
+ klass = cNokogiriXmlCData;
978
+ break;
979
+ case XML_DTD_NODE:
980
+ klass = cNokogiriXmlDtd;
981
+ break;
982
+ case XML_ATTRIBUTE_DECL:
983
+ klass = cNokogiriXmlAttributeDecl;
984
+ break;
985
+ case XML_ELEMENT_DECL:
986
+ klass = cNokogiriXmlElementDecl;
987
+ break;
988
+ default:
989
+ klass = cNokogiriXmlNode;
990
+ }
991
+
992
+ rb_node = Data_Wrap_Struct(klass, mark, debug_node_dealloc, node) ;
993
+
994
+ node->_private = (void *)rb_node;
995
+
996
+ if (DOC_RUBY_OBJECT_TEST(node->doc) && DOC_RUBY_OBJECT(node->doc)) {
997
+ // it's OK if the document isn't fully realized (as in XML::Reader).
998
+ // see http://github.com/tenderlove/nokogiri/issues/closed/#issue/95
999
+ document = DOC_RUBY_OBJECT(node->doc);
1000
+ node_cache = DOC_NODE_CACHE(node->doc);
1001
+ rb_ary_push(node_cache, rb_node);
1002
+ rb_funcall(document, decorate, 1, rb_node);
1003
+ }
1004
+
1005
+ return rb_node ;
1006
+ }
1007
+
1008
+
1009
+ void Nokogiri_xml_node_properties(xmlNodePtr node, VALUE attr_list)
1010
+ {
1011
+ xmlAttrPtr prop;
1012
+ prop = node->properties ;
1013
+ while (prop != NULL) {
1014
+ rb_ary_push(attr_list, Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)prop));
1015
+ prop = prop->next ;
1016
+ }
1017
+ }
1018
+
1019
+ VALUE cNokogiriXmlNode ;
1020
+ VALUE cNokogiriXmlElement ;
1021
+
1022
+ void init_xml_node()
1023
+ {
1024
+ VALUE nokogiri = rb_define_module("Nokogiri");
1025
+ VALUE xml = rb_define_module_under(nokogiri, "XML");
1026
+ VALUE klass = rb_define_class_under(xml, "Node", rb_cObject);
1027
+
1028
+ cNokogiriXmlNode = klass;
1029
+
1030
+ cNokogiriXmlElement = rb_define_class_under(xml, "Element", klass);
1031
+
1032
+ rb_define_singleton_method(klass, "new", new, -1);
1033
+
1034
+ rb_define_method(klass, "add_namespace_definition", add_namespace_definition, 2);
1035
+ rb_define_method(klass, "node_name", get_name, 0);
1036
+ rb_define_method(klass, "document", document, 0);
1037
+ rb_define_method(klass, "node_name=", set_name, 1);
1038
+ rb_define_method(klass, "parent", get_parent, 0);
1039
+ rb_define_method(klass, "child", child, 0);
1040
+ rb_define_method(klass, "children", children, 0);
1041
+ rb_define_method(klass, "next_sibling", next_sibling, 0);
1042
+ rb_define_method(klass, "previous_sibling", previous_sibling, 0);
1043
+ rb_define_method(klass, "next_element", next_element, 0);
1044
+ rb_define_method(klass, "previous_element", previous_element, 0);
1045
+ rb_define_method(klass, "node_type", node_type, 0);
1046
+ rb_define_method(klass, "content", get_content, 0);
1047
+ rb_define_method(klass, "path", path, 0);
1048
+ rb_define_method(klass, "key?", key_eh, 1);
1049
+ rb_define_method(klass, "namespaced_key?", namespaced_key_eh, 2);
1050
+ rb_define_method(klass, "blank?", blank_eh, 0);
1051
+ rb_define_method(klass, "[]=", set, 2);
1052
+ rb_define_method(klass, "attribute_nodes", attribute_nodes, 0);
1053
+ rb_define_method(klass, "attribute", attr, 1);
1054
+ rb_define_method(klass, "attribute_with_ns", attribute_with_ns, 2);
1055
+ rb_define_method(klass, "namespace", namespace, 0);
1056
+ rb_define_method(klass, "namespace_definitions", namespace_definitions, 0);
1057
+ rb_define_method(klass, "encode_special_chars", encode_special_chars, 1);
1058
+ rb_define_method(klass, "dup", duplicate_node, -1);
1059
+ rb_define_method(klass, "unlink", unlink_node, 0);
1060
+ rb_define_method(klass, "internal_subset", internal_subset, 0);
1061
+ rb_define_method(klass, "external_subset", external_subset, 0);
1062
+ rb_define_method(klass, "create_internal_subset", create_internal_subset, 3);
1063
+ rb_define_method(klass, "create_external_subset", create_external_subset, 3);
1064
+ rb_define_method(klass, "pointer_id", pointer_id, 0);
1065
+ rb_define_method(klass, "line", line, 0);
1066
+
1067
+ rb_define_private_method(klass, "add_child_node", add_child, 1);
1068
+ rb_define_private_method(klass, "add_previous_sibling_node", add_previous_sibling, 1);
1069
+ rb_define_private_method(klass, "add_next_sibling_node", add_next_sibling, 1);
1070
+ rb_define_private_method(klass, "replace_node", replace, 1);
1071
+ rb_define_private_method(klass, "dump_html", dump_html, 0);
1072
+ rb_define_private_method(klass, "native_write_to", native_write_to, 4);
1073
+ rb_define_private_method(klass, "native_content=", set_content, 1);
1074
+ rb_define_private_method(klass, "get", get, 1);
1075
+ rb_define_private_method(klass, "set_namespace", set_namespace, 1);
1076
+ rb_define_private_method(klass, "compare", compare, 1);
1077
+
1078
+ decorate = rb_intern("decorate");
1079
+ decorate_bang = rb_intern("decorate!");
1080
+ }