libxml-ruby 3.2.1 → 3.2.4

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY +22 -0
  3. data/Rakefile +24 -16
  4. data/ext/libxml/ruby_libxml.h +0 -22
  5. data/ext/libxml/ruby_xml.c +6 -0
  6. data/ext/libxml/ruby_xml_document.c +6 -0
  7. data/ext/libxml/ruby_xml_encoding.h +2 -0
  8. data/ext/libxml/ruby_xml_error.h +2 -0
  9. data/ext/libxml/ruby_xml_html_parser.c +2 -0
  10. data/ext/libxml/ruby_xml_html_parser_context.c +1 -0
  11. data/ext/libxml/ruby_xml_html_parser_options.c +2 -0
  12. data/ext/libxml/ruby_xml_namespace.c +1 -0
  13. data/ext/libxml/ruby_xml_node.c +12 -4
  14. data/ext/libxml/ruby_xml_parser_context.c +2 -0
  15. data/ext/libxml/ruby_xml_reader.c +3 -0
  16. data/ext/libxml/ruby_xml_reader.h +0 -3
  17. data/ext/libxml/ruby_xml_relaxng.c +2 -0
  18. data/ext/libxml/ruby_xml_relaxng.h +0 -2
  19. data/ext/libxml/ruby_xml_schema.c +223 -81
  20. data/ext/libxml/ruby_xml_schema.h +4 -788
  21. data/ext/libxml/ruby_xml_schema_attribute.c +69 -71
  22. data/ext/libxml/ruby_xml_schema_attribute.h +25 -3
  23. data/ext/libxml/ruby_xml_schema_element.c +28 -54
  24. data/ext/libxml/ruby_xml_schema_element.h +0 -3
  25. data/ext/libxml/ruby_xml_schema_facet.c +19 -21
  26. data/ext/libxml/ruby_xml_schema_facet.h +0 -4
  27. data/ext/libxml/ruby_xml_schema_type.c +56 -37
  28. data/ext/libxml/ruby_xml_version.h +3 -3
  29. data/ext/libxml/ruby_xml_writer.c +4 -0
  30. data/ext/libxml/ruby_xml_writer.h +0 -4
  31. data/ext/libxml/ruby_xml_xinclude.c +4 -0
  32. data/ext/libxml/ruby_xml_xpath.c +1 -0
  33. data/ext/libxml/ruby_xml_xpath.h +2 -0
  34. data/ext/libxml/ruby_xml_xpath_context.c +2 -0
  35. data/ext/libxml/ruby_xml_xpath_object.c +1 -0
  36. data/ext/libxml/ruby_xml_xpointer.c +5 -1
  37. data/lib/libxml-ruby.rb +1 -1
  38. data/libxml-ruby.gemspec +1 -1
  39. data/test/model/shiporder.rnc +2 -2
  40. data/test/model/shiporder.rng +2 -2
  41. data/test/model/shiporder.xsd +7 -3
  42. data/test/model/shiporder_bad.xsd +40 -0
  43. data/test/model/shiporder_import.xsd +45 -0
  44. data/test/test_document.rb +2 -1
  45. data/test/test_dtd.rb +2 -1
  46. data/test/test_helper.rb +6 -0
  47. data/test/test_parser.rb +1 -1
  48. data/test/test_parser_context.rb +1 -7
  49. data/test/test_reader.rb +2 -1
  50. data/test/test_sax_parser.rb +13 -6
  51. data/test/test_schema.rb +92 -29
  52. data/test/test_xml.rb +17 -4
  53. metadata +11 -10
  54. data/test/test.xml +0 -2
@@ -1,6 +1,4 @@
1
1
  #include "ruby_libxml.h"
2
- #define LIBXML_OUTPUT_ENABLED
3
- #define DUMP_CONTENT_MODEL
4
2
  #include "ruby_xml_schema.h"
5
3
 
6
4
  #include "ruby_xml_schema_type.h"
@@ -8,6 +6,78 @@
8
6
  #include "ruby_xml_schema_attribute.h"
9
7
  #include "ruby_xml_schema_facet.h"
10
8
 
9
+ #include <libxml/xmlschemas.h>
10
+
11
+ typedef struct _xmlSchemaBucket xmlSchemaBucket;
12
+ typedef xmlSchemaBucket *xmlSchemaBucketPtr;
13
+
14
+ /**
15
+ * xmlSchemaSchemaRelation:
16
+ *
17
+ * Used to create a graph of schema relationships.
18
+ */
19
+ typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
20
+ typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
21
+ struct _xmlSchemaSchemaRelation {
22
+ xmlSchemaSchemaRelationPtr next;
23
+ int type;
24
+ /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
25
+ const xmlChar *importNamespace;
26
+ xmlSchemaBucketPtr bucket;
27
+ };
28
+
29
+ struct _xmlSchemaBucket {
30
+ int type;
31
+ int flags;
32
+ const xmlChar *schemaLocation;
33
+ const xmlChar *origTargetNamespace;
34
+ const xmlChar *targetNamespace;
35
+ xmlDocPtr doc;
36
+ xmlSchemaSchemaRelationPtr relations;
37
+ int located;
38
+ int parsed;
39
+ int imported;
40
+ int preserveDoc;
41
+ xmlSchemaItemListPtr globals;
42
+ /* Global components. */
43
+ xmlSchemaItemListPtr locals; /* Local components. */
44
+ };
45
+
46
+ /**
47
+ * xmlSchemaImport:
48
+ * (extends xmlSchemaBucket)
49
+ *
50
+ * Reflects a schema. Holds some information
51
+ * about the schema and its toplevel components. Duplicate
52
+ * toplevel components are not checked at this level.
53
+ */
54
+ typedef struct _xmlSchemaImport xmlSchemaImport;
55
+ typedef xmlSchemaImport *xmlSchemaImportPtr;
56
+ struct _xmlSchemaImport {
57
+ int type;
58
+ /* Main OR import OR include. */
59
+ int flags;
60
+ const xmlChar *schemaLocation; /* The URI of the schema document. */
61
+ /* For chameleon includes, @origTargetNamespace will be NULL */
62
+ const xmlChar *origTargetNamespace;
63
+ /*
64
+ * For chameleon includes, @targetNamespace will be the
65
+ * targetNamespace of the including schema.
66
+ */
67
+ const xmlChar *targetNamespace;
68
+ xmlDocPtr doc; /* The schema node-tree. */
69
+ /* @relations will hold any included/imported/redefined schemas. */
70
+ xmlSchemaSchemaRelationPtr relations;
71
+ int located;
72
+ int parsed;
73
+ int imported;
74
+ int preserveDoc;
75
+ xmlSchemaItemListPtr globals;
76
+ xmlSchemaItemListPtr locals;
77
+ /* The imported schema. */
78
+ xmlSchemaPtr schema;
79
+ };
80
+
11
81
  /*
12
82
  * Document-class: LibXML::XML::Schema
13
83
  *
@@ -46,9 +116,37 @@ static void rxml_schema_free(xmlSchemaPtr xschema)
46
116
 
47
117
  VALUE rxml_wrap_schema(xmlSchemaPtr xschema)
48
118
  {
49
- return Data_Wrap_Struct(cXMLSchema, NULL, rxml_schema_free, xschema);
119
+ VALUE result;
120
+
121
+ if (!xschema)
122
+ rb_raise(rb_eArgError, "XML::Schema is required!");
123
+
124
+ result = Data_Wrap_Struct(cXMLSchema, NULL, rxml_schema_free, xschema);
125
+
126
+ /*
127
+ * Create these as instance variables to provide the output of inspect/to_str some
128
+ * idea of what schema this class contains.
129
+ */
130
+ rb_iv_set(result, "@target_namespace", QNIL_OR_STRING(xschema->targetNamespace));
131
+ rb_iv_set(result, "@name", QNIL_OR_STRING(xschema->name));
132
+ rb_iv_set(result, "@id", QNIL_OR_STRING(xschema->id));
133
+ rb_iv_set(result, "@version", QNIL_OR_STRING(xschema->name));
134
+
135
+ return result;
50
136
  }
51
137
 
138
+ static VALUE rxml_schema_init(VALUE class, xmlSchemaParserCtxtPtr xparser)
139
+ {
140
+ xmlSchemaPtr xschema;
141
+
142
+ xschema = xmlSchemaParse(xparser);
143
+ xmlSchemaFreeParserCtxt(xparser);
144
+
145
+ if (!xschema)
146
+ rxml_raise(&xmlLastError);
147
+
148
+ return rxml_wrap_schema(xschema);
149
+ }
52
150
 
53
151
  /*
54
152
  * call-seq:
@@ -59,15 +157,15 @@ VALUE rxml_wrap_schema(xmlSchemaPtr xschema)
59
157
  static VALUE rxml_schema_init_from_uri(VALUE class, VALUE uri)
60
158
  {
61
159
  xmlSchemaParserCtxtPtr xparser;
62
- xmlSchemaPtr xschema;
63
160
 
64
161
  Check_Type(uri, T_STRING);
65
162
 
163
+ xmlResetLastError();
66
164
  xparser = xmlSchemaNewParserCtxt(StringValuePtr(uri));
67
- xschema = xmlSchemaParse(xparser);
68
- xmlSchemaFreeParserCtxt(xparser);
165
+ if (!xparser)
166
+ rxml_raise(&xmlLastError);
69
167
 
70
- return Data_Wrap_Struct(cXMLSchema, NULL, rxml_schema_free, xschema);
168
+ return rxml_schema_init(class, xparser);
71
169
  }
72
170
 
73
171
  /*
@@ -79,19 +177,16 @@ static VALUE rxml_schema_init_from_uri(VALUE class, VALUE uri)
79
177
  static VALUE rxml_schema_init_from_document(VALUE class, VALUE document)
80
178
  {
81
179
  xmlDocPtr xdoc;
82
- xmlSchemaPtr xschema;
83
180
  xmlSchemaParserCtxtPtr xparser;
84
181
 
85
182
  Data_Get_Struct(document, xmlDoc, xdoc);
86
183
 
184
+ xmlResetLastError();
87
185
  xparser = xmlSchemaNewDocParserCtxt(xdoc);
88
- xschema = xmlSchemaParse(xparser);
89
- xmlSchemaFreeParserCtxt(xparser);
186
+ if (!xparser)
187
+ rxml_raise(&xmlLastError);
90
188
 
91
- if (xschema == NULL)
92
- return Qnil;
93
-
94
- return Data_Wrap_Struct(cXMLSchema, NULL, rxml_schema_free, xschema);
189
+ return rxml_schema_init(class, xparser);
95
190
  }
96
191
 
97
192
  /*
@@ -100,57 +195,26 @@ static VALUE rxml_schema_init_from_document(VALUE class, VALUE document)
100
195
  *
101
196
  * Create a new schema using the specified string.
102
197
  */
103
- static VALUE rxml_schema_init_from_string(VALUE self, VALUE schema_str)
198
+ static VALUE rxml_schema_init_from_string(VALUE class, VALUE schema_str)
104
199
  {
105
200
  xmlSchemaParserCtxtPtr xparser;
106
- xmlSchemaPtr xschema;
107
201
 
108
202
  Check_Type(schema_str, T_STRING);
109
203
 
204
+ xmlResetLastError();
110
205
  xparser = xmlSchemaNewMemParserCtxt(StringValuePtr(schema_str), (int)strlen(StringValuePtr(schema_str)));
111
- xschema = xmlSchemaParse(xparser);
112
- xmlSchemaFreeParserCtxt(xparser);
206
+ if (!xparser)
207
+ rxml_raise(&xmlLastError);
113
208
 
114
- return Data_Wrap_Struct(cXMLSchema, NULL, rxml_schema_free, xschema);
115
- }
116
-
117
-
118
- static VALUE rxml_schema_target_namespace(VALUE self)
119
- {
120
- xmlSchemaPtr xschema;
121
-
122
- Data_Get_Struct(self, xmlSchema, xschema);
123
-
124
- QNIL_OR_STRING(xschema->targetNamespace)
125
- }
126
-
127
- static VALUE rxml_schema_name(VALUE self)
128
- {
129
- xmlSchemaPtr xschema;
130
-
131
- Data_Get_Struct(self, xmlSchema, xschema);
132
-
133
- QNIL_OR_STRING(xschema->name)
134
- }
135
-
136
- static VALUE rxml_schema_version(VALUE self)
137
- {
138
- xmlSchemaPtr xschema;
139
-
140
- Data_Get_Struct(self, xmlSchema, xschema);
141
-
142
- QNIL_OR_STRING(xschema->version)
143
- }
144
-
145
- static VALUE rxml_schema_id(VALUE self)
146
- {
147
- xmlSchemaPtr xschema;
148
-
149
- Data_Get_Struct(self, xmlSchema, xschema);
150
-
151
- QNIL_OR_STRING(xschema->id)
209
+ return rxml_schema_init(class, xparser);
152
210
  }
153
211
 
212
+ /*
213
+ * call-seq:
214
+ * XML::Schema.document -> document
215
+ *
216
+ * Return the Schema XML Document
217
+ */
154
218
  static VALUE rxml_schema_document(VALUE self)
155
219
  {
156
220
  xmlSchemaPtr xschema;
@@ -160,7 +224,7 @@ static VALUE rxml_schema_document(VALUE self)
160
224
  return rxml_node_wrap(xmlDocGetRootElement(xschema->doc));
161
225
  }
162
226
 
163
- static void scan_namespaces(xmlSchemaImportPtr ximport, VALUE array, xmlChar *nsname)
227
+ static void scan_namespaces(xmlSchemaImportPtr ximport, VALUE array, const xmlChar *nsname)
164
228
  {
165
229
  xmlNodePtr xnode;
166
230
  xmlNsPtr xns;
@@ -171,7 +235,7 @@ static void scan_namespaces(xmlSchemaImportPtr ximport, VALUE array, xmlChar *ns
171
235
  xns = xnode->nsDef;
172
236
 
173
237
  while (xns)
174
- {
238
+ {
175
239
  VALUE namespace = rxml_namespace_wrap(xns);
176
240
  rb_ary_push(array, namespace);
177
241
  xns = xns->next;
@@ -179,6 +243,12 @@ static void scan_namespaces(xmlSchemaImportPtr ximport, VALUE array, xmlChar *ns
179
243
  }
180
244
  }
181
245
 
246
+ /*
247
+ * call-seq:
248
+ * XML::Schema.namespaces -> array
249
+ *
250
+ * Returns an array of Namespaces defined by the schema
251
+ */
182
252
  static VALUE rxml_schema_namespaces(VALUE self)
183
253
  {
184
254
  VALUE result;
@@ -192,7 +262,7 @@ static VALUE rxml_schema_namespaces(VALUE self)
192
262
  return result;
193
263
  }
194
264
 
195
- static void scan_element(xmlSchemaElementPtr xelement, VALUE hash, xmlChar *name)
265
+ static void scan_schema_element(xmlSchemaElementPtr xelement, VALUE hash, const xmlChar *name)
196
266
  {
197
267
  VALUE element = rxml_wrap_schema_element(xelement);
198
268
  rb_hash_aset(hash, rb_str_new2((const char*)name), element);
@@ -204,40 +274,77 @@ static VALUE rxml_schema_elements(VALUE self)
204
274
  xmlSchemaPtr xschema;
205
275
 
206
276
  Data_Get_Struct(self, xmlSchema, xschema);
207
- xmlHashScan(xschema->elemDecl, (xmlHashScanner)scan_element, (void *)result);
277
+ xmlHashScan(xschema->elemDecl, (xmlHashScanner)scan_schema_element, (void *)result);
208
278
 
209
279
  return result;
210
280
  }
211
281
 
212
- static void scan_type(xmlSchemaTypePtr xtype, VALUE hash, xmlChar *name)
282
+ static void collect_imported_ns_elements(xmlSchemaImportPtr import, VALUE result, const xmlChar *name)
213
283
  {
214
- VALUE type = rxml_wrap_schema_type(xtype);
215
- rb_hash_aset(hash, rb_str_new2((const char*)name), type);
284
+ if (import->imported && import->schema)
285
+ {
286
+ VALUE elements = rb_hash_new();
287
+ xmlHashScan(import->schema->elemDecl, (xmlHashScanner)scan_schema_element, (void *)elements);
288
+ rb_hash_aset(result, QNIL_OR_STRING(import->schema->targetNamespace), elements);
289
+ }
290
+ }
291
+
292
+ /*
293
+ * call-seq:
294
+ * XML::Schema.imported_ns_elements -> hash
295
+ *
296
+ * Returns a hash by namespace of a hash of schema elements within the entire schema including imports
297
+ */
298
+ static VALUE rxml_schema_imported_ns_elements(VALUE self)
299
+ {
300
+ xmlSchemaPtr xschema;
301
+ VALUE result = rb_hash_new();
302
+
303
+ Data_Get_Struct(self, xmlSchema, xschema);
304
+
305
+ if (xschema)
306
+ {
307
+ xmlHashScan(xschema->schemasImports, (xmlHashScanner)collect_imported_ns_elements, (void *)result);
308
+ }
309
+
310
+ return result;
311
+ }
312
+
313
+ static void scan_schema_type(xmlSchemaTypePtr xtype, VALUE hash, const xmlChar *name)
314
+ {
315
+ VALUE type = rxml_wrap_schema_type(xtype);
316
+ rb_hash_aset(hash, rb_str_new2((const char*)name), type);
216
317
  }
217
318
 
218
319
  static VALUE rxml_schema_types(VALUE self)
219
320
  {
220
- VALUE result = rb_hash_new();
221
- xmlSchemaPtr xschema;
321
+ VALUE result = rb_hash_new();
322
+ xmlSchemaPtr xschema;
222
323
 
223
- Data_Get_Struct(self, xmlSchema, xschema);
324
+ Data_Get_Struct(self, xmlSchema, xschema);
224
325
 
225
- if (xschema != NULL && xschema->typeDecl != NULL)
226
- {
227
- xmlHashScan(xschema->typeDecl, (xmlHashScanner)scan_type, (void *)result);
228
- }
326
+ if (xschema != NULL && xschema->typeDecl != NULL)
327
+ {
328
+ xmlHashScan(xschema->typeDecl, (xmlHashScanner)scan_schema_type, (void *)result);
329
+ }
229
330
 
230
- return result;
331
+ return result;
231
332
  }
232
333
 
233
- static void collect_imported_types(xmlSchemaImportPtr import, VALUE result)
334
+ static void collect_imported_types(xmlSchemaImportPtr import, VALUE result, const xmlChar *name)
234
335
  {
235
336
  if (import->imported && import->schema)
236
337
  {
237
- xmlHashScan(import->schema->typeDecl, (xmlHashScanner)scan_type, (void *)result);
338
+ xmlHashScan(import->schema->typeDecl, (xmlHashScanner)scan_schema_type, (void *)result);
238
339
  }
239
340
  }
240
341
 
342
+ /*
343
+ * call-seq:
344
+ * XML::Schema.imported_types -> hash
345
+ *
346
+ * Returns a hash of all types within the entire schema including imports
347
+ */
241
348
  static VALUE rxml_schema_imported_types(VALUE self)
242
349
  {
243
350
  xmlSchemaPtr xschema;
@@ -247,7 +354,38 @@ static VALUE rxml_schema_imported_types(VALUE self)
247
354
 
248
355
  if (xschema)
249
356
  {
250
- xmlHashScan(xschema->schemasImports, (xmlHashScanner)collect_imported_types, (void *)result);
357
+ xmlHashScan(xschema->schemasImports, (xmlHashScanner)collect_imported_types, (void *)result);
358
+ }
359
+
360
+ return result;
361
+ }
362
+
363
+ static void collect_imported_ns_types(xmlSchemaImportPtr import, VALUE result, const xmlChar *name)
364
+ {
365
+ if (import->imported && import->schema)
366
+ {
367
+ VALUE types = rb_hash_new();
368
+ xmlHashScan(import->schema->typeDecl, (xmlHashScanner)scan_schema_type, (void *)types);
369
+ rb_hash_aset(result, QNIL_OR_STRING(import->schema->targetNamespace), types);
370
+ }
371
+ }
372
+
373
+ /*
374
+ * call-seq:
375
+ * XML::Schema.imported_ns_types -> hash
376
+ *
377
+ * Returns a hash by namespace of a hash of schema types within the entire schema including imports
378
+ */
379
+ static VALUE rxml_schema_imported_ns_types(VALUE self)
380
+ {
381
+ xmlSchemaPtr xschema;
382
+ VALUE result = rb_hash_new();
383
+
384
+ Data_Get_Struct(self, xmlSchema, xschema);
385
+
386
+ if (xschema)
387
+ {
388
+ xmlHashScan(xschema->schemasImports, (xmlHashScanner)collect_imported_ns_types, (void *)result);
251
389
  }
252
390
 
253
391
  return result;
@@ -260,16 +398,20 @@ void rxml_init_schema(void)
260
398
  rb_define_singleton_method(cXMLSchema, "from_string", rxml_schema_init_from_string, 1);
261
399
  rb_define_singleton_method(cXMLSchema, "document", rxml_schema_init_from_document, 1);
262
400
 
263
- rb_define_method(cXMLSchema, "target_namespace", rxml_schema_target_namespace, 0);
264
- rb_define_method(cXMLSchema, "name", rxml_schema_name, 0);
265
- rb_define_method(cXMLSchema, "id", rxml_schema_id, 0);
266
- rb_define_method(cXMLSchema, "version", rxml_schema_version, 0);
267
- rb_define_method(cXMLSchema, "document", rxml_schema_document, 0);
401
+ /* Create attr_reader methods for the above instance variables */
402
+ rb_define_attr(cXMLSchema, "target_namespace", 1, 0);
403
+ rb_define_attr(cXMLSchema, "name", 1, 0);
404
+ rb_define_attr(cXMLSchema, "id", 1, 0);
405
+ rb_define_attr(cXMLSchema, "version", 1, 0);
268
406
 
269
- rb_define_method(cXMLSchema, "elements", rxml_schema_elements, 0);
270
- rb_define_method(cXMLSchema, "imported_types", rxml_schema_imported_types, 0);
407
+ // These are just methods so as to hide their values and not overly clutter the output of inspect/to_str
408
+ rb_define_method(cXMLSchema, "document", rxml_schema_document, 0);
271
409
  rb_define_method(cXMLSchema, "namespaces", rxml_schema_namespaces, 0);
410
+ rb_define_method(cXMLSchema, "elements", rxml_schema_elements, 0);
411
+ rb_define_method(cXMLSchema, "imported_ns_elements", rxml_schema_imported_ns_elements, 0);
272
412
  rb_define_method(cXMLSchema, "types", rxml_schema_types, 0);
413
+ rb_define_method(cXMLSchema, "imported_types", rxml_schema_imported_types, 0);
414
+ rb_define_method(cXMLSchema, "imported_ns_types", rxml_schema_imported_ns_types, 0);
273
415
 
274
416
  rxml_init_schema_facet();
275
417
  rxml_init_schema_element();