15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * schematron.c : implementation of the Schematron schema validity checking 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See Copyright for the status of this software. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Daniel Veillard <daniel@veillard.com> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * + double check the semantic, especially 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - multiple rules applying in a single pattern/node 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - the semantic of libxml2 patterns vs. XSLT production referenced 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * by the spec. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * + export of results in SVRL 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * + full parsing and coverage of the spec, conformance of the input to the 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * spec 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * + divergences between the draft and the ISO proposed standard :-( 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * + hook and test include 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * + try and compare with the XSLT version 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IN_LIBXML 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libxml.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_SCHEMATRON_ENABLED 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/parser.h> 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/tree.h> 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/uri.h> 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xpath.h> 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xpathInternals.h> 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/pattern.h> 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/schematron.h> 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SCHEMATRON_PARSE_OPTIONS XML_PARSE_NOENT 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SCT_OLD_NS BAD_CAST "http://www.ascc.net/xml/schematron" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XML_SCHEMATRON_NS BAD_CAST "http://purl.oclc.org/dsdl/schematron" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const xmlChar *xmlSchematronNs = XML_SCHEMATRON_NS; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const xmlChar *xmlOldSchematronNs = SCT_OLD_NS; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IS_SCHEMATRON(node, elem) \ 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((node != NULL) && (node->type == XML_ELEMENT_NODE ) && \ 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (node->ns != NULL) && \ 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(node->name, (const xmlChar *) elem)) && \ 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((xmlStrEqual(node->ns->href, xmlSchematronNs)) || \ 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(node->ns->href, xmlOldSchematronNs)))) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NEXT_SCHEMATRON(node) \ 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (node != NULL) { \ 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((node->type == XML_ELEMENT_NODE ) && (node->ns != NULL) && \ 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((xmlStrEqual(node->ns->href, xmlSchematronNs)) || \ 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(node->ns->href, xmlOldSchematronNs)))) \ 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; \ 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = node->next; \ 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * macro to flag unimplemented blocks 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TODO \ 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError(xmlGenericErrorContext, \ 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Unimplemented block at %s:%d\n", \ 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __FILE__, __LINE__); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMATRON_ASSERT=1, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMATRON_REPORT=2 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} xmlSchematronTestType; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * _xmlSchematronTest: 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A Schematrons test, either an assert or a report 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlSchematronTest xmlSchematronTest; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlSchematronTest *xmlSchematronTestPtr; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlSchematronTest { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronTestPtr next; /* the next test in the list */ 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronTestType type; /* the test type */ 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr node; /* the node in the tree */ 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *test; /* the expression to test */ 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathCompExprPtr comp; /* the compiled expression */ 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *report; /* the message to report */ 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * _xmlSchematronRule: 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A Schematrons rule 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlSchematronRule xmlSchematronRule; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlSchematronRule *xmlSchematronRulePtr; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlSchematronRule { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronRulePtr next; /* the next rule in the list */ 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronRulePtr patnext;/* the next rule in the pattern list */ 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr node; /* the node in the tree */ 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *context; /* the context evaluation rule */ 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronTestPtr tests; /* the list of tests */ 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlPatternPtr pattern; /* the compiled pattern associated */ 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *report; /* the message to report */ 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * _xmlSchematronPattern: 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A Schematrons pattern 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlSchematronPattern xmlSchematronPattern; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlSchematronPattern *xmlSchematronPatternPtr; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlSchematronPattern { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPatternPtr next;/* the next pattern in the list */ 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronRulePtr rules; /* the list of rules */ 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *name; /* the name of the pattern */ 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * _xmlSchematron: 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A Schematrons definition 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlSchematron { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *name; /* schema name */ 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int preserve; /* was the document passed by the user */ 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDocPtr doc; /* pointer to the parsed document */ 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags; /* specific to this schematron */ 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *_private; /* unused by the library */ 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictPtr dict; /* the dictionnary used internally */ 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *title; /* the title if any */ 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbNs; /* the number of namespaces */ 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbPattern; /* the number of patterns */ 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPatternPtr patterns;/* the patterns found */ 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronRulePtr rules; /* the rules gathered */ 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbNamespaces; /* number of namespaces in the array */ 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int maxNamespaces; /* size of the array */ 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar **namespaces; /* the array of namespaces */ 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronValidCtxt: 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A Schematrons validation context 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlSchematronValidCtxt { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int type; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags; /* an or of xmlSchematronValidOptions */ 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictPtr dict; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nberrors; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int err; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPtr schema; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathContextPtr xctxt; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE *outputFile; /* if using XML_SCHEMATRON_OUT_FILE */ 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlBufferPtr outputBuffer; /* if using XML_SCHEMATRON_OUT_BUFFER */ 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlOutputWriteCallback iowrite; /* if using XML_SCHEMATRON_OUT_IO */ 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlOutputCloseCallback ioclose; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *ioctx; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* error reporting data */ 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *userData; /* user specific data block */ 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronValidityErrorFunc error;/* the callback in case of errors */ 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronValidityWarningFunc warning;/* callback in case of warning */ 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlStructuredErrorFunc serror; /* the structured function */ 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlSchematronParserCtxt { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int type; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *URL; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDocPtr doc; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int preserve; /* Whether the doc should be freed */ 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *buffer; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictPtr dict; /* dictionnary for interned string names */ 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nberrors; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int err; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathContextPtr xctxt; /* the XPath context used for compilation */ 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPtr schema; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbNamespaces; /* number of namespaces in the array */ 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int maxNamespaces; /* size of the array */ 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar **namespaces; /* the array of namespaces */ 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbIncludes; /* number of includes in the array */ 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int maxIncludes; /* size of the array */ 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr *includes; /* the array of includes */ 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* error reporting data */ 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *userData; /* user specific data block */ 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronValidityErrorFunc error;/* the callback in case of errors */ 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronValidityWarningFunc warning;/* callback in case of warning */ 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlStructuredErrorFunc serror; /* the structured function */ 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XML_STRON_CTXT_PARSER 1 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XML_STRON_CTXT_VALIDATOR 2 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Error reporting * 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronPErrMemory: 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node: a context node 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @extra: extra informations 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Handle an out of memory condition 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronPErrMemory(xmlSchematronParserCtxtPtr ctxt, 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *extra, xmlNodePtr node) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt != NULL) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nberrors++; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL, 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronPErr: 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the parsing context 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node: the context node 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @error: the error code 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @msg: the error message 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @str1: extra data 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @str2: extra data 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Handle a parser error 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronPErr(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr node, int error, 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *msg, const xmlChar * str1, const xmlChar * str2) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericErrorFunc channel = NULL; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlStructuredErrorFunc schannel = NULL; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *data = NULL; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt != NULL) { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nberrors++; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel = ctxt->error; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = ctxt->userData; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schannel = ctxt->serror; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error, XML_ERR_ERROR, NULL, 0, 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (const char *) str1, (const char *) str2, NULL, 0, 0, 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg, str1, str2); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronVTypeErrMemory: 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node: a context node 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @extra: extra informations 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Handle an out of memory condition 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronVErrMemory(xmlSchematronValidCtxtPtr ctxt, 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *extra, xmlNodePtr node) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt != NULL) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nberrors++; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->err = XML_SCHEMAV_INTERNAL; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL, 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Parsing and compilation of the Schematrontrons * 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronAddTest: 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the schema parsing context 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @type: the type of test 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @rule: the parent rule 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node: the node hosting the test 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @test: the associated test 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @report: the associated report string 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Add a test to a schematron 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new pointer or NULL in case of error 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlSchematronTestPtr 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronAddTest(xmlSchematronParserCtxtPtr ctxt, 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronTestType type, 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronRulePtr rule, 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr node, xmlChar *test, xmlChar *report) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronTestPtr ret; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathCompExprPtr comp; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (rule == NULL) || (node == NULL) || 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (test == NULL)) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * try first to compile the test expression 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp = xmlXPathCtxtCompile(ctxt->xctxt, test); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp == NULL) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, node, 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Failed to compile test expression %s", 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test, NULL); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (xmlSchematronTestPtr) xmlMalloc(sizeof(xmlSchematronTest)); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErrMemory(ctxt, "allocating schema test", node); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret, 0, sizeof(xmlSchematronTest)); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->type = type; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->node = node; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->test = test; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->comp = comp; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->report = report; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->next = NULL; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rule->tests == NULL) { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule->tests = ret; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronTestPtr prev = rule->tests; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (prev->next != NULL) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev = prev->next; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev->next = ret; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (ret); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronFreeTests: 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @tests: a list of tests 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free a list of tests. 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronFreeTests(xmlSchematronTestPtr tests) { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronTestPtr next; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (tests != NULL) { 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = tests->next; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tests->test != NULL) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(tests->test); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tests->comp != NULL) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeCompExpr(tests->comp); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tests->report != NULL) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(tests->report); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(tests); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tests = next; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronAddRule: 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the schema parsing context 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @schema: a schema structure 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node: the node hosting the rule 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @context: the associated context string 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @report: the associated report string 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Add a rule to a schematron 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new pointer or NULL in case of error 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlSchematronRulePtr 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronAddRule(xmlSchematronParserCtxtPtr ctxt, xmlSchematronPtr schema, 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPatternPtr pat, xmlNodePtr node, 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *context, xmlChar *report) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronRulePtr ret; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlPatternPtr pattern; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (context == NULL)) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Try first to compile the pattern 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pattern = xmlPatterncompile(context, ctxt->dict, XML_PATTERN_XPATH, 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->namespaces); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pattern == NULL) { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, node, 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Failed to compile context expression %s", 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context, NULL); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (xmlSchematronRulePtr) xmlMalloc(sizeof(xmlSchematronRule)); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErrMemory(ctxt, "allocating schema rule", node); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret, 0, sizeof(xmlSchematronRule)); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->node = node; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->context = context; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->pattern = pattern; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->report = report; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->next = NULL; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (schema->rules == NULL) { 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schema->rules = ret; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronRulePtr prev = schema->rules; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (prev->next != NULL) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev = prev->next; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev->next = ret; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->patnext = NULL; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pat->rules == NULL) { 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pat->rules = ret; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronRulePtr prev = pat->rules; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (prev->patnext != NULL) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev = prev->patnext; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev->patnext = ret; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (ret); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronFreeRules: 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @rules: a list of rules 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free a list of rules. 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronFreeRules(xmlSchematronRulePtr rules) { 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronRulePtr next; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (rules != NULL) { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = rules->next; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rules->tests) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronFreeTests(rules->tests); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rules->context != NULL) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(rules->context); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rules->pattern) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreePattern(rules->pattern); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rules->report != NULL) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(rules->report); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(rules); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rules = next; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronAddPattern: 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the schema parsing context 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @schema: a schema structure 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node: the node hosting the pattern 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @id: the id or name of the pattern 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Add a pattern to a schematron 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the new pointer or NULL in case of error 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlSchematronPatternPtr 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronAddPattern(xmlSchematronParserCtxtPtr ctxt, 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPtr schema, xmlNodePtr node, xmlChar *name) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPatternPtr ret; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || (name == NULL)) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (xmlSchematronPatternPtr) xmlMalloc(sizeof(xmlSchematronPattern)); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErrMemory(ctxt, "allocating schema pattern", node); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret, 0, sizeof(xmlSchematronPattern)); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->name = name; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->next = NULL; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (schema->patterns == NULL) { 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schema->patterns = ret; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPatternPtr prev = schema->patterns; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (prev->next != NULL) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev = prev->next; 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev->next = ret; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (ret); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronFreePatterns: 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @patterns: a list of patterns 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free a list of patterns. 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronFreePatterns(xmlSchematronPatternPtr patterns) { 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPatternPtr next; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (patterns != NULL) { 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = patterns->next; 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (patterns->name != NULL) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(patterns->name); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(patterns); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) patterns = next; 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronNewSchematron: 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a schema validation context 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Allocate a new Schematron structure. 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly allocated structure or NULL in case or error 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlSchematronPtr 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronNewSchematron(xmlSchematronParserCtxtPtr ctxt) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPtr ret; 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (xmlSchematronPtr) xmlMalloc(sizeof(xmlSchematron)); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErrMemory(ctxt, "allocating schema", NULL); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret, 0, sizeof(xmlSchematron)); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->dict = ctxt->dict; 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictReference(ret->dict); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (ret); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronFree: 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @schema: a schema structure 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Deallocate a Schematron structure. 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronFree(xmlSchematronPtr schema) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (schema == NULL) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((schema->doc != NULL) && (!(schema->preserve))) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(schema->doc); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (schema->namespaces != NULL) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree((char **) schema->namespaces); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronFreeRules(schema->rules); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronFreePatterns(schema->patterns); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictFree(schema->dict); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(schema); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronNewParserCtxt: 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @URL: the location of the schema 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create an XML Schematrons parse context for that file/resource expected 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to contain an XML Schematrons file. 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the parser context or NULL in case of error 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronParserCtxtPtr 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronNewParserCtxt(const char *URL) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronParserCtxtPtr ret; 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (URL == NULL) 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlSchematronParserCtxtPtr) 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlMalloc(sizeof(xmlSchematronParserCtxt)); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErrMemory(NULL, "allocating schema parser context", 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret, 0, sizeof(xmlSchematronParserCtxt)); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->type = XML_STRON_CTXT_PARSER; 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->dict = xmlDictCreate(); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->includes = NULL; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->xctxt = xmlXPathNewContext(NULL); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret->xctxt == NULL) { 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context", 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronFreeParserCtxt(ret); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->xctxt->flags = XML_XPATH_CHECKNS; 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (ret); 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronNewMemParserCtxt: 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @buffer: a pointer to a char array containing the schemas 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @size: the size of the array 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create an XML Schematrons parse context for that memory buffer expected 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to contain an XML Schematrons file. 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the parser context or NULL in case of error 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronParserCtxtPtr 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronNewMemParserCtxt(const char *buffer, int size) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronParserCtxtPtr ret; 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((buffer == NULL) || (size <= 0)) 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlSchematronParserCtxtPtr) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlMalloc(sizeof(xmlSchematronParserCtxt)); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErrMemory(NULL, "allocating schema parser context", 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret, 0, sizeof(xmlSchematronParserCtxt)); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->buffer = buffer; 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->size = size; 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->dict = xmlDictCreate(); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->xctxt = xmlXPathNewContext(NULL); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret->xctxt == NULL) { 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context", 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronFreeParserCtxt(ret); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (ret); 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronNewDocParserCtxt: 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @doc: a preparsed document tree 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create an XML Schematrons parse context for that document. 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NB. The document may be modified during the parsing process. 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the parser context or NULL in case of error 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronParserCtxtPtr 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronNewDocParserCtxt(xmlDocPtr doc) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronParserCtxtPtr ret; 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (doc == NULL) 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlSchematronParserCtxtPtr) 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlMalloc(sizeof(xmlSchematronParserCtxt)); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErrMemory(NULL, "allocating schema parser context", 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret, 0, sizeof(xmlSchematronParserCtxt)); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->doc = doc; 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->dict = xmlDictCreate(); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The application has responsibility for the document */ 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->preserve = 1; 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->xctxt = xmlXPathNewContext(doc); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret->xctxt == NULL) { 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context", 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronFreeParserCtxt(ret); 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (ret); 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronFreeParserCtxt: 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the schema parser context 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free the resources associated to the schema parser context 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronFreeParserCtxt(xmlSchematronParserCtxtPtr ctxt) 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->doc != NULL && !ctxt->preserve) 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(ctxt->doc); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->xctxt != NULL) { 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeContext(ctxt->xctxt); 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->namespaces != NULL) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree((char **) ctxt->namespaces); 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictFree(ctxt->dict); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronPushInclude: 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the schema parser context 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @doc: the included document 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur: the current include node 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Add an included document 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronPushInclude(xmlSchematronParserCtxtPtr ctxt, 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDocPtr doc, xmlNodePtr cur) 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->includes == NULL) { 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->maxIncludes = 10; 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->includes = (xmlNodePtr *) 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlMalloc(ctxt->maxIncludes * 2 * sizeof(xmlNodePtr)); 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->includes == NULL) { 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErrMemory(NULL, "allocating parser includes", 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nbIncludes = 0; 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ctxt->nbIncludes + 2 >= ctxt->maxIncludes) { 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr *tmp; 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = (xmlNodePtr *) 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRealloc(ctxt->includes, ctxt->maxIncludes * 4 * 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(xmlNodePtr)); 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) { 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErrMemory(NULL, "allocating parser includes", 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->includes = tmp; 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->maxIncludes *= 2; 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->includes[2 * ctxt->nbIncludes] = cur; 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->includes[2 * ctxt->nbIncludes + 1] = (xmlNodePtr) doc; 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nbIncludes++; 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronPopInclude: 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the schema parser context 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Pop an include level. The included document is being freed 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the node immediately following the include or NULL if the 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * include list was empty. 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlNodePtr 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronPopInclude(xmlSchematronParserCtxtPtr ctxt) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDocPtr doc; 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr ret; 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->nbIncludes <= 0) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nbIncludes--; 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc = (xmlDocPtr) ctxt->includes[2 * ctxt->nbIncludes + 1]; 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = ctxt->includes[2 * ctxt->nbIncludes]; 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(doc); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret != NULL) 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = ret->next; 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlSchematronPopInclude(ctxt)); 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronAddNamespace: 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the schema parser context 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @prefix: the namespace prefix 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ns: the namespace name 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Add a namespace definition in the context 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronAddNamespace(xmlSchematronParserCtxtPtr ctxt, 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *prefix, const xmlChar *ns) 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->namespaces == NULL) { 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->maxNamespaces = 10; 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->namespaces = (const xmlChar **) 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlMalloc(ctxt->maxNamespaces * 2 * sizeof(const xmlChar *)); 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->namespaces == NULL) { 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErrMemory(NULL, "allocating parser namespaces", 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nbNamespaces = 0; 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ctxt->nbNamespaces + 2 >= ctxt->maxNamespaces) { 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar **tmp; 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = (const xmlChar **) 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRealloc((xmlChar **) ctxt->namespaces, ctxt->maxNamespaces * 4 * 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(const xmlChar *)); 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) { 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErrMemory(NULL, "allocating parser namespaces", 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->namespaces = tmp; 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->maxNamespaces *= 2; 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->namespaces[2 * ctxt->nbNamespaces] = 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictLookup(ctxt->dict, ns, -1); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->namespaces[2 * ctxt->nbNamespaces + 1] = 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictLookup(ctxt->dict, prefix, -1); 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nbNamespaces++; 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->namespaces[2 * ctxt->nbNamespaces] = NULL; 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->namespaces[2 * ctxt->nbNamespaces + 1] = NULL; 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronParseRule: 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a schema validation context 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @rule: the rule node 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * parse a rule element 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronParseRule(xmlSchematronParserCtxtPtr ctxt, 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPatternPtr pattern, 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr rule) 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr cur; 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbChecks = 0; 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *test; 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *context; 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *report; 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronRulePtr ruleptr; 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronTestPtr testptr; 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (rule == NULL)) return; 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context = xmlGetNoNsProp(rule, BAD_CAST "context"); 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (context == NULL) { 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, rule, 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "rule has no context attribute", 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (context[0] == 0) { 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, rule, 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "rule has an empty context attribute", 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL); 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(context); 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ruleptr = xmlSchematronAddRule(ctxt, ctxt->schema, pattern, 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule, context, NULL); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ruleptr == NULL) { 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(context); 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = rule->children; 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT_SCHEMATRON(cur); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (cur != NULL) { 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IS_SCHEMATRON(cur, "assert")) { 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbChecks++; 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test = xmlGetNoNsProp(cur, BAD_CAST "test"); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (test == NULL) { 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, cur, 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "assert has no test attribute", 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL); 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (test[0] == 0) { 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, cur, 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "assert has an empty test attribute", 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL); 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(test); 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO will need dynamic processing instead */ 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) report = xmlNodeGetContent(cur); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_ASSERT, 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ruleptr, cur, test, report); 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (testptr == NULL) 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(test); 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (IS_SCHEMATRON(cur, "report")) { 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbChecks++; 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test = xmlGetNoNsProp(cur, BAD_CAST "test"); 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (test == NULL) { 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, cur, 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "assert has no test attribute", 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL); 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (test[0] == 0) { 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, cur, 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "assert has an empty test attribute", 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL); 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(test); 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO will need dynamic processing instead */ 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) report = xmlNodeGetContent(cur); 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_REPORT, 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ruleptr, cur, test, report); 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (testptr == NULL) 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(test); 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, cur, 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Expecting an assert or a report element instead of %s", 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur->name, NULL); 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = cur->next; 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT_SCHEMATRON(cur); 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nbChecks == 0) { 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, rule, 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "rule has no assert nor report element", NULL, NULL); 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronParsePattern: 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a schema validation context 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @pat: the pattern node 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * parse a pattern element 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronParsePattern(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr pat) 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr cur; 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPatternPtr pattern; 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbRules = 0; 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *id; 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (pat == NULL)) return; 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id = xmlGetNoNsProp(pat, BAD_CAST "id"); 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (id == NULL) { 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id = xmlGetNoNsProp(pat, BAD_CAST "name"); 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pattern = xmlSchematronAddPattern(ctxt, ctxt->schema, pat, id); 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pattern == NULL) { 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (id != NULL) 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(id); 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = pat->children; 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT_SCHEMATRON(cur); 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (cur != NULL) { 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IS_SCHEMATRON(cur, "rule")) { 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronParseRule(ctxt, pattern, cur); 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbRules++; 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, cur, 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Expecting a rule element instead of %s", cur->name, NULL); 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = cur->next; 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT_SCHEMATRON(cur); 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nbRules == 0) { 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, pat, 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Pattern has no rule element", NULL, NULL); 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronLoadInclude: 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a schema validation context 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur: the include element 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Load the include document, Push the current pointer 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the updated node pointer 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlNodePtr 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronLoadInclude(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr cur) 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr ret = NULL; 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDocPtr doc = NULL; 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *href = NULL; 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *base = NULL; 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *URI = NULL; 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (cur == NULL)) 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) href = xmlGetNoNsProp(cur, BAD_CAST "href"); 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (href == NULL) { 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, cur, 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Include has no href attribute", NULL, NULL); 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(cur->next); 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* do the URI base composition, load and find the root */ 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base = xmlNodeGetBase(cur->doc, cur); 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URI = xmlBuildURI(href, base); 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc = xmlReadFile((const char *) URI, NULL, SCHEMATRON_PARSE_OPTIONS); 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (doc == NULL) { 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, cur, 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_FAILED_LOAD, 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "could not load include '%s'.\n", 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URI, NULL); 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto done; 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlDocGetRootElement(doc); 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, cur, 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_FAILED_LOAD, 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "could not find root from include '%s'.\n", 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URI, NULL); 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto done; 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Success, push the include for rollback on exit */ 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPushInclude(ctxt, doc, cur); 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)done: 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (doc != NULL) 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(doc); 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(href); 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base != NULL) 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(base); 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (URI != NULL) 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(URI); 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronParse: 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a schema validation context 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * parse a schema definition resource and build an internal 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * XML Shema struture which can be used to validate instances. 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the internal XML Schematron structure built from the resource or 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NULL in case of error 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronPtr 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronParse(xmlSchematronParserCtxtPtr ctxt) 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPtr ret = NULL; 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDocPtr doc; 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr root, cur; 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int preserve = 0; 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nberrors = 0; 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * First step is to parse the input document into an DOM/Infoset 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->URL != NULL) { 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc = xmlReadFile((const char *) ctxt->URL, NULL, 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCHEMATRON_PARSE_OPTIONS); 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (doc == NULL) { 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, NULL, 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_FAILED_LOAD, 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xmlSchematronParse: could not load '%s'.\n", 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->URL, NULL); 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->preserve = 0; 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ctxt->buffer != NULL) { 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc = xmlReadMemory(ctxt->buffer, ctxt->size, NULL, NULL, 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCHEMATRON_PARSE_OPTIONS); 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (doc == NULL) { 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, NULL, 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_FAILED_PARSE, 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xmlSchematronParse: could not parse.\n", 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL); 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc->URL = xmlStrdup(BAD_CAST "in_memory_buffer"); 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->URL = xmlDictLookup(ctxt->dict, BAD_CAST "in_memory_buffer", -1); 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->preserve = 0; 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ctxt->doc != NULL) { 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc = ctxt->doc; 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preserve = 1; 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->preserve = 1; 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, NULL, 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOTHING_TO_PARSE, 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xmlSchematronParse: could not parse.\n", 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL); 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Then extract the root and Schematron parse it 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root = xmlDocGetRootElement(doc); 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (root == NULL) { 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, (xmlNodePtr) doc, 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "The schema has no document element.\n", NULL, NULL); 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!preserve) { 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(doc); 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IS_SCHEMATRON(root, "schema")) { 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, root, 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "The XML document '%s' is not a XML schematron document", 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->URL, NULL); 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto exit; 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlSchematronNewSchematron(ctxt); 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto exit; 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->schema = ret; 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * scan the schema elements 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = root->children; 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT_SCHEMATRON(cur); 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IS_SCHEMATRON(cur, "title")) { 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *title = xmlNodeGetContent(cur); 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (title != NULL) { 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->title = xmlDictLookup(ret->dict, title, -1); 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(title); 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = cur->next; 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT_SCHEMATRON(cur); 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (IS_SCHEMATRON(cur, "ns")) { 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *prefix = xmlGetNoNsProp(cur, BAD_CAST "prefix"); 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *uri = xmlGetNoNsProp(cur, BAD_CAST "uri"); 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((uri == NULL) || (uri[0] == 0)) { 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, cur, 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ns element has no uri", NULL, NULL); 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((prefix == NULL) || (prefix[0] == 0)) { 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, cur, 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ns element has no prefix", NULL, NULL); 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((prefix) && (uri)) { 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathRegisterNs(ctxt->xctxt, prefix, uri); 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronAddNamespace(ctxt, prefix, uri); 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->nbNs++; 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uri) 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(uri); 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefix) 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(prefix); 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = cur->next; 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT_SCHEMATRON(cur); 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (cur != NULL) { 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IS_SCHEMATRON(cur, "pattern")) { 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronParsePattern(ctxt, cur); 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->nbPattern++; 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, cur, 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Expecting a pattern element instead of %s", cur->name, NULL); 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = cur->next; 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT_SCHEMATRON(cur); 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret->nbPattern == 0) { 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErr(ctxt, root, 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_SCHEMAP_NOROOT, 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "The schematron document '%s' has no pattern", 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->URL, NULL); 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto exit; 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* the original document must be kept for reporting */ 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->doc = doc; 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (preserve) { 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->preserve = 1; 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preserve = 1; 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)exit: 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!preserve) { 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(doc); 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret != NULL) { 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->nberrors != 0) { 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronFree(ret); 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = NULL; 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->namespaces = ctxt->namespaces; 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->nbNamespaces = ctxt->nbNamespaces; 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->namespaces = NULL; 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (ret); 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Schematrontron Reports handler * 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlNodePtr 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronGetNode(xmlSchematronValidCtxtPtr ctxt, 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr cur, const xmlChar *xpath) { 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr node = NULL; 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr ret; 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (cur == NULL) || (xpath == NULL)) 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xctxt->doc = cur->doc; 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xctxt->node = cur; 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlXPathEval(xpath, ctxt->xctxt); 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ret->type == XPATH_NODESET) && 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ret->nodesetval != NULL) && (ret->nodesetval->nodeNr > 0)) 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = ret->nodesetval->nodeTab[0]; 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(ret); 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(node); 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronReportOutput: 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the validation context 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur: the current node tested 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @msg: the message output 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Output part of the report to whatever channel the user selected 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronReportOutput(xmlSchematronValidCtxtPtr ctxt ATTRIBUTE_UNUSED, 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr cur ATTRIBUTE_UNUSED, 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *msg) { 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO */ 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "%s", msg); 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronFormatReport: 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the validation context 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @test: the test node 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur: the current node tested 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Build the string being reported to the user. 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns a report string or NULL in case of error. The string needs 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to be deallocated by teh caller 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlChar * 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt, 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr test, xmlNodePtr cur) { 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *ret = NULL; 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr child, node; 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((test == NULL) || (cur == NULL)) 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child = test->children; 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (child != NULL) { 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((child->type == XML_TEXT_NODE) || 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (child->type == XML_CDATA_SECTION_NODE)) 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlStrcat(ret, child->content); 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (IS_SCHEMATRON(child, "name")) { 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *path; 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path = xmlGetNoNsProp(child, BAD_CAST "path"); 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = cur; 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (path != NULL) { 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = xmlSchematronGetNode(ctxt, cur, path); 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node == NULL) 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = cur; 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(path); 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((node->ns == NULL) || (node->ns->prefix == NULL)) 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlStrcat(ret, node->name); 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlStrcat(ret, node->ns->prefix); 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlStrcat(ret, BAD_CAST ":"); 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlStrcat(ret, node->name); 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child = child->next; 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * remove superfluous \n 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret != NULL) { 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len = xmlStrlen(ret); 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar c; 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (len > 0) { 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = ret[len - 1]; 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t')) { 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((c == ' ') || (c == '\n') || 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (c == '\r') || (c == '\t')) { 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len--; 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (len == 0) 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = ret[len - 1]; 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret[len] = ' '; 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret[len + 1] = 0; 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child = child->next; 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronReportSuccess: 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the validation context 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @test: the compiled test 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur: the current node tested 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @success: boolean value for the result 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * called from the validation engine when an assert or report test have 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * been done. 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronReportSuccess(xmlSchematronValidCtxtPtr ctxt, 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronTestPtr test, xmlNodePtr cur, xmlSchematronPatternPtr pattern, int success) { 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (cur == NULL) || (test == NULL)) 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if quiet and not SVRL report only failures */ 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) && 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((ctxt->flags & XML_SCHEMATRON_OUT_XML) == 0) && 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (test->type == XML_SCHEMATRON_REPORT)) 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->flags & XML_SCHEMATRON_OUT_XML) { 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TODO 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *path; 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char msg[1000]; 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long line; 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *report = NULL; 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((test->type == XML_SCHEMATRON_REPORT) & (!success)) || 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((test->type == XML_SCHEMATRON_ASSERT) & (success))) 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) line = xmlGetLineNo(cur); 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path = xmlGetNodePath(cur); 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (path == NULL) 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path = (xmlChar *) cur->name; 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((test->report != NULL) && (test->report[0] != 0)) 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) report = test->report; 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (test->node != NULL) 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) report = xmlSchematronFormatReport(ctxt, test->node, cur); 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (report == NULL) { 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (test->type == XML_SCHEMATRON_ASSERT) { 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) report = xmlStrdup((const xmlChar *) "node failed assert"); 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) report = xmlStrdup((const xmlChar *) "node failed report"); 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(msg, 999, "%s line %ld: %s\n", (const char *) path, 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) line, (const char *) report); 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->flags & XML_SCHEMATRON_OUT_ERROR) { 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlStructuredErrorFunc schannel = NULL; 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericErrorFunc channel = NULL; 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *data = NULL; 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt != NULL) { 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->serror != NULL) 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schannel = ctxt->serror; 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel = ctxt->error; 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = ctxt->userData; 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __xmlRaiseError(schannel, channel, data, 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, cur, XML_FROM_SCHEMATRONV, 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (test->type == XML_SCHEMATRON_ASSERT)?XML_SCHEMATRONV_ASSERT:XML_SCHEMATRONV_REPORT, 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_ERR_ERROR, NULL, line, 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (pattern == NULL)?NULL:((const char *) pattern->name), 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (const char *) path, 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (const char *) report, 0, 0, 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%s", msg); 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronReportOutput(ctxt, cur, &msg[0]); 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree((char *) report); 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((path != NULL) && (path != (xmlChar *) cur->name)) 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(path); 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronReportPattern: 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the validation context 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @pattern: the current pattern 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * called from the validation engine when starting to check a pattern 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronReportPattern(xmlSchematronValidCtxtPtr ctxt, 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPatternPtr pattern) { 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (pattern == NULL)) 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) || (ctxt->flags & XML_SCHEMATRON_OUT_ERROR)) /* Error gives pattern name as part of error */ 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->flags & XML_SCHEMATRON_OUT_XML) { 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TODO 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char msg[1000]; 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pattern->name == NULL) 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(msg, 999, "Pattern: %s\n", (const char *) pattern->name); 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronReportOutput(ctxt, NULL, &msg[0]); 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Validation against a Schematrontron * 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronSetValidStructuredErrors: 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a Schematron validation context 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @serror: the structured error function 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctx: the functions context 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Set the structured error callback 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronSetValidStructuredErrors(xmlSchematronValidCtxtPtr ctxt, 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlStructuredErrorFunc serror, void *ctx) 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->serror = serror; 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = NULL; 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->warning = NULL; 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->userData = ctx; 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronNewValidCtxt: 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @schema: a precompiled XML Schematrons 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @options: a set of xmlSchematronValidOptions 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create an XML Schematrons validation context based on the given schema. 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the validation context or NULL in case of error 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronValidCtxtPtr 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronNewValidCtxt(xmlSchematronPtr schema, int options) 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronValidCtxtPtr ret; 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (xmlSchematronValidCtxtPtr) xmlMalloc(sizeof(xmlSchematronValidCtxt)); 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronVErrMemory(NULL, "allocating validation context", 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ret, 0, sizeof(xmlSchematronValidCtxt)); 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->type = XML_STRON_CTXT_VALIDATOR; 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->schema = schema; 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->xctxt = xmlXPathNewContext(NULL); 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->flags = options; 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret->xctxt == NULL) { 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context", 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronFreeValidCtxt(ret); 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < schema->nbNamespaces;i++) { 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((schema->namespaces[2 * i] == NULL) || 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (schema->namespaces[2 * i + 1] == NULL)) 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathRegisterNs(ret->xctxt, schema->namespaces[2 * i + 1], 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schema->namespaces[2 * i]); 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (ret); 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronFreeValidCtxt: 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the schema validation context 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free the resources associated to the schema validation context 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronFreeValidCtxt(xmlSchematronValidCtxtPtr ctxt) 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->xctxt != NULL) 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeContext(ctxt->xctxt); 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->dict != NULL) 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictFree(ctxt->dict); 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt); 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlNodePtr 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronNextNode(xmlNodePtr cur) { 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur->children != NULL) { 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Do not descend on entities declarations 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur->children->type != XML_ENTITY_DECL) { 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = cur->children; 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Skip DTDs 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur->type != XML_DTD_NODE) 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(cur); 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (cur->next != NULL) { 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = cur->next; 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((cur->type != XML_ENTITY_DECL) && 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cur->type != XML_DTD_NODE)) 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(cur); 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = cur->parent; 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur == NULL) break; 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur->type == XML_DOCUMENT_NODE) return(NULL); 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur->next != NULL) { 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = cur->next; 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(cur); 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (cur != NULL); 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(cur); 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronRunTest: 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the schema validation context 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @test: the current test 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @instance: the document instace tree 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur: the current node in the instance 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Validate a rule against a tree instance at a given position 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 in case of success, 0 if error and -1 in case of internal error 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronRunTest(xmlSchematronValidCtxtPtr ctxt, 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronTestPtr test, xmlDocPtr instance, xmlNodePtr cur, xmlSchematronPatternPtr pattern) 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr ret; 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int failed; 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed = 0; 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xctxt->doc = instance; 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xctxt->node = cur; 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlXPathCompiledEval(test->comp, ctxt->xctxt); 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) { 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed = 1; 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (ret->type) { 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_XSLT_TREE: 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_NODESET: 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ret->nodesetval == NULL) || 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ret->nodesetval->nodeNr == 0)) 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed = 1; 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_BOOLEAN: 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed = !ret->boolval; 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_NUMBER: 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((xmlXPathIsNaN(ret->floatval)) || 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ret->floatval == 0.0)) 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed = 1; 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_STRING: 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ret->stringval == NULL) || 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ret->stringval[0] == 0)) 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed = 1; 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_UNDEFINED: 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_POINT: 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_RANGE: 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_LOCATIONSET: 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_USERS: 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed = 1; 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(ret); 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((failed) && (test->type == XML_SCHEMATRON_ASSERT)) 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nberrors++; 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if ((!failed) && (test->type == XML_SCHEMATRON_REPORT)) 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nberrors++; 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronReportSuccess(ctxt, test, cur, pattern, !failed); 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(!failed); 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlSchematronValidateDoc: 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the schema validation context 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @instance: the document instace tree 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Validate a tree instance against the schematron 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 0 in case of success, -1 in case of internal error 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and an error count otherwise. 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlSchematronValidateDoc(xmlSchematronValidCtxtPtr ctxt, xmlDocPtr instance) 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr cur, root; 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPatternPtr pattern; 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronRulePtr rule; 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronTestPtr test; 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (ctxt->schema == NULL) || 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ctxt->schema->rules == NULL) || (instance == NULL)) 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nberrors = 0; 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root = xmlDocGetRootElement(instance); 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (root == NULL) { 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TODO 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->nberrors++; 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) || 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ctxt->flags == 0)) { 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * we are just trying to assert the validity of the document, 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * speed primes over the output, run in a single pass 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = root; 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (cur != NULL) { 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule = ctxt->schema->rules; 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (rule != NULL) { 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlPatternMatch(rule->pattern, cur) == 1) { 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test = rule->tests; 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (test != NULL) { 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronRunTest(ctxt, test, instance, cur, (xmlSchematronPatternPtr)rule->pattern); 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test = test->next; 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule = rule->next; 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = xmlSchematronNextNode(cur); 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Process all contexts one at a time 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pattern = ctxt->schema->patterns; 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (pattern != NULL) { 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronReportPattern(ctxt, pattern); 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO convert the pattern rule to a direct XPath and 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * compute directly instead of using the pattern matching 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * over the full document... 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check the exact semantic 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = root; 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (cur != NULL) { 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule = pattern->rules; 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (rule != NULL) { 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlPatternMatch(rule->pattern, cur) == 1) { 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test = rule->tests; 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (test != NULL) { 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronRunTest(ctxt, test, instance, cur, pattern); 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test = test->next; 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rule = rule->patnext; 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = xmlSchematronNextNode(cur); 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pattern = pattern->next; 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ctxt->nberrors); 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef STANDALONE 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)main(void) 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret; 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDocPtr instance; 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronParserCtxtPtr pctxt; 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronValidCtxtPtr vctxt; 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronPtr schema = NULL; 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pctxt = xmlSchematronNewParserCtxt("tst.sct"); 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pctxt == NULL) { 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "failed to build schematron parser\n"); 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schema = xmlSchematronParse(pctxt); 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (schema == NULL) { 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "failed to compile schematron\n"); 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronFreeParserCtxt(pctxt); 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance = xmlReadFile("tst.sct", NULL, 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_PARSE_NOENT | XML_PARSE_NOCDATA); 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (instance == NULL) { 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "failed to parse instance\n"); 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((schema != NULL) && (instance != NULL)) { 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vctxt = xmlSchematronNewValidCtxt(schema); 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (vctxt == NULL) { 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "failed to build schematron validator\n"); 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlSchematronValidateDoc(vctxt, instance); 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronFreeValidCtxt(vctxt); 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlSchematronFree(schema); 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeDoc(instance); 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlCleanupParser(); 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlMemoryDump(); 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define bottom_schematron 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "elfgcchack.h" 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* LIBXML_SCHEMATRON_ENABLED */ 1786