static const xmlChar *xmlSchematronNs = XML_SCHEMATRON_NS;
static const xmlChar *xmlOldSchematronNs = SCT_OLD_NS;
-#define IS_SCHEMATRON(node, elem) \
- ((node != NULL) && (node->type == XML_ELEMENT_NODE ) && \
- (node->ns != NULL) && \
- (xmlStrEqual(node->name, (const xmlChar *) elem)) && \
- ((xmlStrEqual(node->ns->href, xmlSchematronNs)) || \
+#define IS_SCHEMATRON(node, elem) \
+ ((node != NULL) && (node->type == XML_ELEMENT_NODE ) && \
+ (node->ns != NULL) && \
+ (xmlStrEqual(node->name, (const xmlChar *) elem)) && \
+ ((xmlStrEqual(node->ns->href, xmlSchematronNs)) || \
(xmlStrEqual(node->ns->href, xmlOldSchematronNs))))
-#define NEXT_SCHEMATRON(node) \
- while (node != NULL) { \
- if ((node->type == XML_ELEMENT_NODE ) && (node->ns != NULL) && \
- ((xmlStrEqual(node->ns->href, xmlSchematronNs)) || \
- (xmlStrEqual(node->ns->href, xmlOldSchematronNs)))) \
- break; \
- node = node->next; \
+#define NEXT_SCHEMATRON(node) \
+ while (node != NULL) { \
+ if ((node->type == XML_ELEMENT_NODE ) && (node->ns != NULL) && \
+ ((xmlStrEqual(node->ns->href, xmlSchematronNs)) || \
+ (xmlStrEqual(node->ns->href, xmlOldSchematronNs)))) \
+ break; \
+ node = node->next; \
}
/**
*
* macro to flag unimplemented blocks
*/
-#define TODO \
- xmlGenericError(xmlGenericErrorContext, \
- "Unimplemented block at %s:%d\n", \
+#define TODO \
+ xmlGenericError(xmlGenericErrorContext, \
+ "Unimplemented block at %s:%d\n", \
__FILE__, __LINE__);
typedef enum {
XML_SCHEMATRON_REPORT=2
} xmlSchematronTestType;
+/**
+ * _xmlSchematronLet:
+ *
+ * A Schematron let variable
+ */
+typedef struct _xmlSchematronLet xmlSchematronLet;
+typedef xmlSchematronLet *xmlSchematronLetPtr;
+struct _xmlSchematronLet {
+ xmlSchematronLetPtr next; /* the next let variable in the list */
+ xmlChar *name; /* the name of the variable */
+ xmlXPathCompExprPtr comp; /* the compiled expression */
+};
+
/**
* _xmlSchematronTest:
*
typedef struct _xmlSchematronTest xmlSchematronTest;
typedef xmlSchematronTest *xmlSchematronTestPtr;
struct _xmlSchematronTest {
- xmlSchematronTestPtr next; /* the next test in the list */
- xmlSchematronTestType type; /* the test type */
- xmlNodePtr node; /* the node in the tree */
- xmlChar *test; /* the expression to test */
- xmlXPathCompExprPtr comp; /* the compiled expression */
- xmlChar *report; /* the message to report */
+ xmlSchematronTestPtr next; /* the next test in the list */
+ xmlSchematronTestType type; /* the test type */
+ xmlNodePtr node; /* the node in the tree */
+ xmlChar *test; /* the expression to test */
+ xmlXPathCompExprPtr comp; /* the compiled expression */
+ xmlChar *report; /* the message to report */
};
/**
typedef struct _xmlSchematronRule xmlSchematronRule;
typedef xmlSchematronRule *xmlSchematronRulePtr;
struct _xmlSchematronRule {
- xmlSchematronRulePtr next; /* the next rule in the list */
+ xmlSchematronRulePtr next; /* the next rule in the list */
xmlSchematronRulePtr patnext;/* the next rule in the pattern list */
- xmlNodePtr node; /* the node in the tree */
- xmlChar *context; /* the context evaluation rule */
- xmlSchematronTestPtr tests; /* the list of tests */
- xmlPatternPtr pattern; /* the compiled pattern associated */
- xmlChar *report; /* the message to report */
+ xmlNodePtr node; /* the node in the tree */
+ xmlChar *context; /* the context evaluation rule */
+ xmlSchematronTestPtr tests; /* the list of tests */
+ xmlPatternPtr pattern; /* the compiled pattern associated */
+ xmlChar *report; /* the message to report */
+ xmlSchematronLetPtr lets; /* the list of let variables */
};
/**
typedef xmlSchematronPattern *xmlSchematronPatternPtr;
struct _xmlSchematronPattern {
xmlSchematronPatternPtr next;/* the next pattern in the list */
- xmlSchematronRulePtr rules; /* the list of rules */
- xmlChar *name; /* the name of the pattern */
+ xmlSchematronRulePtr rules; /* the list of rules */
+ xmlChar *name; /* the name of the pattern */
};
/**
* A Schematrons definition
*/
struct _xmlSchematron {
- const xmlChar *name; /* schema name */
- int preserve; /* was the document passed by the user */
- xmlDocPtr doc; /* pointer to the parsed document */
- int flags; /* specific to this schematron */
+ const xmlChar *name; /* schema name */
+ int preserve; /* was the document passed by the user */
+ xmlDocPtr doc; /* pointer to the parsed document */
+ int flags; /* specific to this schematron */
- void *_private; /* unused by the library */
- xmlDictPtr dict; /* the dictionary used internally */
+ void *_private; /* unused by the library */
+ xmlDictPtr dict; /* the dictionary used internally */
- const xmlChar *title; /* the title if any */
+ const xmlChar *title; /* the title if any */
- int nbNs; /* the number of namespaces */
+ int nbNs; /* the number of namespaces */
- int nbPattern; /* the number of patterns */
+ int nbPattern; /* the number of patterns */
xmlSchematronPatternPtr patterns;/* the patterns found */
- xmlSchematronRulePtr rules; /* the rules gathered */
- int nbNamespaces; /* number of namespaces in the array */
- int maxNamespaces; /* size of the array */
- const xmlChar **namespaces; /* the array of namespaces */
+ xmlSchematronRulePtr rules; /* the rules gathered */
+ int nbNamespaces; /* number of namespaces in the array */
+ int maxNamespaces; /* size of the array */
+ const xmlChar **namespaces; /* the array of namespaces */
};
/**
*/
struct _xmlSchematronValidCtxt {
int type;
- int flags; /* an or of xmlSchematronValidOptions */
+ int flags; /* an or of xmlSchematronValidOptions */
xmlDictPtr dict;
int nberrors;
xmlSchematronPtr schema;
xmlXPathContextPtr xctxt;
- FILE *outputFile; /* if using XML_SCHEMATRON_OUT_FILE */
- xmlBufferPtr outputBuffer; /* if using XML_SCHEMATRON_OUT_BUFFER */
+ 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;
int nberrors;
int err;
- xmlXPathContextPtr xctxt; /* the XPath context used for compilation */
+ xmlXPathContextPtr xctxt; /* the XPath context used for compilation */
xmlSchematronPtr schema;
- int nbNamespaces; /* number of namespaces in the array */
- int maxNamespaces; /* size of the array */
- const xmlChar **namespaces; /* the array of namespaces */
+ int nbNamespaces; /* number of namespaces in the array */
+ int maxNamespaces; /* size of the array */
+ const xmlChar **namespaces; /* the array of namespaces */
- int nbIncludes; /* number of includes in the array */
- int maxIncludes; /* size of the array */
- xmlNodePtr *includes; /* the array of includes */
+ int nbIncludes; /* number of includes in the array */
+ int maxIncludes; /* size of the array */
+ xmlNodePtr *includes; /* the array of includes */
/* error reporting data */
void *userData; /* user specific data block */
#define XML_STRON_CTXT_VALIDATOR 2
/************************************************************************
- * *
- * Error reporting *
- * *
+ * *
+ * Error reporting *
+ * *
************************************************************************/
/**
ctxt->nberrors++;
channel = ctxt->error;
data = ctxt->userData;
- schannel = ctxt->serror;
+ schannel = ctxt->serror;
}
__xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
error, XML_ERR_ERROR, NULL, 0,
}
/************************************************************************
- * *
- * Parsing and compilation of the Schematrontrons *
- * *
+ * *
+ * Parsing and compilation of the Schematrontrons *
+ * *
************************************************************************/
/**
*/
comp = xmlXPathCtxtCompile(ctxt->xctxt, test);
if (comp == NULL) {
- xmlSchematronPErr(ctxt, node,
- XML_SCHEMAP_NOROOT,
- "Failed to compile test expression %s",
- test, NULL);
- return(NULL);
+ xmlSchematronPErr(ctxt, node,
+ XML_SCHEMAP_NOROOT,
+ "Failed to compile test expression %s",
+ test, NULL);
+ return(NULL);
}
ret = (xmlSchematronTestPtr) xmlMalloc(sizeof(xmlSchematronTest));
ret->report = report;
ret->next = NULL;
if (rule->tests == NULL) {
- rule->tests = ret;
+ rule->tests = ret;
} else {
xmlSchematronTestPtr prev = rule->tests;
- while (prev->next != NULL)
- prev = prev->next;
+ while (prev->next != NULL)
+ prev = prev->next;
prev->next = ret;
}
return (ret);
while (tests != NULL) {
next = tests->next;
- if (tests->test != NULL)
- xmlFree(tests->test);
- if (tests->comp != NULL)
- xmlXPathFreeCompExpr(tests->comp);
- if (tests->report != NULL)
- xmlFree(tests->report);
- xmlFree(tests);
- tests = next;
+ if (tests->test != NULL)
+ xmlFree(tests->test);
+ if (tests->comp != NULL)
+ xmlXPathFreeCompExpr(tests->comp);
+ if (tests->report != NULL)
+ xmlFree(tests->report);
+ xmlFree(tests);
+ tests = next;
+ }
+}
+
+/**
+ * xmlSchematronFreeLets:
+ * @lets: a list of let variables
+ *
+ * Free a list of let variables.
+ */
+static void
+xmlSchematronFreeLets(xmlSchematronLetPtr lets) {
+ xmlSchematronLetPtr next;
+
+ while (lets != NULL) {
+ next = lets->next;
+ if (lets->name != NULL)
+ xmlFree(lets->name);
+ if (lets->comp != NULL)
+ xmlXPathFreeCompExpr(lets->comp);
+ xmlFree(lets);
+ lets = next;
}
}
static xmlSchematronRulePtr
xmlSchematronAddRule(xmlSchematronParserCtxtPtr ctxt, xmlSchematronPtr schema,
xmlSchematronPatternPtr pat, xmlNodePtr node,
- xmlChar *context, xmlChar *report)
+ xmlChar *context, xmlChar *report)
{
xmlSchematronRulePtr ret;
xmlPatternPtr pattern;
pattern = xmlPatterncompile(context, ctxt->dict, XML_PATTERN_XPATH,
ctxt->namespaces);
if (pattern == NULL) {
- xmlSchematronPErr(ctxt, node,
- XML_SCHEMAP_NOROOT,
- "Failed to compile context expression %s",
- context, NULL);
+ xmlSchematronPErr(ctxt, node,
+ XML_SCHEMAP_NOROOT,
+ "Failed to compile context expression %s",
+ context, NULL);
}
ret = (xmlSchematronRulePtr) xmlMalloc(sizeof(xmlSchematronRule));
ret->pattern = pattern;
ret->report = report;
ret->next = NULL;
+ ret->lets = NULL;
if (schema->rules == NULL) {
- schema->rules = ret;
+ schema->rules = ret;
} else {
xmlSchematronRulePtr prev = schema->rules;
- while (prev->next != NULL)
- prev = prev->next;
+ while (prev->next != NULL)
+ prev = prev->next;
prev->next = ret;
}
ret->patnext = NULL;
if (pat->rules == NULL) {
- pat->rules = ret;
+ pat->rules = ret;
} else {
xmlSchematronRulePtr prev = pat->rules;
- while (prev->patnext != NULL)
- prev = prev->patnext;
+ while (prev->patnext != NULL)
+ prev = prev->patnext;
prev->patnext = ret;
}
return (ret);
while (rules != NULL) {
next = rules->next;
- if (rules->tests)
- xmlSchematronFreeTests(rules->tests);
- if (rules->context != NULL)
- xmlFree(rules->context);
- if (rules->pattern)
- xmlFreePattern(rules->pattern);
- if (rules->report != NULL)
- xmlFree(rules->report);
- xmlFree(rules);
- rules = next;
+ if (rules->tests)
+ xmlSchematronFreeTests(rules->tests);
+ if (rules->context != NULL)
+ xmlFree(rules->context);
+ if (rules->pattern)
+ xmlFreePattern(rules->pattern);
+ if (rules->report != NULL)
+ xmlFree(rules->report);
+ if (rules->lets != NULL)
+ xmlSchematronFreeLets(rules->lets);
+ xmlFree(rules);
+ rules = next;
}
}
ret->name = name;
ret->next = NULL;
if (schema->patterns == NULL) {
- schema->patterns = ret;
+ schema->patterns = ret;
} else {
xmlSchematronPatternPtr prev = schema->patterns;
- while (prev->next != NULL)
- prev = prev->next;
+ while (prev->next != NULL)
+ prev = prev->next;
prev->next = ret;
}
return (ret);
while (patterns != NULL) {
next = patterns->next;
- if (patterns->name != NULL)
- xmlFree(patterns->name);
- xmlFree(patterns);
- patterns = next;
+ if (patterns->name != NULL)
+ xmlFree(patterns->name);
+ xmlFree(patterns);
+ patterns = next;
}
}
if (ret->xctxt == NULL) {
xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
NULL);
- xmlSchematronFreeParserCtxt(ret);
+ xmlSchematronFreeParserCtxt(ret);
return (NULL);
}
ret->xctxt->flags = XML_XPATH_CHECKNS;
if (ret->xctxt == NULL) {
xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
NULL);
- xmlSchematronFreeParserCtxt(ret);
+ xmlSchematronFreeParserCtxt(ret);
return (NULL);
}
return (ret);
if (ret->xctxt == NULL) {
xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
NULL);
- xmlSchematronFreeParserCtxt(ret);
+ xmlSchematronFreeParserCtxt(ret);
return (NULL);
}
if (ctxt->includes == NULL) {
ctxt->maxIncludes = 10;
ctxt->includes = (xmlNodePtr *)
- xmlMalloc(ctxt->maxIncludes * 2 * sizeof(xmlNodePtr));
- if (ctxt->includes == NULL) {
- xmlSchematronPErrMemory(NULL, "allocating parser includes",
- NULL);
- return;
- }
+ xmlMalloc(ctxt->maxIncludes * 2 * sizeof(xmlNodePtr));
+ if (ctxt->includes == NULL) {
+ xmlSchematronPErrMemory(NULL, "allocating parser includes",
+ NULL);
+ return;
+ }
ctxt->nbIncludes = 0;
} else if (ctxt->nbIncludes + 2 >= ctxt->maxIncludes) {
xmlNodePtr *tmp;
- tmp = (xmlNodePtr *)
- xmlRealloc(ctxt->includes, ctxt->maxIncludes * 4 *
- sizeof(xmlNodePtr));
- if (tmp == NULL) {
- xmlSchematronPErrMemory(NULL, "allocating parser includes",
- NULL);
- return;
- }
+ tmp = (xmlNodePtr *)
+ xmlRealloc(ctxt->includes, ctxt->maxIncludes * 4 *
+ sizeof(xmlNodePtr));
+ if (tmp == NULL) {
+ xmlSchematronPErrMemory(NULL, "allocating parser includes",
+ NULL);
+ return;
+ }
ctxt->includes = tmp;
- ctxt->maxIncludes *= 2;
+ ctxt->maxIncludes *= 2;
}
ctxt->includes[2 * ctxt->nbIncludes] = cur;
ctxt->includes[2 * ctxt->nbIncludes + 1] = (xmlNodePtr) doc;
ret = ctxt->includes[2 * ctxt->nbIncludes];
xmlFreeDoc(doc);
if (ret != NULL)
- ret = ret->next;
+ ret = ret->next;
if (ret == NULL)
return(xmlSchematronPopInclude(ctxt));
return(ret);
if (ctxt->namespaces == NULL) {
ctxt->maxNamespaces = 10;
ctxt->namespaces = (const xmlChar **)
- xmlMalloc(ctxt->maxNamespaces * 2 * sizeof(const xmlChar *));
- if (ctxt->namespaces == NULL) {
- xmlSchematronPErrMemory(NULL, "allocating parser namespaces",
- NULL);
- return;
- }
+ xmlMalloc(ctxt->maxNamespaces * 2 * sizeof(const xmlChar *));
+ if (ctxt->namespaces == NULL) {
+ xmlSchematronPErrMemory(NULL, "allocating parser namespaces",
+ NULL);
+ return;
+ }
ctxt->nbNamespaces = 0;
} else if (ctxt->nbNamespaces + 2 >= ctxt->maxNamespaces) {
const xmlChar **tmp;
- tmp = (const xmlChar **)
- xmlRealloc((xmlChar **) ctxt->namespaces, ctxt->maxNamespaces * 4 *
- sizeof(const xmlChar *));
- if (tmp == NULL) {
- xmlSchematronPErrMemory(NULL, "allocating parser namespaces",
- NULL);
- return;
- }
+ tmp = (const xmlChar **)
+ xmlRealloc((xmlChar **) ctxt->namespaces, ctxt->maxNamespaces * 4 *
+ sizeof(const xmlChar *));
+ if (tmp == NULL) {
+ xmlSchematronPErrMemory(NULL, "allocating parser namespaces",
+ NULL);
+ return;
+ }
ctxt->namespaces = tmp;
- ctxt->maxNamespaces *= 2;
+ ctxt->maxNamespaces *= 2;
}
ctxt->namespaces[2 * ctxt->nbNamespaces] =
xmlDictLookup(ctxt->dict, ns, -1);
}
+/**
+ * xmlSchematronParseTestReportMsg:
+ * @ctxt: the schema parser context
+ * @con: the assert or report node
+ *
+ * Format the message content of the assert or report test
+ */
+static void
+xmlSchematronParseTestReportMsg(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr con)
+{
+ xmlNodePtr child;
+ xmlXPathCompExprPtr comp;
+
+ child = con->children;
+ while (child != NULL) {
+ if ((child->type == XML_TEXT_NODE) ||
+ (child->type == XML_CDATA_SECTION_NODE))
+ /* Do Nothing */
+ {}
+ else if (IS_SCHEMATRON(child, "name")) {
+ /* Do Nothing */
+ } else if (IS_SCHEMATRON(child, "value-of")) {
+ xmlChar *select;
+
+ select = xmlGetNoNsProp(child, BAD_CAST "select");
+
+ if (select == NULL) {
+ xmlSchematronPErr(ctxt, child,
+ XML_SCHEMAV_ATTRINVALID,
+ "value-of has no select attribute",
+ NULL, NULL);
+ } else {
+ /*
+ * try first to compile the test expression
+ */
+ comp = xmlXPathCtxtCompile(ctxt->xctxt, select);
+ if (comp == NULL) {
+ xmlSchematronPErr(ctxt, child,
+ XML_SCHEMAV_ATTRINVALID,
+ "Failed to compile select expression %s",
+ select, NULL);
+ }
+ xmlXPathFreeCompExpr(comp);
+ }
+ xmlFree(select);
+ }
+ child = child->next;
+ continue;
+ }
+}
+
/**
* xmlSchematronParseRule:
* @ctxt: a schema validation context
static void
xmlSchematronParseRule(xmlSchematronParserCtxtPtr ctxt,
xmlSchematronPatternPtr pattern,
- xmlNodePtr rule)
+ xmlNodePtr rule)
{
xmlNodePtr cur;
int nbChecks = 0;
xmlChar *test;
xmlChar *context;
xmlChar *report;
+ xmlChar *name;
+ xmlChar *value;
xmlSchematronRulePtr ruleptr;
xmlSchematronTestPtr testptr;
context = xmlGetNoNsProp(rule, BAD_CAST "context");
if (context == NULL) {
- xmlSchematronPErr(ctxt, rule,
- XML_SCHEMAP_NOROOT,
- "rule has no context attribute",
- NULL, NULL);
- return;
+ xmlSchematronPErr(ctxt, rule,
+ XML_SCHEMAP_NOROOT,
+ "rule has no context attribute",
+ NULL, NULL);
+ return;
} else if (context[0] == 0) {
- xmlSchematronPErr(ctxt, rule,
- XML_SCHEMAP_NOROOT,
- "rule has an empty context attribute",
- NULL, NULL);
- xmlFree(context);
- return;
+ xmlSchematronPErr(ctxt, rule,
+ XML_SCHEMAP_NOROOT,
+ "rule has an empty context attribute",
+ NULL, NULL);
+ xmlFree(context);
+ return;
} else {
- ruleptr = xmlSchematronAddRule(ctxt, ctxt->schema, pattern,
- rule, context, NULL);
- if (ruleptr == NULL) {
- xmlFree(context);
- return;
- }
+ ruleptr = xmlSchematronAddRule(ctxt, ctxt->schema, pattern,
+ rule, context, NULL);
+ if (ruleptr == NULL) {
+ xmlFree(context);
+ return;
+ }
}
cur = rule->children;
NEXT_SCHEMATRON(cur);
while (cur != NULL) {
- if (IS_SCHEMATRON(cur, "assert")) {
- nbChecks++;
- test = xmlGetNoNsProp(cur, BAD_CAST "test");
- if (test == NULL) {
- xmlSchematronPErr(ctxt, cur,
- XML_SCHEMAP_NOROOT,
- "assert has no test attribute",
- NULL, NULL);
- } else if (test[0] == 0) {
- xmlSchematronPErr(ctxt, cur,
- XML_SCHEMAP_NOROOT,
- "assert has an empty test attribute",
- NULL, NULL);
- xmlFree(test);
- } else {
- /* TODO will need dynamic processing instead */
- report = xmlNodeGetContent(cur);
-
- testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_ASSERT,
- ruleptr, cur, test, report);
- if (testptr == NULL)
- xmlFree(test);
- }
- } else if (IS_SCHEMATRON(cur, "report")) {
- nbChecks++;
- test = xmlGetNoNsProp(cur, BAD_CAST "test");
- if (test == NULL) {
- xmlSchematronPErr(ctxt, cur,
- XML_SCHEMAP_NOROOT,
- "assert has no test attribute",
- NULL, NULL);
- } else if (test[0] == 0) {
- xmlSchematronPErr(ctxt, cur,
- XML_SCHEMAP_NOROOT,
- "assert has an empty test attribute",
- NULL, NULL);
- xmlFree(test);
- } else {
- /* TODO will need dynamic processing instead */
- report = xmlNodeGetContent(cur);
-
- testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_REPORT,
- ruleptr, cur, test, report);
- if (testptr == NULL)
- xmlFree(test);
- }
- } else {
- xmlSchematronPErr(ctxt, cur,
- XML_SCHEMAP_NOROOT,
- "Expecting an assert or a report element instead of %s",
- cur->name, NULL);
- }
- cur = cur->next;
- NEXT_SCHEMATRON(cur);
+ if (IS_SCHEMATRON(cur, "let")) {
+ xmlXPathCompExprPtr var_comp;
+ xmlSchematronLetPtr let;
+
+ name = xmlGetNoNsProp(cur, BAD_CAST "name");
+ if (name == NULL) {
+ xmlSchematronPErr(ctxt, cur,
+ XML_SCHEMAP_NOROOT,
+ "let has no name attribute",
+ NULL, NULL);
+ return;
+ } else if (name[0] == 0) {
+ xmlSchematronPErr(ctxt, cur,
+ XML_SCHEMAP_NOROOT,
+ "let has an empty name attribute",
+ NULL, NULL);
+ xmlFree(name);
+ return;
+ }
+ value = xmlGetNoNsProp(cur, BAD_CAST "value");
+ if (value == NULL) {
+ xmlSchematronPErr(ctxt, cur,
+ XML_SCHEMAP_NOROOT,
+ "let has no value attribute",
+ NULL, NULL);
+ return;
+ } else if (value[0] == 0) {
+ xmlSchematronPErr(ctxt, cur,
+ XML_SCHEMAP_NOROOT,
+ "let has an empty value attribute",
+ NULL, NULL);
+ xmlFree(value);
+ return;
+ }
+
+ var_comp = xmlXPathCtxtCompile(ctxt->xctxt, value);
+ if (var_comp == NULL) {
+ xmlSchematronPErr(ctxt, cur,
+ XML_SCHEMAP_NOROOT,
+ "Failed to compile let expression %s",
+ value, NULL);
+ return;
+ }
+
+ let = (xmlSchematronLetPtr) malloc(sizeof(xmlSchematronLet));
+ let->name = name;
+ let->comp = var_comp;
+ let->next = NULL;
+
+ /* add new let variable to the beginning of the list */
+ if (ruleptr->lets != NULL) {
+ let->next = ruleptr->lets;
+ }
+ ruleptr->lets = let;
+
+ xmlFree(value);
+ } else if (IS_SCHEMATRON(cur, "assert")) {
+ nbChecks++;
+ test = xmlGetNoNsProp(cur, BAD_CAST "test");
+ if (test == NULL) {
+ xmlSchematronPErr(ctxt, cur,
+ XML_SCHEMAP_NOROOT,
+ "assert has no test attribute",
+ NULL, NULL);
+ } else if (test[0] == 0) {
+ xmlSchematronPErr(ctxt, cur,
+ XML_SCHEMAP_NOROOT,
+ "assert has an empty test attribute",
+ NULL, NULL);
+ xmlFree(test);
+ } else {
+ xmlSchematronParseTestReportMsg(ctxt, cur);
+ report = xmlNodeGetContent(cur);
+
+ testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_ASSERT,
+ ruleptr, cur, test, report);
+ if (testptr == NULL)
+ xmlFree(test);
+ }
+ } else if (IS_SCHEMATRON(cur, "report")) {
+ nbChecks++;
+ test = xmlGetNoNsProp(cur, BAD_CAST "test");
+ if (test == NULL) {
+ xmlSchematronPErr(ctxt, cur,
+ XML_SCHEMAP_NOROOT,
+ "assert has no test attribute",
+ NULL, NULL);
+ } else if (test[0] == 0) {
+ xmlSchematronPErr(ctxt, cur,
+ XML_SCHEMAP_NOROOT,
+ "assert has an empty test attribute",
+ NULL, NULL);
+ xmlFree(test);
+ } else {
+ xmlSchematronParseTestReportMsg(ctxt, cur);
+ report = xmlNodeGetContent(cur);
+
+ testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_REPORT,
+ ruleptr, cur, test, report);
+ if (testptr == NULL)
+ xmlFree(test);
+ }
+ } else {
+ xmlSchematronPErr(ctxt, cur,
+ XML_SCHEMAP_NOROOT,
+ "Expecting an assert or a report element instead of %s",
+ cur->name, NULL);
+ }
+ cur = cur->next;
+ NEXT_SCHEMATRON(cur);
}
if (nbChecks == 0) {
- xmlSchematronPErr(ctxt, rule,
- XML_SCHEMAP_NOROOT,
- "rule has no assert nor report element", NULL, NULL);
+ xmlSchematronPErr(ctxt, rule,
+ XML_SCHEMAP_NOROOT,
+ "rule has no assert nor report element", NULL, NULL);
}
}
id = xmlGetNoNsProp(pat, BAD_CAST "id");
if (id == NULL) {
- id = xmlGetNoNsProp(pat, BAD_CAST "name");
+ id = xmlGetNoNsProp(pat, BAD_CAST "name");
}
pattern = xmlSchematronAddPattern(ctxt, ctxt->schema, pat, id);
if (pattern == NULL) {
- if (id != NULL)
- xmlFree(id);
+ if (id != NULL)
+ xmlFree(id);
return;
}
cur = pat->children;
NEXT_SCHEMATRON(cur);
while (cur != NULL) {
- if (IS_SCHEMATRON(cur, "rule")) {
- xmlSchematronParseRule(ctxt, pattern, cur);
- nbRules++;
- } else {
- xmlSchematronPErr(ctxt, cur,
- XML_SCHEMAP_NOROOT,
- "Expecting a rule element instead of %s", cur->name, NULL);
- }
- cur = cur->next;
- NEXT_SCHEMATRON(cur);
+ if (IS_SCHEMATRON(cur, "rule")) {
+ xmlSchematronParseRule(ctxt, pattern, cur);
+ nbRules++;
+ } else {
+ xmlSchematronPErr(ctxt, cur,
+ XML_SCHEMAP_NOROOT,
+ "Expecting a rule element instead of %s", cur->name, NULL);
+ }
+ cur = cur->next;
+ NEXT_SCHEMATRON(cur);
}
if (nbRules == 0) {
- xmlSchematronPErr(ctxt, pat,
- XML_SCHEMAP_NOROOT,
- "Pattern has no rule element", NULL, NULL);
+ xmlSchematronPErr(ctxt, pat,
+ XML_SCHEMAP_NOROOT,
+ "Pattern has no rule element", NULL, NULL);
}
}
href = xmlGetNoNsProp(cur, BAD_CAST "href");
if (href == NULL) {
- xmlSchematronPErr(ctxt, cur,
- XML_SCHEMAP_NOROOT,
- "Include has no href attribute", NULL, NULL);
- return(cur->next);
+ xmlSchematronPErr(ctxt, cur,
+ XML_SCHEMAP_NOROOT,
+ "Include has no href attribute", NULL, NULL);
+ return(cur->next);
}
/* do the URI base composition, load and find the root */
URI = xmlBuildURI(href, base);
doc = xmlReadFile((const char *) URI, NULL, SCHEMATRON_PARSE_OPTIONS);
if (doc == NULL) {
- xmlSchematronPErr(ctxt, cur,
- XML_SCHEMAP_FAILED_LOAD,
- "could not load include '%s'.\n",
- URI, NULL);
- goto done;
+ xmlSchematronPErr(ctxt, cur,
+ XML_SCHEMAP_FAILED_LOAD,
+ "could not load include '%s'.\n",
+ URI, NULL);
+ goto done;
}
ret = xmlDocGetRootElement(doc);
if (ret == NULL) {
- xmlSchematronPErr(ctxt, cur,
- XML_SCHEMAP_FAILED_LOAD,
- "could not find root from include '%s'.\n",
- URI, NULL);
- goto done;
+ xmlSchematronPErr(ctxt, cur,
+ XML_SCHEMAP_FAILED_LOAD,
+ "could not find root from include '%s'.\n",
+ URI, NULL);
+ goto done;
}
/* Success, push the include for rollback on exit */
done:
if (ret == NULL) {
if (doc != NULL)
- xmlFreeDoc(doc);
+ xmlFreeDoc(doc);
}
xmlFree(href);
if (base != NULL)
*/
if (ctxt->URL != NULL) {
doc = xmlReadFile((const char *) ctxt->URL, NULL,
- SCHEMATRON_PARSE_OPTIONS);
+ SCHEMATRON_PARSE_OPTIONS);
if (doc == NULL) {
- xmlSchematronPErr(ctxt, NULL,
- XML_SCHEMAP_FAILED_LOAD,
+ xmlSchematronPErr(ctxt, NULL,
+ XML_SCHEMAP_FAILED_LOAD,
"xmlSchematronParse: could not load '%s'.\n",
ctxt->URL, NULL);
return (NULL);
}
- ctxt->preserve = 0;
+ ctxt->preserve = 0;
} else if (ctxt->buffer != NULL) {
doc = xmlReadMemory(ctxt->buffer, ctxt->size, NULL, NULL,
- SCHEMATRON_PARSE_OPTIONS);
+ SCHEMATRON_PARSE_OPTIONS);
if (doc == NULL) {
- xmlSchematronPErr(ctxt, NULL,
- XML_SCHEMAP_FAILED_PARSE,
+ xmlSchematronPErr(ctxt, NULL,
+ XML_SCHEMAP_FAILED_PARSE,
"xmlSchematronParse: could not parse.\n",
NULL, NULL);
return (NULL);
}
doc->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
ctxt->URL = xmlDictLookup(ctxt->dict, BAD_CAST "in_memory_buffer", -1);
- ctxt->preserve = 0;
+ ctxt->preserve = 0;
} else if (ctxt->doc != NULL) {
doc = ctxt->doc;
- preserve = 1;
- ctxt->preserve = 1;
+ preserve = 1;
+ ctxt->preserve = 1;
} else {
- xmlSchematronPErr(ctxt, NULL,
- XML_SCHEMAP_NOTHING_TO_PARSE,
- "xmlSchematronParse: could not parse.\n",
- NULL, NULL);
+ xmlSchematronPErr(ctxt, NULL,
+ XML_SCHEMAP_NOTHING_TO_PARSE,
+ "xmlSchematronParse: could not parse.\n",
+ NULL, NULL);
return (NULL);
}
*/
root = xmlDocGetRootElement(doc);
if (root == NULL) {
- xmlSchematronPErr(ctxt, (xmlNodePtr) doc,
- XML_SCHEMAP_NOROOT,
- "The schema has no document element.\n", NULL, NULL);
- if (!preserve) {
- xmlFreeDoc(doc);
- }
+ xmlSchematronPErr(ctxt, (xmlNodePtr) doc,
+ XML_SCHEMAP_NOROOT,
+ "The schema has no document element.\n", NULL, NULL);
+ if (!preserve) {
+ xmlFreeDoc(doc);
+ }
return (NULL);
}
if (!IS_SCHEMATRON(root, "schema")) {
- xmlSchematronPErr(ctxt, root,
- XML_SCHEMAP_NOROOT,
- "The XML document '%s' is not a XML schematron document",
- ctxt->URL, NULL);
- goto exit;
+ xmlSchematronPErr(ctxt, root,
+ XML_SCHEMAP_NOROOT,
+ "The XML document '%s' is not a XML schematron document",
+ ctxt->URL, NULL);
+ goto exit;
}
ret = xmlSchematronNewSchematron(ctxt);
if (ret == NULL)
NEXT_SCHEMATRON(cur);
if (IS_SCHEMATRON(cur, "title")) {
xmlChar *title = xmlNodeGetContent(cur);
- if (title != NULL) {
- ret->title = xmlDictLookup(ret->dict, title, -1);
- xmlFree(title);
- }
- cur = cur->next;
- NEXT_SCHEMATRON(cur);
+ if (title != NULL) {
+ ret->title = xmlDictLookup(ret->dict, title, -1);
+ xmlFree(title);
+ }
+ cur = cur->next;
+ NEXT_SCHEMATRON(cur);
}
while (IS_SCHEMATRON(cur, "ns")) {
xmlChar *prefix = xmlGetNoNsProp(cur, BAD_CAST "prefix");
xmlChar *uri = xmlGetNoNsProp(cur, BAD_CAST "uri");
- if ((uri == NULL) || (uri[0] == 0)) {
- xmlSchematronPErr(ctxt, cur,
- XML_SCHEMAP_NOROOT,
- "ns element has no uri", NULL, NULL);
- }
- if ((prefix == NULL) || (prefix[0] == 0)) {
- xmlSchematronPErr(ctxt, cur,
- XML_SCHEMAP_NOROOT,
- "ns element has no prefix", NULL, NULL);
- }
- if ((prefix) && (uri)) {
- xmlXPathRegisterNs(ctxt->xctxt, prefix, uri);
- xmlSchematronAddNamespace(ctxt, prefix, uri);
- ret->nbNs++;
- }
- if (uri)
- xmlFree(uri);
- if (prefix)
- xmlFree(prefix);
- cur = cur->next;
- NEXT_SCHEMATRON(cur);
+ if ((uri == NULL) || (uri[0] == 0)) {
+ xmlSchematronPErr(ctxt, cur,
+ XML_SCHEMAP_NOROOT,
+ "ns element has no uri", NULL, NULL);
+ }
+ if ((prefix == NULL) || (prefix[0] == 0)) {
+ xmlSchematronPErr(ctxt, cur,
+ XML_SCHEMAP_NOROOT,
+ "ns element has no prefix", NULL, NULL);
+ }
+ if ((prefix) && (uri)) {
+ xmlXPathRegisterNs(ctxt->xctxt, prefix, uri);
+ xmlSchematronAddNamespace(ctxt, prefix, uri);
+ ret->nbNs++;
+ }
+ if (uri)
+ xmlFree(uri);
+ if (prefix)
+ xmlFree(prefix);
+ cur = cur->next;
+ NEXT_SCHEMATRON(cur);
}
while (cur != NULL) {
- if (IS_SCHEMATRON(cur, "pattern")) {
- xmlSchematronParsePattern(ctxt, cur);
- ret->nbPattern++;
- } else {
- xmlSchematronPErr(ctxt, cur,
- XML_SCHEMAP_NOROOT,
- "Expecting a pattern element instead of %s", cur->name, NULL);
- }
- cur = cur->next;
- NEXT_SCHEMATRON(cur);
+ if (IS_SCHEMATRON(cur, "pattern")) {
+ xmlSchematronParsePattern(ctxt, cur);
+ ret->nbPattern++;
+ } else {
+ xmlSchematronPErr(ctxt, cur,
+ XML_SCHEMAP_NOROOT,
+ "Expecting a pattern element instead of %s", cur->name, NULL);
+ }
+ cur = cur->next;
+ NEXT_SCHEMATRON(cur);
}
if (ret->nbPattern == 0) {
- xmlSchematronPErr(ctxt, root,
- XML_SCHEMAP_NOROOT,
- "The schematron document '%s' has no pattern",
- ctxt->URL, NULL);
- goto exit;
+ xmlSchematronPErr(ctxt, root,
+ XML_SCHEMAP_NOROOT,
+ "The schematron document '%s' has no pattern",
+ ctxt->URL, NULL);
+ goto exit;
}
/* the original document must be kept for reporting */
ret->doc = doc;
if (preserve) {
- ret->preserve = 1;
+ ret->preserve = 1;
}
preserve = 1;
exit:
if (!preserve) {
- xmlFreeDoc(doc);
+ xmlFreeDoc(doc);
}
if (ret != NULL) {
- if (ctxt->nberrors != 0) {
- xmlSchematronFree(ret);
- ret = NULL;
- } else {
- ret->namespaces = ctxt->namespaces;
- ret->nbNamespaces = ctxt->nbNamespaces;
- ctxt->namespaces = NULL;
- }
+ if (ctxt->nberrors != 0) {
+ xmlSchematronFree(ret);
+ ret = NULL;
+ } else {
+ ret->namespaces = ctxt->namespaces;
+ ret->nbNamespaces = ctxt->nbNamespaces;
+ ctxt->namespaces = NULL;
+ }
}
return (ret);
}
/************************************************************************
- * *
- * Schematrontron Reports handler *
- * *
+ * *
+ * Schematrontron Reports handler *
+ * *
************************************************************************/
static xmlNodePtr
if ((ret->type == XPATH_NODESET) &&
(ret->nodesetval != NULL) && (ret->nodesetval->nodeNr > 0))
- node = ret->nodesetval->nodeTab[0];
+ node = ret->nodesetval->nodeTab[0];
xmlXPathFreeObject(ret);
return(node);
*/
static xmlChar *
xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt,
- xmlNodePtr test, xmlNodePtr cur) {
+ xmlNodePtr test, xmlNodePtr cur) {
xmlChar *ret = NULL;
xmlNodePtr child, node;
+ xmlXPathCompExprPtr comp;
if ((test == NULL) || (cur == NULL))
return(ret);
child = test->children;
while (child != NULL) {
if ((child->type == XML_TEXT_NODE) ||
- (child->type == XML_CDATA_SECTION_NODE))
- ret = xmlStrcat(ret, child->content);
- else if (IS_SCHEMATRON(child, "name")) {
- xmlChar *path;
+ (child->type == XML_CDATA_SECTION_NODE))
+ ret = xmlStrcat(ret, child->content);
+ else if (IS_SCHEMATRON(child, "name")) {
+ xmlChar *path;
- path = xmlGetNoNsProp(child, BAD_CAST "path");
+ path = xmlGetNoNsProp(child, BAD_CAST "path");
node = cur;
- if (path != NULL) {
- node = xmlSchematronGetNode(ctxt, cur, path);
- if (node == NULL)
- node = cur;
- xmlFree(path);
- }
-
- if ((node->ns == NULL) || (node->ns->prefix == NULL))
- ret = xmlStrcat(ret, node->name);
- else {
- ret = xmlStrcat(ret, node->ns->prefix);
- ret = xmlStrcat(ret, BAD_CAST ":");
- ret = xmlStrcat(ret, node->name);
- }
- } else {
- child = child->next;
- continue;
- }
-
- /*
- * remove superfluous \n
- */
- if (ret != NULL) {
- int len = xmlStrlen(ret);
- xmlChar c;
-
- if (len > 0) {
- c = ret[len - 1];
- if ((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t')) {
- while ((c == ' ') || (c == '\n') ||
- (c == '\r') || (c == '\t')) {
- len--;
- if (len == 0)
- break;
- c = ret[len - 1];
- }
- ret[len] = ' ';
- ret[len + 1] = 0;
- }
- }
- }
+ if (path != NULL) {
+ node = xmlSchematronGetNode(ctxt, cur, path);
+ if (node == NULL)
+ node = cur;
+ xmlFree(path);
+ }
+
+ if ((node->ns == NULL) || (node->ns->prefix == NULL))
+ ret = xmlStrcat(ret, node->name);
+ else {
+ ret = xmlStrcat(ret, node->ns->prefix);
+ ret = xmlStrcat(ret, BAD_CAST ":");
+ ret = xmlStrcat(ret, node->name);
+ }
+ } else if (IS_SCHEMATRON(child, "value-of")) {
+ xmlChar *select;
+ xmlXPathObjectPtr eval;
+
+ select = xmlGetNoNsProp(child, BAD_CAST "select");
+ comp = xmlXPathCtxtCompile(ctxt->xctxt, select);
+ eval = xmlXPathCompiledEval(comp, ctxt->xctxt);
+
+ switch (eval->type) {
+ case XPATH_NODESET: {
+ int indx;
+ xmlChar *spacer = BAD_CAST " ";
+
+ if (eval->nodesetval) {
+ for (indx = 0; indx < eval->nodesetval->nodeNr; indx++) {
+ if (indx > 0)
+ ret = xmlStrcat(ret, spacer);
+ ret = xmlStrcat(ret, eval->nodesetval->nodeTab[indx]->name);
+ }
+ } else {
+ xmlGenericError(xmlGenericErrorContext,
+ "Empty node set\n");
+ }
+ break;
+ }
+ case XPATH_BOOLEAN: {
+ const char *str = eval->boolval ? "True" : "False";
+ ret = xmlStrcat(ret, BAD_CAST str);
+ break;
+ }
+ case XPATH_NUMBER: {
+ xmlChar *buf;
+ int size;
+
+ size = snprintf(NULL, 0, "%0g", eval->floatval);
+ buf = (xmlChar*) malloc(size * sizeof(xmlChar));
+ /* xmlStrPrintf(buf, size, "%0g", eval->floatval); // doesn't work */
+ sprintf((char*) buf, "%0g", eval->floatval);
+ ret = xmlStrcat(ret, buf);
+ free(buf);
+ break;
+ }
+ case XPATH_STRING:
+ ret = xmlStrcat(ret, eval->stringval);
+ break;
+ default:
+ xmlGenericError(xmlGenericErrorContext,
+ "Unsupported XPATH Type: %d\n", eval->type);
+ }
+ xmlXPathFreeObject(eval);
+ xmlXPathFreeCompExpr(comp);
+ xmlFree(select);
+ } else {
+ child = child->next;
+ continue;
+ }
+
+ /*
+ * remove superfluous \n
+ */
+ if (ret != NULL) {
+ int len = xmlStrlen(ret);
+ xmlChar c;
+
+ if (len > 0) {
+ c = ret[len - 1];
+ if ((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t')) {
+ while ((c == ' ') || (c == '\n') ||
+ (c == '\r') || (c == '\t')) {
+ len--;
+ if (len == 0)
+ break;
+ c = ret[len - 1];
+ }
+ ret[len] = ' ';
+ ret[len + 1] = 0;
+ }
+ }
+ }
child = child->next;
}
*/
static void
xmlSchematronReportSuccess(xmlSchematronValidCtxtPtr ctxt,
- xmlSchematronTestPtr test, xmlNodePtr cur, xmlSchematronPatternPtr pattern, 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 */
if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) &&
((ctxt->flags & XML_SCHEMATRON_OUT_XML) == 0) &&
- (test->type == XML_SCHEMATRON_REPORT))
+ (test->type == XML_SCHEMATRON_REPORT))
return;
if (ctxt->flags & XML_SCHEMATRON_OUT_XML) {
TODO
} else {
xmlChar *path;
- char msg[1000];
- long line;
- const xmlChar *report = NULL;
+ char msg[1000];
+ long line;
+ const xmlChar *report = NULL;
if (((test->type == XML_SCHEMATRON_REPORT) & (!success)) ||
- ((test->type == XML_SCHEMATRON_ASSERT) & (success)))
- return;
- line = xmlGetLineNo(cur);
- path = xmlGetNodePath(cur);
- if (path == NULL)
- path = (xmlChar *) cur->name;
+ ((test->type == XML_SCHEMATRON_ASSERT) & (success)))
+ return;
+ line = xmlGetLineNo(cur);
+ path = xmlGetNodePath(cur);
+ if (path == NULL)
+ path = (xmlChar *) cur->name;
#if 0
- if ((test->report != NULL) && (test->report[0] != 0))
- report = test->report;
+ if ((test->report != NULL) && (test->report[0] != 0))
+ report = test->report;
#endif
- if (test->node != NULL)
+ if (test->node != NULL)
report = xmlSchematronFormatReport(ctxt, test->node, cur);
- if (report == NULL) {
- if (test->type == XML_SCHEMATRON_ASSERT) {
+ if (report == NULL) {
+ if (test->type == XML_SCHEMATRON_ASSERT) {
report = xmlStrdup((const xmlChar *) "node failed assert");
- } else {
+ } else {
report = xmlStrdup((const xmlChar *) "node failed report");
- }
- }
- snprintf(msg, 999, "%s line %ld: %s\n", (const char *) path,
- line, (const char *) report);
+ }
+ }
+ snprintf(msg, 999, "%s line %ld: %s\n", (const char *) path,
+ line, (const char *) report);
if (ctxt->flags & XML_SCHEMATRON_OUT_ERROR) {
xmlStructuredErrorFunc schannel = NULL;
else
channel = ctxt->error;
data = ctxt->userData;
- }
+ }
__xmlRaiseError(schannel, channel, data,
NULL, cur, XML_FROM_SCHEMATRONV,
(const char *) report, 0, 0,
"%s", msg);
} else {
- xmlSchematronReportOutput(ctxt, cur, &msg[0]);
+ xmlSchematronReportOutput(ctxt, cur, &msg[0]);
}
xmlFree((char *) report);
- if ((path != NULL) && (path != (xmlChar *) cur->name))
- xmlFree(path);
+ if ((path != NULL) && (path != (xmlChar *) cur->name))
+ xmlFree(path);
}
}
*/
static void
xmlSchematronReportPattern(xmlSchematronValidCtxtPtr ctxt,
- xmlSchematronPatternPtr pattern) {
+ xmlSchematronPatternPtr pattern) {
if ((ctxt == NULL) || (pattern == NULL))
return;
if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) || (ctxt->flags & XML_SCHEMATRON_OUT_ERROR)) /* Error gives pattern name as part of error */
if (ctxt->flags & XML_SCHEMATRON_OUT_XML) {
TODO
} else {
- char msg[1000];
+ char msg[1000];
- if (pattern->name == NULL)
- return;
- snprintf(msg, 999, "Pattern: %s\n", (const char *) pattern->name);
- xmlSchematronReportOutput(ctxt, NULL, &msg[0]);
+ if (pattern->name == NULL)
+ return;
+ snprintf(msg, 999, "Pattern: %s\n", (const char *) pattern->name);
+ xmlSchematronReportOutput(ctxt, NULL, &msg[0]);
}
}
/************************************************************************
- * *
- * Validation against a Schematrontron *
- * *
+ * *
+ * Validation against a Schematrontron *
+ * *
************************************************************************/
/**
if (ret->xctxt == NULL) {
xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
NULL);
- xmlSchematronFreeValidCtxt(ret);
+ xmlSchematronFreeValidCtxt(ret);
return (NULL);
}
for (i = 0;i < schema->nbNamespaces;i++) {
if ((schema->namespaces[2 * i] == NULL) ||
(schema->namespaces[2 * i + 1] == NULL))
- break;
- xmlXPathRegisterNs(ret->xctxt, schema->namespaces[2 * i + 1],
- schema->namespaces[2 * i]);
+ break;
+ xmlXPathRegisterNs(ret->xctxt, schema->namespaces[2 * i + 1],
+ schema->namespaces[2 * i]);
}
return (ret);
}
static xmlNodePtr
xmlSchematronNextNode(xmlNodePtr cur) {
if (cur->children != NULL) {
- /*
- * Do not descend on entities declarations
- */
- if (cur->children->type != XML_ENTITY_DECL) {
- cur = cur->children;
- /*
- * Skip DTDs
- */
- if (cur->type != XML_DTD_NODE)
- return(cur);
- }
+ /*
+ * Do not descend on entities declarations
+ */
+ if (cur->children->type != XML_ENTITY_DECL) {
+ cur = cur->children;
+ /*
+ * Skip DTDs
+ */
+ if (cur->type != XML_DTD_NODE)
+ return(cur);
+ }
}
while (cur->next != NULL) {
- cur = cur->next;
- if ((cur->type != XML_ENTITY_DECL) &&
- (cur->type != XML_DTD_NODE))
- return(cur);
+ cur = cur->next;
+ if ((cur->type != XML_ENTITY_DECL) &&
+ (cur->type != XML_DTD_NODE))
+ return(cur);
}
do {
- cur = cur->parent;
- if (cur == NULL) break;
- if (cur->type == XML_DOCUMENT_NODE) return(NULL);
- if (cur->next != NULL) {
- cur = cur->next;
- return(cur);
- }
+ cur = cur->parent;
+ if (cur == NULL) break;
+ if (cur->type == XML_DOCUMENT_NODE) return(NULL);
+ if (cur->next != NULL) {
+ cur = cur->next;
+ return(cur);
+ }
} while (cur != NULL);
return(cur);
}
ctxt->xctxt->node = cur;
ret = xmlXPathCompiledEval(test->comp, ctxt->xctxt);
if (ret == NULL) {
- failed = 1;
+ failed = 1;
} else {
switch (ret->type) {
- case XPATH_XSLT_TREE:
- case XPATH_NODESET:
- if ((ret->nodesetval == NULL) ||
- (ret->nodesetval->nodeNr == 0))
- failed = 1;
- break;
- case XPATH_BOOLEAN:
- failed = !ret->boolval;
- break;
- case XPATH_NUMBER:
- if ((xmlXPathIsNaN(ret->floatval)) ||
- (ret->floatval == 0.0))
- failed = 1;
- break;
- case XPATH_STRING:
- if ((ret->stringval == NULL) ||
- (ret->stringval[0] == 0))
- failed = 1;
- break;
- case XPATH_UNDEFINED:
- case XPATH_POINT:
- case XPATH_RANGE:
- case XPATH_LOCATIONSET:
- case XPATH_USERS:
- failed = 1;
- break;
- }
- xmlXPathFreeObject(ret);
+ case XPATH_XSLT_TREE:
+ case XPATH_NODESET:
+ if ((ret->nodesetval == NULL) ||
+ (ret->nodesetval->nodeNr == 0))
+ failed = 1;
+ break;
+ case XPATH_BOOLEAN:
+ failed = !ret->boolval;
+ break;
+ case XPATH_NUMBER:
+ if ((xmlXPathIsNaN(ret->floatval)) ||
+ (ret->floatval == 0.0))
+ failed = 1;
+ break;
+ case XPATH_STRING:
+ if ((ret->stringval == NULL) ||
+ (ret->stringval[0] == 0))
+ failed = 1;
+ break;
+ case XPATH_UNDEFINED:
+#ifdef LIBXML_XPTR_LOCS_ENABLED
+ case XPATH_POINT:
+ case XPATH_RANGE:
+ case XPATH_LOCATIONSET:
+#endif
+ case XPATH_USERS:
+ failed = 1;
+ break;
+ }
+ xmlXPathFreeObject(ret);
}
if ((failed) && (test->type == XML_SCHEMATRON_ASSERT))
ctxt->nberrors++;
return(!failed);
}
+/**
+ * xmlSchematronRegisterVariables:
+ * @ctxt: the schema validation context
+ * @let: the list of let variables
+ * @instance: the document instance tree
+ * @cur: the current node
+ *
+ * Registers a list of let variables to the current context of @cur
+ *
+ * Returns -1 in case of errors, otherwise 0
+ */
+static int
+xmlSchematronRegisterVariables(xmlXPathContextPtr ctxt, xmlSchematronLetPtr let,
+ xmlDocPtr instance, xmlNodePtr cur)
+{
+ xmlXPathObjectPtr let_eval;
+
+ ctxt->doc = instance;
+ ctxt->node = cur;
+ while (let != NULL) {
+ let_eval = xmlXPathCompiledEval(let->comp, ctxt);
+ if (let_eval == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "Evaluation of compiled expression failed\n");
+ return -1;
+ }
+ if(xmlXPathRegisterVariableNS(ctxt, let->name, NULL, let_eval)) {
+ xmlGenericError(xmlGenericErrorContext,
+ "Registering a let variable failed\n");
+ return -1;
+ }
+ let = let->next;
+ }
+ return 0;
+}
+
+/**
+ * xmlSchematronUnregisterVariables:
+ * @ctxt: the schema validation context
+ * @let: the list of let variables
+ *
+ * Unregisters a list of let variables from the context
+ *
+ * Returns -1 in case of errors, otherwise 0
+ */
+static int
+xmlSchematronUnregisterVariables(xmlXPathContextPtr ctxt, xmlSchematronLetPtr let)
+{
+ while (let != NULL) {
+ if (xmlXPathRegisterVariableNS(ctxt, let->name, NULL, NULL)) {
+ xmlGenericError(xmlGenericErrorContext,
+ "Unregistering a let variable failed\n");
+ return -1;
+ }
+ let = let->next;
+ }
+ return 0;
+}
+
/**
* xmlSchematronValidateDoc:
* @ctxt: the schema validation context
root = xmlDocGetRootElement(instance);
if (root == NULL) {
TODO
- ctxt->nberrors++;
- return(1);
+ ctxt->nberrors++;
+ return(1);
}
if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) ||
(ctxt->flags == 0)) {
- /*
- * we are just trying to assert the validity of the document,
- * speed primes over the output, run in a single pass
- */
- cur = root;
- while (cur != NULL) {
- rule = ctxt->schema->rules;
- while (rule != NULL) {
- if (xmlPatternMatch(rule->pattern, cur) == 1) {
- test = rule->tests;
- while (test != NULL) {
- xmlSchematronRunTest(ctxt, test, instance, cur, (xmlSchematronPatternPtr)rule->pattern);
- test = test->next;
- }
- }
- rule = rule->next;
- }
-
- cur = xmlSchematronNextNode(cur);
- }
+ /*
+ * we are just trying to assert the validity of the document,
+ * speed primes over the output, run in a single pass
+ */
+ cur = root;
+ while (cur != NULL) {
+ rule = ctxt->schema->rules;
+ while (rule != NULL) {
+ if (xmlPatternMatch(rule->pattern, cur) == 1) {
+ test = rule->tests;
+
+ if (xmlSchematronRegisterVariables(ctxt->xctxt, rule->lets, instance, cur))
+ return -1;
+
+ while (test != NULL) {
+ xmlSchematronRunTest(ctxt, test, instance, cur, (xmlSchematronPatternPtr)rule->pattern);
+ test = test->next;
+ }
+
+ if (xmlSchematronUnregisterVariables(ctxt->xctxt, rule->lets))
+ return -1;
+
+ }
+ 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...
- * Check the exact semantic
- */
- cur = root;
- while (cur != NULL) {
- rule = pattern->rules;
- while (rule != NULL) {
- if (xmlPatternMatch(rule->pattern, cur) == 1) {
- test = rule->tests;
- while (test != NULL) {
- xmlSchematronRunTest(ctxt, test, instance, cur, pattern);
- test = test->next;
- }
- }
- rule = rule->patnext;
- }
-
- cur = xmlSchematronNextNode(cur);
- }
- pattern = pattern->next;
- }
+ * 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...
+ * Check the exact semantic
+ */
+ cur = root;
+ while (cur != NULL) {
+ rule = pattern->rules;
+ while (rule != NULL) {
+ if (xmlPatternMatch(rule->pattern, cur) == 1) {
+ test = rule->tests;
+ xmlSchematronRegisterVariables(ctxt->xctxt, rule->lets,
+ instance, cur);
+
+ while (test != NULL) {
+ xmlSchematronRunTest(ctxt, test, instance, cur, pattern);
+ test = test->next;
+ }
+
+ xmlSchematronUnregisterVariables(ctxt->xctxt, rule->lets);
+ }
+ rule = rule->patnext;
+ }
+
+ cur = xmlSchematronNextNode(cur);
+ }
+ pattern = pattern->next;
+ }
}
return(ctxt->nberrors);
}
fprintf(stderr, "failed to build schematron parser\n");
} else {
schema = xmlSchematronParse(pctxt);
- if (schema == NULL) {
- fprintf(stderr, "failed to compile schematron\n");
- }
- xmlSchematronFreeParserCtxt(pctxt);
+ if (schema == NULL) {
+ fprintf(stderr, "failed to compile schematron\n");
+ }
+ xmlSchematronFreeParserCtxt(pctxt);
}
instance = xmlReadFile("tst.sct", NULL,
XML_PARSE_NOENT | XML_PARSE_NOCDATA);
if (instance == NULL) {
- fprintf(stderr, "failed to parse instance\n");
+ fprintf(stderr, "failed to parse instance\n");
}
if ((schema != NULL) && (instance != NULL)) {
vctxt = xmlSchematronNewValidCtxt(schema);
- if (vctxt == NULL) {
- fprintf(stderr, "failed to build schematron validator\n");
- } else {
- ret = xmlSchematronValidateDoc(vctxt, instance);
- xmlSchematronFreeValidCtxt(vctxt);
- }
+ if (vctxt == NULL) {
+ fprintf(stderr, "failed to build schematron validator\n");
+ } else {
+ ret = xmlSchematronValidateDoc(vctxt, instance);
+ xmlSchematronFreeValidCtxt(vctxt);
+ }
}
xmlSchematronFree(schema);
xmlFreeDoc(instance);
return (0);
}
#endif
-#define bottom_schematron
-#include "elfgcchack.h"
+
#endif /* LIBXML_SCHEMATRON_ENABLED */