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
@@ -1,15 +1,14 @@
1
1
  #ifndef NOKOGIRI_XML_NODE
2
2
  #define NOKOGIRI_XML_NODE
3
3
 
4
- #include <native.h>
4
+ #include <nokogiri.h>
5
5
 
6
6
  void init_xml_node();
7
- VALUE Nokogiri_wrap_xml_node(xmlNodePtr root);
8
7
 
9
8
  extern VALUE cNokogiriXmlNode ;
10
9
  extern VALUE cNokogiriXmlElement ;
10
+ extern VALUE cNokogiriXmlEntityDeclaration ;
11
11
 
12
- VALUE Nokogiri_wrap_xml_node(xmlNodePtr node) ;
12
+ VALUE Nokogiri_wrap_xml_node(VALUE klass, xmlNodePtr node) ;
13
13
  void Nokogiri_xml_node_properties(xmlNodePtr node, VALUE attr_hash) ;
14
- void Nokogiri_xml_node_namespaces(xmlNodePtr node, VALUE attr_hash) ;
15
14
  #endif
@@ -7,16 +7,12 @@
7
7
  *
8
8
  * Duplicate this node set
9
9
  */
10
- static VALUE dup(VALUE self)
10
+ static VALUE duplicate(VALUE self)
11
11
  {
12
12
  xmlNodeSetPtr node_set;
13
13
  Data_Get_Struct(self, xmlNodeSet, node_set);
14
14
 
15
- xmlNodeSetPtr dupl = xmlXPathNodeSetCreate(NULL);
16
- int i;
17
- for(i = 0; i < node_set->nodeNr; i++) {
18
- xmlXPathNodeSetAdd(dupl, node_set->nodeTab[i]);
19
- }
15
+ xmlNodeSetPtr dupl = xmlXPathNodeSetMerge(NULL, node_set);
20
16
 
21
17
  return Nokogiri_wrap_xml_node_set(dupl);
22
18
  }
@@ -58,27 +54,212 @@ static VALUE push(VALUE self, VALUE rb_node)
58
54
  return self;
59
55
  }
60
56
 
57
+ /*
58
+ * call-seq:
59
+ * delete(node)
60
+ *
61
+ * Delete +node+ from the Nodeset, if it is a member. Returns the deleted node
62
+ * if found, otherwise returns nil.
63
+ */
64
+ static VALUE delete(VALUE self, VALUE rb_node)
65
+ {
66
+ xmlNodeSetPtr node_set ;
67
+ xmlNodePtr node ;
68
+
69
+ if(! rb_funcall(rb_node, rb_intern("is_a?"), 1, cNokogiriXmlNode))
70
+ rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node");
71
+
72
+ Data_Get_Struct(self, xmlNodeSet, node_set);
73
+ Data_Get_Struct(rb_node, xmlNode, node);
74
+
75
+ if (xmlXPathNodeSetContains(node_set, node)) {
76
+ xmlXPathNodeSetDel(node_set, node);
77
+ return rb_node ;
78
+ }
79
+
80
+ return Qnil ;
81
+ }
82
+
83
+
61
84
  /*
62
85
  * call-seq:
63
- * [](i)
86
+ * &(node_set)
64
87
  *
65
- * Get the node at index +i+
88
+ * Set Intersection Returns a new NodeSet containing nodes common to the two NodeSets.
66
89
  */
67
- static VALUE index_at(VALUE self, VALUE number)
90
+ static VALUE intersection(VALUE self, VALUE rb_other)
68
91
  {
69
- int i = NUM2INT(number);
70
92
  xmlNodeSetPtr node_set;
93
+ xmlNodeSetPtr other;
94
+
95
+ if(! rb_funcall(rb_other, rb_intern("is_a?"), 1, cNokogiriXmlNodeSet))
96
+ rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
97
+
71
98
  Data_Get_Struct(self, xmlNodeSet, node_set);
99
+ Data_Get_Struct(rb_other, xmlNodeSet, other);
72
100
 
73
- if(i >= node_set->nodeNr || abs(i) > node_set->nodeNr)
74
- return Qnil;
101
+ return Nokogiri_wrap_xml_node_set(xmlXPathIntersection(node_set, other));
102
+ }
75
103
 
76
- if(i < 0)
77
- i = i + node_set->nodeNr;
78
104
 
79
- return Nokogiri_wrap_xml_node(node_set->nodeTab[i]);
105
+ /*
106
+ * call-seq:
107
+ * include?(node)
108
+ *
109
+ * Returns true if any member of node set equals +node+.
110
+ */
111
+ static VALUE include_eh(VALUE self, VALUE rb_node)
112
+ {
113
+ xmlNodeSetPtr node_set;
114
+ xmlNodePtr node;
115
+
116
+ if(! rb_funcall(rb_node, rb_intern("is_a?"), 1, cNokogiriXmlNode))
117
+ rb_raise(rb_eArgError, "node must be a Nokogiri::XML::Node");
118
+
119
+ Data_Get_Struct(self, xmlNodeSet, node_set);
120
+ Data_Get_Struct(rb_node, xmlNode, node);
121
+
122
+ return (xmlXPathNodeSetContains(node_set, node) ? Qtrue : Qfalse);
80
123
  }
81
124
 
125
+
126
+ /*
127
+ * call-seq:
128
+ * +(node_set)
129
+ *
130
+ * Concatenation - returns a new NodeSet built by concatenating the node set
131
+ * with +node_set+ to produce a third NodeSet
132
+ */
133
+ static VALUE plus(VALUE self, VALUE rb_other)
134
+ {
135
+ xmlNodeSetPtr node_set;
136
+ xmlNodeSetPtr other;
137
+ xmlNodeSetPtr new;
138
+
139
+ if(! rb_funcall(rb_other, rb_intern("is_a?"), 1, cNokogiriXmlNodeSet))
140
+ rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
141
+
142
+ Data_Get_Struct(self, xmlNodeSet, node_set);
143
+ Data_Get_Struct(rb_other, xmlNodeSet, other);
144
+
145
+ new = xmlXPathNodeSetMerge(NULL, node_set);
146
+ new = xmlXPathNodeSetMerge(new, other);
147
+
148
+ return Nokogiri_wrap_xml_node_set(new);
149
+ }
150
+
151
+ /*
152
+ * call-seq:
153
+ * -(node_set)
154
+ *
155
+ * Difference - returns a new NodeSet that is a copy of this NodeSet, removing
156
+ * each item that also appears in +node_set+
157
+ */
158
+ static VALUE minus(VALUE self, VALUE rb_other)
159
+ {
160
+ xmlNodeSetPtr node_set;
161
+ xmlNodeSetPtr other;
162
+ xmlNodeSetPtr new;
163
+ int j ;
164
+
165
+ if(! rb_funcall(rb_other, rb_intern("is_a?"), 1, cNokogiriXmlNodeSet))
166
+ rb_raise(rb_eArgError, "node_set must be a Nokogiri::XML::NodeSet");
167
+
168
+ Data_Get_Struct(self, xmlNodeSet, node_set);
169
+ Data_Get_Struct(rb_other, xmlNodeSet, other);
170
+
171
+ new = xmlXPathNodeSetMerge(NULL, node_set);
172
+ for (j = 0 ; j < other->nodeNr ; ++j) {
173
+ xmlXPathNodeSetDel(new, other->nodeTab[j]);
174
+ }
175
+
176
+ return Nokogiri_wrap_xml_node_set(new);
177
+ }
178
+
179
+
180
+ static VALUE index_at(VALUE self, long offset)
181
+ {
182
+ xmlNodeSetPtr node_set;
183
+ Data_Get_Struct(self, xmlNodeSet, node_set);
184
+
185
+ if(offset >= node_set->nodeNr || abs(offset) > node_set->nodeNr) return Qnil;
186
+ if(offset < 0) offset = offset + node_set->nodeNr;
187
+
188
+ return Nokogiri_wrap_xml_node(Qnil, node_set->nodeTab[offset]);
189
+ }
190
+
191
+ static VALUE subseq(VALUE self, long beg, long len)
192
+ {
193
+ int j;
194
+ xmlNodeSetPtr node_set;
195
+ xmlNodeSetPtr new_set ;
196
+
197
+ Data_Get_Struct(self, xmlNodeSet, node_set);
198
+
199
+ if (beg > node_set->nodeNr) return Qnil ;
200
+ if (beg < 0 || len < 0) return Qnil ;
201
+
202
+ new_set = xmlXPathNodeSetCreate(NULL);
203
+ for (j = beg ; j < beg+len ; ++j) {
204
+ xmlXPathNodeSetAdd(new_set, node_set->nodeTab[j]);
205
+ }
206
+ return Nokogiri_wrap_xml_node_set(new_set);
207
+ }
208
+
209
+ /*
210
+ * call-seq:
211
+ * [index] -> Node or nil
212
+ * [start, length] -> NodeSet or nil
213
+ * [range] -> NodeSet or nil
214
+ * slice(index) -> Node or nil
215
+ * slice(start, length) -> NodeSet or nil
216
+ * slice(range) -> NodeSet or nil
217
+ *
218
+ * Element reference - returns the node at +index+, or returns a NodeSet
219
+ * containing nodes starting at +start+ and continuing for +length+ elements, or
220
+ * returns a NodeSet containing nodes specified by +range+. Negative +indices+
221
+ * count backward from the end of the +node_set+ (-1 is the last node). Returns
222
+ * nil if the +index+ (or +start+) are out of range.
223
+ */
224
+ static VALUE slice(int argc, VALUE *argv, VALUE self)
225
+ {
226
+ VALUE arg ;
227
+ long beg, len ;
228
+ xmlNodeSetPtr node_set;
229
+ Data_Get_Struct(self, xmlNodeSet, node_set);
230
+
231
+ if (argc == 2) {
232
+ beg = NUM2LONG(argv[0]);
233
+ len = NUM2LONG(argv[1]);
234
+ if (beg < 0) {
235
+ beg += node_set->nodeNr ;
236
+ }
237
+ return subseq(self, beg, len);
238
+ }
239
+
240
+ if (argc != 1) {
241
+ rb_scan_args(argc, argv, "11", NULL, NULL);
242
+ }
243
+ arg = argv[0];
244
+
245
+ if (FIXNUM_P(arg)) {
246
+ return index_at(self, FIX2LONG(arg));
247
+ }
248
+
249
+ /* if arg is Range */
250
+ switch (rb_range_beg_len(arg, &beg, &len, node_set->nodeNr, 0)) {
251
+ case Qfalse:
252
+ break;
253
+ case Qnil:
254
+ return Qnil;
255
+ default:
256
+ return subseq(self, beg, len);
257
+ }
258
+
259
+ return index_at(self, NUM2LONG(arg));
260
+ }
261
+
262
+
82
263
  /*
83
264
  * call-seq:
84
265
  * to_a
@@ -96,7 +277,7 @@ static VALUE to_array(VALUE self, VALUE rb_node)
96
277
  if(set->nodeTab[i]->_private) {
97
278
  elts[i] = (VALUE)set->nodeTab[i]->_private;
98
279
  } else {
99
- elts[i] = Nokogiri_wrap_xml_node(set->nodeTab[i]);
280
+ elts[i] = Nokogiri_wrap_xml_node(Qnil, set->nodeTab[i]);
100
281
  }
101
282
  }
102
283
 
@@ -123,7 +304,7 @@ static VALUE unlink_nodeset(VALUE self)
123
304
  for (j = 0 ; j < nodeNr ; j++) {
124
305
  VALUE node ;
125
306
  xmlNodePtr node_ptr;
126
- node = Nokogiri_wrap_xml_node(node_set->nodeTab[j]);
307
+ node = Nokogiri_wrap_xml_node(Qnil, node_set->nodeTab[j]);
127
308
  rb_funcall(node, rb_intern("unlink"), 0); /* modifies the C struct out from under the object */
128
309
  Data_Get_Struct(node, xmlNode, node_ptr);
129
310
  node_set->nodeTab[j] = node_ptr ;
@@ -191,9 +372,15 @@ void init_xml_node_set(void)
191
372
 
192
373
  rb_define_alloc_func(klass, allocate);
193
374
  rb_define_method(klass, "length", length, 0);
194
- rb_define_method(klass, "[]", index_at, 1);
375
+ rb_define_method(klass, "[]", slice, -1);
376
+ rb_define_method(klass, "slice", slice, -1);
195
377
  rb_define_method(klass, "push", push, 1);
378
+ rb_define_method(klass, "+", plus, 1);
379
+ rb_define_method(klass, "-", minus, 1);
196
380
  rb_define_method(klass, "unlink", unlink_nodeset, 0);
197
381
  rb_define_method(klass, "to_a", to_array, 0);
198
- rb_define_method(klass, "dup", dup, 0);
382
+ rb_define_method(klass, "dup", duplicate, 0);
383
+ rb_define_method(klass, "delete", delete, 1);
384
+ rb_define_method(klass, "&", intersection, 1);
385
+ rb_define_method(klass, "include?", include_eh, 1);
199
386
  }
@@ -1,7 +1,7 @@
1
1
  #ifndef NOKOGIRI_XML_NODE_SET
2
2
  #define NOKOGIRI_XML_NODE_SET
3
3
 
4
- #include <native.h>
4
+ #include <nokogiri.h>
5
5
  void init_xml_node_set();
6
6
 
7
7
  extern VALUE cNokogiriXmlNodeSet ;
@@ -7,10 +7,17 @@
7
7
  * Create a new ProcessingInstruction element on the +document+ with +name+
8
8
  * and +content+
9
9
  */
10
- static VALUE new(VALUE klass, VALUE doc, VALUE name, VALUE content)
10
+ static VALUE new(int argc, VALUE *argv, VALUE klass)
11
11
  {
12
12
  xmlDocPtr xml_doc;
13
- Data_Get_Struct(doc, xmlDoc, xml_doc);
13
+ VALUE document;
14
+ VALUE name;
15
+ VALUE content;
16
+ VALUE rest;
17
+
18
+ rb_scan_args(argc, argv, "3*", &document, &name, &content, &rest);
19
+
20
+ Data_Get_Struct(document, xmlDoc, xml_doc);
14
21
 
15
22
  xmlNodePtr node = xmlNewDocPI(
16
23
  xml_doc,
@@ -18,7 +25,10 @@ static VALUE new(VALUE klass, VALUE doc, VALUE name, VALUE content)
18
25
  (const xmlChar *)StringValuePtr(content)
19
26
  );
20
27
 
21
- VALUE rb_node = Nokogiri_wrap_xml_node(node);
28
+ NOKOGIRI_ROOT_NODE(node);
29
+
30
+ VALUE rb_node = Nokogiri_wrap_xml_node(klass, node);
31
+ rb_funcall2(rb_node, rb_intern("initialize"), argc, argv);
22
32
 
23
33
  if(rb_block_given_p()) rb_yield(rb_node);
24
34
 
@@ -40,5 +50,5 @@ void init_xml_processing_instruction()
40
50
 
41
51
  cNokogiriXmlProcessingInstruction = klass;
42
52
 
43
- rb_define_singleton_method(klass, "new", new, 3);
53
+ rb_define_singleton_method(klass, "new", new, -1);
44
54
  }
@@ -1,7 +1,7 @@
1
1
  #ifndef NOKOGIRI_XML_PROCESSING_INSTRUCTION
2
2
  #define NOKOGIRI_XML_PROCESSING_INSTRUCTION
3
3
 
4
- #include <native.h>
4
+ #include <nokogiri.h>
5
5
 
6
6
  void init_xml_processing_instruction();
7
7
 
@@ -25,6 +25,46 @@ static int has_attributes(xmlTextReaderPtr reader)
25
25
  return(0);
26
26
  }
27
27
 
28
+ #define XMLNS_PREFIX "xmlns"
29
+ #define XMLNS_PREFIX_LEN 6 /* including either colon or \0 */
30
+ #define XMLNS_BUFFER_LEN 128
31
+ static void Nokogiri_xml_node_namespaces(xmlNodePtr node, VALUE attr_hash)
32
+ {
33
+ xmlNsPtr ns;
34
+ static char buffer[XMLNS_BUFFER_LEN] ;
35
+ char *key ;
36
+ size_t keylen ;
37
+
38
+ if (node->type != XML_ELEMENT_NODE) return ;
39
+
40
+ ns = node->nsDef;
41
+ while (ns != NULL) {
42
+
43
+ keylen = XMLNS_PREFIX_LEN + (ns->prefix ? (strlen((const char*)ns->prefix) + 1) : 0) ;
44
+ if (keylen > XMLNS_BUFFER_LEN) {
45
+ key = (char*)malloc(keylen) ;
46
+ } else {
47
+ key = buffer ;
48
+ }
49
+
50
+ if (ns->prefix) {
51
+ sprintf(key, "%s:%s", XMLNS_PREFIX, ns->prefix);
52
+ } else {
53
+ sprintf(key, "%s", XMLNS_PREFIX);
54
+ }
55
+
56
+ rb_hash_aset(attr_hash,
57
+ NOKOGIRI_STR_NEW2(key, node->doc->encoding),
58
+ (ns->href ? NOKOGIRI_STR_NEW2(ns->href, node->doc->encoding) : Qnil)
59
+ );
60
+ if (key != buffer) {
61
+ free(key);
62
+ }
63
+ ns = ns->next ;
64
+ }
65
+ }
66
+
67
+
28
68
  /*
29
69
  * call-seq:
30
70
  * default?
@@ -127,11 +167,8 @@ static VALUE attribute_nodes(VALUE self)
127
167
  // at this document, but I have to because of the assertions in
128
168
  // the node wrapping code.
129
169
  if(! DOC_RUBY_OBJECT_TEST(ptr->doc)) {
130
- VALUE rb_doc = Data_Wrap_Struct(cNokogiriXmlDocument, 0, 0, ptr->doc);
131
- ptr->doc->_private = malloc(sizeof(nokogiriTuple));
132
- rb_iv_set(rb_doc, "@decorators", Qnil);
133
- ((nokogiriTuplePtr)(ptr->doc->_private))->doc = (void *)rb_doc;
134
- ((nokogiriTuplePtr)(ptr->doc->_private))->unlinkedNodes = xmlXPathNodeSetCreate(NULL);
170
+ VALUE rb_doc = Nokogiri_wrap_xml_document(cNokogiriXmlDocument, ptr->doc);
171
+ RDATA(rb_doc)->dfree = NULL;
135
172
  }
136
173
  VALUE enc = rb_iv_get(self, "@encoding");
137
174
 
@@ -430,7 +467,7 @@ static VALUE from_memory(int argc, VALUE *argv, VALUE klass)
430
467
 
431
468
  rb_scan_args(argc, argv, "13", &rb_buffer, &rb_url, &encoding, &rb_options);
432
469
 
433
- rb_buffer = StringValue(rb_buffer) ;
470
+ if (!RTEST(rb_buffer)) rb_raise(rb_eArgError, "string cannot be nil");
434
471
  if (RTEST(rb_url)) c_url = StringValuePtr(rb_url);
435
472
  if (RTEST(encoding)) c_encoding = StringValuePtr(encoding);
436
473
  if (RTEST(rb_options)) c_options = NUM2INT(rb_options);
@@ -449,7 +486,48 @@ static VALUE from_memory(int argc, VALUE *argv, VALUE klass)
449
486
  }
450
487
 
451
488
  VALUE rb_reader = Data_Wrap_Struct(klass, NULL, dealloc, reader);
452
- rb_funcall(rb_reader, rb_intern("initialize"), 2, rb_url, encoding);
489
+ rb_funcall(rb_reader, rb_intern("initialize"), 3, rb_buffer, rb_url, encoding);
490
+
491
+ return rb_reader;
492
+ }
493
+
494
+ /*
495
+ * call-seq:
496
+ * from_io(io, url = nil, encoding = nil, options = 0)
497
+ *
498
+ * Create a new reader that parses +io+
499
+ */
500
+ static VALUE from_io(int argc, VALUE *argv, VALUE klass)
501
+ {
502
+ VALUE rb_io, rb_url, encoding, rb_options;
503
+
504
+ const char * c_url = NULL;
505
+ const char * c_encoding = NULL;
506
+ int c_options = 0;
507
+
508
+ rb_scan_args(argc, argv, "13", &rb_io, &rb_url, &encoding, &rb_options);
509
+
510
+ if (!RTEST(rb_io)) rb_raise(rb_eArgError, "io cannot be nil");
511
+ if (RTEST(rb_url)) c_url = StringValuePtr(rb_url);
512
+ if (RTEST(encoding)) c_encoding = StringValuePtr(encoding);
513
+ if (RTEST(rb_options)) c_options = NUM2INT(rb_options);
514
+
515
+ xmlTextReaderPtr reader = xmlReaderForIO(
516
+ (xmlInputReadCallback)io_read_callback,
517
+ (xmlInputCloseCallback)io_close_callback,
518
+ (void *)rb_io,
519
+ c_url,
520
+ c_encoding,
521
+ c_options
522
+ );
523
+
524
+ if(reader == NULL) {
525
+ xmlFreeTextReader(reader);
526
+ rb_raise(rb_eRuntimeError, "couldn't create a parser");
527
+ }
528
+
529
+ VALUE rb_reader = Data_Wrap_Struct(klass, NULL, dealloc, reader);
530
+ rb_funcall(rb_reader, rb_intern("initialize"), 3, rb_io, rb_url, encoding);
453
531
 
454
532
  return rb_reader;
455
533
  }
@@ -471,6 +549,8 @@ void init_xml_reader()
471
549
  cNokogiriXmlReader = klass;
472
550
 
473
551
  rb_define_singleton_method(klass, "from_memory", from_memory, -1);
552
+ rb_define_singleton_method(klass, "from_io", from_io, -1);
553
+
474
554
  rb_define_method(klass, "read", read_more, 0);
475
555
  rb_define_method(klass, "state", state, 0);
476
556
  rb_define_method(klass, "name", name, 0);