#define NEXT_SCHEMATRON(node) \
while (node != NULL) { \
- if ((node->type == XML_ELEMENT_NODE ) && (node->ns != NULL) && \
+ if ((node->type == XML_ELEMENT_NODE ) && (node->ns != NULL) && \
((xmlStrEqual(node->ns->href, xmlSchematronNs)) || \
(xmlStrEqual(node->ns->href, xmlOldSchematronNs)))) \
break; \
*
* macro to flag unimplemented blocks
*/
-#define TODO \
+#define TODO \
xmlGenericError(xmlGenericErrorContext, \
"Unimplemented block at %s:%d\n", \
__FILE__, __LINE__);
FILE *outputFile; /* if using XML_SCHEMATRON_OUT_FILE */
xmlBufferPtr outputBuffer; /* if using XML_SCHEMATRON_OUT_BUFFER */
+#ifdef LIBXML_OUTPUT_ENABLED
xmlOutputWriteCallback iowrite; /* if using XML_SCHEMATRON_OUT_IO */
xmlOutputCloseCallback ioclose;
+#endif
void *ioctx;
+
+ /* error reporting data */
+ void *userData; /* user specific data block */
+ xmlSchematronValidityErrorFunc error;/* the callback in case of errors */
+ xmlSchematronValidityWarningFunc warning;/* callback in case of warning */
+ xmlStructuredErrorFunc serror; /* the structured function */
};
struct _xmlSchematronParserCtxt {
int maxIncludes; /* size of the array */
xmlNodePtr *includes; /* the array of includes */
- /* error rreporting data */
+ /* error reporting data */
void *userData; /* user specific data block */
xmlSchematronValidityErrorFunc error;/* the callback in case of errors */
xmlSchematronValidityWarningFunc warning;/* callback in case of warning */
xmlStructuredErrorFunc serror; /* the structured function */
-
};
#define XML_STRON_CTXT_PARSER 1
* @msg: the error message
* @str1: extra data
* @str2: extra data
- *
+ *
* Handle a parser error
*/
static void
if (schema->namespaces != NULL)
xmlFree((char **) schema->namespaces);
-
+
xmlSchematronFreeRules(schema->rules);
xmlSchematronFreePatterns(schema->patterns);
xmlDictFree(schema->dict);
xmlFree(ctxt);
}
+#if 0
/**
* xmlSchematronPushInclude:
* @ctxt: the schema parser context
return(xmlSchematronPopInclude(ctxt));
return(ret);
}
+#endif
/**
* xmlSchematronAddNamespace:
ctxt->namespaces = tmp;
ctxt->maxNamespaces *= 2;
}
- ctxt->namespaces[2 * ctxt->nbNamespaces] =
+ ctxt->namespaces[2 * ctxt->nbNamespaces] =
xmlDictLookup(ctxt->dict, ns, -1);
- ctxt->namespaces[2 * ctxt->nbNamespaces + 1] =
+ ctxt->namespaces[2 * ctxt->nbNamespaces + 1] =
xmlDictLookup(ctxt->dict, prefix, -1);
ctxt->nbNamespaces++;
ctxt->namespaces[2 * ctxt->nbNamespaces] = NULL;
}
}
+#if 0
/**
* xmlSchematronLoadInclude:
* @ctxt: a schema validation context
xmlFree(URI);
return(ret);
}
+#endif
/**
* xmlSchematronParse:
}
/* the original document must be kept for reporting */
ret->doc = doc;
+ if (preserve) {
+ ret->preserve = 1;
+ }
preserve = 1;
exit:
* to be deallocated by teh caller
*/
static xmlChar *
-xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt,
+xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt,
xmlNodePtr test, xmlNodePtr cur) {
xmlChar *ret = NULL;
xmlNodePtr child, node;
xmlFree(path);
}
- if ((node->ns == NULL) || (node->ns->prefix == NULL))
+ if ((node->ns == NULL) || (node->ns->prefix == NULL))
ret = xmlStrcat(ret, node->name);
else {
ret = xmlStrcat(ret, node->ns->prefix);
* been done.
*/
static void
-xmlSchematronReportSuccess(xmlSchematronValidCtxtPtr ctxt,
- xmlSchematronTestPtr test, xmlNodePtr cur, int success) {
+xmlSchematronReportSuccess(xmlSchematronValidCtxtPtr ctxt,
+ xmlSchematronTestPtr test, xmlNodePtr cur, xmlSchematronPatternPtr pattern, int success) {
if ((ctxt == NULL) || (cur == NULL) || (test == NULL))
return;
/* if quiet and not SVRL report only failures */
report = xmlSchematronFormatReport(ctxt, test->node, cur);
if (report == NULL) {
if (test->type == XML_SCHEMATRON_ASSERT) {
- snprintf(msg, 999, "%s line %ld: node failed assert\n",
- (const char *) path, line);
+ report = xmlStrdup((const xmlChar *) "node failed assert");
} else {
- snprintf(msg, 999, "%s line %ld: node failed report\n",
- (const char *) path, line);
+ report = xmlStrdup((const xmlChar *) "node failed report");
+ }
}
- } else {
snprintf(msg, 999, "%s line %ld: %s\n", (const char *) path,
line, (const char *) report);
- xmlFree((char *) report);
+
+ if (ctxt->flags & XML_SCHEMATRON_OUT_ERROR) {
+ xmlStructuredErrorFunc schannel = NULL;
+ xmlGenericErrorFunc channel = NULL;
+ void *data = NULL;
+
+ if (ctxt != NULL) {
+ if (ctxt->serror != NULL)
+ schannel = ctxt->serror;
+ else
+ channel = ctxt->error;
+ data = ctxt->userData;
}
+
+ __xmlRaiseError(schannel, channel, data,
+ NULL, cur, XML_FROM_SCHEMATRONV,
+ (test->type == XML_SCHEMATRON_ASSERT)?XML_SCHEMATRONV_ASSERT:XML_SCHEMATRONV_REPORT,
+ XML_ERR_ERROR, NULL, line,
+ (pattern == NULL)?NULL:((const char *) pattern->name),
+ (const char *) path,
+ (const char *) report, 0, 0,
+ "%s", msg);
+ } else {
xmlSchematronReportOutput(ctxt, cur, &msg[0]);
+ }
+
+ xmlFree((char *) report);
+
if ((path != NULL) && (path != (xmlChar *) cur->name))
xmlFree(path);
}
* called from the validation engine when starting to check a pattern
*/
static void
-xmlSchematronReportPattern(xmlSchematronValidCtxtPtr ctxt,
+xmlSchematronReportPattern(xmlSchematronValidCtxtPtr ctxt,
xmlSchematronPatternPtr pattern) {
if ((ctxt == NULL) || (pattern == NULL))
return;
- if (ctxt->flags & XML_SCHEMATRON_OUT_QUIET)
+ if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) || (ctxt->flags & XML_SCHEMATRON_OUT_ERROR)) /* Error gives pattern name as part of error */
return;
if (ctxt->flags & XML_SCHEMATRON_OUT_XML) {
TODO
************************************************************************/
/**
+ * xmlSchematronSetValidStructuredErrors:
+ * @ctxt: a Schematron validation context
+ * @serror: the structured error function
+ * @ctx: the functions context
+ *
+ * Set the structured error callback
+ */
+void
+xmlSchematronSetValidStructuredErrors(xmlSchematronValidCtxtPtr ctxt,
+ xmlStructuredErrorFunc serror, void *ctx)
+{
+ if (ctxt == NULL)
+ return;
+ ctxt->serror = serror;
+ ctxt->error = NULL;
+ ctxt->warning = NULL;
+ ctxt->userData = ctx;
+}
+
+/**
* xmlSchematronNewValidCtxt:
* @schema: a precompiled XML Schematrons
* @options: a set of xmlSchematronValidOptions
(cur->type != XML_DTD_NODE))
return(cur);
}
-
+
do {
cur = cur->parent;
if (cur == NULL) break;
* xmlSchematronRunTest:
* @ctxt: the schema validation context
* @test: the current test
- * @instance: the document instace tree
+ * @instance: the document instace tree
* @cur: the current node in the instance
*
* Validate a rule against a tree instance at a given position
*/
static int
xmlSchematronRunTest(xmlSchematronValidCtxtPtr ctxt,
- xmlSchematronTestPtr test, xmlDocPtr instance, xmlNodePtr cur)
+ xmlSchematronTestPtr test, xmlDocPtr instance, xmlNodePtr cur, xmlSchematronPatternPtr pattern)
{
xmlXPathObjectPtr ret;
int failed;
else if ((!failed) && (test->type == XML_SCHEMATRON_REPORT))
ctxt->nberrors++;
- xmlSchematronReportSuccess(ctxt, test, cur, !failed);
+ xmlSchematronReportSuccess(ctxt, test, cur, pattern, !failed);
return(!failed);
}
/**
* xmlSchematronValidateDoc:
* @ctxt: the schema validation context
- * @instance: the document instace tree
+ * @instance: the document instace tree
*
* Validate a tree instance against the schematron
*
if (xmlPatternMatch(rule->pattern, cur) == 1) {
test = rule->tests;
while (test != NULL) {
- xmlSchematronRunTest(ctxt, test, instance, cur);
+ xmlSchematronRunTest(ctxt, test, instance, cur, (xmlSchematronPatternPtr)rule->pattern);
test = test->next;
}
}
rule = rule->next;
}
-
+
cur = xmlSchematronNextNode(cur);
}
} else {
* Process all contexts one at a time
*/
pattern = ctxt->schema->patterns;
-
+
while (pattern != NULL) {
xmlSchematronReportPattern(ctxt, pattern);
/*
* TODO convert the pattern rule to a direct XPath and
* compute directly instead of using the pattern matching
- * over the full document...
+ * over the full document...
* Check the exact semantic
*/
cur = root;
if (xmlPatternMatch(rule->pattern, cur) == 1) {
test = rule->tests;
while (test != NULL) {
- xmlSchematronRunTest(ctxt, test, instance, cur);
+ xmlSchematronRunTest(ctxt, test, instance, cur, pattern);
test = test->next;
}
}
rule = rule->patnext;
}
-
+
cur = xmlSchematronNextNode(cur);
}
pattern = pattern->next;