38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * schematron.c : implementation of the Schematron schema validity checking
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * See Copyright for the status of this software.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Daniel Veillard <daniel@veillard.com>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * TODO:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * + double check the semantic, especially
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * - multiple rules applying in a single pattern/node
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * - the semantic of libxml2 patterns vs. XSLT production referenced
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * by the spec.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * + export of results in SVRL
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * + full parsing and coverage of the spec, conformance of the input to the
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * spec
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * + divergences between the draft and the ISO proposed standard :-(
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * + hook and test include
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * + try and compare with the XSLT version
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#define IN_LIBXML
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include "libxml.h"
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef LIBXML_SCHEMATRON_ENABLED
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <string.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <libxml/parser.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <libxml/tree.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <libxml/uri.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <libxml/xpath.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <libxml/xpathInternals.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <libxml/pattern.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include <libxml/schematron.h>
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#define SCHEMATRON_PARSE_OPTIONS XML_PARSE_NOENT
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#define SCT_OLD_NS BAD_CAST "http://www.ascc.net/xml/schematron"
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#define XML_SCHEMATRON_NS BAD_CAST "http://purl.oclc.org/dsdl/schematron"
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic const xmlChar *xmlSchematronNs = XML_SCHEMATRON_NS;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic const xmlChar *xmlOldSchematronNs = SCT_OLD_NS;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#define IS_SCHEMATRON(node, elem) \
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ((node != NULL) && (node->type == XML_ELEMENT_NODE ) && \
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (node->ns != NULL) && \
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (xmlStrEqual(node->name, (const xmlChar *) elem)) && \
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ((xmlStrEqual(node->ns->href, xmlSchematronNs)) || \
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (xmlStrEqual(node->ns->href, xmlOldSchematronNs))))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#define NEXT_SCHEMATRON(node) \
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (node != NULL) { \
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((node->type == XML_ELEMENT_NODE ) && (node->ns != NULL) && \
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ((xmlStrEqual(node->ns->href, xmlSchematronNs)) || \
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (xmlStrEqual(node->ns->href, xmlOldSchematronNs)))) \
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync break; \
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync node = node->next; \
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * TODO:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * macro to flag unimplemented blocks
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#define TODO \
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGenericError(xmlGenericErrorContext, \
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "Unimplemented block at %s:%d\n", \
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __FILE__, __LINE__);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsynctypedef enum {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMATRON_ASSERT=1,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMATRON_REPORT=2
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync} xmlSchematronTestType;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * _xmlSchematronTest:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * A Schematrons test, either an assert or a report
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsynctypedef struct _xmlSchematronTest xmlSchematronTest;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsynctypedef xmlSchematronTest *xmlSchematronTestPtr;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstruct _xmlSchematronTest {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronTestPtr next; /* the next test in the list */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronTestType type; /* the test type */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlNodePtr node; /* the node in the tree */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *test; /* the expression to test */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlXPathCompExprPtr comp; /* the compiled expression */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *report; /* the message to report */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync};
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * _xmlSchematronRule:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * A Schematrons rule
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsynctypedef struct _xmlSchematronRule xmlSchematronRule;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsynctypedef xmlSchematronRule *xmlSchematronRulePtr;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstruct _xmlSchematronRule {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronRulePtr next; /* the next rule in the list */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronRulePtr patnext;/* the next rule in the pattern list */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlNodePtr node; /* the node in the tree */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *context; /* the context evaluation rule */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronTestPtr tests; /* the list of tests */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlPatternPtr pattern; /* the compiled pattern associated */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *report; /* the message to report */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync};
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * _xmlSchematronPattern:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * A Schematrons pattern
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsynctypedef struct _xmlSchematronPattern xmlSchematronPattern;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsynctypedef xmlSchematronPattern *xmlSchematronPatternPtr;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstruct _xmlSchematronPattern {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPatternPtr next;/* the next pattern in the list */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronRulePtr rules; /* the list of rules */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *name; /* the name of the pattern */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync};
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * _xmlSchematron:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * A Schematrons definition
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstruct _xmlSchematron {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync const xmlChar *name; /* schema name */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int preserve; /* was the document passed by the user */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlDocPtr doc; /* pointer to the parsed document */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int flags; /* specific to this schematron */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync void *_private; /* unused by the library */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlDictPtr dict; /* the dictionnary used internally */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync const xmlChar *title; /* the title if any */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int nbNs; /* the number of namespaces */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int nbPattern; /* the number of patterns */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPatternPtr patterns;/* the patterns found */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronRulePtr rules; /* the rules gathered */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int nbNamespaces; /* number of namespaces in the array */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int maxNamespaces; /* size of the array */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync const xmlChar **namespaces; /* the array of namespaces */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync};
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronValidCtxt:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * A Schematrons validation context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstruct _xmlSchematronValidCtxt {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int type;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int flags; /* an or of xmlSchematronValidOptions */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlDictPtr dict;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int nberrors;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int err;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPtr schema;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlXPathContextPtr xctxt;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync FILE *outputFile; /* if using XML_SCHEMATRON_OUT_FILE */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlBufferPtr outputBuffer; /* if using XML_SCHEMATRON_OUT_BUFFER */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlOutputWriteCallback iowrite; /* if using XML_SCHEMATRON_OUT_IO */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlOutputCloseCallback ioclose;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync void *ioctx;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync};
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstruct _xmlSchematronParserCtxt {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int type;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync const xmlChar *URL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlDocPtr doc;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int preserve; /* Whether the doc should be freed */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync const char *buffer;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int size;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlDictPtr dict; /* dictionnary for interned string names */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int nberrors;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int err;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlXPathContextPtr xctxt; /* the XPath context used for compilation */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPtr schema;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int nbNamespaces; /* number of namespaces in the array */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int maxNamespaces; /* size of the array */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync const xmlChar **namespaces; /* the array of namespaces */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int nbIncludes; /* number of includes in the array */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int maxIncludes; /* size of the array */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlNodePtr *includes; /* the array of includes */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* error rreporting data */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync void *userData; /* user specific data block */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronValidityErrorFunc error;/* the callback in case of errors */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronValidityWarningFunc warning;/* callback in case of warning */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlStructuredErrorFunc serror; /* the structured function */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync};
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#define XML_STRON_CTXT_PARSER 1
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#define XML_STRON_CTXT_VALIDATOR 2
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/************************************************************************
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Error reporting *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ************************************************************************/
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronPErrMemory:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @node: a context node
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @extra: extra informations
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Handle an out of memory condition
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic void
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronPErrMemory(xmlSchematronParserCtxtPtr ctxt,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync const char *extra, xmlNodePtr node)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->nberrors++;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync extra);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronPErr:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: the parsing context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @node: the context node
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @error: the error code
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @msg: the error message
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @str1: extra data
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @str2: extra data
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Handle a parser error
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic void
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronPErr(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr node, int error,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync const char *msg, const xmlChar * str1, const xmlChar * str2)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlGenericErrorFunc channel = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlStructuredErrorFunc schannel = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync void *data = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->nberrors++;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync channel = ctxt->error;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync data = ctxt->userData;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync schannel = ctxt->serror;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync error, XML_ERR_ERROR, NULL, 0,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (const char *) str1, (const char *) str2, NULL, 0, 0,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync msg, str1, str2);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronVTypeErrMemory:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @node: a context node
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @extra: extra informations
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Handle an out of memory condition
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic void
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronVErrMemory(xmlSchematronValidCtxtPtr ctxt,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync const char *extra, xmlNodePtr node)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->nberrors++;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->err = XML_SCHEMAV_INTERNAL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync extra);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/************************************************************************
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Parsing and compilation of the Schematrontrons *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ************************************************************************/
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronAddTest:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: the schema parsing context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @type: the type of test
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @rule: the parent rule
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @node: the node hosting the test
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @test: the associated test
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @report: the associated report string
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Add a test to a schematron
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns the new pointer or NULL in case of error
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic xmlSchematronTestPtr
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronAddTest(xmlSchematronParserCtxtPtr ctxt,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronTestType type,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronRulePtr rule,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlNodePtr node, xmlChar *test, xmlChar *report)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronTestPtr ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlXPathCompExprPtr comp;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((ctxt == NULL) || (rule == NULL) || (node == NULL) ||
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (test == NULL))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * try first to compile the test expression
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync comp = xmlXPathCtxtCompile(ctxt->xctxt, test);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (comp == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, node,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "Failed to compile test expression %s",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync test, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = (xmlSchematronTestPtr) xmlMalloc(sizeof(xmlSchematronTest));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErrMemory(ctxt, "allocating schema test", node);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync memset(ret, 0, sizeof(xmlSchematronTest));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->type = type;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->node = node;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->test = test;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->comp = comp;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->report = report;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->next = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (rule->tests == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync rule->tests = ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronTestPtr prev = rule->tests;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (prev->next != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync prev = prev->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync prev->next = ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronFreeTests:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @tests: a list of tests
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Free a list of tests.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic void
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronFreeTests(xmlSchematronTestPtr tests) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronTestPtr next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (tests != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync next = tests->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tests->test != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(tests->test);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tests->comp != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlXPathFreeCompExpr(tests->comp);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tests->report != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(tests->report);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(tests);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tests = next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronAddRule:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: the schema parsing context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @schema: a schema structure
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @node: the node hosting the rule
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @context: the associated context string
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @report: the associated report string
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Add a rule to a schematron
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns the new pointer or NULL in case of error
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic xmlSchematronRulePtr
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronAddRule(xmlSchematronParserCtxtPtr ctxt, xmlSchematronPtr schema,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPatternPtr pat, xmlNodePtr node,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *context, xmlChar *report)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronRulePtr ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlPatternPtr pattern;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (context == NULL))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Try first to compile the pattern
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pattern = xmlPatterncompile(context, ctxt->dict, XML_PATTERN_XPATH,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->namespaces);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (pattern == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, node,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "Failed to compile context expression %s",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync context, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = (xmlSchematronRulePtr) xmlMalloc(sizeof(xmlSchematronRule));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErrMemory(ctxt, "allocating schema rule", node);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync memset(ret, 0, sizeof(xmlSchematronRule));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->node = node;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->context = context;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->pattern = pattern;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->report = report;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->next = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (schema->rules == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync schema->rules = ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronRulePtr prev = schema->rules;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (prev->next != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync prev = prev->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync prev->next = ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->patnext = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (pat->rules == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pat->rules = ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronRulePtr prev = pat->rules;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (prev->patnext != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync prev = prev->patnext;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync prev->patnext = ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronFreeRules:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @rules: a list of rules
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Free a list of rules.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic void
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronFreeRules(xmlSchematronRulePtr rules) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronRulePtr next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (rules != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync next = rules->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (rules->tests)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronFreeTests(rules->tests);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (rules->context != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(rules->context);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (rules->pattern)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFreePattern(rules->pattern);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (rules->report != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(rules->report);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(rules);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync rules = next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronAddPattern:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: the schema parsing context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @schema: a schema structure
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @node: the node hosting the pattern
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @id: the id or name of the pattern
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Add a pattern to a schematron
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns the new pointer or NULL in case of error
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic xmlSchematronPatternPtr
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronAddPattern(xmlSchematronParserCtxtPtr ctxt,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPtr schema, xmlNodePtr node, xmlChar *name)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPatternPtr ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || (name == NULL))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = (xmlSchematronPatternPtr) xmlMalloc(sizeof(xmlSchematronPattern));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErrMemory(ctxt, "allocating schema pattern", node);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync memset(ret, 0, sizeof(xmlSchematronPattern));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->name = name;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->next = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (schema->patterns == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync schema->patterns = ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPatternPtr prev = schema->patterns;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (prev->next != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync prev = prev->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync prev->next = ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronFreePatterns:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @patterns: a list of patterns
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Free a list of patterns.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic void
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronFreePatterns(xmlSchematronPatternPtr patterns) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPatternPtr next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (patterns != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync next = patterns->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (patterns->name != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(patterns->name);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(patterns);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync patterns = next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronNewSchematron:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: a schema validation context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Allocate a new Schematron structure.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns the newly allocated structure or NULL in case or error
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic xmlSchematronPtr
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronNewSchematron(xmlSchematronParserCtxtPtr ctxt)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPtr ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = (xmlSchematronPtr) xmlMalloc(sizeof(xmlSchematron));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErrMemory(ctxt, "allocating schema", NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync memset(ret, 0, sizeof(xmlSchematron));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->dict = ctxt->dict;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlDictReference(ret->dict);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronFree:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @schema: a schema structure
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Deallocate a Schematron structure.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronFree(xmlSchematronPtr schema)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (schema == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((schema->doc != NULL) && (!(schema->preserve)))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFreeDoc(schema->doc);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (schema->namespaces != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree((char **) schema->namespaces);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronFreeRules(schema->rules);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronFreePatterns(schema->patterns);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlDictFree(schema->dict);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(schema);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronNewParserCtxt:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @URL: the location of the schema
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Create an XML Schematrons parse context for that file/resource expected
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * to contain an XML Schematrons file.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns the parser context or NULL in case of error
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronParserCtxtPtr
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronNewParserCtxt(const char *URL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronParserCtxtPtr ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (URL == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret =
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (xmlSchematronParserCtxtPtr)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlMalloc(sizeof(xmlSchematronParserCtxt));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErrMemory(NULL, "allocating schema parser context",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync memset(ret, 0, sizeof(xmlSchematronParserCtxt));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->type = XML_STRON_CTXT_PARSER;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->dict = xmlDictCreate();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->includes = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->xctxt = xmlXPathNewContext(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret->xctxt == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronFreeParserCtxt(ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->xctxt->flags = XML_XPATH_CHECKNS;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronNewMemParserCtxt:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @buffer: a pointer to a char array containing the schemas
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @size: the size of the array
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Create an XML Schematrons parse context for that memory buffer expected
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * to contain an XML Schematrons file.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns the parser context or NULL in case of error
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronParserCtxtPtr
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronNewMemParserCtxt(const char *buffer, int size)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronParserCtxtPtr ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((buffer == NULL) || (size <= 0))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret =
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (xmlSchematronParserCtxtPtr)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlMalloc(sizeof(xmlSchematronParserCtxt));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErrMemory(NULL, "allocating schema parser context",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync memset(ret, 0, sizeof(xmlSchematronParserCtxt));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->buffer = buffer;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->size = size;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->dict = xmlDictCreate();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->xctxt = xmlXPathNewContext(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret->xctxt == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronFreeParserCtxt(ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronNewDocParserCtxt:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @doc: a preparsed document tree
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Create an XML Schematrons parse context for that document.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * NB. The document may be modified during the parsing process.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns the parser context or NULL in case of error
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronParserCtxtPtr
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronNewDocParserCtxt(xmlDocPtr doc)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronParserCtxtPtr ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (doc == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret =
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (xmlSchematronParserCtxtPtr)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlMalloc(sizeof(xmlSchematronParserCtxt));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErrMemory(NULL, "allocating schema parser context",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync memset(ret, 0, sizeof(xmlSchematronParserCtxt));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->doc = doc;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->dict = xmlDictCreate();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* The application has responsibility for the document */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->preserve = 1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->xctxt = xmlXPathNewContext(doc);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret->xctxt == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronFreeParserCtxt(ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronFreeParserCtxt:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: the schema parser context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Free the resources associated to the schema parser context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronFreeParserCtxt(xmlSchematronParserCtxtPtr ctxt)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt->doc != NULL && !ctxt->preserve)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFreeDoc(ctxt->doc);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt->xctxt != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlXPathFreeContext(ctxt->xctxt);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt->namespaces != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree((char **) ctxt->namespaces);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlDictFree(ctxt->dict);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(ctxt);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if 0
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronPushInclude:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: the schema parser context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @doc: the included document
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @cur: the current include node
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Add an included document
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic void
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronPushInclude(xmlSchematronParserCtxtPtr ctxt,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlDocPtr doc, xmlNodePtr cur)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt->includes == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->maxIncludes = 10;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->includes = (xmlNodePtr *)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlMalloc(ctxt->maxIncludes * 2 * sizeof(xmlNodePtr));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt->includes == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErrMemory(NULL, "allocating parser includes",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->nbIncludes = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else if (ctxt->nbIncludes + 2 >= ctxt->maxIncludes) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlNodePtr *tmp;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tmp = (xmlNodePtr *)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlRealloc(ctxt->includes, ctxt->maxIncludes * 4 *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync sizeof(xmlNodePtr));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tmp == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErrMemory(NULL, "allocating parser includes",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->includes = tmp;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->maxIncludes *= 2;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->includes[2 * ctxt->nbIncludes] = cur;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->includes[2 * ctxt->nbIncludes + 1] = (xmlNodePtr) doc;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->nbIncludes++;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronPopInclude:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: the schema parser context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Pop an include level. The included document is being freed
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns the node immediately following the include or NULL if the
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * include list was empty.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic xmlNodePtr
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronPopInclude(xmlSchematronParserCtxtPtr ctxt)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlDocPtr doc;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlNodePtr ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt->nbIncludes <= 0)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->nbIncludes--;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync doc = (xmlDocPtr) ctxt->includes[2 * ctxt->nbIncludes + 1];
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = ctxt->includes[2 * ctxt->nbIncludes];
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFreeDoc(doc);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = ret->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(xmlSchematronPopInclude(ctxt));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronAddNamespace:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: the schema parser context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @prefix: the namespace prefix
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ns: the namespace name
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Add a namespace definition in the context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic void
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronAddNamespace(xmlSchematronParserCtxtPtr ctxt,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync const xmlChar *prefix, const xmlChar *ns)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt->namespaces == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->maxNamespaces = 10;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->namespaces = (const xmlChar **)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlMalloc(ctxt->maxNamespaces * 2 * sizeof(const xmlChar *));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt->namespaces == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErrMemory(NULL, "allocating parser namespaces",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->nbNamespaces = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else if (ctxt->nbNamespaces + 2 >= ctxt->maxNamespaces) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync const xmlChar **tmp;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync tmp = (const xmlChar **)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlRealloc((xmlChar **) ctxt->namespaces, ctxt->maxNamespaces * 4 *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync sizeof(const xmlChar *));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (tmp == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErrMemory(NULL, "allocating parser namespaces",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->namespaces = tmp;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->maxNamespaces *= 2;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->namespaces[2 * ctxt->nbNamespaces] =
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlDictLookup(ctxt->dict, ns, -1);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->namespaces[2 * ctxt->nbNamespaces + 1] =
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlDictLookup(ctxt->dict, prefix, -1);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->nbNamespaces++;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->namespaces[2 * ctxt->nbNamespaces] = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->namespaces[2 * ctxt->nbNamespaces + 1] = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronParseRule:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: a schema validation context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @rule: the rule node
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * parse a rule element
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic void
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronParseRule(xmlSchematronParserCtxtPtr ctxt,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPatternPtr pattern,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlNodePtr rule)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlNodePtr cur;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int nbChecks = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *test;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *context;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *report;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronRulePtr ruleptr;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronTestPtr testptr;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((ctxt == NULL) || (rule == NULL)) return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync context = xmlGetNoNsProp(rule, BAD_CAST "context");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (context == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, rule,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "rule has no context attribute",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else if (context[0] == 0) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, rule,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "rule has an empty context attribute",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(context);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ruleptr = xmlSchematronAddRule(ctxt, ctxt->schema, pattern,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync rule, context, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ruleptr == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(context);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cur = rule->children;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NEXT_SCHEMATRON(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (cur != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (IS_SCHEMATRON(cur, "assert")) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync nbChecks++;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync test = xmlGetNoNsProp(cur, BAD_CAST "test");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (test == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, cur,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "assert has no test attribute",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else if (test[0] == 0) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, cur,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "assert has an empty test attribute",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(test);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* TODO will need dynamic processing instead */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync report = xmlNodeGetContent(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_ASSERT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ruleptr, cur, test, report);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (testptr == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(test);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else if (IS_SCHEMATRON(cur, "report")) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync nbChecks++;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync test = xmlGetNoNsProp(cur, BAD_CAST "test");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (test == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, cur,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "assert has no test attribute",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else if (test[0] == 0) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, cur,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "assert has an empty test attribute",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(test);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* TODO will need dynamic processing instead */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync report = xmlNodeGetContent(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_REPORT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ruleptr, cur, test, report);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (testptr == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(test);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, cur,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "Expecting an assert or a report element instead of %s",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cur->name, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cur = cur->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NEXT_SCHEMATRON(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (nbChecks == 0) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, rule,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "rule has no assert nor report element", NULL, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronParsePattern:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: a schema validation context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @pat: the pattern node
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * parse a pattern element
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic void
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronParsePattern(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr pat)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlNodePtr cur;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPatternPtr pattern;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int nbRules = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *id;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((ctxt == NULL) || (pat == NULL)) return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync id = xmlGetNoNsProp(pat, BAD_CAST "id");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (id == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync id = xmlGetNoNsProp(pat, BAD_CAST "name");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pattern = xmlSchematronAddPattern(ctxt, ctxt->schema, pat, id);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (pattern == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (id != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(id);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cur = pat->children;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NEXT_SCHEMATRON(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (cur != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (IS_SCHEMATRON(cur, "rule")) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronParseRule(ctxt, pattern, cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync nbRules++;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, cur,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "Expecting a rule element instead of %s", cur->name, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cur = cur->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NEXT_SCHEMATRON(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (nbRules == 0) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, pat,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "Pattern has no rule element", NULL, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if 0
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronLoadInclude:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: a schema validation context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @cur: the include element
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Load the include document, Push the current pointer
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns the updated node pointer
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic xmlNodePtr
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronLoadInclude(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr cur)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlNodePtr ret = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlDocPtr doc = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *href = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *base = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *URI = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((ctxt == NULL) || (cur == NULL))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync href = xmlGetNoNsProp(cur, BAD_CAST "href");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (href == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, cur,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "Include has no href attribute", NULL, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(cur->next);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* do the URI base composition, load and find the root */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync base = xmlNodeGetBase(cur->doc, cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync URI = xmlBuildURI(href, base);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync doc = xmlReadFile((const char *) URI, NULL, SCHEMATRON_PARSE_OPTIONS);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (doc == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, cur,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_FAILED_LOAD,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "could not load include '%s'.\n",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync URI, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync goto done;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = xmlDocGetRootElement(doc);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, cur,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_FAILED_LOAD,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "could not find root from include '%s'.\n",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync URI, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync goto done;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* Success, push the include for rollback on exit */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPushInclude(ctxt, doc, cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncdone:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (doc != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFreeDoc(doc);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(href);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (base != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(base);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (URI != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(URI);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronParse:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: a schema validation context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * parse a schema definition resource and build an internal
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * XML Shema struture which can be used to validate instances.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns the internal XML Schematron structure built from the resource or
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * NULL in case of error
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronPtr
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronParse(xmlSchematronParserCtxtPtr ctxt)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPtr ret = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlDocPtr doc;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlNodePtr root, cur;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int preserve = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->nberrors = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * First step is to parse the input document into an DOM/Infoset
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt->URL != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync doc = xmlReadFile((const char *) ctxt->URL, NULL,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync SCHEMATRON_PARSE_OPTIONS);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (doc == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, NULL,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_FAILED_LOAD,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "xmlSchematronParse: could not load '%s'.\n",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->URL, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->preserve = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else if (ctxt->buffer != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync doc = xmlReadMemory(ctxt->buffer, ctxt->size, NULL, NULL,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync SCHEMATRON_PARSE_OPTIONS);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (doc == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, NULL,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_FAILED_PARSE,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "xmlSchematronParse: could not parse.\n",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync doc->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->URL = xmlDictLookup(ctxt->dict, BAD_CAST "in_memory_buffer", -1);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->preserve = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else if (ctxt->doc != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync doc = ctxt->doc;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync preserve = 1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->preserve = 1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, NULL,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOTHING_TO_PARSE,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "xmlSchematronParse: could not parse.\n",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Then extract the root and Schematron parse it
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync root = xmlDocGetRootElement(doc);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (root == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, (xmlNodePtr) doc,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "The schema has no document element.\n", NULL, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (!preserve) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFreeDoc(doc);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (!IS_SCHEMATRON(root, "schema")) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, root,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "The XML document '%s' is not a XML schematron document",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->URL, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync goto exit;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = xmlSchematronNewSchematron(ctxt);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync goto exit;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->schema = ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * scan the schema elements
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cur = root->children;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NEXT_SCHEMATRON(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (IS_SCHEMATRON(cur, "title")) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *title = xmlNodeGetContent(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (title != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->title = xmlDictLookup(ret->dict, title, -1);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(title);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cur = cur->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NEXT_SCHEMATRON(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (IS_SCHEMATRON(cur, "ns")) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *prefix = xmlGetNoNsProp(cur, BAD_CAST "prefix");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *uri = xmlGetNoNsProp(cur, BAD_CAST "uri");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((uri == NULL) || (uri[0] == 0)) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, cur,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "ns element has no uri", NULL, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((prefix == NULL) || (prefix[0] == 0)) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, cur,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "ns element has no prefix", NULL, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((prefix) && (uri)) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlXPathRegisterNs(ctxt->xctxt, prefix, uri);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronAddNamespace(ctxt, prefix, uri);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->nbNs++;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (uri)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(uri);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (prefix)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(prefix);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cur = cur->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NEXT_SCHEMATRON(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (cur != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (IS_SCHEMATRON(cur, "pattern")) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronParsePattern(ctxt, cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->nbPattern++;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, cur,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "Expecting a pattern element instead of %s", cur->name, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cur = cur->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NEXT_SCHEMATRON(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret->nbPattern == 0) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErr(ctxt, root,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_SCHEMAP_NOROOT,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync "The schematron document '%s' has no pattern",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->URL, NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync goto exit;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* the original document must be kept for reporting */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->doc = doc;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (preserve) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->preserve = 1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync preserve = 1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncexit:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (!preserve) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFreeDoc(doc);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt->nberrors != 0) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronFree(ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->namespaces = ctxt->namespaces;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->nbNamespaces = ctxt->nbNamespaces;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->namespaces = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/************************************************************************
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Schematrontron Reports handler *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ************************************************************************/
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic xmlNodePtr
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronGetNode(xmlSchematronValidCtxtPtr ctxt,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlNodePtr cur, const xmlChar *xpath) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlNodePtr node = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlXPathObjectPtr ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((ctxt == NULL) || (cur == NULL) || (xpath == NULL))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->xctxt->doc = cur->doc;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->xctxt->node = cur;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = xmlXPathEval(xpath, ctxt->xctxt);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((ret->type == XPATH_NODESET) &&
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (ret->nodesetval != NULL) && (ret->nodesetval->nodeNr > 0))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync node = ret->nodesetval->nodeTab[0];
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlXPathFreeObject(ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(node);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronReportOutput:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: the validation context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @cur: the current node tested
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @msg: the message output
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Output part of the report to whatever channel the user selected
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic void
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronReportOutput(xmlSchematronValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlNodePtr cur ATTRIBUTE_UNUSED,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync const char *msg) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* TODO */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync fprintf(stderr, "%s", msg);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronFormatReport:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: the validation context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @test: the test node
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @cur: the current node tested
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Build the string being reported to the user.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns a report string or NULL in case of error. The string needs
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * to be deallocated by teh caller
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic xmlChar *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlNodePtr test, xmlNodePtr cur) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *ret = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlNodePtr child, node;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((test == NULL) || (cur == NULL))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync child = test->children;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (child != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((child->type == XML_TEXT_NODE) ||
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (child->type == XML_CDATA_SECTION_NODE))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = xmlStrcat(ret, child->content);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync else if (IS_SCHEMATRON(child, "name")) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *path;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync path = xmlGetNoNsProp(child, BAD_CAST "path");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync node = cur;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (path != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync node = xmlSchematronGetNode(ctxt, cur, path);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (node == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync node = cur;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(path);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((node->ns == NULL) || (node->ns->prefix == NULL))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = xmlStrcat(ret, node->name);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = xmlStrcat(ret, node->ns->prefix);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = xmlStrcat(ret, BAD_CAST ":");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = xmlStrcat(ret, node->name);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync child = child->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync continue;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * remove superfluous \n
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int len = xmlStrlen(ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar c;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (len > 0) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync c = ret[len - 1];
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t')) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while ((c == ' ') || (c == '\n') ||
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (c == '\r') || (c == '\t')) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync len--;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (len == 0)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync break;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync c = ret[len - 1];
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret[len] = ' ';
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret[len + 1] = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync child = child->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronReportSuccess:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: the validation context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @test: the compiled test
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @cur: the current node tested
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @success: boolean value for the result
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * called from the validation engine when an assert or report test have
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * been done.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic void
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronReportSuccess(xmlSchematronValidCtxtPtr ctxt,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronTestPtr test, xmlNodePtr cur, int success) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((ctxt == NULL) || (cur == NULL) || (test == NULL))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /* if quiet and not SVRL report only failures */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) &&
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ((ctxt->flags & XML_SCHEMATRON_OUT_XML) == 0) &&
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (test->type == XML_SCHEMATRON_REPORT))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt->flags & XML_SCHEMATRON_OUT_XML) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync TODO
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlChar *path;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync char msg[1000];
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync long line;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync const xmlChar *report = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (((test->type == XML_SCHEMATRON_REPORT) & (!success)) ||
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ((test->type == XML_SCHEMATRON_ASSERT) & (success)))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync line = xmlGetLineNo(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync path = xmlGetNodePath(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (path == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync path = (xmlChar *) cur->name;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#if 0
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((test->report != NULL) && (test->report[0] != 0))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync report = test->report;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (test->node != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync report = xmlSchematronFormatReport(ctxt, test->node, cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (report == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (test->type == XML_SCHEMATRON_ASSERT) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync snprintf(msg, 999, "%s line %ld: node failed assert\n",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (const char *) path, line);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync snprintf(msg, 999, "%s line %ld: node failed report\n",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (const char *) path, line);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync snprintf(msg, 999, "%s line %ld: %s\n", (const char *) path,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync line, (const char *) report);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree((char *) report);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronReportOutput(ctxt, cur, &msg[0]);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((path != NULL) && (path != (xmlChar *) cur->name))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(path);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronReportPattern:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: the validation context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @pattern: the current pattern
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * called from the validation engine when starting to check a pattern
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic void
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronReportPattern(xmlSchematronValidCtxtPtr ctxt,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPatternPtr pattern) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((ctxt == NULL) || (pattern == NULL))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt->flags & XML_SCHEMATRON_OUT_QUIET)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt->flags & XML_SCHEMATRON_OUT_XML) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync TODO
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync char msg[1000];
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (pattern->name == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync snprintf(msg, 999, "Pattern: %s\n", (const char *) pattern->name);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronReportOutput(ctxt, NULL, &msg[0]);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/************************************************************************
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Validation against a Schematrontron *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ************************************************************************/
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronNewValidCtxt:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @schema: a precompiled XML Schematrons
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @options: a set of xmlSchematronValidOptions
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Create an XML Schematrons validation context based on the given schema.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns the validation context or NULL in case of error
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronValidCtxtPtr
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronNewValidCtxt(xmlSchematronPtr schema, int options)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int i;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronValidCtxtPtr ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = (xmlSchematronValidCtxtPtr) xmlMalloc(sizeof(xmlSchematronValidCtxt));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronVErrMemory(NULL, "allocating validation context",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync memset(ret, 0, sizeof(xmlSchematronValidCtxt));
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->type = XML_STRON_CTXT_VALIDATOR;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->schema = schema;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->xctxt = xmlXPathNewContext(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret->flags = options;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret->xctxt == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPErrMemory(NULL, "allocating schema parser XPath context",
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronFreeValidCtxt(ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync for (i = 0;i < schema->nbNamespaces;i++) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((schema->namespaces[2 * i] == NULL) ||
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (schema->namespaces[2 * i + 1] == NULL))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync break;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlXPathRegisterNs(ret->xctxt, schema->namespaces[2 * i + 1],
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync schema->namespaces[2 * i]);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronFreeValidCtxt:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: the schema validation context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Free the resources associated to the schema validation context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncvoid
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronFreeValidCtxt(xmlSchematronValidCtxtPtr ctxt)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt == NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt->xctxt != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlXPathFreeContext(ctxt->xctxt);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ctxt->dict != NULL)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlDictFree(ctxt->dict);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFree(ctxt);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic xmlNodePtr
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronNextNode(xmlNodePtr cur) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (cur->children != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Do not descend on entities declarations
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (cur->children->type != XML_ENTITY_DECL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cur = cur->children;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Skip DTDs
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (cur->type != XML_DTD_NODE)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (cur->next != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cur = cur->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((cur->type != XML_ENTITY_DECL) &&
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (cur->type != XML_DTD_NODE))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync do {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cur = cur->parent;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (cur == NULL) break;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (cur->type == XML_DOCUMENT_NODE) return(NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (cur->next != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cur = cur->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } while (cur != NULL);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronRunTest:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: the schema validation context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @test: the current test
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @instance: the document instace tree
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @cur: the current node in the instance
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Validate a rule against a tree instance at a given position
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns 1 in case of success, 0 if error and -1 in case of internal error
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncstatic int
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronRunTest(xmlSchematronValidCtxtPtr ctxt,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronTestPtr test, xmlDocPtr instance, xmlNodePtr cur)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlXPathObjectPtr ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int failed;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync failed = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->xctxt->doc = instance;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->xctxt->node = cur;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = xmlXPathCompiledEval(test->comp, ctxt->xctxt);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (ret == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync failed = 1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync switch (ret->type) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync case XPATH_XSLT_TREE:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync case XPATH_NODESET:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((ret->nodesetval == NULL) ||
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (ret->nodesetval->nodeNr == 0))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync failed = 1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync break;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync case XPATH_BOOLEAN:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync failed = !ret->boolval;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync break;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync case XPATH_NUMBER:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((xmlXPathIsNaN(ret->floatval)) ||
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (ret->floatval == 0.0))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync failed = 1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync break;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync case XPATH_STRING:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((ret->stringval == NULL) ||
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (ret->stringval[0] == 0))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync failed = 1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync break;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync case XPATH_UNDEFINED:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync case XPATH_POINT:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync case XPATH_RANGE:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync case XPATH_LOCATIONSET:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync case XPATH_USERS:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync failed = 1;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync break;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlXPathFreeObject(ret);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((failed) && (test->type == XML_SCHEMATRON_ASSERT))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->nberrors++;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync else if ((!failed) && (test->type == XML_SCHEMATRON_REPORT))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->nberrors++;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronReportSuccess(ctxt, test, cur, !failed);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(!failed);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync/**
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * xmlSchematronValidateDoc:
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @ctxt: the schema validation context
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * @instance: the document instace tree
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Validate a tree instance against the schematron
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync *
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Returns 0 in case of success, -1 in case of internal error
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * and an error count otherwise.
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncint
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncxmlSchematronValidateDoc(xmlSchematronValidCtxtPtr ctxt, xmlDocPtr instance)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlNodePtr cur, root;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPatternPtr pattern;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronRulePtr rule;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronTestPtr test;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((ctxt == NULL) || (ctxt->schema == NULL) ||
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (ctxt->schema->rules == NULL) || (instance == NULL))
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(-1);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->nberrors = 0;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync root = xmlDocGetRootElement(instance);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (root == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync TODO
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ctxt->nberrors++;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(1);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((ctxt->flags & XML_SCHEMATRON_OUT_QUIET) ||
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync (ctxt->flags == 0)) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * we are just trying to assert the validity of the document,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * speed primes over the output, run in a single pass
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cur = root;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (cur != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync rule = ctxt->schema->rules;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (rule != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (xmlPatternMatch(rule->pattern, cur) == 1) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync test = rule->tests;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (test != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronRunTest(ctxt, test, instance, cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync test = test->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync rule = rule->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cur = xmlSchematronNextNode(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Process all contexts one at a time
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pattern = ctxt->schema->patterns;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (pattern != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronReportPattern(ctxt, pattern);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync /*
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * TODO convert the pattern rule to a direct XPath and
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * compute directly instead of using the pattern matching
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * over the full document...
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync * Check the exact semantic
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync */
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cur = root;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (cur != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync rule = pattern->rules;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (rule != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (xmlPatternMatch(rule->pattern, cur) == 1) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync test = rule->tests;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync while (test != NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronRunTest(ctxt, test, instance, cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync test = test->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync rule = rule->patnext;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync cur = xmlSchematronNextNode(cur);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pattern = pattern->next;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return(ctxt->nberrors);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#ifdef STANDALONE
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncint
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsyncmain(void)
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync{
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync int ret;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlDocPtr instance;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronParserCtxtPtr pctxt;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronValidCtxtPtr vctxt;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronPtr schema = NULL;
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync pctxt = xmlSchematronNewParserCtxt("tst.sct");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (pctxt == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync fprintf(stderr, "failed to build schematron parser\n");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync schema = xmlSchematronParse(pctxt);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (schema == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync fprintf(stderr, "failed to compile schematron\n");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronFreeParserCtxt(pctxt);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync instance = xmlReadFile("tst.sct", NULL,
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync XML_PARSE_NOENT | XML_PARSE_NOCDATA);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (instance == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync fprintf(stderr, "failed to parse instance\n");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if ((schema != NULL) && (instance != NULL)) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync vctxt = xmlSchematronNewValidCtxt(schema);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync if (vctxt == NULL) {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync fprintf(stderr, "failed to build schematron validator\n");
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync } else {
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync ret = xmlSchematronValidateDoc(vctxt, instance);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronFreeValidCtxt(vctxt);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync }
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlSchematronFree(schema);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlFreeDoc(instance);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlCleanupParser();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync xmlMemoryDump();
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync return (0);
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync}
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#define bottom_schematron
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#include "elfgcchack.h"
38ae7e4efe803ea78b6499cd05a394db32623e41vboxsync#endif /* LIBXML_SCHEMATRON_ENABLED */