@helm2/poc_jenki_rce 0.0.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of @helm2/poc_jenki_rce might be problematic. Click here for more details.

Files changed (160) hide show
  1. package/LICENSE +19 -0
  2. package/Makefile +18 -0
  3. package/README.md +52 -0
  4. package/binding.gyp +81 -0
  5. package/index.d.ts +273 -0
  6. package/index.js +45 -0
  7. package/lib/bindings.js +1 -0
  8. package/lib/document.js +118 -0
  9. package/lib/element.js +82 -0
  10. package/lib/sax_parser.js +38 -0
  11. package/package.json +70 -0
  12. package/src/html_document.cc +7 -0
  13. package/src/html_document.h +18 -0
  14. package/src/libxmljs.cc +252 -0
  15. package/src/libxmljs.h +53 -0
  16. package/src/xml_attribute.cc +173 -0
  17. package/src/xml_attribute.h +40 -0
  18. package/src/xml_comment.cc +117 -0
  19. package/src/xml_comment.h +30 -0
  20. package/src/xml_document.cc +810 -0
  21. package/src/xml_document.h +67 -0
  22. package/src/xml_element.cc +565 -0
  23. package/src/xml_element.h +61 -0
  24. package/src/xml_namespace.cc +158 -0
  25. package/src/xml_namespace.h +39 -0
  26. package/src/xml_node.cc +761 -0
  27. package/src/xml_node.h +73 -0
  28. package/src/xml_pi.cc +161 -0
  29. package/src/xml_pi.h +34 -0
  30. package/src/xml_sax_parser.cc +424 -0
  31. package/src/xml_sax_parser.h +73 -0
  32. package/src/xml_syntax_error.cc +66 -0
  33. package/src/xml_syntax_error.h +25 -0
  34. package/src/xml_text.cc +320 -0
  35. package/src/xml_text.h +48 -0
  36. package/src/xml_textwriter.cc +315 -0
  37. package/src/xml_textwriter.h +62 -0
  38. package/src/xml_xpath_context.cc +70 -0
  39. package/src/xml_xpath_context.h +23 -0
  40. package/vendor/libxml/Copyright +23 -0
  41. package/vendor/libxml/DOCBparser.c +305 -0
  42. package/vendor/libxml/HTMLparser.c +7287 -0
  43. package/vendor/libxml/HTMLtree.c +1200 -0
  44. package/vendor/libxml/Makefile +2983 -0
  45. package/vendor/libxml/SAX.c +180 -0
  46. package/vendor/libxml/SAX2.c +3036 -0
  47. package/vendor/libxml/buf.c +1351 -0
  48. package/vendor/libxml/buf.h +72 -0
  49. package/vendor/libxml/c14n.c +2234 -0
  50. package/vendor/libxml/catalog.c +3828 -0
  51. package/vendor/libxml/chvalid.c +336 -0
  52. package/vendor/libxml/config.h +294 -0
  53. package/vendor/libxml/config.h.gch +0 -0
  54. package/vendor/libxml/debugXML.c +3423 -0
  55. package/vendor/libxml/dict.c +1298 -0
  56. package/vendor/libxml/elfgcchack.h +17818 -0
  57. package/vendor/libxml/enc.h +32 -0
  58. package/vendor/libxml/encoding.c +3975 -0
  59. package/vendor/libxml/entities.c +1163 -0
  60. package/vendor/libxml/error.c +998 -0
  61. package/vendor/libxml/globals.c +1126 -0
  62. package/vendor/libxml/hash.c +1146 -0
  63. package/vendor/libxml/include/libxml/DOCBparser.h +96 -0
  64. package/vendor/libxml/include/libxml/HTMLparser.h +306 -0
  65. package/vendor/libxml/include/libxml/HTMLtree.h +147 -0
  66. package/vendor/libxml/include/libxml/Makefile +725 -0
  67. package/vendor/libxml/include/libxml/Makefile.am +54 -0
  68. package/vendor/libxml/include/libxml/Makefile.in +725 -0
  69. package/vendor/libxml/include/libxml/SAX.h +173 -0
  70. package/vendor/libxml/include/libxml/SAX2.h +178 -0
  71. package/vendor/libxml/include/libxml/c14n.h +128 -0
  72. package/vendor/libxml/include/libxml/catalog.h +182 -0
  73. package/vendor/libxml/include/libxml/chvalid.h +230 -0
  74. package/vendor/libxml/include/libxml/debugXML.h +217 -0
  75. package/vendor/libxml/include/libxml/dict.h +79 -0
  76. package/vendor/libxml/include/libxml/encoding.h +245 -0
  77. package/vendor/libxml/include/libxml/entities.h +151 -0
  78. package/vendor/libxml/include/libxml/globals.h +508 -0
  79. package/vendor/libxml/include/libxml/hash.h +236 -0
  80. package/vendor/libxml/include/libxml/list.h +137 -0
  81. package/vendor/libxml/include/libxml/nanoftp.h +163 -0
  82. package/vendor/libxml/include/libxml/nanohttp.h +81 -0
  83. package/vendor/libxml/include/libxml/parser.h +1243 -0
  84. package/vendor/libxml/include/libxml/parserInternals.h +644 -0
  85. package/vendor/libxml/include/libxml/pattern.h +100 -0
  86. package/vendor/libxml/include/libxml/relaxng.h +217 -0
  87. package/vendor/libxml/include/libxml/schemasInternals.h +958 -0
  88. package/vendor/libxml/include/libxml/schematron.h +142 -0
  89. package/vendor/libxml/include/libxml/threads.h +89 -0
  90. package/vendor/libxml/include/libxml/tree.h +1311 -0
  91. package/vendor/libxml/include/libxml/uri.h +94 -0
  92. package/vendor/libxml/include/libxml/valid.h +458 -0
  93. package/vendor/libxml/include/libxml/xinclude.h +129 -0
  94. package/vendor/libxml/include/libxml/xlink.h +189 -0
  95. package/vendor/libxml/include/libxml/xmlIO.h +368 -0
  96. package/vendor/libxml/include/libxml/xmlautomata.h +146 -0
  97. package/vendor/libxml/include/libxml/xmlerror.h +945 -0
  98. package/vendor/libxml/include/libxml/xmlexports.h +77 -0
  99. package/vendor/libxml/include/libxml/xmlmemory.h +224 -0
  100. package/vendor/libxml/include/libxml/xmlmodule.h +57 -0
  101. package/vendor/libxml/include/libxml/xmlreader.h +428 -0
  102. package/vendor/libxml/include/libxml/xmlregexp.h +222 -0
  103. package/vendor/libxml/include/libxml/xmlsave.h +88 -0
  104. package/vendor/libxml/include/libxml/xmlschemas.h +246 -0
  105. package/vendor/libxml/include/libxml/xmlschemastypes.h +151 -0
  106. package/vendor/libxml/include/libxml/xmlstring.h +140 -0
  107. package/vendor/libxml/include/libxml/xmlunicode.h +202 -0
  108. package/vendor/libxml/include/libxml/xmlversion.h +484 -0
  109. package/vendor/libxml/include/libxml/xmlwin32version.h +239 -0
  110. package/vendor/libxml/include/libxml/xmlwriter.h +488 -0
  111. package/vendor/libxml/include/libxml/xpath.h +564 -0
  112. package/vendor/libxml/include/libxml/xpathInternals.h +632 -0
  113. package/vendor/libxml/include/libxml/xpointer.h +114 -0
  114. package/vendor/libxml/include/win32config.h +122 -0
  115. package/vendor/libxml/include/wsockcompat.h +54 -0
  116. package/vendor/libxml/legacy.c +1343 -0
  117. package/vendor/libxml/libxml.h +134 -0
  118. package/vendor/libxml/list.c +779 -0
  119. package/vendor/libxml/nanoftp.c +2118 -0
  120. package/vendor/libxml/nanohttp.c +1899 -0
  121. package/vendor/libxml/parser.c +15553 -0
  122. package/vendor/libxml/parserInternals.c +2164 -0
  123. package/vendor/libxml/pattern.c +2621 -0
  124. package/vendor/libxml/relaxng.c +11101 -0
  125. package/vendor/libxml/rngparser.c +1595 -0
  126. package/vendor/libxml/runsuite.c +1157 -0
  127. package/vendor/libxml/save.h +36 -0
  128. package/vendor/libxml/schematron.c +1787 -0
  129. package/vendor/libxml/threads.c +1049 -0
  130. package/vendor/libxml/timsort.h +601 -0
  131. package/vendor/libxml/tree.c +10183 -0
  132. package/vendor/libxml/trio.c +6895 -0
  133. package/vendor/libxml/trio.h +230 -0
  134. package/vendor/libxml/triodef.h +228 -0
  135. package/vendor/libxml/trionan.c +914 -0
  136. package/vendor/libxml/trionan.h +84 -0
  137. package/vendor/libxml/triop.h +150 -0
  138. package/vendor/libxml/triostr.c +2112 -0
  139. package/vendor/libxml/triostr.h +144 -0
  140. package/vendor/libxml/uri.c +2561 -0
  141. package/vendor/libxml/valid.c +7138 -0
  142. package/vendor/libxml/xinclude.c +2657 -0
  143. package/vendor/libxml/xlink.c +183 -0
  144. package/vendor/libxml/xmlIO.c +4135 -0
  145. package/vendor/libxml/xmlcatalog.c +624 -0
  146. package/vendor/libxml/xmllint.c +3796 -0
  147. package/vendor/libxml/xmlmemory.c +1163 -0
  148. package/vendor/libxml/xmlmodule.c +468 -0
  149. package/vendor/libxml/xmlreader.c +6033 -0
  150. package/vendor/libxml/xmlregexp.c +8271 -0
  151. package/vendor/libxml/xmlsave.c +2735 -0
  152. package/vendor/libxml/xmlschemas.c +29173 -0
  153. package/vendor/libxml/xmlschemastypes.c +6276 -0
  154. package/vendor/libxml/xmlstring.c +1050 -0
  155. package/vendor/libxml/xmlunicode.c +3179 -0
  156. package/vendor/libxml/xmlwriter.c +4738 -0
  157. package/vendor/libxml/xpath.c +14734 -0
  158. package/vendor/libxml/xpointer.c +2969 -0
  159. package/vendor/libxml/xzlib.c +815 -0
  160. package/vendor/libxml/xzlib.h +19 -0
@@ -0,0 +1,1787 @@
1
+ /*
2
+ * schematron.c : implementation of the Schematron schema validity checking
3
+ *
4
+ * See Copyright for the status of this software.
5
+ *
6
+ * Daniel Veillard <daniel@veillard.com>
7
+ */
8
+
9
+ /*
10
+ * TODO:
11
+ * + double check the semantic, especially
12
+ * - multiple rules applying in a single pattern/node
13
+ * - the semantic of libxml2 patterns vs. XSLT production referenced
14
+ * by the spec.
15
+ * + export of results in SVRL
16
+ * + full parsing and coverage of the spec, conformance of the input to the
17
+ * spec
18
+ * + divergences between the draft and the ISO proposed standard :-(
19
+ * + hook and test include
20
+ * + try and compare with the XSLT version
21
+ */
22
+
23
+ #define IN_LIBXML
24
+ #include "libxml.h"
25
+
26
+ #ifdef LIBXML_SCHEMATRON_ENABLED
27
+
28
+ #include <string.h>
29
+ #include <libxml/parser.h>
30
+ #include <libxml/tree.h>
31
+ #include <libxml/uri.h>
32
+ #include <libxml/xpath.h>
33
+ #include <libxml/xpathInternals.h>
34
+ #include <libxml/pattern.h>
35
+ #include <libxml/schematron.h>
36
+
37
+ #define SCHEMATRON_PARSE_OPTIONS XML_PARSE_NOENT
38
+
39
+ #define SCT_OLD_NS BAD_CAST "http://www.ascc.net/xml/schematron"
40
+
41
+ #define XML_SCHEMATRON_NS BAD_CAST "http://purl.oclc.org/dsdl/schematron"
42
+
43
+
44
+ static const xmlChar *xmlSchematronNs = XML_SCHEMATRON_NS;
45
+ static const xmlChar *xmlOldSchematronNs = SCT_OLD_NS;
46
+
47
+ #define IS_SCHEMATRON(node, elem) \
48
+ ((node != NULL) && (node->type == XML_ELEMENT_NODE ) && \
49
+ (node->ns != NULL) && \
50
+ (xmlStrEqual(node->name, (const xmlChar *) elem)) && \
51
+ ((xmlStrEqual(node->ns->href, xmlSchematronNs)) || \
52
+ (xmlStrEqual(node->ns->href, xmlOldSchematronNs))))
53
+
54
+ #define NEXT_SCHEMATRON(node) \
55
+ while (node != NULL) { \
56
+ if ((node->type == XML_ELEMENT_NODE ) && (node->ns != NULL) && \
57
+ ((xmlStrEqual(node->ns->href, xmlSchematronNs)) || \
58
+ (xmlStrEqual(node->ns->href, xmlOldSchematronNs)))) \
59
+ break; \
60
+ node = node->next; \
61
+ }
62
+
63
+ /**
64
+ * TODO:
65
+ *
66
+ * macro to flag unimplemented blocks
67
+ */
68
+ #define TODO \
69
+ xmlGenericError(xmlGenericErrorContext, \
70
+ "Unimplemented block at %s:%d\n", \
71
+ __FILE__, __LINE__);
72
+
73
+ typedef enum {
74
+ XML_SCHEMATRON_ASSERT=1,
75
+ XML_SCHEMATRON_REPORT=2
76
+ } xmlSchematronTestType;
77
+
78
+ /**
79
+ * _xmlSchematronTest:
80
+ *
81
+ * A Schematrons test, either an assert or a report
82
+ */
83
+ typedef struct _xmlSchematronTest xmlSchematronTest;
84
+ typedef xmlSchematronTest *xmlSchematronTestPtr;
85
+ struct _xmlSchematronTest {
86
+ xmlSchematronTestPtr next; /* the next test in the list */
87
+ xmlSchematronTestType type; /* the test type */
88
+ xmlNodePtr node; /* the node in the tree */
89
+ xmlChar *test; /* the expression to test */
90
+ xmlXPathCompExprPtr comp; /* the compiled expression */
91
+ xmlChar *report; /* the message to report */
92
+ };
93
+
94
+ /**
95
+ * _xmlSchematronRule:
96
+ *
97
+ * A Schematrons rule
98
+ */
99
+ typedef struct _xmlSchematronRule xmlSchematronRule;
100
+ typedef xmlSchematronRule *xmlSchematronRulePtr;
101
+ struct _xmlSchematronRule {
102
+ xmlSchematronRulePtr next; /* the next rule in the list */
103
+ xmlSchematronRulePtr patnext;/* the next rule in the pattern list */
104
+ xmlNodePtr node; /* the node in the tree */
105
+ xmlChar *context; /* the context evaluation rule */
106
+ xmlSchematronTestPtr tests; /* the list of tests */
107
+ xmlPatternPtr pattern; /* the compiled pattern associated */
108
+ xmlChar *report; /* the message to report */
109
+ };
110
+
111
+ /**
112
+ * _xmlSchematronPattern:
113
+ *
114
+ * A Schematrons pattern
115
+ */
116
+ typedef struct _xmlSchematronPattern xmlSchematronPattern;
117
+ typedef xmlSchematronPattern *xmlSchematronPatternPtr;
118
+ struct _xmlSchematronPattern {
119
+ xmlSchematronPatternPtr next;/* the next pattern in the list */
120
+ xmlSchematronRulePtr rules; /* the list of rules */
121
+ xmlChar *name; /* the name of the pattern */
122
+ };
123
+
124
+ /**
125
+ * _xmlSchematron:
126
+ *
127
+ * A Schematrons definition
128
+ */
129
+ struct _xmlSchematron {
130
+ const xmlChar *name; /* schema name */
131
+ int preserve; /* was the document passed by the user */
132
+ xmlDocPtr doc; /* pointer to the parsed document */
133
+ int flags; /* specific to this schematron */
134
+
135
+ void *_private; /* unused by the library */
136
+ xmlDictPtr dict; /* the dictionary used internally */
137
+
138
+ const xmlChar *title; /* the title if any */
139
+
140
+ int nbNs; /* the number of namespaces */
141
+
142
+ int nbPattern; /* the number of patterns */
143
+ xmlSchematronPatternPtr patterns;/* the patterns found */
144
+ xmlSchematronRulePtr rules; /* the rules gathered */
145
+ int nbNamespaces; /* number of namespaces in the array */
146
+ int maxNamespaces; /* size of the array */
147
+ const xmlChar **namespaces; /* the array of namespaces */
148
+ };
149
+
150
+ /**
151
+ * xmlSchematronValidCtxt:
152
+ *
153
+ * A Schematrons validation context
154
+ */
155
+ struct _xmlSchematronValidCtxt {
156
+ int type;
157
+ int flags; /* an or of xmlSchematronValidOptions */
158
+
159
+ xmlDictPtr dict;
160
+ int nberrors;
161
+ int err;
162
+
163
+ xmlSchematronPtr schema;
164
+ xmlXPathContextPtr xctxt;
165
+
166
+ FILE *outputFile; /* if using XML_SCHEMATRON_OUT_FILE */
167
+ xmlBufferPtr outputBuffer; /* if using XML_SCHEMATRON_OUT_BUFFER */
168
+ #ifdef LIBXML_OUTPUT_ENABLED
169
+ xmlOutputWriteCallback iowrite; /* if using XML_SCHEMATRON_OUT_IO */
170
+ xmlOutputCloseCallback ioclose;
171
+ #endif
172
+ void *ioctx;
173
+
174
+ /* error reporting data */
175
+ void *userData; /* user specific data block */
176
+ xmlSchematronValidityErrorFunc error;/* the callback in case of errors */
177
+ xmlSchematronValidityWarningFunc warning;/* callback in case of warning */
178
+ xmlStructuredErrorFunc serror; /* the structured function */
179
+ };
180
+
181
+ struct _xmlSchematronParserCtxt {
182
+ int type;
183
+ const xmlChar *URL;
184
+ xmlDocPtr doc;
185
+ int preserve; /* Whether the doc should be freed */
186
+ const char *buffer;
187
+ int size;
188
+
189
+ xmlDictPtr dict; /* dictionary for interned string names */
190
+
191
+ int nberrors;
192
+ int err;
193
+ xmlXPathContextPtr xctxt; /* the XPath context used for compilation */
194
+ xmlSchematronPtr schema;
195
+
196
+ int nbNamespaces; /* number of namespaces in the array */
197
+ int maxNamespaces; /* size of the array */
198
+ const xmlChar **namespaces; /* the array of namespaces */
199
+
200
+ int nbIncludes; /* number of includes in the array */
201
+ int maxIncludes; /* size of the array */
202
+ xmlNodePtr *includes; /* the array of includes */
203
+
204
+ /* error reporting data */
205
+ void *userData; /* user specific data block */
206
+ xmlSchematronValidityErrorFunc error;/* the callback in case of errors */
207
+ xmlSchematronValidityWarningFunc warning;/* callback in case of warning */
208
+ xmlStructuredErrorFunc serror; /* the structured function */
209
+ };
210
+
211
+ #define XML_STRON_CTXT_PARSER 1
212
+ #define XML_STRON_CTXT_VALIDATOR 2
213
+
214
+ /************************************************************************
215
+ * *
216
+ * Error reporting *
217
+ * *
218
+ ************************************************************************/
219
+
220
+ /**
221
+ * xmlSchematronPErrMemory:
222
+ * @node: a context node
223
+ * @extra: extra information
224
+ *
225
+ * Handle an out of memory condition
226
+ */
227
+ static void
228
+ xmlSchematronPErrMemory(xmlSchematronParserCtxtPtr ctxt,
229
+ const char *extra, xmlNodePtr node)
230
+ {
231
+ if (ctxt != NULL)
232
+ ctxt->nberrors++;
233
+ __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
234
+ extra);
235
+ }
236
+
237
+ /**
238
+ * xmlSchematronPErr:
239
+ * @ctxt: the parsing context
240
+ * @node: the context node
241
+ * @error: the error code
242
+ * @msg: the error message
243
+ * @str1: extra data
244
+ * @str2: extra data
245
+ *
246
+ * Handle a parser error
247
+ */
248
+ static void LIBXML_ATTR_FORMAT(4,0)
249
+ xmlSchematronPErr(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr node, int error,
250
+ const char *msg, const xmlChar * str1, const xmlChar * str2)
251
+ {
252
+ xmlGenericErrorFunc channel = NULL;
253
+ xmlStructuredErrorFunc schannel = NULL;
254
+ void *data = NULL;
255
+
256
+ if (ctxt != NULL) {
257
+ ctxt->nberrors++;
258
+ channel = ctxt->error;
259
+ data = ctxt->userData;
260
+ schannel = ctxt->serror;
261
+ }
262
+ __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
263
+ error, XML_ERR_ERROR, NULL, 0,
264
+ (const char *) str1, (const char *) str2, NULL, 0, 0,
265
+ msg, str1, str2);
266
+ }
267
+
268
+ /**
269
+ * xmlSchematronVTypeErrMemory:
270
+ * @node: a context node
271
+ * @extra: extra information
272
+ *
273
+ * Handle an out of memory condition
274
+ */
275
+ static void
276
+ xmlSchematronVErrMemory(xmlSchematronValidCtxtPtr ctxt,
277
+ const char *extra, xmlNodePtr node)
278
+ {
279
+ if (ctxt != NULL) {
280
+ ctxt->nberrors++;
281
+ ctxt->err = XML_SCHEMAV_INTERNAL;
282
+ }
283
+ __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
284
+ extra);
285
+ }
286
+
287
+ /************************************************************************
288
+ * *
289
+ * Parsing and compilation of the Schematrontrons *
290
+ * *
291
+ ************************************************************************/
292
+
293
+ /**
294
+ * xmlSchematronAddTest:
295
+ * @ctxt: the schema parsing context
296
+ * @type: the type of test
297
+ * @rule: the parent rule
298
+ * @node: the node hosting the test
299
+ * @test: the associated test
300
+ * @report: the associated report string
301
+ *
302
+ * Add a test to a schematron
303
+ *
304
+ * Returns the new pointer or NULL in case of error
305
+ */
306
+ static xmlSchematronTestPtr
307
+ xmlSchematronAddTest(xmlSchematronParserCtxtPtr ctxt,
308
+ xmlSchematronTestType type,
309
+ xmlSchematronRulePtr rule,
310
+ xmlNodePtr node, xmlChar *test, xmlChar *report)
311
+ {
312
+ xmlSchematronTestPtr ret;
313
+ xmlXPathCompExprPtr comp;
314
+
315
+ if ((ctxt == NULL) || (rule == NULL) || (node == NULL) ||
316
+ (test == NULL))
317
+ return(NULL);
318
+
319
+ /*
320
+ * try first to compile the test expression
321
+ */
322
+ comp = xmlXPathCtxtCompile(ctxt->xctxt, test);
323
+ if (comp == NULL) {
324
+ xmlSchematronPErr(ctxt, node,
325
+ XML_SCHEMAP_NOROOT,
326
+ "Failed to compile test expression %s",
327
+ test, NULL);
328
+ return(NULL);
329
+ }
330
+
331
+ ret = (xmlSchematronTestPtr) xmlMalloc(sizeof(xmlSchematronTest));
332
+ if (ret == NULL) {
333
+ xmlSchematronPErrMemory(ctxt, "allocating schema test", node);
334
+ return (NULL);
335
+ }
336
+ memset(ret, 0, sizeof(xmlSchematronTest));
337
+ ret->type = type;
338
+ ret->node = node;
339
+ ret->test = test;
340
+ ret->comp = comp;
341
+ ret->report = report;
342
+ ret->next = NULL;
343
+ if (rule->tests == NULL) {
344
+ rule->tests = ret;
345
+ } else {
346
+ xmlSchematronTestPtr prev = rule->tests;
347
+
348
+ while (prev->next != NULL)
349
+ prev = prev->next;
350
+ prev->next = ret;
351
+ }
352
+ return (ret);
353
+ }
354
+
355
+ /**
356
+ * xmlSchematronFreeTests:
357
+ * @tests: a list of tests
358
+ *
359
+ * Free a list of tests.
360
+ */
361
+ static void
362
+ xmlSchematronFreeTests(xmlSchematronTestPtr tests) {
363
+ xmlSchematronTestPtr next;
364
+
365
+ while (tests != NULL) {
366
+ next = tests->next;
367
+ if (tests->test != NULL)
368
+ xmlFree(tests->test);
369
+ if (tests->comp != NULL)
370
+ xmlXPathFreeCompExpr(tests->comp);
371
+ if (tests->report != NULL)
372
+ xmlFree(tests->report);
373
+ xmlFree(tests);
374
+ tests = next;
375
+ }
376
+ }
377
+
378
+ /**
379
+ * xmlSchematronAddRule:
380
+ * @ctxt: the schema parsing context
381
+ * @schema: a schema structure
382
+ * @node: the node hosting the rule
383
+ * @context: the associated context string
384
+ * @report: the associated report string
385
+ *
386
+ * Add a rule to a schematron
387
+ *
388
+ * Returns the new pointer or NULL in case of error
389
+ */
390
+ static xmlSchematronRulePtr
391
+ xmlSchematronAddRule(xmlSchematronParserCtxtPtr ctxt, xmlSchematronPtr schema,
392
+ xmlSchematronPatternPtr pat, xmlNodePtr node,
393
+ xmlChar *context, xmlChar *report)
394
+ {
395
+ xmlSchematronRulePtr ret;
396
+ xmlPatternPtr pattern;
397
+
398
+ if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
399
+ (context == NULL))
400
+ return(NULL);
401
+
402
+ /*
403
+ * Try first to compile the pattern
404
+ */
405
+ pattern = xmlPatterncompile(context, ctxt->dict, XML_PATTERN_XPATH,
406
+ ctxt->namespaces);
407
+ if (pattern == NULL) {
408
+ xmlSchematronPErr(ctxt, node,
409
+ XML_SCHEMAP_NOROOT,
410
+ "Failed to compile context expression %s",
411
+ context, NULL);
412
+ }
413
+
414
+ ret = (xmlSchematronRulePtr) xmlMalloc(sizeof(xmlSchematronRule));
415
+ if (ret == NULL) {
416
+ xmlSchematronPErrMemory(ctxt, "allocating schema rule", node);
417
+ return (NULL);
418
+ }
419
+ memset(ret, 0, sizeof(xmlSchematronRule));
420
+ ret->node = node;
421
+ ret->context = context;
422
+ ret->pattern = pattern;
423
+ ret->report = report;
424
+ ret->next = NULL;
425
+ if (schema->rules == NULL) {
426
+ schema->rules = ret;
427
+ } else {
428
+ xmlSchematronRulePtr prev = schema->rules;
429
+
430
+ while (prev->next != NULL)
431
+ prev = prev->next;
432
+ prev->next = ret;
433
+ }
434
+ ret->patnext = NULL;
435
+ if (pat->rules == NULL) {
436
+ pat->rules = ret;
437
+ } else {
438
+ xmlSchematronRulePtr prev = pat->rules;
439
+
440
+ while (prev->patnext != NULL)
441
+ prev = prev->patnext;
442
+ prev->patnext = ret;
443
+ }
444
+ return (ret);
445
+ }
446
+
447
+ /**
448
+ * xmlSchematronFreeRules:
449
+ * @rules: a list of rules
450
+ *
451
+ * Free a list of rules.
452
+ */
453
+ static void
454
+ xmlSchematronFreeRules(xmlSchematronRulePtr rules) {
455
+ xmlSchematronRulePtr next;
456
+
457
+ while (rules != NULL) {
458
+ next = rules->next;
459
+ if (rules->tests)
460
+ xmlSchematronFreeTests(rules->tests);
461
+ if (rules->context != NULL)
462
+ xmlFree(rules->context);
463
+ if (rules->pattern)
464
+ xmlFreePattern(rules->pattern);
465
+ if (rules->report != NULL)
466
+ xmlFree(rules->report);
467
+ xmlFree(rules);
468
+ rules = next;
469
+ }
470
+ }
471
+
472
+ /**
473
+ * xmlSchematronAddPattern:
474
+ * @ctxt: the schema parsing context
475
+ * @schema: a schema structure
476
+ * @node: the node hosting the pattern
477
+ * @id: the id or name of the pattern
478
+ *
479
+ * Add a pattern to a schematron
480
+ *
481
+ * Returns the new pointer or NULL in case of error
482
+ */
483
+ static xmlSchematronPatternPtr
484
+ xmlSchematronAddPattern(xmlSchematronParserCtxtPtr ctxt,
485
+ xmlSchematronPtr schema, xmlNodePtr node, xmlChar *name)
486
+ {
487
+ xmlSchematronPatternPtr ret;
488
+
489
+ if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || (name == NULL))
490
+ return(NULL);
491
+
492
+ ret = (xmlSchematronPatternPtr) xmlMalloc(sizeof(xmlSchematronPattern));
493
+ if (ret == NULL) {
494
+ xmlSchematronPErrMemory(ctxt, "allocating schema pattern", node);
495
+ return (NULL);
496
+ }
497
+ memset(ret, 0, sizeof(xmlSchematronPattern));
498
+ ret->name = name;
499
+ ret->next = NULL;
500
+ if (schema->patterns == NULL) {
501
+ schema->patterns = ret;
502
+ } else {
503
+ xmlSchematronPatternPtr prev = schema->patterns;
504
+
505
+ while (prev->next != NULL)
506
+ prev = prev->next;
507
+ prev->next = ret;
508
+ }
509
+ return (ret);
510
+ }
511
+
512
+ /**
513
+ * xmlSchematronFreePatterns:
514
+ * @patterns: a list of patterns
515
+ *
516
+ * Free a list of patterns.
517
+ */
518
+ static void
519
+ xmlSchematronFreePatterns(xmlSchematronPatternPtr patterns) {
520
+ xmlSchematronPatternPtr next;
521
+
522
+ while (patterns != NULL) {
523
+ next = patterns->next;
524
+ if (patterns->name != NULL)
525
+ xmlFree(patterns->name);
526
+ xmlFree(patterns);
527
+ patterns = next;
528
+ }
529
+ }
530
+
531
+ /**
532
+ * xmlSchematronNewSchematron:
533
+ * @ctxt: a schema validation context
534
+ *
535
+ * Allocate a new Schematron structure.
536
+ *
537
+ * Returns the newly allocated structure or NULL in case or error
538
+ */
539
+ static xmlSchematronPtr
540
+ xmlSchematronNewSchematron(xmlSchematronParserCtxtPtr ctxt)
541
+ {
542
+ xmlSchematronPtr ret;
543
+
544
+ ret = (xmlSchematronPtr) xmlMalloc(sizeof(xmlSchematron));
545
+ if (ret == NULL) {
546
+ xmlSchematronPErrMemory(ctxt, "allocating schema", NULL);
547
+ return (NULL);
548
+ }
549
+ memset(ret, 0, sizeof(xmlSchematron));
550
+ ret->dict = ctxt->dict;
551
+ xmlDictReference(ret->dict);
552
+
553
+ return (ret);
554
+ }
555
+
556
+ /**
557
+ * xmlSchematronFree:
558
+ * @schema: a schema structure
559
+ *
560
+ * Deallocate a Schematron structure.
561
+ */
562
+ void
563
+ xmlSchematronFree(xmlSchematronPtr schema)
564
+ {
565
+ if (schema == NULL)
566
+ return;
567
+
568
+ if ((schema->doc != NULL) && (!(schema->preserve)))
569
+ xmlFreeDoc(schema->doc);
570
+
571
+ if (schema->namespaces != NULL)
572
+ xmlFree((char **) schema->namespaces);
573
+
574
+ xmlSchematronFreeRules(schema->rules);
575
+ xmlSchematronFreePatterns(schema->patterns);
576
+ xmlDictFree(schema->dict);
577
+ xmlFree(schema);
578
+ }
579
+
580
+ /**
581
+ * xmlSchematronNewParserCtxt:
582
+ * @URL: the location of the schema
583
+ *
584
+ * Create an XML Schematrons parse context for that file/resource expected
585
+ * to contain an XML Schematrons file.
586
+ *
587
+ * Returns the parser context or NULL in case of error
588
+ */
589
+ xmlSchematronParserCtxtPtr
590
+ xmlSchematronNewParserCtxt(const char *URL)
591
+ {
592
+ xmlSchematronParserCtxtPtr ret;
593
+
594
+ if (URL == NULL)
595
+ return (NULL);
596
+
597
+ ret =
598
+ (xmlSchematronParserCtxtPtr)
599
+ xmlMalloc(sizeof(xmlSchematronParserCtxt));
600
+ if (ret == NULL) {
601
+ xmlSchematronPErrMemory(NULL, "allocating schema parser context",
602
+ NULL);
603
+ return (NULL);
604
+ }
605
+ memset(ret, 0, sizeof(xmlSchematronParserCtxt));
606
+ ret->type = XML_STRON_CTXT_PARSER;
607
+ ret->dict = xmlDictCreate();
608
+ ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
609
+ ret->includes = NULL;
610
+ ret->xctxt = xmlXPathNewContext(NULL);
611
+ if (ret->xctxt == NULL) {
612
+ xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
613
+ NULL);
614
+ xmlSchematronFreeParserCtxt(ret);
615
+ return (NULL);
616
+ }
617
+ ret->xctxt->flags = XML_XPATH_CHECKNS;
618
+ return (ret);
619
+ }
620
+
621
+ /**
622
+ * xmlSchematronNewMemParserCtxt:
623
+ * @buffer: a pointer to a char array containing the schemas
624
+ * @size: the size of the array
625
+ *
626
+ * Create an XML Schematrons parse context for that memory buffer expected
627
+ * to contain an XML Schematrons file.
628
+ *
629
+ * Returns the parser context or NULL in case of error
630
+ */
631
+ xmlSchematronParserCtxtPtr
632
+ xmlSchematronNewMemParserCtxt(const char *buffer, int size)
633
+ {
634
+ xmlSchematronParserCtxtPtr ret;
635
+
636
+ if ((buffer == NULL) || (size <= 0))
637
+ return (NULL);
638
+
639
+ ret =
640
+ (xmlSchematronParserCtxtPtr)
641
+ xmlMalloc(sizeof(xmlSchematronParserCtxt));
642
+ if (ret == NULL) {
643
+ xmlSchematronPErrMemory(NULL, "allocating schema parser context",
644
+ NULL);
645
+ return (NULL);
646
+ }
647
+ memset(ret, 0, sizeof(xmlSchematronParserCtxt));
648
+ ret->buffer = buffer;
649
+ ret->size = size;
650
+ ret->dict = xmlDictCreate();
651
+ ret->xctxt = xmlXPathNewContext(NULL);
652
+ if (ret->xctxt == NULL) {
653
+ xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
654
+ NULL);
655
+ xmlSchematronFreeParserCtxt(ret);
656
+ return (NULL);
657
+ }
658
+ return (ret);
659
+ }
660
+
661
+ /**
662
+ * xmlSchematronNewDocParserCtxt:
663
+ * @doc: a preparsed document tree
664
+ *
665
+ * Create an XML Schematrons parse context for that document.
666
+ * NB. The document may be modified during the parsing process.
667
+ *
668
+ * Returns the parser context or NULL in case of error
669
+ */
670
+ xmlSchematronParserCtxtPtr
671
+ xmlSchematronNewDocParserCtxt(xmlDocPtr doc)
672
+ {
673
+ xmlSchematronParserCtxtPtr ret;
674
+
675
+ if (doc == NULL)
676
+ return (NULL);
677
+
678
+ ret =
679
+ (xmlSchematronParserCtxtPtr)
680
+ xmlMalloc(sizeof(xmlSchematronParserCtxt));
681
+ if (ret == NULL) {
682
+ xmlSchematronPErrMemory(NULL, "allocating schema parser context",
683
+ NULL);
684
+ return (NULL);
685
+ }
686
+ memset(ret, 0, sizeof(xmlSchematronParserCtxt));
687
+ ret->doc = doc;
688
+ ret->dict = xmlDictCreate();
689
+ /* The application has responsibility for the document */
690
+ ret->preserve = 1;
691
+ ret->xctxt = xmlXPathNewContext(doc);
692
+ if (ret->xctxt == NULL) {
693
+ xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
694
+ NULL);
695
+ xmlSchematronFreeParserCtxt(ret);
696
+ return (NULL);
697
+ }
698
+
699
+ return (ret);
700
+ }
701
+
702
+ /**
703
+ * xmlSchematronFreeParserCtxt:
704
+ * @ctxt: the schema parser context
705
+ *
706
+ * Free the resources associated to the schema parser context
707
+ */
708
+ void
709
+ xmlSchematronFreeParserCtxt(xmlSchematronParserCtxtPtr ctxt)
710
+ {
711
+ if (ctxt == NULL)
712
+ return;
713
+ if (ctxt->doc != NULL && !ctxt->preserve)
714
+ xmlFreeDoc(ctxt->doc);
715
+ if (ctxt->xctxt != NULL) {
716
+ xmlXPathFreeContext(ctxt->xctxt);
717
+ }
718
+ if (ctxt->namespaces != NULL)
719
+ xmlFree((char **) ctxt->namespaces);
720
+ xmlDictFree(ctxt->dict);
721
+ xmlFree(ctxt);
722
+ }
723
+
724
+ #if 0
725
+ /**
726
+ * xmlSchematronPushInclude:
727
+ * @ctxt: the schema parser context
728
+ * @doc: the included document
729
+ * @cur: the current include node
730
+ *
731
+ * Add an included document
732
+ */
733
+ static void
734
+ xmlSchematronPushInclude(xmlSchematronParserCtxtPtr ctxt,
735
+ xmlDocPtr doc, xmlNodePtr cur)
736
+ {
737
+ if (ctxt->includes == NULL) {
738
+ ctxt->maxIncludes = 10;
739
+ ctxt->includes = (xmlNodePtr *)
740
+ xmlMalloc(ctxt->maxIncludes * 2 * sizeof(xmlNodePtr));
741
+ if (ctxt->includes == NULL) {
742
+ xmlSchematronPErrMemory(NULL, "allocating parser includes",
743
+ NULL);
744
+ return;
745
+ }
746
+ ctxt->nbIncludes = 0;
747
+ } else if (ctxt->nbIncludes + 2 >= ctxt->maxIncludes) {
748
+ xmlNodePtr *tmp;
749
+
750
+ tmp = (xmlNodePtr *)
751
+ xmlRealloc(ctxt->includes, ctxt->maxIncludes * 4 *
752
+ sizeof(xmlNodePtr));
753
+ if (tmp == NULL) {
754
+ xmlSchematronPErrMemory(NULL, "allocating parser includes",
755
+ NULL);
756
+ return;
757
+ }
758
+ ctxt->includes = tmp;
759
+ ctxt->maxIncludes *= 2;
760
+ }
761
+ ctxt->includes[2 * ctxt->nbIncludes] = cur;
762
+ ctxt->includes[2 * ctxt->nbIncludes + 1] = (xmlNodePtr) doc;
763
+ ctxt->nbIncludes++;
764
+ }
765
+
766
+ /**
767
+ * xmlSchematronPopInclude:
768
+ * @ctxt: the schema parser context
769
+ *
770
+ * Pop an include level. The included document is being freed
771
+ *
772
+ * Returns the node immediately following the include or NULL if the
773
+ * include list was empty.
774
+ */
775
+ static xmlNodePtr
776
+ xmlSchematronPopInclude(xmlSchematronParserCtxtPtr ctxt)
777
+ {
778
+ xmlDocPtr doc;
779
+ xmlNodePtr ret;
780
+
781
+ if (ctxt->nbIncludes <= 0)
782
+ return(NULL);
783
+ ctxt->nbIncludes--;
784
+ doc = (xmlDocPtr) ctxt->includes[2 * ctxt->nbIncludes + 1];
785
+ ret = ctxt->includes[2 * ctxt->nbIncludes];
786
+ xmlFreeDoc(doc);
787
+ if (ret != NULL)
788
+ ret = ret->next;
789
+ if (ret == NULL)
790
+ return(xmlSchematronPopInclude(ctxt));
791
+ return(ret);
792
+ }
793
+ #endif
794
+
795
+ /**
796
+ * xmlSchematronAddNamespace:
797
+ * @ctxt: the schema parser context
798
+ * @prefix: the namespace prefix
799
+ * @ns: the namespace name
800
+ *
801
+ * Add a namespace definition in the context
802
+ */
803
+ static void
804
+ xmlSchematronAddNamespace(xmlSchematronParserCtxtPtr ctxt,
805
+ const xmlChar *prefix, const xmlChar *ns)
806
+ {
807
+ if (ctxt->namespaces == NULL) {
808
+ ctxt->maxNamespaces = 10;
809
+ ctxt->namespaces = (const xmlChar **)
810
+ xmlMalloc(ctxt->maxNamespaces * 2 * sizeof(const xmlChar *));
811
+ if (ctxt->namespaces == NULL) {
812
+ xmlSchematronPErrMemory(NULL, "allocating parser namespaces",
813
+ NULL);
814
+ return;
815
+ }
816
+ ctxt->nbNamespaces = 0;
817
+ } else if (ctxt->nbNamespaces + 2 >= ctxt->maxNamespaces) {
818
+ const xmlChar **tmp;
819
+
820
+ tmp = (const xmlChar **)
821
+ xmlRealloc((xmlChar **) ctxt->namespaces, ctxt->maxNamespaces * 4 *
822
+ sizeof(const xmlChar *));
823
+ if (tmp == NULL) {
824
+ xmlSchematronPErrMemory(NULL, "allocating parser namespaces",
825
+ NULL);
826
+ return;
827
+ }
828
+ ctxt->namespaces = tmp;
829
+ ctxt->maxNamespaces *= 2;
830
+ }
831
+ ctxt->namespaces[2 * ctxt->nbNamespaces] =
832
+ xmlDictLookup(ctxt->dict, ns, -1);
833
+ ctxt->namespaces[2 * ctxt->nbNamespaces + 1] =
834
+ xmlDictLookup(ctxt->dict, prefix, -1);
835
+ ctxt->nbNamespaces++;
836
+ ctxt->namespaces[2 * ctxt->nbNamespaces] = NULL;
837
+ ctxt->namespaces[2 * ctxt->nbNamespaces + 1] = NULL;
838
+
839
+ }
840
+
841
+ /**
842
+ * xmlSchematronParseRule:
843
+ * @ctxt: a schema validation context
844
+ * @rule: the rule node
845
+ *
846
+ * parse a rule element
847
+ */
848
+ static void
849
+ xmlSchematronParseRule(xmlSchematronParserCtxtPtr ctxt,
850
+ xmlSchematronPatternPtr pattern,
851
+ xmlNodePtr rule)
852
+ {
853
+ xmlNodePtr cur;
854
+ int nbChecks = 0;
855
+ xmlChar *test;
856
+ xmlChar *context;
857
+ xmlChar *report;
858
+ xmlSchematronRulePtr ruleptr;
859
+ xmlSchematronTestPtr testptr;
860
+
861
+ if ((ctxt == NULL) || (rule == NULL)) return;
862
+
863
+ context = xmlGetNoNsProp(rule, BAD_CAST "context");
864
+ if (context == NULL) {
865
+ xmlSchematronPErr(ctxt, rule,
866
+ XML_SCHEMAP_NOROOT,
867
+ "rule has no context attribute",
868
+ NULL, NULL);
869
+ return;
870
+ } else if (context[0] == 0) {
871
+ xmlSchematronPErr(ctxt, rule,
872
+ XML_SCHEMAP_NOROOT,
873
+ "rule has an empty context attribute",
874
+ NULL, NULL);
875
+ xmlFree(context);
876
+ return;
877
+ } else {
878
+ ruleptr = xmlSchematronAddRule(ctxt, ctxt->schema, pattern,
879
+ rule, context, NULL);
880
+ if (ruleptr == NULL) {
881
+ xmlFree(context);
882
+ return;
883
+ }
884
+ }
885
+
886
+ cur = rule->children;
887
+ NEXT_SCHEMATRON(cur);
888
+ while (cur != NULL) {
889
+ if (IS_SCHEMATRON(cur, "assert")) {
890
+ nbChecks++;
891
+ test = xmlGetNoNsProp(cur, BAD_CAST "test");
892
+ if (test == NULL) {
893
+ xmlSchematronPErr(ctxt, cur,
894
+ XML_SCHEMAP_NOROOT,
895
+ "assert has no test attribute",
896
+ NULL, NULL);
897
+ } else if (test[0] == 0) {
898
+ xmlSchematronPErr(ctxt, cur,
899
+ XML_SCHEMAP_NOROOT,
900
+ "assert has an empty test attribute",
901
+ NULL, NULL);
902
+ xmlFree(test);
903
+ } else {
904
+ /* TODO will need dynamic processing instead */
905
+ report = xmlNodeGetContent(cur);
906
+
907
+ testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_ASSERT,
908
+ ruleptr, cur, test, report);
909
+ if (testptr == NULL)
910
+ xmlFree(test);
911
+ }
912
+ } else if (IS_SCHEMATRON(cur, "report")) {
913
+ nbChecks++;
914
+ test = xmlGetNoNsProp(cur, BAD_CAST "test");
915
+ if (test == NULL) {
916
+ xmlSchematronPErr(ctxt, cur,
917
+ XML_SCHEMAP_NOROOT,
918
+ "assert has no test attribute",
919
+ NULL, NULL);
920
+ } else if (test[0] == 0) {
921
+ xmlSchematronPErr(ctxt, cur,
922
+ XML_SCHEMAP_NOROOT,
923
+ "assert has an empty test attribute",
924
+ NULL, NULL);
925
+ xmlFree(test);
926
+ } else {
927
+ /* TODO will need dynamic processing instead */
928
+ report = xmlNodeGetContent(cur);
929
+
930
+ testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_REPORT,
931
+ ruleptr, cur, test, report);
932
+ if (testptr == NULL)
933
+ xmlFree(test);
934
+ }
935
+ } else {
936
+ xmlSchematronPErr(ctxt, cur,
937
+ XML_SCHEMAP_NOROOT,
938
+ "Expecting an assert or a report element instead of %s",
939
+ cur->name, NULL);
940
+ }
941
+ cur = cur->next;
942
+ NEXT_SCHEMATRON(cur);
943
+ }
944
+ if (nbChecks == 0) {
945
+ xmlSchematronPErr(ctxt, rule,
946
+ XML_SCHEMAP_NOROOT,
947
+ "rule has no assert nor report element", NULL, NULL);
948
+ }
949
+ }
950
+
951
+ /**
952
+ * xmlSchematronParsePattern:
953
+ * @ctxt: a schema validation context
954
+ * @pat: the pattern node
955
+ *
956
+ * parse a pattern element
957
+ */
958
+ static void
959
+ xmlSchematronParsePattern(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr pat)
960
+ {
961
+ xmlNodePtr cur;
962
+ xmlSchematronPatternPtr pattern;
963
+ int nbRules = 0;
964
+ xmlChar *id;
965
+
966
+ if ((ctxt == NULL) || (pat == NULL)) return;
967
+
968
+ id = xmlGetNoNsProp(pat, BAD_CAST "id");
969
+ if (id == NULL) {
970
+ id = xmlGetNoNsProp(pat, BAD_CAST "name");
971
+ }
972
+ pattern = xmlSchematronAddPattern(ctxt, ctxt->schema, pat, id);
973
+ if (pattern == NULL) {
974
+ if (id != NULL)
975
+ xmlFree(id);
976
+ return;
977
+ }
978
+ cur = pat->children;
979
+ NEXT_SCHEMATRON(cur);
980
+ while (cur != NULL) {
981
+ if (IS_SCHEMATRON(cur, "rule")) {
982
+ xmlSchematronParseRule(ctxt, pattern, cur);
983
+ nbRules++;
984
+ } else {
985
+ xmlSchematronPErr(ctxt, cur,
986
+ XML_SCHEMAP_NOROOT,
987
+ "Expecting a rule element instead of %s", cur->name, NULL);
988
+ }
989
+ cur = cur->next;
990
+ NEXT_SCHEMATRON(cur);
991
+ }
992
+ if (nbRules == 0) {
993
+ xmlSchematronPErr(ctxt, pat,
994
+ XML_SCHEMAP_NOROOT,
995
+ "Pattern has no rule element", NULL, NULL);
996
+ }
997
+ }
998
+
999
+ #if 0
1000
+ /**
1001
+ * xmlSchematronLoadInclude:
1002
+ * @ctxt: a schema validation context
1003
+ * @cur: the include element
1004
+ *
1005
+ * Load the include document, Push the current pointer
1006
+ *
1007
+ * Returns the updated node pointer
1008
+ */
1009
+ static xmlNodePtr
1010
+ xmlSchematronLoadInclude(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr cur)
1011
+ {
1012
+ xmlNodePtr ret = NULL;
1013
+ xmlDocPtr doc = NULL;
1014
+ xmlChar *href = NULL;
1015
+ xmlChar *base = NULL;
1016
+ xmlChar *URI = NULL;
1017
+
1018
+ if ((ctxt == NULL) || (cur == NULL))
1019
+ return(NULL);
1020
+
1021
+ href = xmlGetNoNsProp(cur, BAD_CAST "href");
1022
+ if (href == NULL) {
1023
+ xmlSchematronPErr(ctxt, cur,
1024
+ XML_SCHEMAP_NOROOT,
1025
+ "Include has no href attribute", NULL, NULL);
1026
+ return(cur->next);
1027
+ }
1028
+
1029
+ /* do the URI base composition, load and find the root */
1030
+ base = xmlNodeGetBase(cur->doc, cur);
1031
+ URI = xmlBuildURI(href, base);
1032
+ doc = xmlReadFile((const char *) URI, NULL, SCHEMATRON_PARSE_OPTIONS);
1033
+ if (doc == NULL) {
1034
+ xmlSchematronPErr(ctxt, cur,
1035
+ XML_SCHEMAP_FAILED_LOAD,
1036
+ "could not load include '%s'.\n",
1037
+ URI, NULL);
1038
+ goto done;
1039
+ }
1040
+ ret = xmlDocGetRootElement(doc);
1041
+ if (ret == NULL) {
1042
+ xmlSchematronPErr(ctxt, cur,
1043
+ XML_SCHEMAP_FAILED_LOAD,
1044
+ "could not find root from include '%s'.\n",
1045
+ URI, NULL);
1046
+ goto done;
1047
+ }
1048
+
1049
+ /* Success, push the include for rollback on exit */
1050
+ xmlSchematronPushInclude(ctxt, doc, cur);
1051
+
1052
+ done:
1053
+ if (ret == NULL) {
1054
+ if (doc != NULL)
1055
+ xmlFreeDoc(doc);
1056
+ }
1057
+ xmlFree(href);
1058
+ if (base != NULL)
1059
+ xmlFree(base);
1060
+ if (URI != NULL)
1061
+ xmlFree(URI);
1062
+ return(ret);
1063
+ }
1064
+ #endif
1065
+
1066
+ /**
1067
+ * xmlSchematronParse:
1068
+ * @ctxt: a schema validation context
1069
+ *
1070
+ * parse a schema definition resource and build an internal
1071
+ * XML Schema structure which can be used to validate instances.
1072
+ *
1073
+ * Returns the internal XML Schematron structure built from the resource or
1074
+ * NULL in case of error
1075
+ */
1076
+ xmlSchematronPtr
1077
+ xmlSchematronParse(xmlSchematronParserCtxtPtr ctxt)
1078
+ {
1079
+ xmlSchematronPtr ret = NULL;
1080
+ xmlDocPtr doc;
1081
+ xmlNodePtr root, cur;
1082
+ int preserve = 0;
1083
+
1084
+ if (ctxt == NULL)
1085
+ return (NULL);
1086
+
1087
+ ctxt->nberrors = 0;
1088
+
1089
+ /*
1090
+ * First step is to parse the input document into an DOM/Infoset
1091
+ */
1092
+ if (ctxt->URL != NULL) {
1093
+ doc = xmlReadFile((const char *) ctxt->URL, NULL,
1094
+ SCHEMATRON_PARSE_OPTIONS);
1095
+ if (doc == NULL) {
1096
+ xmlSchematronPErr(ctxt, NULL,
1097
+ XML_SCHEMAP_FAILED_LOAD,
1098
+ "xmlSchematronParse: could not load '%s'.\n",
1099
+ ctxt->URL, NULL);
1100
+ return (NULL);
1101
+ }
1102
+ ctxt->preserve = 0;
1103
+ } else if (ctxt->buffer != NULL) {
1104
+ doc = xmlReadMemory(ctxt->buffer, ctxt->size, NULL, NULL,
1105
+ SCHEMATRON_PARSE_OPTIONS);
1106
+ if (doc == NULL) {
1107
+ xmlSchematronPErr(ctxt, NULL,
1108
+ XML_SCHEMAP_FAILED_PARSE,
1109
+ "xmlSchematronParse: could not parse.\n",
1110
+ NULL, NULL);
1111
+ return (NULL);
1112
+ }
1113
+ doc->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
1114
+ ctxt->URL = xmlDictLookup(ctxt->dict, BAD_CAST "in_memory_buffer", -1);
1115
+ ctxt->preserve = 0;
1116
+ } else if (ctxt->doc != NULL) {
1117
+ doc = ctxt->doc;
1118
+ preserve = 1;
1119
+ ctxt->preserve = 1;
1120
+ } else {
1121
+ xmlSchematronPErr(ctxt, NULL,
1122
+ XML_SCHEMAP_NOTHING_TO_PARSE,
1123
+ "xmlSchematronParse: could not parse.\n",
1124
+ NULL, NULL);
1125
+ return (NULL);
1126
+ }
1127
+
1128
+ /*
1129
+ * Then extract the root and Schematron parse it
1130
+ */
1131
+ root = xmlDocGetRootElement(doc);
1132
+ if (root == NULL) {
1133
+ xmlSchematronPErr(ctxt, (xmlNodePtr) doc,
1134
+ XML_SCHEMAP_NOROOT,
1135
+ "The schema has no document element.\n", NULL, NULL);
1136
+ if (!preserve) {
1137
+ xmlFreeDoc(doc);
1138
+ }
1139
+ return (NULL);
1140
+ }
1141
+
1142
+ if (!IS_SCHEMATRON(root, "schema")) {
1143
+ xmlSchematronPErr(ctxt, root,
1144
+ XML_SCHEMAP_NOROOT,
1145
+ "The XML document '%s' is not a XML schematron document",
1146
+ ctxt->URL, NULL);
1147
+ goto exit;
1148
+ }
1149
+ ret = xmlSchematronNewSchematron(ctxt);
1150
+ if (ret == NULL)
1151
+ goto exit;
1152
+ ctxt->schema = ret;
1153
+
1154
+ /*
1155
+ * scan the schema elements
1156
+ */
1157
+ cur = root->children;
1158
+ NEXT_SCHEMATRON(cur);
1159
+ if (IS_SCHEMATRON(cur, "title")) {
1160
+ xmlChar *title = xmlNodeGetContent(cur);
1161
+ if (title != NULL) {
1162
+ ret->title = xmlDictLookup(ret->dict, title, -1);
1163
+ xmlFree(title);
1164
+ }
1165
+ cur = cur->next;
1166
+ NEXT_SCHEMATRON(cur);
1167
+ }
1168
+ while (IS_SCHEMATRON(cur, "ns")) {
1169
+ xmlChar *prefix = xmlGetNoNsProp(cur, BAD_CAST "prefix");
1170
+ xmlChar *uri = xmlGetNoNsProp(cur, BAD_CAST "uri");
1171
+ if ((uri == NULL) || (uri[0] == 0)) {
1172
+ xmlSchematronPErr(ctxt, cur,
1173
+ XML_SCHEMAP_NOROOT,
1174
+ "ns element has no uri", NULL, NULL);
1175
+ }
1176
+ if ((prefix == NULL) || (prefix[0] == 0)) {
1177
+ xmlSchematronPErr(ctxt, cur,
1178
+ XML_SCHEMAP_NOROOT,
1179
+ "ns element has no prefix", NULL, NULL);
1180
+ }
1181
+ if ((prefix) && (uri)) {
1182
+ xmlXPathRegisterNs(ctxt->xctxt, prefix, uri);
1183
+ xmlSchematronAddNamespace(ctxt, prefix, uri);
1184
+ ret->nbNs++;
1185
+ }
1186
+ if (uri)
1187
+ xmlFree(uri);
1188
+ if (prefix)
1189
+ xmlFree(prefix);
1190
+ cur = cur->next;
1191
+ NEXT_SCHEMATRON(cur);
1192
+ }
1193
+ while (cur != NULL) {
1194
+ if (IS_SCHEMATRON(cur, "pattern")) {
1195
+ xmlSchematronParsePattern(ctxt, cur);
1196
+ ret->nbPattern++;
1197
+ } else {
1198
+ xmlSchematronPErr(ctxt, cur,
1199
+ XML_SCHEMAP_NOROOT,
1200
+ "Expecting a pattern element instead of %s", cur->name, NULL);
1201
+ }
1202
+ cur = cur->next;
1203
+ NEXT_SCHEMATRON(cur);
1204
+ }
1205
+ if (ret->nbPattern == 0) {
1206
+ xmlSchematronPErr(ctxt, root,
1207
+ XML_SCHEMAP_NOROOT,
1208
+ "The schematron document '%s' has no pattern",
1209
+ ctxt->URL, NULL);
1210
+ goto exit;
1211
+ }
1212
+ /* the original document must be kept for reporting */
1213
+ ret->doc = doc;
1214
+ if (preserve) {
1215
+ ret->preserve = 1;
1216
+ }
1217
+ preserve = 1;
1218
+
1219
+ exit:
1220
+ if (!preserve) {
1221
+ xmlFreeDoc(doc);
1222
+ }
1223
+ if (ret != NULL) {
1224
+ if (ctxt->nberrors != 0) {
1225
+ xmlSchematronFree(ret);
1226
+ ret = NULL;
1227
+ } else {
1228
+ ret->namespaces = ctxt->namespaces;
1229
+ ret->nbNamespaces = ctxt->nbNamespaces;
1230
+ ctxt->namespaces = NULL;
1231
+ }
1232
+ }
1233
+ return (ret);
1234
+ }
1235
+
1236
+ /************************************************************************
1237
+ * *
1238
+ * Schematrontron Reports handler *
1239
+ * *
1240
+ ************************************************************************/
1241
+
1242
+ static xmlNodePtr
1243
+ xmlSchematronGetNode(xmlSchematronValidCtxtPtr ctxt,
1244
+ xmlNodePtr cur, const xmlChar *xpath) {
1245
+ xmlNodePtr node = NULL;
1246
+ xmlXPathObjectPtr ret;
1247
+
1248
+ if ((ctxt == NULL) || (cur == NULL) || (xpath == NULL))
1249
+ return(NULL);
1250
+
1251
+ ctxt->xctxt->doc = cur->doc;
1252
+ ctxt->xctxt->node = cur;
1253
+ ret = xmlXPathEval(xpath, ctxt->xctxt);
1254
+ if (ret == NULL)
1255
+ return(NULL);
1256
+
1257
+ if ((ret->type == XPATH_NODESET) &&
1258
+ (ret->nodesetval != NULL) && (ret->nodesetval->nodeNr > 0))
1259
+ node = ret->nodesetval->nodeTab[0];
1260
+
1261
+ xmlXPathFreeObject(ret);
1262
+ return(node);
1263
+ }
1264
+
1265
+ /**
1266
+ * xmlSchematronReportOutput:
1267
+ * @ctxt: the validation context
1268
+ * @cur: the current node tested
1269
+ * @msg: the message output
1270
+ *
1271
+ * Output part of the report to whatever channel the user selected
1272
+ */
1273
+ static void
1274
+ xmlSchematronReportOutput(xmlSchematronValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
1275
+ xmlNodePtr cur ATTRIBUTE_UNUSED,
1276
+ const char *msg) {
1277
+ /* TODO */
1278
+ fprintf(stderr, "%s", msg);
1279
+ }
1280
+
1281
+ /**
1282
+ * xmlSchematronFormatReport:
1283
+ * @ctxt: the validation context
1284
+ * @test: the test node
1285
+ * @cur: the current node tested
1286
+ *
1287
+ * Build the string being reported to the user.
1288
+ *
1289
+ * Returns a report string or NULL in case of error. The string needs
1290
+ * to be deallocated by the caller
1291
+ */
1292
+ static xmlChar *
1293
+ xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt,
1294
+ xmlNodePtr test, xmlNodePtr cur) {
1295
+ xmlChar *ret = NULL;
1296
+ xmlNodePtr child, node;
1297
+
1298
+ if ((test == NULL) || (cur == NULL))
1299
+ return(ret);
1300
+
1301
+ child = test->children;
1302
+ while (child != NULL) {
1303
+ if ((child->type == XML_TEXT_NODE) ||
1304
+ (child->type == XML_CDATA_SECTION_NODE))
1305
+ ret = xmlStrcat(ret, child->content);
1306
+ else if (IS_SCHEMATRON(child, "name")) {
1307
+ xmlChar *path;
1308
+
1309
+ path = xmlGetNoNsProp(child, BAD_CAST "path");
1310
+
1311
+ node = cur;
1312
+ if (path != NULL) {
1313
+ node = xmlSchematronGetNode(ctxt, cur, path);
1314
+ if (node == NULL)
1315
+ node = cur;
1316
+ xmlFree(path);
1317
+ }
1318
+
1319
+ if ((node->ns == NULL) || (node->ns->prefix == NULL))
1320
+ ret = xmlStrcat(ret, node->name);
1321
+ else {
1322
+ ret = xmlStrcat(ret, node->ns->prefix);
1323
+ ret = xmlStrcat(ret, BAD_CAST ":");
1324
+ ret = xmlStrcat(ret, node->name);
1325
+ }
1326
+ } else {
1327
+ child = child->next;
1328
+ continue;
1329
+ }
1330
+
1331
+ /*
1332
+ * remove superfluous \n
1333
+ */
1334
+ if (ret != NULL) {
1335
+ int len = xmlStrlen(ret);
1336
+ xmlChar c;
1337
+
1338
+ if (len > 0) {
1339
+ c = ret[len - 1];
1340
+ if ((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t')) {
1341
+ while ((c == ' ') || (c == '\n') ||
1342
+ (c == '\r') || (c == '\t')) {
1343
+ len--;
1344
+ if (len == 0)
1345
+ break;
1346
+ c = ret[len - 1];
1347
+ }
1348
+ ret[len] = ' ';
1349
+ ret[len + 1] = 0;
1350
+ }
1351
+ }
1352
+ }
1353
+
1354
+ child = child->next;
1355
+ }
1356
+ return(ret);
1357
+ }
1358
+
1359
+ /**
1360
+ * xmlSchematronReportSuccess:
1361
+ * @ctxt: the validation context
1362
+ * @test: the compiled test
1363
+ * @cur: the current node tested
1364
+ * @success: boolean value for the result
1365
+ *
1366
+ * called from the validation engine when an assert or report test have
1367
+ * been done.
1368
+ */
1369
+ static void
1370
+ xmlSchematronReportSuccess(xmlSchematronValidCtxtPtr ctxt,
1371
+ xmlSchematronTestPtr test, xmlNodePtr cur, xmlSchematronPatternPtr pattern, int success) {
1372
+ if ((ctxt == NULL) || (cur == NULL) || (test == NULL))
1373
+ return;
1374
+ /* if quiet and not SVRL report only failures */
1375
+ if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) &&
1376
+ ((ctxt->flags & XML_SCHEMATRON_OUT_XML) == 0) &&
1377
+ (test->type == XML_SCHEMATRON_REPORT))
1378
+ return;
1379
+ if (ctxt->flags & XML_SCHEMATRON_OUT_XML) {
1380
+ TODO
1381
+ } else {
1382
+ xmlChar *path;
1383
+ char msg[1000];
1384
+ long line;
1385
+ const xmlChar *report = NULL;
1386
+
1387
+ if (((test->type == XML_SCHEMATRON_REPORT) & (!success)) ||
1388
+ ((test->type == XML_SCHEMATRON_ASSERT) & (success)))
1389
+ return;
1390
+ line = xmlGetLineNo(cur);
1391
+ path = xmlGetNodePath(cur);
1392
+ if (path == NULL)
1393
+ path = (xmlChar *) cur->name;
1394
+ #if 0
1395
+ if ((test->report != NULL) && (test->report[0] != 0))
1396
+ report = test->report;
1397
+ #endif
1398
+ if (test->node != NULL)
1399
+ report = xmlSchematronFormatReport(ctxt, test->node, cur);
1400
+ if (report == NULL) {
1401
+ if (test->type == XML_SCHEMATRON_ASSERT) {
1402
+ report = xmlStrdup((const xmlChar *) "node failed assert");
1403
+ } else {
1404
+ report = xmlStrdup((const xmlChar *) "node failed report");
1405
+ }
1406
+ }
1407
+ snprintf(msg, 999, "%s line %ld: %s\n", (const char *) path,
1408
+ line, (const char *) report);
1409
+
1410
+ if (ctxt->flags & XML_SCHEMATRON_OUT_ERROR) {
1411
+ xmlStructuredErrorFunc schannel = NULL;
1412
+ xmlGenericErrorFunc channel = NULL;
1413
+ void *data = NULL;
1414
+
1415
+ if (ctxt != NULL) {
1416
+ if (ctxt->serror != NULL)
1417
+ schannel = ctxt->serror;
1418
+ else
1419
+ channel = ctxt->error;
1420
+ data = ctxt->userData;
1421
+ }
1422
+
1423
+ __xmlRaiseError(schannel, channel, data,
1424
+ NULL, cur, XML_FROM_SCHEMATRONV,
1425
+ (test->type == XML_SCHEMATRON_ASSERT)?XML_SCHEMATRONV_ASSERT:XML_SCHEMATRONV_REPORT,
1426
+ XML_ERR_ERROR, NULL, line,
1427
+ (pattern == NULL)?NULL:((const char *) pattern->name),
1428
+ (const char *) path,
1429
+ (const char *) report, 0, 0,
1430
+ "%s", msg);
1431
+ } else {
1432
+ xmlSchematronReportOutput(ctxt, cur, &msg[0]);
1433
+ }
1434
+
1435
+ xmlFree((char *) report);
1436
+
1437
+ if ((path != NULL) && (path != (xmlChar *) cur->name))
1438
+ xmlFree(path);
1439
+ }
1440
+ }
1441
+
1442
+ /**
1443
+ * xmlSchematronReportPattern:
1444
+ * @ctxt: the validation context
1445
+ * @pattern: the current pattern
1446
+ *
1447
+ * called from the validation engine when starting to check a pattern
1448
+ */
1449
+ static void
1450
+ xmlSchematronReportPattern(xmlSchematronValidCtxtPtr ctxt,
1451
+ xmlSchematronPatternPtr pattern) {
1452
+ if ((ctxt == NULL) || (pattern == NULL))
1453
+ return;
1454
+ if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) || (ctxt->flags & XML_SCHEMATRON_OUT_ERROR)) /* Error gives pattern name as part of error */
1455
+ return;
1456
+ if (ctxt->flags & XML_SCHEMATRON_OUT_XML) {
1457
+ TODO
1458
+ } else {
1459
+ char msg[1000];
1460
+
1461
+ if (pattern->name == NULL)
1462
+ return;
1463
+ snprintf(msg, 999, "Pattern: %s\n", (const char *) pattern->name);
1464
+ xmlSchematronReportOutput(ctxt, NULL, &msg[0]);
1465
+ }
1466
+ }
1467
+
1468
+
1469
+ /************************************************************************
1470
+ * *
1471
+ * Validation against a Schematrontron *
1472
+ * *
1473
+ ************************************************************************/
1474
+
1475
+ /**
1476
+ * xmlSchematronSetValidStructuredErrors:
1477
+ * @ctxt: a Schematron validation context
1478
+ * @serror: the structured error function
1479
+ * @ctx: the functions context
1480
+ *
1481
+ * Set the structured error callback
1482
+ */
1483
+ void
1484
+ xmlSchematronSetValidStructuredErrors(xmlSchematronValidCtxtPtr ctxt,
1485
+ xmlStructuredErrorFunc serror, void *ctx)
1486
+ {
1487
+ if (ctxt == NULL)
1488
+ return;
1489
+ ctxt->serror = serror;
1490
+ ctxt->error = NULL;
1491
+ ctxt->warning = NULL;
1492
+ ctxt->userData = ctx;
1493
+ }
1494
+
1495
+ /**
1496
+ * xmlSchematronNewValidCtxt:
1497
+ * @schema: a precompiled XML Schematrons
1498
+ * @options: a set of xmlSchematronValidOptions
1499
+ *
1500
+ * Create an XML Schematrons validation context based on the given schema.
1501
+ *
1502
+ * Returns the validation context or NULL in case of error
1503
+ */
1504
+ xmlSchematronValidCtxtPtr
1505
+ xmlSchematronNewValidCtxt(xmlSchematronPtr schema, int options)
1506
+ {
1507
+ int i;
1508
+ xmlSchematronValidCtxtPtr ret;
1509
+
1510
+ ret = (xmlSchematronValidCtxtPtr) xmlMalloc(sizeof(xmlSchematronValidCtxt));
1511
+ if (ret == NULL) {
1512
+ xmlSchematronVErrMemory(NULL, "allocating validation context",
1513
+ NULL);
1514
+ return (NULL);
1515
+ }
1516
+ memset(ret, 0, sizeof(xmlSchematronValidCtxt));
1517
+ ret->type = XML_STRON_CTXT_VALIDATOR;
1518
+ ret->schema = schema;
1519
+ ret->xctxt = xmlXPathNewContext(NULL);
1520
+ ret->flags = options;
1521
+ if (ret->xctxt == NULL) {
1522
+ xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
1523
+ NULL);
1524
+ xmlSchematronFreeValidCtxt(ret);
1525
+ return (NULL);
1526
+ }
1527
+ for (i = 0;i < schema->nbNamespaces;i++) {
1528
+ if ((schema->namespaces[2 * i] == NULL) ||
1529
+ (schema->namespaces[2 * i + 1] == NULL))
1530
+ break;
1531
+ xmlXPathRegisterNs(ret->xctxt, schema->namespaces[2 * i + 1],
1532
+ schema->namespaces[2 * i]);
1533
+ }
1534
+ return (ret);
1535
+ }
1536
+
1537
+ /**
1538
+ * xmlSchematronFreeValidCtxt:
1539
+ * @ctxt: the schema validation context
1540
+ *
1541
+ * Free the resources associated to the schema validation context
1542
+ */
1543
+ void
1544
+ xmlSchematronFreeValidCtxt(xmlSchematronValidCtxtPtr ctxt)
1545
+ {
1546
+ if (ctxt == NULL)
1547
+ return;
1548
+ if (ctxt->xctxt != NULL)
1549
+ xmlXPathFreeContext(ctxt->xctxt);
1550
+ if (ctxt->dict != NULL)
1551
+ xmlDictFree(ctxt->dict);
1552
+ xmlFree(ctxt);
1553
+ }
1554
+
1555
+ static xmlNodePtr
1556
+ xmlSchematronNextNode(xmlNodePtr cur) {
1557
+ if (cur->children != NULL) {
1558
+ /*
1559
+ * Do not descend on entities declarations
1560
+ */
1561
+ if (cur->children->type != XML_ENTITY_DECL) {
1562
+ cur = cur->children;
1563
+ /*
1564
+ * Skip DTDs
1565
+ */
1566
+ if (cur->type != XML_DTD_NODE)
1567
+ return(cur);
1568
+ }
1569
+ }
1570
+
1571
+ while (cur->next != NULL) {
1572
+ cur = cur->next;
1573
+ if ((cur->type != XML_ENTITY_DECL) &&
1574
+ (cur->type != XML_DTD_NODE))
1575
+ return(cur);
1576
+ }
1577
+
1578
+ do {
1579
+ cur = cur->parent;
1580
+ if (cur == NULL) break;
1581
+ if (cur->type == XML_DOCUMENT_NODE) return(NULL);
1582
+ if (cur->next != NULL) {
1583
+ cur = cur->next;
1584
+ return(cur);
1585
+ }
1586
+ } while (cur != NULL);
1587
+ return(cur);
1588
+ }
1589
+
1590
+ /**
1591
+ * xmlSchematronRunTest:
1592
+ * @ctxt: the schema validation context
1593
+ * @test: the current test
1594
+ * @instance: the document instance tree
1595
+ * @cur: the current node in the instance
1596
+ *
1597
+ * Validate a rule against a tree instance at a given position
1598
+ *
1599
+ * Returns 1 in case of success, 0 if error and -1 in case of internal error
1600
+ */
1601
+ static int
1602
+ xmlSchematronRunTest(xmlSchematronValidCtxtPtr ctxt,
1603
+ xmlSchematronTestPtr test, xmlDocPtr instance, xmlNodePtr cur, xmlSchematronPatternPtr pattern)
1604
+ {
1605
+ xmlXPathObjectPtr ret;
1606
+ int failed;
1607
+
1608
+ failed = 0;
1609
+ ctxt->xctxt->doc = instance;
1610
+ ctxt->xctxt->node = cur;
1611
+ ret = xmlXPathCompiledEval(test->comp, ctxt->xctxt);
1612
+ if (ret == NULL) {
1613
+ failed = 1;
1614
+ } else {
1615
+ switch (ret->type) {
1616
+ case XPATH_XSLT_TREE:
1617
+ case XPATH_NODESET:
1618
+ if ((ret->nodesetval == NULL) ||
1619
+ (ret->nodesetval->nodeNr == 0))
1620
+ failed = 1;
1621
+ break;
1622
+ case XPATH_BOOLEAN:
1623
+ failed = !ret->boolval;
1624
+ break;
1625
+ case XPATH_NUMBER:
1626
+ if ((xmlXPathIsNaN(ret->floatval)) ||
1627
+ (ret->floatval == 0.0))
1628
+ failed = 1;
1629
+ break;
1630
+ case XPATH_STRING:
1631
+ if ((ret->stringval == NULL) ||
1632
+ (ret->stringval[0] == 0))
1633
+ failed = 1;
1634
+ break;
1635
+ case XPATH_UNDEFINED:
1636
+ case XPATH_POINT:
1637
+ case XPATH_RANGE:
1638
+ case XPATH_LOCATIONSET:
1639
+ case XPATH_USERS:
1640
+ failed = 1;
1641
+ break;
1642
+ }
1643
+ xmlXPathFreeObject(ret);
1644
+ }
1645
+ if ((failed) && (test->type == XML_SCHEMATRON_ASSERT))
1646
+ ctxt->nberrors++;
1647
+ else if ((!failed) && (test->type == XML_SCHEMATRON_REPORT))
1648
+ ctxt->nberrors++;
1649
+
1650
+ xmlSchematronReportSuccess(ctxt, test, cur, pattern, !failed);
1651
+
1652
+ return(!failed);
1653
+ }
1654
+
1655
+ /**
1656
+ * xmlSchematronValidateDoc:
1657
+ * @ctxt: the schema validation context
1658
+ * @instance: the document instance tree
1659
+ *
1660
+ * Validate a tree instance against the schematron
1661
+ *
1662
+ * Returns 0 in case of success, -1 in case of internal error
1663
+ * and an error count otherwise.
1664
+ */
1665
+ int
1666
+ xmlSchematronValidateDoc(xmlSchematronValidCtxtPtr ctxt, xmlDocPtr instance)
1667
+ {
1668
+ xmlNodePtr cur, root;
1669
+ xmlSchematronPatternPtr pattern;
1670
+ xmlSchematronRulePtr rule;
1671
+ xmlSchematronTestPtr test;
1672
+
1673
+ if ((ctxt == NULL) || (ctxt->schema == NULL) ||
1674
+ (ctxt->schema->rules == NULL) || (instance == NULL))
1675
+ return(-1);
1676
+ ctxt->nberrors = 0;
1677
+ root = xmlDocGetRootElement(instance);
1678
+ if (root == NULL) {
1679
+ TODO
1680
+ ctxt->nberrors++;
1681
+ return(1);
1682
+ }
1683
+ if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) ||
1684
+ (ctxt->flags == 0)) {
1685
+ /*
1686
+ * we are just trying to assert the validity of the document,
1687
+ * speed primes over the output, run in a single pass
1688
+ */
1689
+ cur = root;
1690
+ while (cur != NULL) {
1691
+ rule = ctxt->schema->rules;
1692
+ while (rule != NULL) {
1693
+ if (xmlPatternMatch(rule->pattern, cur) == 1) {
1694
+ test = rule->tests;
1695
+ while (test != NULL) {
1696
+ xmlSchematronRunTest(ctxt, test, instance, cur, (xmlSchematronPatternPtr)rule->pattern);
1697
+ test = test->next;
1698
+ }
1699
+ }
1700
+ rule = rule->next;
1701
+ }
1702
+
1703
+ cur = xmlSchematronNextNode(cur);
1704
+ }
1705
+ } else {
1706
+ /*
1707
+ * Process all contexts one at a time
1708
+ */
1709
+ pattern = ctxt->schema->patterns;
1710
+
1711
+ while (pattern != NULL) {
1712
+ xmlSchematronReportPattern(ctxt, pattern);
1713
+
1714
+ /*
1715
+ * TODO convert the pattern rule to a direct XPath and
1716
+ * compute directly instead of using the pattern matching
1717
+ * over the full document...
1718
+ * Check the exact semantic
1719
+ */
1720
+ cur = root;
1721
+ while (cur != NULL) {
1722
+ rule = pattern->rules;
1723
+ while (rule != NULL) {
1724
+ if (xmlPatternMatch(rule->pattern, cur) == 1) {
1725
+ test = rule->tests;
1726
+ while (test != NULL) {
1727
+ xmlSchematronRunTest(ctxt, test, instance, cur, pattern);
1728
+ test = test->next;
1729
+ }
1730
+ }
1731
+ rule = rule->patnext;
1732
+ }
1733
+
1734
+ cur = xmlSchematronNextNode(cur);
1735
+ }
1736
+ pattern = pattern->next;
1737
+ }
1738
+ }
1739
+ return(ctxt->nberrors);
1740
+ }
1741
+
1742
+ #ifdef STANDALONE
1743
+ int
1744
+ main(void)
1745
+ {
1746
+ int ret;
1747
+ xmlDocPtr instance;
1748
+ xmlSchematronParserCtxtPtr pctxt;
1749
+ xmlSchematronValidCtxtPtr vctxt;
1750
+ xmlSchematronPtr schema = NULL;
1751
+
1752
+ pctxt = xmlSchematronNewParserCtxt("tst.sct");
1753
+ if (pctxt == NULL) {
1754
+ fprintf(stderr, "failed to build schematron parser\n");
1755
+ } else {
1756
+ schema = xmlSchematronParse(pctxt);
1757
+ if (schema == NULL) {
1758
+ fprintf(stderr, "failed to compile schematron\n");
1759
+ }
1760
+ xmlSchematronFreeParserCtxt(pctxt);
1761
+ }
1762
+ instance = xmlReadFile("tst.sct", NULL,
1763
+ XML_PARSE_NOENT | XML_PARSE_NOCDATA);
1764
+ if (instance == NULL) {
1765
+ fprintf(stderr, "failed to parse instance\n");
1766
+ }
1767
+ if ((schema != NULL) && (instance != NULL)) {
1768
+ vctxt = xmlSchematronNewValidCtxt(schema);
1769
+ if (vctxt == NULL) {
1770
+ fprintf(stderr, "failed to build schematron validator\n");
1771
+ } else {
1772
+ ret = xmlSchematronValidateDoc(vctxt, instance);
1773
+ xmlSchematronFreeValidCtxt(vctxt);
1774
+ }
1775
+ }
1776
+ xmlSchematronFree(schema);
1777
+ xmlFreeDoc(instance);
1778
+
1779
+ xmlCleanupParser();
1780
+ xmlMemoryDump();
1781
+
1782
+ return (0);
1783
+ }
1784
+ #endif
1785
+ #define bottom_schematron
1786
+ #include "elfgcchack.h"
1787
+ #endif /* LIBXML_SCHEMATRON_ENABLED */