mirror of
https://gitlab.gnome.org/GNOME/libxml2
synced 2025-03-28 21:33:13 +00:00
started adding schematron to the xmllint tool, the report infrastructure
* schematron.c xmllint.c: started adding schematron to the xmllint tool, the report infrastructure is gonna be fun. Daniel
This commit is contained in:
parent
5c68274c86
commit
d4501d77ca
@ -1,3 +1,8 @@
|
||||
Sun Jul 24 10:25:41 EDT 2005 Daniel Veillard <daniel@veillard.com>
|
||||
|
||||
* schematron.c xmllint.c: started adding schematron to the xmllint
|
||||
tool, the report infrastructure is gonna be fun.
|
||||
|
||||
Sat Jul 23 23:23:51 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
|
||||
|
||||
* test/schemas/any6* test/schemas/any7*: Added regression tests
|
||||
|
102
schematron.c
102
schematron.c
@ -63,6 +63,7 @@ struct _xmlSchematronTest {
|
||||
xmlNodePtr node; /* the node in the tree */
|
||||
xmlChar *test; /* the expression to test */
|
||||
xmlXPathCompExprPtr comp; /* the compiled expression */
|
||||
xmlChar *report; /* the message to report */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -78,6 +79,7 @@ struct _xmlSchematronRule {
|
||||
xmlChar *context; /* the context evaluation rule */
|
||||
xmlSchematronTestPtr tests; /* the list of tests */
|
||||
xmlPatternPtr pattern; /* the compiled pattern associated */
|
||||
xmlChar *report; /* the message to report */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -247,6 +249,7 @@ xmlSchematronVErrMemory(xmlSchematronValidCtxtPtr ctxt,
|
||||
* @schema: a schema structure
|
||||
* @node: the node hosting the test
|
||||
* @context: the associated context string
|
||||
* @report: the associated report string
|
||||
*
|
||||
* Add a test to a schematron
|
||||
*
|
||||
@ -255,7 +258,7 @@ xmlSchematronVErrMemory(xmlSchematronValidCtxtPtr ctxt,
|
||||
static xmlSchematronTestPtr
|
||||
xmlSchematronAddTest(xmlSchematronParserCtxtPtr ctxt, int type,
|
||||
xmlSchematronRulePtr rule,
|
||||
xmlNodePtr node, xmlChar *test)
|
||||
xmlNodePtr node, xmlChar *test, xmlChar *report)
|
||||
{
|
||||
xmlSchematronTestPtr ret;
|
||||
xmlXPathCompExprPtr comp;
|
||||
@ -286,6 +289,7 @@ xmlSchematronAddTest(xmlSchematronParserCtxtPtr ctxt, int type,
|
||||
ret->node = node;
|
||||
ret->test = test;
|
||||
ret->comp = comp;
|
||||
ret->report = report;
|
||||
ret->next = rule->tests;
|
||||
rule->tests = ret;
|
||||
return (ret);
|
||||
@ -307,6 +311,8 @@ xmlSchematronFreeTests(xmlSchematronTestPtr tests) {
|
||||
xmlFree(tests->test);
|
||||
if (tests->comp != NULL)
|
||||
xmlXPathFreeCompExpr(tests->comp);
|
||||
if (tests->report != NULL)
|
||||
xmlFree(tests->report);
|
||||
xmlFree(tests);
|
||||
tests = next;
|
||||
}
|
||||
@ -318,6 +324,7 @@ xmlSchematronFreeTests(xmlSchematronTestPtr tests) {
|
||||
* @schema: a schema structure
|
||||
* @node: the node hosting the rule
|
||||
* @context: the associated context string
|
||||
* @report: the associated report string
|
||||
*
|
||||
* Add a rule to a schematron
|
||||
*
|
||||
@ -325,7 +332,7 @@ xmlSchematronFreeTests(xmlSchematronTestPtr tests) {
|
||||
*/
|
||||
static xmlSchematronRulePtr
|
||||
xmlSchematronAddRule(xmlSchematronParserCtxtPtr ctxt, xmlSchematronPtr schema,
|
||||
xmlNodePtr node, xmlChar *context)
|
||||
xmlNodePtr node, xmlChar *context, xmlChar *report)
|
||||
{
|
||||
xmlSchematronRulePtr ret;
|
||||
xmlPatternPtr pattern;
|
||||
@ -356,6 +363,7 @@ xmlSchematronAddRule(xmlSchematronParserCtxtPtr ctxt, xmlSchematronPtr schema,
|
||||
ret->context = context;
|
||||
ret->next = schema->rules;
|
||||
ret->pattern = pattern;
|
||||
ret->report = report;
|
||||
schema->rules = ret;
|
||||
return (ret);
|
||||
}
|
||||
@ -378,6 +386,8 @@ xmlSchematronFreeRules(xmlSchematronRulePtr rules) {
|
||||
xmlFree(rules->context);
|
||||
if (rules->pattern)
|
||||
xmlFreePattern(rules->pattern);
|
||||
if (rules->report != NULL)
|
||||
xmlFree(rules->report);
|
||||
xmlFree(rules);
|
||||
rules = next;
|
||||
}
|
||||
@ -704,6 +714,7 @@ xmlSchematronParseRule(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr rule)
|
||||
int nbChecks = 0;
|
||||
xmlChar *test;
|
||||
xmlChar *context;
|
||||
xmlChar *report;
|
||||
xmlSchematronRulePtr ruleptr;
|
||||
xmlSchematronTestPtr testptr;
|
||||
|
||||
@ -724,7 +735,7 @@ xmlSchematronParseRule(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr rule)
|
||||
xmlFree(context);
|
||||
return;
|
||||
} else {
|
||||
ruleptr = xmlSchematronAddRule(ctxt, ctxt->schema, rule, context);
|
||||
ruleptr = xmlSchematronAddRule(ctxt, ctxt->schema, rule, context, NULL);
|
||||
if (ruleptr == NULL) {
|
||||
xmlFree(context);
|
||||
return;
|
||||
@ -749,8 +760,11 @@ xmlSchematronParseRule(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr rule)
|
||||
NULL, NULL);
|
||||
xmlFree(test);
|
||||
} else {
|
||||
/* TODO will need dynamic processing instead */
|
||||
report = xmlNodeGetContent(cur);
|
||||
|
||||
testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_ASSERT,
|
||||
ruleptr, cur, test);
|
||||
ruleptr, cur, test, report);
|
||||
if (testptr == NULL)
|
||||
xmlFree(test);
|
||||
}
|
||||
@ -769,8 +783,11 @@ xmlSchematronParseRule(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr rule)
|
||||
NULL, NULL);
|
||||
xmlFree(test);
|
||||
} else {
|
||||
/* TODO will need dynamic processing instead */
|
||||
report = xmlNodeGetContent(cur);
|
||||
|
||||
testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_REPORT,
|
||||
ruleptr, cur, test);
|
||||
ruleptr, cur, test, report);
|
||||
if (testptr == NULL)
|
||||
xmlFree(test);
|
||||
}
|
||||
@ -1057,9 +1074,68 @@ exit:
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* xmlSchematronReportOutput:
|
||||
* @ctxt: the validation context
|
||||
* @cur: the current node tested
|
||||
* @msg: the message output
|
||||
*
|
||||
* Output part of the report to whatever channel the user selected
|
||||
*/
|
||||
static void
|
||||
xmlSchematronReportOutput(xmlSchematronValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
|
||||
xmlNodePtr cur ATTRIBUTE_UNUSED,
|
||||
const char *msg ATTRIBUTE_UNUSED) {
|
||||
/* TODO */
|
||||
fprintf(stderr, "%s", msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* xmlSchematronReportSuccess:
|
||||
* @ctxt: the validation context
|
||||
* @test: the compiled test
|
||||
* @cur: the current node tested
|
||||
* @success: boolean value for the result
|
||||
*
|
||||
* called from the validation engine when an assert or report test have
|
||||
* been done.
|
||||
*/
|
||||
static void
|
||||
xmlSchematronReportSuccess(xmlSchematronValidCtxtPtr ctxt,
|
||||
xmlSchematronTestPtr test, xmlNodePtr cur) {
|
||||
xmlSchematronTestPtr test, xmlNodePtr cur, int success) {
|
||||
if ((ctxt == NULL) || (cur == NULL) || (test == NULL))
|
||||
return;
|
||||
/* if quiet and not SVRL report only failures */
|
||||
if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) &&
|
||||
((ctxt->flags & XML_SCHEMATRON_OUT_XML) == 0) && (success))
|
||||
return;
|
||||
if (ctxt->flags & XML_SCHEMATRON_OUT_XML) {
|
||||
TODO
|
||||
} else {
|
||||
xmlChar *path;
|
||||
char msg[1000];
|
||||
long line;
|
||||
const xmlChar *report;
|
||||
|
||||
if (success)
|
||||
return;
|
||||
line = xmlGetLineNo(cur);
|
||||
path = xmlGetNodePath(cur);
|
||||
if (path == NULL)
|
||||
path = (xmlChar *) cur->name;
|
||||
if ((test->report != NULL) && (test->report[0] != 0))
|
||||
report = test->report;
|
||||
else if (test->type == XML_SCHEMATRON_ASSERT) {
|
||||
report = BAD_CAST "node failed assert";
|
||||
} else {
|
||||
report = BAD_CAST "node failed report";
|
||||
}
|
||||
snprintf(msg, 999, "%s line %ld:\n %s\n", (const char *) path,
|
||||
line, (const char *) report);
|
||||
xmlSchematronReportOutput(ctxt, cur, &msg[0]);
|
||||
if ((path != NULL) && (path != (xmlChar *) cur->name))
|
||||
xmlFree(path);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
@ -1095,6 +1171,7 @@ xmlSchematronNewValidCtxt(xmlSchematronPtr schema, int options)
|
||||
ret->type = XML_STRON_CTXT_VALIDATOR;
|
||||
ret->schema = schema;
|
||||
ret->xctxt = xmlXPathNewContext(NULL);
|
||||
ret->flags = options;
|
||||
if (ret->xctxt == NULL) {
|
||||
xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
|
||||
NULL);
|
||||
@ -1216,15 +1293,9 @@ xmlSchematronRunTest(xmlSchematronValidCtxtPtr ctxt,
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
if (test->type == XML_SCHEMATRON_REPORT) {
|
||||
if (!failed) {
|
||||
printf("report failed\n");
|
||||
}
|
||||
} else {
|
||||
if (failed) {
|
||||
printf("assert failed\n");
|
||||
}
|
||||
}
|
||||
if (failed)
|
||||
ctxt->nberrors++;
|
||||
xmlSchematronReportSuccess(ctxt, test, cur, !failed);
|
||||
|
||||
return(!failed);
|
||||
}
|
||||
@ -1255,7 +1326,6 @@ xmlSchematronValidateDoc(xmlSchematronValidCtxtPtr ctxt, xmlDocPtr instance)
|
||||
rule = ctxt->schema->rules;
|
||||
while (rule != NULL) {
|
||||
if (xmlPatternMatch(rule->pattern, cur) == 1) {
|
||||
printf("%s matches\n", cur->name);
|
||||
test = rule->tests;
|
||||
while (test != NULL) {
|
||||
xmlSchematronRunTest(ctxt, test, instance, cur);
|
||||
|
93
xmllint.c
93
xmllint.c
@ -85,6 +85,9 @@
|
||||
#endif
|
||||
#include <libxml/globals.h>
|
||||
#include <libxml/xmlreader.h>
|
||||
#ifdef LIBXML_SCHEMATRON_ENABLED
|
||||
#include <libxml/schematron.h>
|
||||
#endif
|
||||
#ifdef LIBXML_SCHEMAS_ENABLED
|
||||
#include <libxml/relaxng.h>
|
||||
#include <libxml/xmlschemas.h>
|
||||
@ -143,6 +146,10 @@ static xmlRelaxNGPtr relaxngschemas = NULL;
|
||||
static char * schema = NULL;
|
||||
static xmlSchemaPtr wxschemas = NULL;
|
||||
#endif
|
||||
#ifdef LIBXML_SCHEMAS_ENABLED
|
||||
static char * schematron = NULL;
|
||||
static xmlSchematronPtr wxschematron = NULL;
|
||||
#endif
|
||||
static int repeat = 0;
|
||||
static int insert = 0;
|
||||
#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
|
||||
@ -2580,6 +2587,42 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
|
||||
xmlFreeValidCtxt(cvp);
|
||||
}
|
||||
#endif /* LIBXML_VALID_ENABLED */
|
||||
#ifdef LIBXML_SCHEMATRON_ENABLED
|
||||
if (wxschematron != NULL) {
|
||||
xmlSchematronValidCtxtPtr ctxt;
|
||||
int ret;
|
||||
int flag = XML_SCHEMATRON_OUT_TEXT;
|
||||
|
||||
if ((timing) && (!repeat)) {
|
||||
startTimer();
|
||||
}
|
||||
|
||||
if (debug)
|
||||
flag = XML_SCHEMATRON_OUT_XML;
|
||||
ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
|
||||
#if 0
|
||||
xmlSchematronSetValidErrors(ctxt,
|
||||
(xmlSchematronValidityErrorFunc) fprintf,
|
||||
(xmlSchematronValidityWarningFunc) fprintf,
|
||||
stderr);
|
||||
#endif
|
||||
ret = xmlSchematronValidateDoc(ctxt, doc);
|
||||
if (ret == 0) {
|
||||
fprintf(stderr, "%s validates\n", filename);
|
||||
} else if (ret > 0) {
|
||||
fprintf(stderr, "%s fails to validate\n", filename);
|
||||
progresult = XMLLINT_ERR_VALID;
|
||||
} else {
|
||||
fprintf(stderr, "%s validation generated an internal error\n",
|
||||
filename);
|
||||
progresult = XMLLINT_ERR_VALID;
|
||||
}
|
||||
xmlSchematronFreeValidCtxt(ctxt);
|
||||
if ((timing) && (!repeat)) {
|
||||
endTimer("Validating");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef LIBXML_SCHEMAS_ENABLED
|
||||
if (relaxngschemas != NULL) {
|
||||
xmlRelaxNGValidCtxtPtr ctxt;
|
||||
@ -3111,6 +3154,13 @@ main(int argc, char **argv) {
|
||||
i++;
|
||||
schema = argv[i];
|
||||
noent++;
|
||||
#endif
|
||||
#ifdef LIBXML_SCHEMATRON_ENABLED
|
||||
} else if ((!strcmp(argv[i], "-schematron")) ||
|
||||
(!strcmp(argv[i], "--schematron"))) {
|
||||
i++;
|
||||
schematron = argv[i];
|
||||
noent++;
|
||||
#endif
|
||||
} else if ((!strcmp(argv[i], "-nonet")) ||
|
||||
(!strcmp(argv[i], "--nonet"))) {
|
||||
@ -3193,6 +3243,40 @@ main(int argc, char **argv) {
|
||||
argv[0]);
|
||||
}
|
||||
|
||||
#ifdef LIBXML_SCHEMATRON_ENABLED
|
||||
if ((schematron != NULL) && (sax == 0)
|
||||
#ifdef LIBXML_READER_ENABLED
|
||||
&& (stream == 0)
|
||||
#endif /* LIBXML_READER_ENABLED */
|
||||
) {
|
||||
xmlSchematronParserCtxtPtr ctxt;
|
||||
|
||||
/* forces loading the DTDs */
|
||||
xmlLoadExtDtdDefaultValue |= 1;
|
||||
options |= XML_PARSE_DTDLOAD;
|
||||
if (timing) {
|
||||
startTimer();
|
||||
}
|
||||
ctxt = xmlSchematronNewParserCtxt(schematron);
|
||||
#if 0
|
||||
xmlSchematronSetParserErrors(ctxt,
|
||||
(xmlSchematronValidityErrorFunc) fprintf,
|
||||
(xmlSchematronValidityWarningFunc) fprintf,
|
||||
stderr);
|
||||
#endif
|
||||
wxschematron = xmlSchematronParse(ctxt);
|
||||
if (wxschematron == NULL) {
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"Schematron schema %s failed to compile\n", schematron);
|
||||
progresult = XMLLINT_ERR_SCHEMACOMP;
|
||||
schematron = NULL;
|
||||
}
|
||||
xmlSchematronFreeParserCtxt(ctxt);
|
||||
if (timing) {
|
||||
endTimer("Compiling the schemas");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef LIBXML_SCHEMAS_ENABLED
|
||||
if ((relaxng != NULL) && (sax == 0)
|
||||
#ifdef LIBXML_READER_ENABLED
|
||||
@ -3309,6 +3393,11 @@ main(int argc, char **argv) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ((!strcmp(argv[i], "-schematron")) ||
|
||||
(!strcmp(argv[i], "--schematron"))) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
#ifdef LIBXML_PATTERN_ENABLED
|
||||
if ((!strcmp(argv[i], "-pattern")) ||
|
||||
(!strcmp(argv[i], "--pattern"))) {
|
||||
@ -3375,6 +3464,10 @@ main(int argc, char **argv) {
|
||||
if ((files == 0) && (!generate) && (version == 0)) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
#ifdef LIBXML_SCHEMATRON_ENABLED
|
||||
if (wxschematron != NULL)
|
||||
xmlSchematronFree(wxschematron);
|
||||
#endif
|
||||
#ifdef LIBXML_SCHEMAS_ENABLED
|
||||
if (relaxngschemas != NULL)
|
||||
xmlRelaxNGFree(relaxngschemas);
|
||||
|
Loading…
x
Reference in New Issue
Block a user