nokogiri 1.2.3 → 1.3.0

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 (200) hide show
  1. data/.autotest +14 -2
  2. data/CHANGELOG.ja.rdoc +38 -0
  3. data/CHANGELOG.rdoc +43 -0
  4. data/Manifest.txt +80 -5
  5. data/README.ja.rdoc +12 -11
  6. data/README.rdoc +4 -2
  7. data/Rakefile +103 -173
  8. data/bin/nokogiri +47 -0
  9. data/ext/nokogiri/extconf.rb +19 -13
  10. data/ext/nokogiri/html_document.c +39 -3
  11. data/ext/nokogiri/html_document.h +1 -1
  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.h +1 -1
  15. data/ext/nokogiri/html_sax_parser.h +1 -1
  16. data/ext/nokogiri/{native.c → nokogiri.c} +11 -3
  17. data/ext/nokogiri/{native.h → nokogiri.h} +18 -4
  18. data/ext/nokogiri/xml_attr.c +14 -5
  19. data/ext/nokogiri/xml_attr.h +1 -1
  20. data/ext/nokogiri/xml_cdata.c +15 -6
  21. data/ext/nokogiri/xml_cdata.h +1 -1
  22. data/ext/nokogiri/xml_comment.c +13 -4
  23. data/ext/nokogiri/xml_comment.h +1 -1
  24. data/ext/nokogiri/xml_document.c +50 -41
  25. data/ext/nokogiri/xml_document.h +1 -1
  26. data/ext/nokogiri/xml_document_fragment.c +12 -4
  27. data/ext/nokogiri/xml_document_fragment.h +1 -1
  28. data/ext/nokogiri/xml_dtd.c +1 -1
  29. data/ext/nokogiri/xml_dtd.h +1 -1
  30. data/ext/nokogiri/xml_entity_reference.c +13 -4
  31. data/ext/nokogiri/xml_entity_reference.h +1 -1
  32. data/ext/nokogiri/xml_io.h +1 -1
  33. data/ext/nokogiri/xml_namespace.c +69 -0
  34. data/ext/nokogiri/xml_namespace.h +12 -0
  35. data/ext/nokogiri/xml_node.c +232 -124
  36. data/ext/nokogiri/xml_node.h +3 -4
  37. data/ext/nokogiri/xml_node_set.c +206 -19
  38. data/ext/nokogiri/xml_node_set.h +1 -1
  39. data/ext/nokogiri/xml_processing_instruction.c +14 -4
  40. data/ext/nokogiri/xml_processing_instruction.h +1 -1
  41. data/ext/nokogiri/xml_reader.c +87 -7
  42. data/ext/nokogiri/xml_reader.h +1 -1
  43. data/ext/nokogiri/xml_relax_ng.c +106 -0
  44. data/ext/nokogiri/xml_relax_ng.h +9 -0
  45. data/ext/nokogiri/xml_sax_parser.c +122 -2
  46. data/ext/nokogiri/xml_sax_parser.h +1 -1
  47. data/ext/nokogiri/xml_sax_push_parser.c +1 -0
  48. data/ext/nokogiri/xml_sax_push_parser.h +1 -1
  49. data/ext/nokogiri/xml_schema.c +107 -0
  50. data/ext/nokogiri/xml_schema.h +9 -0
  51. data/ext/nokogiri/xml_syntax_error.h +1 -1
  52. data/ext/nokogiri/xml_text.c +10 -3
  53. data/ext/nokogiri/xml_text.h +1 -1
  54. data/ext/nokogiri/xml_xpath.h +1 -1
  55. data/ext/nokogiri/xml_xpath_context.h +1 -1
  56. data/ext/nokogiri/xslt_stylesheet.c +29 -16
  57. data/ext/nokogiri/xslt_stylesheet.h +1 -1
  58. data/lib/action-nokogiri.rb +7 -1
  59. data/lib/nokogiri.rb +21 -5
  60. data/lib/nokogiri/css/generated_parser.rb +49 -14
  61. data/lib/nokogiri/css/generated_tokenizer.rb +2 -2
  62. data/lib/nokogiri/css/node.rb +13 -3
  63. data/lib/nokogiri/css/parser.rb +8 -0
  64. data/lib/nokogiri/css/parser.y +7 -7
  65. data/lib/nokogiri/css/tokenizer.rb +2 -0
  66. data/lib/nokogiri/css/xpath_visitor.rb +10 -6
  67. data/lib/nokogiri/decorators/hpricot/node.rb +1 -1
  68. data/lib/nokogiri/decorators/hpricot/node_set.rb +2 -2
  69. data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +2 -0
  70. data/lib/nokogiri/decorators/slop.rb +3 -1
  71. data/lib/nokogiri/ffi/html/document.rb +37 -0
  72. data/lib/nokogiri/ffi/html/element_description.rb +85 -0
  73. data/lib/nokogiri/ffi/html/entity_lookup.rb +16 -0
  74. data/lib/nokogiri/ffi/html/sax/parser.rb +21 -0
  75. data/lib/nokogiri/ffi/io_callbacks.rb +32 -0
  76. data/lib/nokogiri/ffi/libxml.rb +314 -0
  77. data/lib/nokogiri/ffi/structs/common_node.rb +26 -0
  78. data/lib/nokogiri/ffi/structs/html_elem_desc.rb +24 -0
  79. data/lib/nokogiri/ffi/structs/html_entity_desc.rb +13 -0
  80. data/lib/nokogiri/ffi/structs/xml_alloc.rb +16 -0
  81. data/lib/nokogiri/ffi/structs/xml_attr.rb +19 -0
  82. data/lib/nokogiri/ffi/structs/xml_buffer.rb +16 -0
  83. data/lib/nokogiri/ffi/structs/xml_document.rb +108 -0
  84. data/lib/nokogiri/ffi/structs/xml_dtd.rb +26 -0
  85. data/lib/nokogiri/ffi/structs/xml_node.rb +28 -0
  86. data/lib/nokogiri/ffi/structs/xml_node_set.rb +53 -0
  87. data/lib/nokogiri/ffi/structs/xml_notation.rb +11 -0
  88. data/lib/nokogiri/ffi/structs/xml_ns.rb +15 -0
  89. data/lib/nokogiri/ffi/structs/xml_relax_ng.rb +14 -0
  90. data/lib/nokogiri/ffi/structs/xml_sax_handler.rb +51 -0
  91. data/lib/nokogiri/ffi/structs/xml_sax_push_parser_context.rb +14 -0
  92. data/lib/nokogiri/ffi/structs/xml_schema.rb +13 -0
  93. data/lib/nokogiri/ffi/structs/xml_syntax_error.rb +31 -0
  94. data/lib/nokogiri/ffi/structs/xml_text_reader.rb +12 -0
  95. data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +37 -0
  96. data/lib/nokogiri/ffi/structs/xml_xpath_object.rb +35 -0
  97. data/lib/nokogiri/ffi/structs/xml_xpath_parser_context.rb +20 -0
  98. data/lib/nokogiri/ffi/structs/xslt_stylesheet.rb +13 -0
  99. data/lib/nokogiri/ffi/xml/attr.rb +41 -0
  100. data/lib/nokogiri/ffi/xml/cdata.rb +19 -0
  101. data/lib/nokogiri/ffi/xml/comment.rb +18 -0
  102. data/lib/nokogiri/ffi/xml/document.rb +107 -0
  103. data/lib/nokogiri/ffi/xml/document_fragment.rb +26 -0
  104. data/lib/nokogiri/ffi/xml/dtd.rb +42 -0
  105. data/lib/nokogiri/ffi/xml/entity_reference.rb +19 -0
  106. data/lib/nokogiri/ffi/xml/namespace.rb +38 -0
  107. data/lib/nokogiri/ffi/xml/node.rb +380 -0
  108. data/lib/nokogiri/ffi/xml/node_set.rb +130 -0
  109. data/lib/nokogiri/ffi/xml/processing_instruction.rb +20 -0
  110. data/lib/nokogiri/ffi/xml/reader.rb +217 -0
  111. data/lib/nokogiri/ffi/xml/relax_ng.rb +51 -0
  112. data/lib/nokogiri/ffi/xml/sax/parser.rb +148 -0
  113. data/lib/nokogiri/ffi/xml/sax/push_parser.rb +38 -0
  114. data/lib/nokogiri/ffi/xml/schema.rb +55 -0
  115. data/lib/nokogiri/ffi/xml/syntax_error.rb +76 -0
  116. data/lib/nokogiri/ffi/xml/text.rb +18 -0
  117. data/lib/nokogiri/ffi/xml/xpath.rb +19 -0
  118. data/lib/nokogiri/ffi/xml/xpath_context.rb +135 -0
  119. data/lib/nokogiri/ffi/xslt/stylesheet.rb +47 -0
  120. data/lib/nokogiri/hpricot.rb +14 -3
  121. data/lib/nokogiri/html.rb +11 -46
  122. data/lib/nokogiri/html/builder.rb +27 -1
  123. data/lib/nokogiri/html/document.rb +62 -6
  124. data/lib/nokogiri/html/document_fragment.rb +15 -0
  125. data/lib/nokogiri/html/element_description.rb +23 -0
  126. data/lib/nokogiri/html/entity_lookup.rb +2 -0
  127. data/lib/nokogiri/html/sax/parser.rb +27 -1
  128. data/lib/nokogiri/version.rb +26 -1
  129. data/lib/nokogiri/version_warning.rb +11 -0
  130. data/lib/nokogiri/xml.rb +25 -51
  131. data/lib/nokogiri/xml/builder.rb +166 -10
  132. data/lib/nokogiri/xml/cdata.rb +3 -1
  133. data/lib/nokogiri/xml/document.rb +39 -6
  134. data/lib/nokogiri/xml/document_fragment.rb +41 -1
  135. data/lib/nokogiri/xml/dtd.rb +3 -1
  136. data/lib/nokogiri/xml/entity_declaration.rb +3 -1
  137. data/lib/nokogiri/xml/fragment_handler.rb +24 -3
  138. data/lib/nokogiri/xml/namespace.rb +7 -0
  139. data/lib/nokogiri/xml/node.rb +314 -65
  140. data/lib/nokogiri/xml/node/save_options.rb +12 -2
  141. data/lib/nokogiri/xml/node_set.rb +58 -8
  142. data/lib/nokogiri/xml/parse_options.rb +80 -0
  143. data/lib/nokogiri/xml/processing_instruction.rb +2 -0
  144. data/lib/nokogiri/xml/reader.rb +42 -3
  145. data/lib/nokogiri/xml/relax_ng.rb +32 -0
  146. data/lib/nokogiri/xml/sax.rb +0 -7
  147. data/lib/nokogiri/xml/sax/document.rb +84 -0
  148. data/lib/nokogiri/xml/sax/parser.rb +38 -2
  149. data/lib/nokogiri/xml/sax/push_parser.rb +12 -0
  150. data/lib/nokogiri/xml/schema.rb +65 -0
  151. data/lib/nokogiri/xml/syntax_error.rb +11 -0
  152. data/lib/nokogiri/xml/xpath.rb +1 -1
  153. data/lib/nokogiri/xml/xpath_context.rb +2 -0
  154. data/lib/nokogiri/xslt.rb +21 -1
  155. data/lib/nokogiri/xslt/stylesheet.rb +19 -0
  156. data/lib/xsd/xmlparser/nokogiri.rb +12 -2
  157. data/tasks/test.rb +42 -19
  158. data/test/css/test_parser.rb +29 -0
  159. data/test/ffi/test_document.rb +35 -0
  160. data/test/files/address_book.rlx +12 -0
  161. data/test/files/address_book.xml +10 -0
  162. data/test/files/po.xml +32 -0
  163. data/test/files/po.xsd +66 -0
  164. data/test/helper.rb +38 -8
  165. data/test/html/sax/test_parser.rb +12 -0
  166. data/test/html/test_builder.rb +25 -2
  167. data/test/html/test_document.rb +91 -20
  168. data/test/html/test_document_fragment.rb +97 -0
  169. data/test/html/test_element_description.rb +95 -0
  170. data/test/html/test_node.rb +66 -3
  171. data/test/test_convert_xpath.rb +1 -1
  172. data/test/test_memory_leak.rb +57 -18
  173. data/test/test_nokogiri.rb +24 -2
  174. data/test/test_reader.rb +77 -0
  175. data/test/test_xslt_transforms.rb +120 -82
  176. data/test/xml/node/test_subclass.rb +44 -0
  177. data/test/xml/sax/test_parser.rb +9 -0
  178. data/test/xml/sax/test_push_parser.rb +24 -0
  179. data/test/xml/test_attr.rb +7 -0
  180. data/test/xml/test_builder.rb +48 -0
  181. data/test/xml/test_cdata.rb +19 -0
  182. data/test/xml/test_comment.rb +6 -0
  183. data/test/xml/test_document.rb +101 -2
  184. data/test/xml/test_document_fragment.rb +55 -3
  185. data/test/xml/test_entity_reference.rb +4 -0
  186. data/test/xml/test_namespace.rb +43 -0
  187. data/test/xml/test_node.rb +255 -8
  188. data/test/xml/test_node_attributes.rb +34 -0
  189. data/test/xml/test_node_encoding.rb +9 -2
  190. data/test/xml/test_node_set.rb +197 -1
  191. data/test/xml/test_parse_options.rb +52 -0
  192. data/test/xml/test_processing_instruction.rb +5 -0
  193. data/test/xml/test_relax_ng.rb +60 -0
  194. data/test/xml/test_schema.rb +65 -0
  195. data/test/xml/test_text.rb +5 -0
  196. data/test/xml/test_unparented_node.rb +3 -3
  197. metadata +128 -12
  198. data/lib/nokogiri/xml/comment.rb +0 -6
  199. data/lib/nokogiri/xml/element.rb +0 -6
  200. data/lib/nokogiri/xml/text.rb +0 -6
@@ -0,0 +1,20 @@
1
+ module Nokogiri
2
+ module XML
3
+ class ProcessingInstruction < Node
4
+
5
+ attr_accessor :cstruct # :nodoc:
6
+
7
+ def self.new(document, name, content, *rest) # :nodoc:
8
+ node_ptr = LibXML.xmlNewDocPI(document.cstruct, name.to_s, content.to_s)
9
+ node_cstruct = LibXML::XmlNode.new(node_ptr)
10
+ node_cstruct.keep_reference_from_document!
11
+
12
+ node = Node.wrap(node_cstruct, self)
13
+ node.send :initialize, document, name, content, *rest
14
+ yield node if block_given?
15
+ node
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,217 @@
1
+ module Nokogiri
2
+ module XML
3
+ class Reader
4
+
5
+ attr_accessor :cstruct # :nodoc:
6
+ attr_accessor :reader_callback # :nodoc:
7
+
8
+ def default? # :nodoc:
9
+ LibXML.xmlTextReaderIsDefault(cstruct) == 1
10
+ end
11
+
12
+ def value? # :nodoc:
13
+ LibXML.xmlTextReaderHasValue(cstruct) == 1
14
+ end
15
+
16
+ def attributes? # :nodoc:
17
+ # this implementation of xmlTextReaderHasAttributes explicitly includes
18
+ # namespaces and properties, because some earlier versions ignore
19
+ # namespaces.
20
+ node_ptr = LibXML.xmlTextReaderCurrentNode(cstruct)
21
+ return false if node_ptr.null?
22
+ node = LibXML::XmlNode.new node_ptr
23
+ node[:type] == Node::ELEMENT_NODE && (!node[:properties].null? || !node[:nsDef].null?)
24
+ end
25
+
26
+ def namespaces # :nodoc:
27
+ return {} unless attributes?
28
+
29
+ ptr = LibXML.xmlTextReaderExpand(cstruct)
30
+ return nil if ptr.null?
31
+
32
+ node = Node.wrap(ptr)
33
+ Reader.node_namespaces(node)
34
+ end
35
+
36
+ def attribute_nodes # :nodoc:
37
+ return {} unless attributes?
38
+
39
+ ptr = LibXML.xmlTextReaderExpand(cstruct)
40
+ return nil if ptr.null?
41
+ node_struct = LibXML::XmlNode.new(ptr)
42
+
43
+ # FIXME I'm not sure if this is correct..... I don't really like pointing
44
+ # at this document, but I have to because of the assertions in
45
+ # the node wrapping code.
46
+ unless node_struct.document.ruby_doc
47
+ doc_struct = LibXML::XmlDocumentCast.new(node_struct[:doc])
48
+ doc_struct.alloc_tuple
49
+ doc = Document.wrap(doc_struct)
50
+ end
51
+
52
+ node = Node.wrap(node_struct)
53
+ node.attribute_nodes
54
+ end
55
+
56
+ def attribute_at(index) # :nodoc:
57
+ return nil if index.nil?
58
+ index = index.to_i
59
+ attr_ptr = LibXML.xmlTextReaderGetAttributeNo(cstruct, index)
60
+ return nil if attr_ptr.null?
61
+
62
+ attr = attr_ptr.read_string
63
+ LibXML.xmlFree attr_ptr
64
+ attr
65
+ end
66
+
67
+ def attribute(name) # :nodoc:
68
+ return nil if name.nil?
69
+ attr_ptr = LibXML.xmlTextReaderGetAttribute(cstruct, name.to_s)
70
+ if attr_ptr.null?
71
+ # this section is an attempt to workaround older versions of libxml that
72
+ # don't handle namespaces properly in all attribute-and-friends functions
73
+ prefix_ptr = FFI::MemoryPointer.new :pointer
74
+ localname = LibXML.xmlSplitQName2(name, prefix_ptr)
75
+ prefix = prefix_ptr.get_pointer(0)
76
+ if ! localname.null?
77
+ attr_ptr = LibXML.xmlTextReaderLookupNamespace(cstruct, localname.read_string)
78
+ LibXML.xmlFree(localname)
79
+ else
80
+ if prefix.null? || prefix.read_string.length == 0
81
+ attr_ptr = LibXML.xmlTextReaderLookupNamespace(cstruct, nil)
82
+ else
83
+ attr_ptr = LibXML.xmlTextReaderLookupNamespace(cstruct, prefix.read_string)
84
+ end
85
+ end
86
+ LibXML.xmlFree(prefix)
87
+ end
88
+ return nil if attr_ptr.null?
89
+
90
+ attr = attr_ptr.read_string
91
+ LibXML.xmlFree(attr_ptr)
92
+ attr
93
+ end
94
+
95
+ def attribute_count # :nodoc:
96
+ count = LibXML.xmlTextReaderAttributeCount(cstruct)
97
+ count == -1 ? nil : count
98
+ end
99
+
100
+ def depth # :nodoc:
101
+ val = LibXML.xmlTextReaderDepth(cstruct)
102
+ val == -1 ? nil : val
103
+ end
104
+
105
+ def xml_version # :nodoc:
106
+ val = LibXML.xmlTextReaderConstXmlVersion(cstruct)
107
+ val.null? ? nil : val.read_string
108
+ end
109
+
110
+ def lang # :nodoc:
111
+ val = LibXML.xmlTextReaderConstXmlLang(cstruct)
112
+ val.null? ? nil : val.read_string
113
+ end
114
+
115
+ def value # :nodoc:
116
+ val = LibXML.xmlTextReaderConstValue(cstruct)
117
+ val.null? ? nil : val.read_string
118
+ end
119
+
120
+ def prefix # :nodoc:
121
+ val = LibXML.xmlTextReaderConstPrefix(cstruct)
122
+ val.null? ? nil : val.read_string
123
+ end
124
+
125
+ def namespace_uri # :nodoc:
126
+ val = LibXML.xmlTextReaderConstNamespaceUri(cstruct)
127
+ val.null? ? nil : val.read_string
128
+ end
129
+
130
+ def local_name # :nodoc:
131
+ val = LibXML.xmlTextReaderConstLocalName(cstruct)
132
+ val.null? ? nil : val.read_string
133
+ end
134
+
135
+ def name # :nodoc:
136
+ val = LibXML.xmlTextReaderConstName(cstruct)
137
+ val.null? ? nil : val.read_string
138
+ end
139
+
140
+ def state # :nodoc:
141
+ LibXML.xmlTextReaderReadState(cstruct)
142
+ end
143
+
144
+ def read # :nodoc:
145
+ error_list = self.errors
146
+
147
+ LibXML.xmlSetStructuredErrorFunc(nil, SyntaxError.error_array_pusher(error_list))
148
+ ret = LibXML.xmlTextReaderRead(cstruct)
149
+ LibXML.xmlSetStructuredErrorFunc(nil, nil)
150
+
151
+ return self if ret == 1
152
+ return nil if ret == 0
153
+
154
+ error = LibXML.xmlGetLastError()
155
+ if error
156
+ raise SyntaxError.wrap(error)
157
+ else
158
+ raise RuntimeError, "Error pulling: #{ret}"
159
+ end
160
+
161
+ nil
162
+ end
163
+
164
+ def self.from_memory(buffer, url=nil, encoding=nil, options=0) # :nodoc:
165
+ raise(ArgumentError, "string cannot be nil") if buffer.nil?
166
+
167
+ memory = FFI::MemoryPointer.new(buffer.length) # we need to manage native memory lifecycle
168
+ memory.put_bytes(0, buffer)
169
+ reader_ptr = LibXML.xmlReaderForMemory(memory, memory.total, url, encoding, options)
170
+ raise(RuntimeError, "couldn't create a reader") if reader_ptr.null?
171
+
172
+ reader = allocate
173
+ reader.cstruct = LibXML::XmlTextReader.new(reader_ptr)
174
+ reader.send(:initialize, memory, url, encoding)
175
+ reader
176
+ end
177
+
178
+ def self.from_io(io, url=nil, encoding=nil, options=0) # :nodoc:
179
+ raise(ArgumentError, "io cannot be nil") if io.nil?
180
+
181
+ cb = IoCallbacks.reader(io) # we will keep a reference to prevent it from being GC'd
182
+ reader_ptr = LibXML.xmlReaderForIO(cb, nil, nil, url, encoding, options)
183
+ raise "couldn't create a parser" if reader_ptr.null?
184
+
185
+ reader = allocate
186
+ reader.cstruct = LibXML::XmlTextReader.new(reader_ptr)
187
+ reader.send(:initialize, io, url, encoding)
188
+ reader.reader_callback = cb
189
+ reader
190
+ end
191
+
192
+ private
193
+
194
+ class << self
195
+ def node_namespaces(node) # :nodoc:
196
+ cstruct = node.cstruct
197
+ ahash = {}
198
+ return ahash unless cstruct[:type] == Node::ELEMENT_NODE
199
+ ns = cstruct[:nsDef]
200
+ while ! ns.null?
201
+ ns_cstruct = LibXML::XmlNs.new(ns)
202
+ prefix = ns_cstruct[:prefix]
203
+ key = if prefix.nil? || prefix.empty?
204
+ "xmlns"
205
+ else
206
+ "xmlns:#{prefix}"
207
+ end
208
+ ahash[key] = ns_cstruct[:href] # TODO: encoding?
209
+ ns = ns_cstruct[:next] # TODO: encoding?
210
+ end
211
+ ahash
212
+ end
213
+ end
214
+
215
+ end
216
+ end
217
+ end
@@ -0,0 +1,51 @@
1
+ module Nokogiri
2
+ module XML
3
+ class RelaxNG < Schema
4
+ def validate_document(document) # :nodoc:
5
+ errors = []
6
+
7
+ ctx = LibXML.xmlRelaxNGNewValidCtxt(cstruct)
8
+ raise RuntimeError.new("Could not create a validation context") if ctx.null?
9
+
10
+ LibXML.xmlRelaxNGSetValidStructuredErrors(ctx,
11
+ SyntaxError.error_array_pusher(errors), nil) unless Nokogiri.is_2_6_16?
12
+
13
+ LibXML.xmlRelaxNGValidateDoc(ctx, document.cstruct)
14
+
15
+ LibXML.xmlRelaxNGFreeValidCtxt(ctx)
16
+
17
+ errors
18
+ end
19
+ private :validate_document
20
+
21
+ def self.read_memory(content) # :nodoc:
22
+ ctx = LibXML.xmlRelaxNGNewMemParserCtxt(content, content.length)
23
+
24
+ errors = []
25
+
26
+ LibXML.xmlSetStructuredErrorFunc(nil, SyntaxError.error_array_pusher(errors))
27
+ LibXML.xmlRelaxNGSetParserStructuredErrors(
28
+ ctx, SyntaxError.error_array_pusher(errors), nil) unless Nokogiri.is_2_6_16?
29
+
30
+ schema_ptr = LibXML.xmlRelaxNGParse(ctx)
31
+
32
+ LibXML.xmlSetStructuredErrorFunc(nil, nil)
33
+ LibXML.xmlRelaxNGFreeParserCtxt(ctx)
34
+
35
+ if schema_ptr.null?
36
+ error = LibXML.xmlGetLastError
37
+ if error
38
+ raise SyntaxError.wrap(error)
39
+ else
40
+ raise RuntimeError, "Could not parse document"
41
+ end
42
+ end
43
+
44
+ schema = allocate
45
+ schema.cstruct = LibXML::XmlRelaxNG.new schema_ptr
46
+ schema.errors = errors
47
+ schema
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,148 @@
1
+ module Nokogiri
2
+ module XML
3
+ module SAX
4
+ class Parser
5
+
6
+ attr_accessor :cstruct # :nodoc:
7
+
8
+ def parse_memory(data) # :nodoc:
9
+ raise(ArgumentError, 'data cannot be nil') if data.nil?
10
+ LibXML.xmlSAXUserParseMemory(cstruct, nil, data, data.length)
11
+ data
12
+ end
13
+
14
+ def native_parse_io(io, encoding) # :nodoc:
15
+ sax_ctx = LibXML.xmlCreateIOParserCtxt(cstruct, nil, IoCallbacks.reader(io), nil, nil, encoding)
16
+ LibXML.xmlParseDocument(sax_ctx)
17
+ LibXML.xmlFreeParserCtxt(sax_ctx)
18
+ io
19
+ end
20
+
21
+ def native_parse_file(data) # :nodoc:
22
+ LibXML.xmlSAXUserParseFile(cstruct, nil, data)
23
+ end
24
+
25
+ def self.new(doc = XML::SAX::Document.new, encoding = 'ASCII') # :nodoc:
26
+ parser = allocate
27
+ parser.document = doc
28
+ parser.encoding = encoding
29
+ parser.cstruct = LibXML::XmlSaxHandler.allocate
30
+ parser.send(:setup_lambdas)
31
+ parser
32
+ end
33
+
34
+ private
35
+
36
+ def setup_lambdas # :nodoc:
37
+ @closures = {} # we need to keep references to the closures to avoid GC
38
+
39
+ [ :startDocument, :endDocument, :startElement, :endElement, :characters,
40
+ :comment, :warning, :error, :cdataBlock, :startElementNs, :endElementNs ].each do |sym|
41
+ @closures[sym] = lambda { |*args| send("__internal__#{sym}", *args) } # "i'm your private dancer", etc.
42
+ end
43
+
44
+ @closures.each { |k,v| cstruct[k] = v }
45
+
46
+ cstruct[:initialized] = Nokogiri::LibXML::XmlSaxHandler::XML_SAX2_MAGIC
47
+ end
48
+
49
+ def __internal__startDocument(_) # :nodoc:
50
+ @document.start_document
51
+ end
52
+
53
+ def __internal__endDocument(_) # :nodoc:
54
+ @document.end_document
55
+ end
56
+
57
+ def __internal__startElement(_, name, attributes) # :nodoc:
58
+ attrs = []
59
+ unless attributes.null?
60
+ j = 0
61
+ while ! (value = attributes.get_pointer(LibXML.pointer_offset(j))).null?
62
+ attrs << value.read_string
63
+ j += 1
64
+ end
65
+ end
66
+ @document.start_element name, attrs
67
+ end
68
+
69
+ def __internal__endElement(_, name) # :nodoc:
70
+ @document.end_element name
71
+ end
72
+
73
+ def __internal__characters(_, data, data_length) # :nodoc:
74
+ @document.characters data.slice(0, data_length)
75
+ end
76
+
77
+ def __internal__comment(_, data) # :nodoc:
78
+ @document.comment data
79
+ end
80
+
81
+ def __internal__warning(_, msg) # :nodoc:
82
+ # TODO: vasprintf here
83
+ @document.warning(msg)
84
+ end
85
+
86
+ def __internal__error(_, msg) # :nodoc:
87
+ # TODO: vasprintf here
88
+ @document.error(msg)
89
+ end
90
+
91
+ def __internal__cdataBlock(_, data, data_length) # :nodoc:
92
+ @document.cdata_block data.slice(0, data_length)
93
+ end
94
+
95
+ def __internal__startElementNs(_, localname, prefix, uri, nb_namespaces, namespaces, nb_attributes, nb_defaulted, attributes) # :nodoc:
96
+ localname = localname.null? ? nil : localname.read_string
97
+ prefix = prefix .null? ? nil : prefix .read_string
98
+ uri = uri .null? ? nil : uri .read_string
99
+
100
+ attr_hash = {}
101
+ ns_hash = {}
102
+
103
+ if ! attributes.null?
104
+ # Each attribute is an array of [localname, prefix, URI, value, end]
105
+ (0..(nb_attributes-1)*5).step(5) do |j|
106
+ key = attributes.get_pointer(LibXML.pointer_offset(j)).read_string
107
+ value_length = attributes.get_pointer(LibXML.pointer_offset(j+4)).address \
108
+ - attributes.get_pointer(LibXML.pointer_offset(j+3)).address
109
+ value = attributes.get_pointer(LibXML.pointer_offset(j+3)).get_string(0, value_length)
110
+ attr_hash[key] = value
111
+ end
112
+ end
113
+
114
+ if ! namespaces.null?
115
+ (0..(nb_namespaces-1)*2).step(2) do |j|
116
+ key = namespaces.get_pointer(LibXML.pointer_offset(j))
117
+ key = key.null? ? nil : key.read_string
118
+ value = namespaces.get_pointer(LibXML.pointer_offset(j+1))
119
+ value = value.null? ? nil : value.read_string
120
+ ns_hash[key] = value
121
+ end
122
+ end
123
+
124
+ @document.start_element_ns(localname, attr_hash, prefix, uri, ns_hash)
125
+
126
+ if @document.respond_to?(:start_element)
127
+ name = prefix ? "#{prefix}:#{localname}" : localname
128
+ @document.start_element(name, attr_hash.to_a.flatten)
129
+ end
130
+ end
131
+
132
+ def __internal__endElementNs(_, localname, prefix, uri) # :nodoc:
133
+ localname = localname.null? ? nil : localname.read_string
134
+ prefix = prefix .null? ? nil : prefix .read_string
135
+ uri = uri .null? ? nil : uri .read_string
136
+
137
+ @document.end_element_ns(localname, prefix, uri)
138
+
139
+ if @document.respond_to?(:end_element)
140
+ name = prefix ? "#{prefix}:#{localname}" : localname
141
+ @document.end_element(name)
142
+ end
143
+ end
144
+
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,38 @@
1
+ module Nokogiri
2
+ module XML
3
+ module SAX
4
+ class PushParser
5
+
6
+ attr_accessor :cstruct # :nodoc:
7
+
8
+ private
9
+
10
+ def native_write(chunk, last_chunk) # :nodoc:
11
+ size = 0
12
+ unless chunk.nil?
13
+ chunk = chunk.to_s
14
+ size = chunk.length
15
+ end
16
+
17
+ last_chunk = last_chunk ? 1 : 0
18
+
19
+ rcode = LibXML.xmlParseChunk(cstruct, chunk, size, last_chunk)
20
+ raise RuntimeError, "Couldn't parse chunk" if 0 != rcode
21
+
22
+ self
23
+ end
24
+
25
+ def initialize_native(sax, filename) # :nodoc:
26
+ filename = filename.to_s unless filename.nil?
27
+ ctx_ptr = LibXML.xmlCreatePushParserCtxt(
28
+ sax.cstruct, nil, nil, 0, filename
29
+ )
30
+ raise(RuntimeError, "Could not create a parser context") if ctx_ptr.null?
31
+ self.cstruct = LibXML::XmlSaxPushParserContext.new(ctx_ptr) ;
32
+ self
33
+ end
34
+
35
+ end
36
+ end
37
+ end
38
+ end