superfeedr-nokogiri 1.4.0.20091116183308

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. data/.autotest +27 -0
  2. data/CHANGELOG.ja.rdoc +330 -0
  3. data/CHANGELOG.rdoc +314 -0
  4. data/Manifest.txt +269 -0
  5. data/README.ja.rdoc +105 -0
  6. data/README.rdoc +118 -0
  7. data/Rakefile +244 -0
  8. data/bin/nokogiri +49 -0
  9. data/ext/nokogiri/extconf.rb +145 -0
  10. data/ext/nokogiri/html_document.c +145 -0
  11. data/ext/nokogiri/html_document.h +10 -0
  12. data/ext/nokogiri/html_element_description.c +272 -0
  13. data/ext/nokogiri/html_element_description.h +10 -0
  14. data/ext/nokogiri/html_entity_lookup.c +32 -0
  15. data/ext/nokogiri/html_entity_lookup.h +8 -0
  16. data/ext/nokogiri/html_sax_parser_context.c +92 -0
  17. data/ext/nokogiri/html_sax_parser_context.h +11 -0
  18. data/ext/nokogiri/nokogiri.c +89 -0
  19. data/ext/nokogiri/nokogiri.h +145 -0
  20. data/ext/nokogiri/xml_attr.c +92 -0
  21. data/ext/nokogiri/xml_attr.h +9 -0
  22. data/ext/nokogiri/xml_attribute_decl.c +67 -0
  23. data/ext/nokogiri/xml_attribute_decl.h +9 -0
  24. data/ext/nokogiri/xml_cdata.c +54 -0
  25. data/ext/nokogiri/xml_cdata.h +9 -0
  26. data/ext/nokogiri/xml_comment.c +52 -0
  27. data/ext/nokogiri/xml_comment.h +9 -0
  28. data/ext/nokogiri/xml_document.c +388 -0
  29. data/ext/nokogiri/xml_document.h +24 -0
  30. data/ext/nokogiri/xml_document_fragment.c +46 -0
  31. data/ext/nokogiri/xml_document_fragment.h +10 -0
  32. data/ext/nokogiri/xml_dtd.c +192 -0
  33. data/ext/nokogiri/xml_dtd.h +10 -0
  34. data/ext/nokogiri/xml_element_content.c +123 -0
  35. data/ext/nokogiri/xml_element_content.h +10 -0
  36. data/ext/nokogiri/xml_element_decl.c +69 -0
  37. data/ext/nokogiri/xml_element_decl.h +9 -0
  38. data/ext/nokogiri/xml_entity_decl.c +97 -0
  39. data/ext/nokogiri/xml_entity_decl.h +10 -0
  40. data/ext/nokogiri/xml_entity_reference.c +50 -0
  41. data/ext/nokogiri/xml_entity_reference.h +9 -0
  42. data/ext/nokogiri/xml_io.c +31 -0
  43. data/ext/nokogiri/xml_io.h +11 -0
  44. data/ext/nokogiri/xml_namespace.c +74 -0
  45. data/ext/nokogiri/xml_namespace.h +12 -0
  46. data/ext/nokogiri/xml_node.c +1060 -0
  47. data/ext/nokogiri/xml_node.h +13 -0
  48. data/ext/nokogiri/xml_node_set.c +397 -0
  49. data/ext/nokogiri/xml_node_set.h +9 -0
  50. data/ext/nokogiri/xml_processing_instruction.c +54 -0
  51. data/ext/nokogiri/xml_processing_instruction.h +9 -0
  52. data/ext/nokogiri/xml_reader.c +593 -0
  53. data/ext/nokogiri/xml_reader.h +10 -0
  54. data/ext/nokogiri/xml_relax_ng.c +159 -0
  55. data/ext/nokogiri/xml_relax_ng.h +9 -0
  56. data/ext/nokogiri/xml_sax_parser.c +286 -0
  57. data/ext/nokogiri/xml_sax_parser.h +43 -0
  58. data/ext/nokogiri/xml_sax_parser_context.c +155 -0
  59. data/ext/nokogiri/xml_sax_parser_context.h +10 -0
  60. data/ext/nokogiri/xml_sax_push_parser.c +114 -0
  61. data/ext/nokogiri/xml_sax_push_parser.h +9 -0
  62. data/ext/nokogiri/xml_schema.c +156 -0
  63. data/ext/nokogiri/xml_schema.h +9 -0
  64. data/ext/nokogiri/xml_syntax_error.c +261 -0
  65. data/ext/nokogiri/xml_syntax_error.h +13 -0
  66. data/ext/nokogiri/xml_text.c +48 -0
  67. data/ext/nokogiri/xml_text.h +9 -0
  68. data/ext/nokogiri/xml_xpath.c +53 -0
  69. data/ext/nokogiri/xml_xpath.h +11 -0
  70. data/ext/nokogiri/xml_xpath_context.c +239 -0
  71. data/ext/nokogiri/xml_xpath_context.h +9 -0
  72. data/ext/nokogiri/xslt_stylesheet.c +131 -0
  73. data/ext/nokogiri/xslt_stylesheet.h +9 -0
  74. data/lib/nokogiri.rb +116 -0
  75. data/lib/nokogiri/css.rb +25 -0
  76. data/lib/nokogiri/css/generated_parser.rb +646 -0
  77. data/lib/nokogiri/css/generated_tokenizer.rb +142 -0
  78. data/lib/nokogiri/css/node.rb +99 -0
  79. data/lib/nokogiri/css/parser.rb +82 -0
  80. data/lib/nokogiri/css/parser.y +227 -0
  81. data/lib/nokogiri/css/syntax_error.rb +7 -0
  82. data/lib/nokogiri/css/tokenizer.rb +7 -0
  83. data/lib/nokogiri/css/tokenizer.rex +54 -0
  84. data/lib/nokogiri/css/xpath_visitor.rb +162 -0
  85. data/lib/nokogiri/decorators/slop.rb +33 -0
  86. data/lib/nokogiri/ffi/html/document.rb +28 -0
  87. data/lib/nokogiri/ffi/html/element_description.rb +85 -0
  88. data/lib/nokogiri/ffi/html/entity_lookup.rb +16 -0
  89. data/lib/nokogiri/ffi/html/sax/parser_context.rb +38 -0
  90. data/lib/nokogiri/ffi/io_callbacks.rb +42 -0
  91. data/lib/nokogiri/ffi/libxml.rb +356 -0
  92. data/lib/nokogiri/ffi/structs/common_node.rb +26 -0
  93. data/lib/nokogiri/ffi/structs/html_elem_desc.rb +24 -0
  94. data/lib/nokogiri/ffi/structs/html_entity_desc.rb +13 -0
  95. data/lib/nokogiri/ffi/structs/xml_alloc.rb +16 -0
  96. data/lib/nokogiri/ffi/structs/xml_attr.rb +19 -0
  97. data/lib/nokogiri/ffi/structs/xml_attribute.rb +27 -0
  98. data/lib/nokogiri/ffi/structs/xml_buffer.rb +16 -0
  99. data/lib/nokogiri/ffi/structs/xml_document.rb +108 -0
  100. data/lib/nokogiri/ffi/structs/xml_dtd.rb +28 -0
  101. data/lib/nokogiri/ffi/structs/xml_element.rb +26 -0
  102. data/lib/nokogiri/ffi/structs/xml_element_content.rb +17 -0
  103. data/lib/nokogiri/ffi/structs/xml_entity.rb +32 -0
  104. data/lib/nokogiri/ffi/structs/xml_enumeration.rb +12 -0
  105. data/lib/nokogiri/ffi/structs/xml_node.rb +28 -0
  106. data/lib/nokogiri/ffi/structs/xml_node_set.rb +53 -0
  107. data/lib/nokogiri/ffi/structs/xml_notation.rb +11 -0
  108. data/lib/nokogiri/ffi/structs/xml_ns.rb +15 -0
  109. data/lib/nokogiri/ffi/structs/xml_parser_context.rb +19 -0
  110. data/lib/nokogiri/ffi/structs/xml_relax_ng.rb +14 -0
  111. data/lib/nokogiri/ffi/structs/xml_sax_handler.rb +51 -0
  112. data/lib/nokogiri/ffi/structs/xml_sax_push_parser_context.rb +15 -0
  113. data/lib/nokogiri/ffi/structs/xml_schema.rb +13 -0
  114. data/lib/nokogiri/ffi/structs/xml_syntax_error.rb +31 -0
  115. data/lib/nokogiri/ffi/structs/xml_text_reader.rb +12 -0
  116. data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +37 -0
  117. data/lib/nokogiri/ffi/structs/xml_xpath_object.rb +35 -0
  118. data/lib/nokogiri/ffi/structs/xml_xpath_parser_context.rb +20 -0
  119. data/lib/nokogiri/ffi/structs/xslt_stylesheet.rb +13 -0
  120. data/lib/nokogiri/ffi/xml/attr.rb +41 -0
  121. data/lib/nokogiri/ffi/xml/attribute_decl.rb +27 -0
  122. data/lib/nokogiri/ffi/xml/cdata.rb +19 -0
  123. data/lib/nokogiri/ffi/xml/comment.rb +18 -0
  124. data/lib/nokogiri/ffi/xml/document.rb +135 -0
  125. data/lib/nokogiri/ffi/xml/document_fragment.rb +21 -0
  126. data/lib/nokogiri/ffi/xml/dtd.rb +69 -0
  127. data/lib/nokogiri/ffi/xml/element_content.rb +43 -0
  128. data/lib/nokogiri/ffi/xml/element_decl.rb +19 -0
  129. data/lib/nokogiri/ffi/xml/entity_decl.rb +27 -0
  130. data/lib/nokogiri/ffi/xml/entity_reference.rb +19 -0
  131. data/lib/nokogiri/ffi/xml/namespace.rb +44 -0
  132. data/lib/nokogiri/ffi/xml/node.rb +444 -0
  133. data/lib/nokogiri/ffi/xml/node_set.rb +133 -0
  134. data/lib/nokogiri/ffi/xml/processing_instruction.rb +20 -0
  135. data/lib/nokogiri/ffi/xml/reader.rb +227 -0
  136. data/lib/nokogiri/ffi/xml/relax_ng.rb +85 -0
  137. data/lib/nokogiri/ffi/xml/sax/parser.rb +142 -0
  138. data/lib/nokogiri/ffi/xml/sax/parser_context.rb +67 -0
  139. data/lib/nokogiri/ffi/xml/sax/push_parser.rb +39 -0
  140. data/lib/nokogiri/ffi/xml/schema.rb +92 -0
  141. data/lib/nokogiri/ffi/xml/syntax_error.rb +91 -0
  142. data/lib/nokogiri/ffi/xml/text.rb +18 -0
  143. data/lib/nokogiri/ffi/xml/xpath.rb +19 -0
  144. data/lib/nokogiri/ffi/xml/xpath_context.rb +135 -0
  145. data/lib/nokogiri/ffi/xslt/stylesheet.rb +47 -0
  146. data/lib/nokogiri/html.rb +35 -0
  147. data/lib/nokogiri/html/builder.rb +35 -0
  148. data/lib/nokogiri/html/document.rb +88 -0
  149. data/lib/nokogiri/html/document_fragment.rb +15 -0
  150. data/lib/nokogiri/html/element_description.rb +23 -0
  151. data/lib/nokogiri/html/entity_lookup.rb +13 -0
  152. data/lib/nokogiri/html/sax/parser.rb +48 -0
  153. data/lib/nokogiri/html/sax/parser_context.rb +16 -0
  154. data/lib/nokogiri/syntax_error.rb +4 -0
  155. data/lib/nokogiri/version.rb +33 -0
  156. data/lib/nokogiri/version_warning.rb +11 -0
  157. data/lib/nokogiri/xml.rb +67 -0
  158. data/lib/nokogiri/xml/attr.rb +14 -0
  159. data/lib/nokogiri/xml/attribute_decl.rb +18 -0
  160. data/lib/nokogiri/xml/builder.rb +405 -0
  161. data/lib/nokogiri/xml/cdata.rb +11 -0
  162. data/lib/nokogiri/xml/character_data.rb +7 -0
  163. data/lib/nokogiri/xml/document.rb +131 -0
  164. data/lib/nokogiri/xml/document_fragment.rb +69 -0
  165. data/lib/nokogiri/xml/dtd.rb +11 -0
  166. data/lib/nokogiri/xml/element_content.rb +36 -0
  167. data/lib/nokogiri/xml/element_decl.rb +13 -0
  168. data/lib/nokogiri/xml/entity_decl.rb +15 -0
  169. data/lib/nokogiri/xml/fragment_handler.rb +71 -0
  170. data/lib/nokogiri/xml/namespace.rb +13 -0
  171. data/lib/nokogiri/xml/node.rb +665 -0
  172. data/lib/nokogiri/xml/node/save_options.rb +42 -0
  173. data/lib/nokogiri/xml/node_set.rb +307 -0
  174. data/lib/nokogiri/xml/notation.rb +6 -0
  175. data/lib/nokogiri/xml/parse_options.rb +85 -0
  176. data/lib/nokogiri/xml/pp.rb +2 -0
  177. data/lib/nokogiri/xml/pp/character_data.rb +18 -0
  178. data/lib/nokogiri/xml/pp/node.rb +56 -0
  179. data/lib/nokogiri/xml/processing_instruction.rb +8 -0
  180. data/lib/nokogiri/xml/reader.rb +74 -0
  181. data/lib/nokogiri/xml/relax_ng.rb +32 -0
  182. data/lib/nokogiri/xml/sax.rb +4 -0
  183. data/lib/nokogiri/xml/sax/document.rb +160 -0
  184. data/lib/nokogiri/xml/sax/parser.rb +115 -0
  185. data/lib/nokogiri/xml/sax/parser_context.rb +16 -0
  186. data/lib/nokogiri/xml/sax/push_parser.rb +60 -0
  187. data/lib/nokogiri/xml/schema.rb +61 -0
  188. data/lib/nokogiri/xml/syntax_error.rb +38 -0
  189. data/lib/nokogiri/xml/xpath.rb +10 -0
  190. data/lib/nokogiri/xml/xpath/syntax_error.rb +8 -0
  191. data/lib/nokogiri/xml/xpath_context.rb +16 -0
  192. data/lib/nokogiri/xslt.rb +48 -0
  193. data/lib/nokogiri/xslt/stylesheet.rb +25 -0
  194. data/lib/xsd/xmlparser/nokogiri.rb +71 -0
  195. data/tasks/test.rb +100 -0
  196. data/test/css/test_nthiness.rb +159 -0
  197. data/test/css/test_parser.rb +277 -0
  198. data/test/css/test_tokenizer.rb +183 -0
  199. data/test/css/test_xpath_visitor.rb +76 -0
  200. data/test/ffi/test_document.rb +35 -0
  201. data/test/files/2ch.html +108 -0
  202. data/test/files/address_book.rlx +12 -0
  203. data/test/files/address_book.xml +10 -0
  204. data/test/files/bar/bar.xsd +4 -0
  205. data/test/files/dont_hurt_em_why.xml +422 -0
  206. data/test/files/exslt.xml +8 -0
  207. data/test/files/exslt.xslt +35 -0
  208. data/test/files/foo/foo.xsd +4 -0
  209. data/test/files/po.xml +32 -0
  210. data/test/files/po.xsd +66 -0
  211. data/test/files/shift_jis.html +10 -0
  212. data/test/files/shift_jis.xml +5 -0
  213. data/test/files/snuggles.xml +3 -0
  214. data/test/files/staff.dtd +10 -0
  215. data/test/files/staff.xml +59 -0
  216. data/test/files/staff.xslt +32 -0
  217. data/test/files/tlm.html +850 -0
  218. data/test/files/valid_bar.xml +2 -0
  219. data/test/helper.rb +136 -0
  220. data/test/html/sax/test_parser.rb +64 -0
  221. data/test/html/sax/test_parser_context.rb +48 -0
  222. data/test/html/test_builder.rb +164 -0
  223. data/test/html/test_document.rb +390 -0
  224. data/test/html/test_document_encoding.rb +77 -0
  225. data/test/html/test_document_fragment.rb +132 -0
  226. data/test/html/test_element_description.rb +94 -0
  227. data/test/html/test_named_characters.rb +14 -0
  228. data/test/html/test_node.rb +228 -0
  229. data/test/html/test_node_encoding.rb +27 -0
  230. data/test/test_convert_xpath.rb +135 -0
  231. data/test/test_css_cache.rb +45 -0
  232. data/test/test_gc.rb +15 -0
  233. data/test/test_memory_leak.rb +77 -0
  234. data/test/test_nokogiri.rb +134 -0
  235. data/test/test_reader.rb +358 -0
  236. data/test/test_xslt_transforms.rb +131 -0
  237. data/test/xml/node/test_save_options.rb +20 -0
  238. data/test/xml/node/test_subclass.rb +44 -0
  239. data/test/xml/sax/test_parser.rb +307 -0
  240. data/test/xml/sax/test_parser_context.rb +56 -0
  241. data/test/xml/sax/test_push_parser.rb +131 -0
  242. data/test/xml/test_attr.rb +38 -0
  243. data/test/xml/test_attribute_decl.rb +82 -0
  244. data/test/xml/test_builder.rb +167 -0
  245. data/test/xml/test_cdata.rb +38 -0
  246. data/test/xml/test_comment.rb +29 -0
  247. data/test/xml/test_document.rb +607 -0
  248. data/test/xml/test_document_encoding.rb +26 -0
  249. data/test/xml/test_document_fragment.rb +138 -0
  250. data/test/xml/test_dtd.rb +82 -0
  251. data/test/xml/test_dtd_encoding.rb +33 -0
  252. data/test/xml/test_element_content.rb +56 -0
  253. data/test/xml/test_element_decl.rb +73 -0
  254. data/test/xml/test_entity_decl.rb +83 -0
  255. data/test/xml/test_entity_reference.rb +21 -0
  256. data/test/xml/test_namespace.rb +68 -0
  257. data/test/xml/test_node.rb +889 -0
  258. data/test/xml/test_node_attributes.rb +34 -0
  259. data/test/xml/test_node_encoding.rb +107 -0
  260. data/test/xml/test_node_set.rb +531 -0
  261. data/test/xml/test_parse_options.rb +52 -0
  262. data/test/xml/test_processing_instruction.rb +30 -0
  263. data/test/xml/test_reader_encoding.rb +126 -0
  264. data/test/xml/test_relax_ng.rb +60 -0
  265. data/test/xml/test_schema.rb +89 -0
  266. data/test/xml/test_syntax_error.rb +27 -0
  267. data/test/xml/test_text.rb +30 -0
  268. data/test/xml/test_unparented_node.rb +381 -0
  269. data/test/xml/test_xpath.rb +106 -0
  270. metadata +430 -0
@@ -0,0 +1,69 @@
1
+ # :stopdoc:
2
+ module Nokogiri
3
+ module XML
4
+ class DTD < Node
5
+ def validate document
6
+ error_list = []
7
+ ctxt = LibXML.xmlNewValidCtxt
8
+
9
+ LibXML.xmlSetStructuredErrorFunc(nil, SyntaxError.error_array_pusher(error_list))
10
+ LibXML.xmlValidateDtd ctxt, document.cstruct, cstruct
11
+
12
+ LibXML.xmlSetStructuredErrorFunc nil, nil
13
+
14
+ LibXML.xmlFreeValidCtxt ctxt
15
+
16
+ error_list
17
+ end
18
+
19
+ def system_id
20
+ cstruct[:system_id]
21
+ end
22
+
23
+ def external_id
24
+ cstruct[:external_id]
25
+ end
26
+
27
+ def elements
28
+ internal_attributes :elements
29
+ end
30
+
31
+ def entities
32
+ internal_attributes :entities
33
+ end
34
+
35
+ def attributes
36
+ internal_attributes :attributes
37
+ end
38
+
39
+ def notations
40
+ attr_ptr = cstruct[:notations]
41
+ return nil if attr_ptr.null?
42
+
43
+ ahash = {}
44
+ proc = lambda do |payload, data, name|
45
+ notation_cstruct = LibXML::XmlNotation.new(payload)
46
+ ahash[name] = Notation.new(notation_cstruct[:name], notation_cstruct[:PublicID],
47
+ notation_cstruct[:SystemID])
48
+ end
49
+ LibXML.xmlHashScan(attr_ptr, proc, nil)
50
+ ahash
51
+ end
52
+
53
+ private
54
+
55
+ def internal_attributes attr_name
56
+ attr_ptr = cstruct[attr_name.to_sym]
57
+ return nil if attr_ptr.null?
58
+
59
+ ahash = {}
60
+ proc = lambda do |payload, data, name|
61
+ ahash[name] = Node.wrap(payload)
62
+ end
63
+ LibXML.xmlHashScan(attr_ptr, proc, nil)
64
+ ahash
65
+ end
66
+ end
67
+ end
68
+ end
69
+ # :startdoc:
@@ -0,0 +1,43 @@
1
+ # :stopdoc:
2
+ module Nokogiri
3
+ module XML
4
+ class ElementContent
5
+ attr_accessor :cstruct
6
+
7
+ def self.wrap pointer, document
8
+ return nil if pointer.null?
9
+
10
+ c = ElementContent.allocate
11
+ c.cstruct = LibXML::XmlElementContent.new pointer
12
+ c.instance_variable_set :@document, document
13
+ c
14
+ end
15
+
16
+ def type
17
+ cstruct[:type]
18
+ end
19
+
20
+ def prefix
21
+ cstruct[:prefix]
22
+ end
23
+
24
+ def occur
25
+ cstruct[:ocur]
26
+ end
27
+
28
+ def name
29
+ cstruct[:name]
30
+ end
31
+
32
+ private
33
+ def c1
34
+ self.class.wrap cstruct[:c1], document
35
+ end
36
+
37
+ def c2
38
+ self.class.wrap cstruct[:c2], document
39
+ end
40
+ end
41
+ end
42
+ end
43
+ # :startdoc:
@@ -0,0 +1,19 @@
1
+ # :stopdoc:
2
+ module Nokogiri
3
+ module XML
4
+ class ElementDecl < Nokogiri::XML::Node
5
+ def element_type
6
+ cstruct[:etype]
7
+ end
8
+
9
+ def prefix
10
+ cstruct[:prefix]
11
+ end
12
+
13
+ def content
14
+ ElementContent.wrap cstruct[:content], document
15
+ end
16
+ end
17
+ end
18
+ end
19
+ # :startdoc:
@@ -0,0 +1,27 @@
1
+ # :stopdoc:
2
+ module Nokogiri
3
+ module XML
4
+ class EntityDecl < Nokogiri::XML::Node
5
+ def content
6
+ cstruct[:content]
7
+ end
8
+
9
+ def entity_type
10
+ cstruct[:etype]
11
+ end
12
+
13
+ def external_id
14
+ cstruct[:external_id]
15
+ end
16
+
17
+ def system_id
18
+ cstruct[:system_id]
19
+ end
20
+
21
+ def original_content
22
+ cstruct[:orig]
23
+ end
24
+ end
25
+ end
26
+ end
27
+ # :startdoc:
@@ -0,0 +1,19 @@
1
+ module Nokogiri
2
+ module XML
3
+ class EntityReference < Node
4
+
5
+ def self.new(document, name, *rest) # :nodoc:
6
+ node_ptr = LibXML.xmlNewReference(document.cstruct, name)
7
+ node_cstruct = LibXML::XmlNode.new(node_ptr)
8
+ node_cstruct.keep_reference_from_document!
9
+
10
+ node = Node.wrap(node_cstruct, self)
11
+ node.send :initialize, document, name, *rest
12
+ yield node if block_given?
13
+ node
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,44 @@
1
+ module Nokogiri
2
+ module XML
3
+ class Namespace
4
+ # :stopdoc:
5
+
6
+ attr_accessor :cstruct
7
+ attr_accessor :document
8
+
9
+ def prefix
10
+ cstruct[:prefix].nil? ? nil : cstruct[:prefix] # TODO: encoding?
11
+ end
12
+
13
+ def href
14
+ cstruct[:href].nil? ? nil : cstruct[:href] # TODO: encoding?
15
+ end
16
+
17
+ class << self
18
+ def wrap(document, node_struct)
19
+ if node_struct.is_a?(FFI::Pointer)
20
+ # cast native pointers up into a node cstruct
21
+ return nil if node_struct.null?
22
+ node_struct = LibXML::XmlNs.new(node_struct)
23
+ end
24
+
25
+ ruby_node = node_struct.ruby_node
26
+ return ruby_node unless ruby_node.nil?
27
+
28
+ ns = Nokogiri::XML::Namespace.allocate
29
+ ns.document = document.ruby_doc
30
+ ns.cstruct = node_struct
31
+
32
+ ns.cstruct.ruby_node = ns
33
+
34
+ cache = ns.document.instance_variable_get(:@node_cache)
35
+ cache << ns
36
+
37
+ ns
38
+ end
39
+ end
40
+
41
+ # :startdoc:
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,444 @@
1
+ module Nokogiri
2
+ module XML
3
+ class Node
4
+ # :stopdoc:
5
+
6
+ attr_accessor :cstruct
7
+
8
+ def pointer_id
9
+ cstruct.pointer
10
+ end
11
+
12
+ def encode_special_chars(string)
13
+ char_ptr = LibXML.xmlEncodeSpecialChars(self[:doc], string)
14
+ encoded = char_ptr.read_string
15
+ # TODO: encoding?
16
+ LibXML.xmlFree(char_ptr)
17
+ encoded
18
+ end
19
+
20
+ def internal_subset
21
+ doc = cstruct.document
22
+ dtd = LibXML.xmlGetIntSubset(doc)
23
+ return nil if dtd.null?
24
+ Node.wrap(dtd)
25
+ end
26
+
27
+ def external_subset
28
+ doc = cstruct.document
29
+ return nil if doc[:extSubset].null?
30
+
31
+ Node.wrap(doc[:extSubset])
32
+ end
33
+
34
+ def create_internal_subset name, external_id, system_id
35
+ raise("Document already has an internal subset") if internal_subset
36
+
37
+ doc = cstruct.document
38
+ dtd_ptr = LibXML.xmlCreateIntSubset doc, name, external_id, system_id
39
+
40
+ return nil if dtd_ptr.null?
41
+
42
+ Node.wrap dtd_ptr
43
+ end
44
+
45
+ def create_external_subset name, external_id, system_id
46
+ raise("Document already has an external subset") if external_subset
47
+
48
+ doc = cstruct.document
49
+ dtd_ptr = LibXML.xmlNewDtd doc, name, external_id, system_id
50
+
51
+ return nil if dtd_ptr.null?
52
+
53
+ Node.wrap dtd_ptr
54
+ end
55
+
56
+ def dup(deep = 1)
57
+ dup_ptr = LibXML.xmlDocCopyNode(cstruct, cstruct.document, deep)
58
+ return nil if dup_ptr.null?
59
+ Node.wrap(dup_ptr, self.class)
60
+ end
61
+
62
+ def unlink
63
+ LibXML.xmlUnlinkNode(cstruct)
64
+ cstruct.keep_reference_from_document!
65
+ self
66
+ end
67
+
68
+ def blank?
69
+ LibXML.xmlIsBlankNode(cstruct) == 1
70
+ end
71
+
72
+ def next_sibling
73
+ cstruct_node_from :next
74
+ end
75
+
76
+ def previous_sibling
77
+ cstruct_node_from :prev
78
+ end
79
+
80
+ def replace_with_node(new_node)
81
+ LibXML.xmlReplaceNode(cstruct, new_node.cstruct)
82
+ Node.send(:relink_namespace, new_node.cstruct)
83
+ self
84
+ end
85
+
86
+ def children
87
+ return NodeSet.new(nil) if cstruct[:children].null?
88
+ child = Node.wrap(cstruct[:children])
89
+
90
+ set = NodeSet.new child.document
91
+ set_ptr = LibXML.xmlXPathNodeSetCreate(child.cstruct)
92
+
93
+ set.cstruct = LibXML::XmlNodeSet.new(set_ptr)
94
+ return set unless child
95
+
96
+ child_ptr = child.cstruct[:next]
97
+ while ! child_ptr.null?
98
+ child = Node.wrap(child_ptr)
99
+ LibXML.xmlXPathNodeSetAdd(set.cstruct, child.cstruct)
100
+ child_ptr = child.cstruct[:next]
101
+ end
102
+
103
+ return set
104
+ end
105
+
106
+ def child
107
+ (val = cstruct[:children]).null? ? nil : Node.wrap(val)
108
+ end
109
+
110
+ def key?(attribute)
111
+ ! (prop = LibXML.xmlHasProp(cstruct, attribute.to_s)).null?
112
+ end
113
+
114
+ def namespaced_key?(attribute, namespace)
115
+ prop = LibXML.xmlHasNsProp(cstruct, attribute.to_s,
116
+ namespace.nil? ? nil : namespace.to_s)
117
+ prop.null? ? false : true
118
+ end
119
+
120
+ def []=(property, value)
121
+ LibXML.xmlSetProp(cstruct, property, value)
122
+ value
123
+ end
124
+
125
+ def get(attribute)
126
+ return nil unless attribute
127
+ propstr = LibXML.xmlGetProp(cstruct, attribute.to_s)
128
+ return nil if propstr.null?
129
+ rval = propstr.read_string # TODO: encoding?
130
+ LibXML.xmlFree(propstr)
131
+ rval
132
+ end
133
+
134
+ def set_namespace(namespace)
135
+ LibXML.xmlSetNs(cstruct, namespace.cstruct)
136
+ self
137
+ end
138
+
139
+ def attribute(name)
140
+ attribute_nodes.find { |x| x.name == name }
141
+ end
142
+
143
+ def attribute_with_ns(name, namespace)
144
+ prop = LibXML.xmlHasNsProp(cstruct, name.to_s,
145
+ namespace.nil? ? NULL : namespace.to_s)
146
+ return prop if prop.null?
147
+ Node.wrap(prop)
148
+ end
149
+
150
+ def attribute_nodes
151
+ Node.node_properties cstruct
152
+ end
153
+
154
+ def namespace
155
+ cstruct[:ns].null? ? nil : Namespace.wrap(cstruct.document, cstruct[:ns])
156
+ end
157
+
158
+ def namespace_definitions
159
+ list = []
160
+ ns_ptr = cstruct[:nsDef]
161
+ return list if ns_ptr.null?
162
+ while ! ns_ptr.null?
163
+ ns = Namespace.wrap(cstruct.document, ns_ptr)
164
+ list << ns
165
+ ns_ptr = ns.cstruct[:next]
166
+ end
167
+ list
168
+ end
169
+
170
+ def node_type
171
+ cstruct[:type]
172
+ end
173
+
174
+ def native_content=(content)
175
+ LibXML.xmlNodeSetContent(cstruct, content)
176
+ content
177
+ end
178
+
179
+ def content
180
+ content_ptr = LibXML.xmlNodeGetContent(cstruct)
181
+ return nil if content_ptr.null?
182
+ content = content_ptr.read_string # TODO: encoding?
183
+ LibXML.xmlFree(content_ptr)
184
+ content
185
+ end
186
+
187
+ def add_child(child)
188
+ Node.reparent_node_with(child, self) do |child_cstruct, my_cstruct|
189
+ LibXML.xmlAddChild(my_cstruct, child_cstruct)
190
+ end
191
+ end
192
+
193
+ def parent
194
+ cstruct_node_from :parent
195
+ end
196
+
197
+ def node_name=(string)
198
+ LibXML.xmlNodeSetName(cstruct, string)
199
+ string
200
+ end
201
+
202
+ def node_name
203
+ cstruct[:name] # TODO: encoding?
204
+ end
205
+
206
+ def path
207
+ path_ptr = LibXML.xmlGetNodePath(cstruct)
208
+ val = path_ptr.null? ? nil : path_ptr.read_string # TODO: encoding?
209
+ LibXML.xmlFree(path_ptr)
210
+ val
211
+ end
212
+
213
+ def add_next_sibling(next_sibling)
214
+ Node.reparent_node_with(next_sibling, self) do |sibling_cstruct, my_cstruct|
215
+ LibXML.xmlAddNextSibling(my_cstruct, sibling_cstruct)
216
+ end
217
+ end
218
+
219
+ def add_previous_sibling(prev_sibling)
220
+ Node.reparent_node_with(prev_sibling, self) do |sibling_cstruct, my_cstruct|
221
+ LibXML.xmlAddPrevSibling(my_cstruct, sibling_cstruct)
222
+ end
223
+ end
224
+
225
+ def native_write_to(io, encoding, indent_string, options)
226
+ set_xml_indent_tree_output 1
227
+ set_xml_tree_indent_string indent_string
228
+ savectx = LibXML.xmlSaveToIO(IoCallbacks.writer(io), nil, nil, encoding, options)
229
+ LibXML.xmlSaveTree(savectx, cstruct)
230
+ LibXML.xmlSaveClose(savectx)
231
+ io
232
+ end
233
+
234
+ def line
235
+ cstruct[:line]
236
+ end
237
+
238
+ def add_namespace_definition(prefix, href)
239
+ ns = LibXML.xmlNewNs(cstruct, href, prefix)
240
+ if ns.null?
241
+ ns = LibXML.xmlSearchNs(cstruct.document, cstruct,
242
+ prefix.nil? ? nil : prefix.to_s)
243
+ end
244
+ LibXML.xmlSetNs(cstruct, ns) if prefix.nil?
245
+ Namespace.wrap(cstruct.document, ns)
246
+ end
247
+
248
+ def self.new(name, doc, *rest)
249
+ ptr = LibXML.xmlNewNode(nil, name.to_s)
250
+
251
+ node_cstruct = LibXML::XmlNode.new(ptr)
252
+ node_cstruct[:doc] = doc.cstruct[:doc]
253
+ node_cstruct.keep_reference_from_document!
254
+
255
+ node = Node.wrap(
256
+ node_cstruct,
257
+ Node == self ? nil : self
258
+ )
259
+ node.send :initialize, name, doc, *rest
260
+ yield node if block_given?
261
+ node
262
+ end
263
+
264
+ def dump_html
265
+ return to_xml if type == DOCUMENT_NODE
266
+ buffer = LibXML::XmlBuffer.new(LibXML.xmlBufferCreate())
267
+ LibXML.htmlNodeDump(buffer, cstruct[:doc], cstruct)
268
+ buffer[:content] # TODO: encoding?
269
+ end
270
+
271
+ def compare(other)
272
+ LibXML.xmlXPathCmpNodes(other.cstruct, self.cstruct)
273
+ end
274
+
275
+ def self.wrap(node_struct, klass=nil)
276
+ if node_struct.is_a?(FFI::Pointer)
277
+ # cast native pointers up into a node cstruct
278
+ return nil if node_struct.null?
279
+ node_struct = LibXML::XmlNode.new(node_struct)
280
+ end
281
+
282
+ raise "wrapping a node without a document" unless node_struct.document
283
+
284
+ document_struct = node_struct.document
285
+ document_obj = document_struct.nil? ? nil : document_struct.ruby_doc
286
+ if node_struct[:type] == DOCUMENT_NODE || node_struct[:type] == HTML_DOCUMENT_NODE
287
+ return document_obj
288
+ end
289
+
290
+ ruby_node = node_struct.ruby_node
291
+ return ruby_node unless ruby_node.nil?
292
+
293
+ klasses = case node_struct[:type]
294
+ when ELEMENT_NODE then [XML::Element]
295
+ when TEXT_NODE then [XML::Text]
296
+ when ENTITY_REF_NODE then [XML::EntityReference]
297
+ when ATTRIBUTE_DECL then [XML::AttributeDecl, LibXML::XmlAttribute]
298
+ when ELEMENT_DECL then [XML::ElementDecl, LibXML::XmlElement]
299
+ when COMMENT_NODE then [XML::Comment]
300
+ when DOCUMENT_FRAG_NODE then [XML::DocumentFragment]
301
+ when PI_NODE then [XML::ProcessingInstruction]
302
+ when ATTRIBUTE_NODE then [XML::Attr]
303
+ when ENTITY_DECL then [XML::EntityDecl, LibXML::XmlEntity]
304
+ when CDATA_SECTION_NODE then [XML::CDATA]
305
+ when DTD_NODE then [XML::DTD, LibXML::XmlDtd]
306
+ else [XML::Node]
307
+ end
308
+
309
+ if klass
310
+ node = klass.allocate
311
+ else
312
+ node = klasses.first.allocate
313
+ end
314
+ node.cstruct = klasses[1] ? klasses[1].new(node_struct.pointer) : node_struct
315
+
316
+ node.cstruct.ruby_node = node
317
+
318
+ if document_obj
319
+ node.instance_variable_set(:@document, document_obj)
320
+ cache = document_obj.instance_variable_get(:@node_cache)
321
+ cache << node
322
+ document_obj.decorate(node)
323
+ end
324
+
325
+ node
326
+ end
327
+
328
+ def document
329
+ cstruct.document.ruby_doc
330
+ end
331
+
332
+ class << self
333
+ def node_properties(cstruct)
334
+ attr = []
335
+ prop_cstruct = cstruct[:properties]
336
+ while ! prop_cstruct.null?
337
+ prop = Node.wrap(prop_cstruct)
338
+ attr << prop
339
+ prop_cstruct = prop.cstruct[:next]
340
+ end
341
+ attr
342
+ end
343
+ end
344
+
345
+ private
346
+
347
+ def self.reparent_node_with(node, other, &block)
348
+ raise(ArgumentError, "node must be a Nokogiri::XML::Node") unless node.is_a?(Nokogiri::XML::Node)
349
+ raise(ArgumentError, "cannot reparent a document node") if node.node_type == DOCUMENT_NODE || node.node_type == HTML_DOCUMENT_NODE
350
+
351
+ # If a document fragment is added, we need to reparent all of it's
352
+ # children
353
+ if node.type == DOCUMENT_FRAG_NODE
354
+ node.children.each do |child|
355
+ reparent_node_with(child, other, &block)
356
+ end
357
+ return node
358
+ end
359
+
360
+ if node.type == TEXT_NODE
361
+ node.cstruct.keep_reference_from_document!
362
+ node.cstruct = LibXML::XmlNode.new(LibXML.xmlDocCopyNode(node.cstruct, other.cstruct.document, 1))
363
+ end
364
+
365
+ if node.cstruct[:doc] == other.cstruct[:doc]
366
+ LibXML.xmlUnlinkNode(node.cstruct)
367
+ if node.type == TEXT_NODE && other.type == TEXT_NODE && Nokogiri.is_2_6_16?
368
+ other.cstruct.pointer.put_pointer(other.cstruct.offset_of(:content), LibXML.xmlStrdup(other.cstruct[:content]))
369
+ end
370
+ reparented_struct = block.call(node.cstruct, other.cstruct)
371
+ raise(RuntimeError, "Could not reparent node (1)") unless reparented_struct
372
+ else
373
+ duped_node = LibXML.xmlDocCopyNode(node.cstruct, other.cstruct.document, 1)
374
+ raise(RuntimeError, "Could not reparent node (xmlDocCopyNode)") unless duped_node
375
+ reparented_struct = block.call(duped_node, other.cstruct)
376
+ raise(RuntimeError, "Could not reparent node (2)") unless reparented_struct
377
+ LibXML.xmlUnlinkNode(node.cstruct)
378
+ node.cstruct.keep_reference_from_document!
379
+ end
380
+
381
+ reparented_struct = LibXML::XmlNode.new(reparented_struct)
382
+
383
+ # the child was a text node that was coalesced. we need to have the object
384
+ # point at SOMETHING, or we'll totally bomb out.
385
+ if reparented_struct != node.cstruct
386
+ node.cstruct = reparented_struct
387
+ end
388
+
389
+ relink_namespace reparented_struct
390
+
391
+ reparented = Node.wrap(reparented_struct)
392
+ reparented.decorate!
393
+ reparented
394
+ end
395
+
396
+ def self.relink_namespace(reparented_struct)
397
+ return if reparented_struct[:parent].null?
398
+
399
+ # Make sure that our reparented node has the correct namespaces
400
+ if reparented_struct[:ns].null? && reparented_struct[:doc] != reparented_struct[:parent]
401
+ LibXML.xmlSetNs(reparented_struct, LibXML::XmlNode.new(reparented_struct[:parent])[:ns])
402
+ end
403
+
404
+ # Search our parents for an existing definition
405
+ if ! reparented_struct[:nsDef].null?
406
+ ns = LibXML.xmlSearchNsByHref(
407
+ reparented_struct[:doc],
408
+ reparented_struct[:parent],
409
+ LibXML::XmlNs.new(reparented_struct[:nsDef])[:href]
410
+ )
411
+ reparented_struct[:nsDef] = nil unless ns.null?
412
+ end
413
+
414
+ # Only walk all children if there actually is a namespace we need to reparent.
415
+ return if reparented_struct[:ns].null?
416
+
417
+ # When a node gets reparented, walk it's children to make sure that
418
+ # their namespaces are reparented as well.
419
+ child_ptr = reparented_struct[:children]
420
+ while ! child_ptr.null?
421
+ child_struct = LibXML::XmlNode.new(child_ptr)
422
+ relink_namespace child_struct
423
+ child_ptr = child_struct[:next]
424
+ end
425
+ end
426
+
427
+ def cstruct_node_from(sym)
428
+ (val = cstruct[sym]).null? ? nil : Node.wrap(val)
429
+ end
430
+
431
+ def set_xml_indent_tree_output(value)
432
+ LibXML.__xmlIndentTreeOutput.write_int(value)
433
+ end
434
+
435
+ def set_xml_tree_indent_string(value)
436
+ LibXML.__xmlTreeIndentString.write_pointer(LibXML.xmlStrdup(value.to_s))
437
+ end
438
+
439
+ # :startdoc:
440
+ end
441
+ end
442
+ end
443
+ class Nokogiri::XML::Element < Nokogiri::XML::Node; end
444
+ class Nokogiri::XML::CharacterData < Nokogiri::XML::Node; end