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