diff --git a/ChangeLog b/ChangeLog index e74824ac..66aab6bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Fri Mar 14 13:44:29 CET 2008 Daniel Veillard + + * include/libxml/schematron.h include/libxml/xmlerror.h schematron.c: + applied patch from Tobias Minich to allow plugin schematron error + reporting in the normal error system, should fix #513998 + Fri Mar 14 11:52:09 CET 2008 Daniel Veillard * parser.c xinclude.c: patch from Vasily Chekalkin fixes memory diff --git a/include/libxml/schematron.h b/include/libxml/schematron.h index 6eaa699a..9e36c0e8 100644 --- a/include/libxml/schematron.h +++ b/include/libxml/schematron.h @@ -25,6 +25,7 @@ typedef enum { XML_SCHEMATRON_OUT_QUIET = 1 << 0, /* quiet no report */ XML_SCHEMATRON_OUT_TEXT = 1 << 1, /* build a textual report */ XML_SCHEMATRON_OUT_XML = 1 << 2, /* output SVRL */ + XML_SCHEMATRON_OUT_ERROR = 1 << 3, /* output via xmlStructuredErrorFunc */ XML_SCHEMATRON_OUT_FILE = 1 << 8, /* output to a file descriptor */ XML_SCHEMATRON_OUT_BUFFER = 1 << 9, /* output to a buffer */ XML_SCHEMATRON_OUT_IO = 1 << 10 /* output to I/O mechanism */ @@ -81,12 +82,12 @@ XMLPUBFUN void XMLCALL /* * Interfaces for validating */ -/****** XMLPUBFUN void XMLCALL xmlSchematronSetValidStructuredErrors( xmlSchematronValidCtxtPtr ctxt, xmlStructuredErrorFunc serror, void *ctx); +/****** XMLPUBFUN void XMLCALL xmlSchematronSetValidErrors (xmlSchematronValidCtxtPtr ctxt, xmlSchematronValidityErrorFunc err, diff --git a/include/libxml/xmlerror.h b/include/libxml/xmlerror.h index 36d2b02a..8cbab5ec 100644 --- a/include/libxml/xmlerror.h +++ b/include/libxml/xmlerror.h @@ -61,7 +61,8 @@ typedef enum { XML_FROM_CHECK, /* The error checking module */ XML_FROM_WRITER, /* The xmlwriter module */ XML_FROM_MODULE, /* The dynamically loaded module module*/ - XML_FROM_I18N /* The module handling character conversion */ + XML_FROM_I18N, /* The module handling character conversion */ + XML_FROM_SCHEMATRONV /* The Schematron validator module */ } xmlErrorDomain; /** @@ -774,6 +775,8 @@ typedef enum { XML_SCHEMAP_AU_PROPS_CORRECT, /* 3088 */ XML_SCHEMAP_A_PROPS_CORRECT_3, /* 3089 */ XML_SCHEMAP_COS_ALL_LIMITED, /* 3090 */ + XML_SCHEMATRONV_ASSERT = 4000, /* 4000 */ + XML_SCHEMATRONV_REPORT, XML_MODULE_OPEN = 4900, /* 4900 */ XML_MODULE_CLOSE, /* 4901 */ XML_CHECK_FOUND_ELEMENT = 5000, diff --git a/schematron.c b/schematron.c index 146ffc9a..81f47044 100644 --- a/schematron.c +++ b/schematron.c @@ -168,6 +168,12 @@ struct _xmlSchematronValidCtxt { xmlOutputWriteCallback iowrite; /* if using XML_SCHEMATRON_OUT_IO */ xmlOutputCloseCallback ioclose; 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 { @@ -193,12 +199,11 @@ 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 @@ -1361,7 +1366,7 @@ xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt, */ static void xmlSchematronReportSuccess(xmlSchematronValidCtxtPtr ctxt, - xmlSchematronTestPtr test, xmlNodePtr cur, int success) { + xmlSchematronTestPtr test, xmlNodePtr cur, xmlSchematronPatternPtr pattern, int success) { if ((ctxt == NULL) || (cur == NULL) || (test == NULL)) return; /* if quiet and not SVRL report only failures */ @@ -1392,18 +1397,41 @@ xmlSchematronReportSuccess(xmlSchematronValidCtxtPtr ctxt, 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, + msg); + } else { xmlSchematronReportOutput(ctxt, cur, &msg[0]); + } + + xmlFree((char *) report); + if ((path != NULL) && (path != (xmlChar *) cur->name)) xmlFree(path); } @@ -1421,7 +1449,7 @@ 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 @@ -1442,6 +1470,26 @@ xmlSchematronReportPattern(xmlSchematronValidCtxtPtr ctxt, * * ************************************************************************/ +/** + * 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 @@ -1550,7 +1598,7 @@ xmlSchematronNextNode(xmlNodePtr cur) { */ static int xmlSchematronRunTest(xmlSchematronValidCtxtPtr ctxt, - xmlSchematronTestPtr test, xmlDocPtr instance, xmlNodePtr cur) + xmlSchematronTestPtr test, xmlDocPtr instance, xmlNodePtr cur, xmlSchematronPatternPtr pattern) { xmlXPathObjectPtr ret; int failed; @@ -1597,7 +1645,7 @@ xmlSchematronRunTest(xmlSchematronValidCtxtPtr ctxt, else if ((!failed) && (test->type == XML_SCHEMATRON_REPORT)) ctxt->nberrors++; - xmlSchematronReportSuccess(ctxt, test, cur, !failed); + xmlSchematronReportSuccess(ctxt, test, cur, pattern, !failed); return(!failed); } @@ -1643,7 +1691,7 @@ xmlSchematronValidateDoc(xmlSchematronValidCtxtPtr ctxt, xmlDocPtr instance) if (xmlPatternMatch(rule->pattern, cur) == 1) { test = rule->tests; while (test != NULL) { - xmlSchematronRunTest(ctxt, test, instance, cur); + xmlSchematronRunTest(ctxt, test, instance, cur, rule->pattern); test = test->next; } } @@ -1674,7 +1722,7 @@ xmlSchematronValidateDoc(xmlSchematronValidCtxtPtr ctxt, xmlDocPtr instance) 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; } }