webengine/osswebengine/WebCore/platform/symbian/Libxml2/Libxml2_xmlschemas.c
changeset 0 dd21522fd290
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2  * schemas.c : implementation of the XML Schema handling and
       
     3  *             schema validity checking
       
     4  *
       
     5  * See Copyright for the status of this software.
       
     6  *
       
     7  * Daniel Veillard <veillard@redhat.com>
       
     8  */
       
     9 
       
    10 /*
       
    11  * TODO:
       
    12  *   - when types are redefined in includes, check that all
       
    13  *     types in the redef list are equal
       
    14  *     -> need a type equality operation.
       
    15  */
       
    16 #define IN_LIBXML
       
    17 #include "XmlEnglibxml.h"
       
    18 
       
    19 #if defined(LIBXML_SCHEMAS_ENABLED) || defined(XMLENGINE_XMLSCHEMA_DATATYPES)
       
    20 
       
    21 
       
    22 #include <string.h>
       
    23 #include "Libxml2_xmlmemory.h"
       
    24 #include "Libxml2_parser.h"
       
    25 #include "Libxml2_parserInternals.h"
       
    26 #include "Libxml2_hash.h"
       
    27 #include "Libxml2_uri.h"
       
    28 
       
    29 #include "Libxml2_xmlschemas.h"
       
    30 #include "Libxml2_schemasInternals.h"
       
    31 #include "Libxml2_xmlschemastypes.h"
       
    32 
       
    33 #ifdef LIBXML_AUTOMATA_ENABLED
       
    34 #include <xmlautomata.h>
       
    35 #endif
       
    36 
       
    37 #ifdef LIBXML_REGEXP_ENABLED
       
    38 #include <xmlregexp.h>
       
    39 #endif
       
    40 
       
    41 #include "Libxml2_dict.h"
       
    42 
       
    43 /* #define DEBUG 1 */
       
    44 
       
    45 /* #define DEBUG_CONTENT 1 */
       
    46 
       
    47 /* #define DEBUG_TYPE 1 */
       
    48 
       
    49 /* #define DEBUG_CONTENT_REGEXP 1 */
       
    50 
       
    51 /* #define DEBUG_AUTOMATA 1 */
       
    52 
       
    53 #define UNBOUNDED (1 << 30)
       
    54 #define TODO                                \
       
    55     xmlGenericError(xmlGenericErrorContext,             \
       
    56         "Unimplemented block at %s:%d\n",               \
       
    57             __FILE__, __LINE__);
       
    58 
       
    59 #define XML_SCHEMAS_DEFAULT_NAMESPACE (const xmlChar*)"the default namespace"
       
    60 
       
    61 /*
       
    62  * The XML Schemas namespaces
       
    63  */  //TODO: define exported functions that return these Or export these
       
    64 static const xmlChar* const xmlSchemaNs = (const xmlChar*)
       
    65     "http://www.w3.org/2001/XMLSchema";
       
    66 
       
    67 static const xmlChar* const xmlSchemaInstanceNs = (const xmlChar*)
       
    68     "http://www.w3.org/2001/XMLSchema-instance";
       
    69 
       
    70 /**
       
    71  * xmlSchemaFreeAnnot:
       
    72  * @annot:  a schema type structure
       
    73  *
       
    74  * Deallocate a annotation structure
       
    75  */
       
    76 static void
       
    77 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
       
    78 {
       
    79     if (annot == NULL)
       
    80         return;
       
    81     xmlFree(annot);
       
    82 }
       
    83 
       
    84 /**
       
    85  * xmlSchemaFreeType:
       
    86  * @type:  a schema type structure
       
    87  *
       
    88  * Deallocate a Schema Type structure.
       
    89  */
       
    90 void
       
    91 xmlSchemaFreeType(xmlSchemaTypePtr type)
       
    92 {
       
    93     if (type == NULL)
       
    94         return;
       
    95     if (type->annot != NULL)
       
    96         xmlSchemaFreeAnnot(type->annot);
       
    97     if (type->facets != NULL) {
       
    98         xmlSchemaFacetPtr facet, next;
       
    99 
       
   100         facet = type->facets;
       
   101         while (facet != NULL) {
       
   102             next = facet->next;
       
   103             xmlSchemaFreeFacet(facet);
       
   104             facet = next;
       
   105         }
       
   106     }
       
   107     xmlFree(type);
       
   108 }
       
   109 
       
   110 
       
   111 /**
       
   112  * xmlSchemaFreeFacet:
       
   113  * @facet:  a schema facet structure
       
   114  *
       
   115  * Deallocate a Schema Facet structure.
       
   116  */
       
   117 void
       
   118 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
       
   119 {
       
   120     if (facet == NULL)
       
   121         return;
       
   122     if (facet->val != NULL)
       
   123         xmlSchemaFreeValue(facet->val);
       
   124 #ifdef LIBXML_REGEXP_ENABLED
       
   125     if (facet->regexp != NULL)
       
   126         xmlRegFreeRegexp(facet->regexp);
       
   127 #endif
       
   128     if (facet->annot != NULL)
       
   129         xmlSchemaFreeAnnot(facet->annot);
       
   130     xmlFree(facet);
       
   131 }
       
   132 
       
   133 #endif /* defined(LIBXML_SCHEMAS_ENABLED) || defined(XMLENGINE_XMLSCHEMA_DATATYPES) */
       
   134 
       
   135 #ifdef LIBXML_SCHEMAS_ENABLED
       
   136 
       
   137 #define IS_SCHEMA(node, type)                       \
       
   138    ((node != NULL) && (node->ns != NULL) &&             \
       
   139     (xmlStrEqual(node->name, (const xmlChar *) type)) &&        \
       
   140     (xmlStrEqual(node->ns->href, xmlSchemaNs)))
       
   141 
       
   142 #define XML_SCHEMAS_PARSE_ERROR     1
       
   143 
       
   144 #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
       
   145 
       
   146 struct _xmlSchemaParserCtxt {
       
   147     void *userData;             /* user specific data block */
       
   148     xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
       
   149     xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
       
   150     xmlSchemaValidError err;
       
   151     int nberrors;
       
   152     xmlStructuredErrorFunc serror;
       
   153 
       
   154     xmlSchemaPtr topschema; /* The main schema */
       
   155     xmlHashTablePtr namespaces; /* Hash table of namespaces to schemas */
       
   156 
       
   157     xmlSchemaPtr schema;        /* The schema in use */
       
   158     const xmlChar *container;   /* the current element, group, ... */
       
   159     int counter;
       
   160 
       
   161     const xmlChar *URL;
       
   162     xmlDocPtr doc;
       
   163     int preserve;       /* Whether the doc should be freed  */
       
   164 
       
   165     const char *buffer;
       
   166     int size;
       
   167 
       
   168     /*
       
   169      * Used to build complex element content models
       
   170      */
       
   171     xmlAutomataPtr am;
       
   172     xmlAutomataStatePtr start;
       
   173     xmlAutomataStatePtr end;
       
   174     xmlAutomataStatePtr state;
       
   175 
       
   176     xmlDictPtr dict;        /* dictionnary for interned string names */
       
   177     int        includes;    /* the inclusion level, 0 for root or imports */
       
   178 };
       
   179 
       
   180 
       
   181 #define XML_SCHEMAS_ATTR_UNKNOWN 1
       
   182 #define XML_SCHEMAS_ATTR_CHECKED 2
       
   183 
       
   184 typedef struct _xmlSchemaAttrState xmlSchemaAttrState;
       
   185 typedef xmlSchemaAttrState *xmlSchemaAttrStatePtr;
       
   186 struct _xmlSchemaAttrState {
       
   187     xmlAttrPtr attr;
       
   188     int state;
       
   189 };
       
   190 
       
   191 /**
       
   192  * xmlSchemaValidCtxt:
       
   193  *
       
   194  * A Schemas validation context
       
   195  */
       
   196 
       
   197 struct _xmlSchemaValidCtxt {
       
   198     void *userData;             /* user specific data block */
       
   199     xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
       
   200     xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
       
   201     xmlStructuredErrorFunc serror;
       
   202 
       
   203     xmlSchemaPtr schema;        /* The schema in use */
       
   204     xmlDocPtr doc;
       
   205     xmlParserInputBufferPtr input;
       
   206     xmlCharEncoding enc;
       
   207     xmlSAXHandlerPtr sax;
       
   208     void *user_data;
       
   209 
       
   210     xmlDocPtr myDoc;
       
   211     int err;
       
   212     int nberrors;
       
   213 
       
   214     xmlNodePtr node;
       
   215     xmlNodePtr cur;
       
   216     xmlSchemaTypePtr type;
       
   217 
       
   218     xmlRegExecCtxtPtr regexp;
       
   219     xmlSchemaValPtr value;
       
   220 
       
   221     int attrNr;
       
   222     int attrBase;
       
   223     int attrMax;
       
   224     xmlSchemaAttrStatePtr attr;
       
   225 };
       
   226 
       
   227 /*
       
   228  * These are the entries in the schemas importSchemas hash table
       
   229  */
       
   230 typedef struct _xmlSchemaImport xmlSchemaImport;
       
   231 typedef xmlSchemaImport *xmlSchemaImportPtr;
       
   232 struct _xmlSchemaImport {
       
   233     const xmlChar *schemaLocation;
       
   234     xmlSchemaPtr schema;
       
   235 };
       
   236 
       
   237 /*
       
   238  * These are the entries associated to includes in a schemas
       
   239  */
       
   240 typedef struct _xmlSchemaInclude xmlSchemaInclude;
       
   241 typedef xmlSchemaInclude *xmlSchemaIncludePtr;
       
   242 struct _xmlSchemaInclude {
       
   243     xmlSchemaIncludePtr next;
       
   244 
       
   245     const xmlChar *schemaLocation;
       
   246     xmlDocPtr doc;
       
   247 };
       
   248 
       
   249 
       
   250 
       
   251 /************************************************************************
       
   252  *                                  *
       
   253  *          Some predeclarations                *
       
   254  *                                  *
       
   255  ************************************************************************/
       
   256 static int xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
       
   257                                         xmlSchemaTypePtr type,
       
   258                                         const xmlChar * value);
       
   259 
       
   260 static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
       
   261                                  xmlSchemaPtr schema,
       
   262                                  xmlNodePtr node);
       
   263 static int
       
   264 xmlSchemaValidateSimpleValueInternal(xmlSchemaValidCtxtPtr ctxt,
       
   265                              xmlSchemaTypePtr type,
       
   266                  const xmlChar * value,
       
   267                  int fireErrors);
       
   268 
       
   269 /************************************************************************
       
   270  *                                  *
       
   271  *          Datatype error handlers             *
       
   272  *                                  *
       
   273  ************************************************************************/
       
   274 
       
   275 /**
       
   276  * xmlSchemaPErrMemory:
       
   277  * @node: a context node
       
   278  * @extra:  extra informations
       
   279  *
       
   280  * Handle an out of memory condition
       
   281  */
       
   282 static void
       
   283 xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
       
   284                     const char *extra, xmlNodePtr node)
       
   285 {
       
   286     if (ctxt != NULL)
       
   287         ctxt->nberrors++;
       
   288     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
       
   289                      extra);
       
   290 }
       
   291 
       
   292 /**
       
   293  * xmlSchemaPErr:
       
   294  * @ctxt: the parsing context
       
   295  * @node: the context node
       
   296  * @error: the error code
       
   297  * @msg: the error message
       
   298  * @str1: extra data
       
   299  * @str2: extra data
       
   300  *
       
   301  * Handle a parser error
       
   302  */
       
   303 static void
       
   304 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
       
   305               const char *msg, const xmlChar * str1, const xmlChar * str2)
       
   306 {
       
   307     xmlGenericErrorFunc channel = NULL;
       
   308     xmlStructuredErrorFunc schannel = NULL;
       
   309     void *data = NULL;
       
   310 
       
   311     if (ctxt != NULL) {
       
   312         ctxt->nberrors++;
       
   313         channel = ctxt->error;
       
   314         data = ctxt->userData;
       
   315     schannel = ctxt->serror;
       
   316     }
       
   317     __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
       
   318                     error, XML_ERR_ERROR, NULL, 0,
       
   319                     (const char *) str1, (const char *) str2, NULL, 0, 0,
       
   320                     msg, str1, str2);
       
   321 }
       
   322 
       
   323 /**
       
   324  * xmlSchemaPErr2:
       
   325  * @ctxt: the parsing context
       
   326  * @node: the context node
       
   327  * @node: the current child
       
   328  * @error: the error code
       
   329  * @msg: the error message
       
   330  * @str1: extra data
       
   331  * @str2: extra data
       
   332  *
       
   333  * Handle a parser error
       
   334  */
       
   335 static void
       
   336 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
       
   337                xmlNodePtr child, int error,
       
   338                const char *msg, const xmlChar * str1, const xmlChar * str2)
       
   339 {
       
   340     if (child != NULL)
       
   341         xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
       
   342     else
       
   343         xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
       
   344 }
       
   345 
       
   346 /**
       
   347  * xmlSchemaVTypeErrMemory:
       
   348  * @node: a context node
       
   349  * @extra:  extra informations
       
   350  *
       
   351  * Handle an out of memory condition
       
   352  */
       
   353 static void
       
   354 xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
       
   355                     const char *extra, xmlNodePtr node)
       
   356 {
       
   357     if (ctxt != NULL) {
       
   358         ctxt->nberrors++;
       
   359         ctxt->err = XML_SCHEMAS_ERR_INTERNAL;
       
   360     }
       
   361     __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
       
   362                      extra);
       
   363 }
       
   364 
       
   365 /**
       
   366  * xmlSchemaVErr3:
       
   367  * @ctxt: the validation context
       
   368  * @node: the context node
       
   369  * @error: the error code
       
   370  * @msg: the error message
       
   371  * @str1: extra data
       
   372  * @str2: extra data
       
   373  * @str3: extra data
       
   374  *
       
   375  * Handle a validation error
       
   376  */
       
   377 static void
       
   378 xmlSchemaVErr3(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node, int error,
       
   379                const char *msg, const xmlChar *str1, const xmlChar *str2,
       
   380            const xmlChar *str3)
       
   381 {
       
   382     xmlStructuredErrorFunc schannel = NULL;
       
   383     xmlGenericErrorFunc channel = NULL;
       
   384     void *data = NULL;
       
   385 
       
   386     if (ctxt != NULL) {
       
   387         ctxt->nberrors++;
       
   388     ctxt->err = error;
       
   389         channel = ctxt->error;
       
   390         schannel = ctxt->serror;
       
   391         data = ctxt->userData;
       
   392     }
       
   393     /* reajust to global error numbers */
       
   394     error += XML_SCHEMAV_NOROOT - XML_SCHEMAS_ERR_NOROOT;
       
   395     __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASV,
       
   396                     error, XML_ERR_ERROR, NULL, 0,
       
   397                     (const char *) str1, (const char *) str2,
       
   398             (const char *) str3, 0, 0,
       
   399                     msg, str1, str2, str3);
       
   400 }
       
   401 /**
       
   402  * xmlSchemaVErr:
       
   403  * @ctxt: the validation context
       
   404  * @node: the context node
       
   405  * @error: the error code
       
   406  * @msg: the error message
       
   407  * @str1: extra data
       
   408  * @str2: extra data
       
   409  *
       
   410  * Handle a validation error
       
   411  */
       
   412 static void
       
   413 xmlSchemaVErr(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node, int error,
       
   414               const char *msg, const xmlChar * str1, const xmlChar * str2)
       
   415 {
       
   416     xmlStructuredErrorFunc schannel = NULL;
       
   417     xmlGenericErrorFunc channel = NULL;
       
   418     void *data = NULL;
       
   419 
       
   420     if (ctxt != NULL) {
       
   421         ctxt->nberrors++;
       
   422     ctxt->err = error;
       
   423         channel = ctxt->error;
       
   424         data = ctxt->userData;
       
   425         schannel = ctxt->serror;
       
   426     }
       
   427     /* reajust to global error numbers */
       
   428     error += XML_SCHEMAV_NOROOT - XML_SCHEMAS_ERR_NOROOT;
       
   429     __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASV,
       
   430                     error, XML_ERR_ERROR, NULL, 0,
       
   431                     (const char *) str1, (const char *) str2, NULL, 0, 0,
       
   432                     msg, str1, str2);
       
   433 }
       
   434 
       
   435 /************************************************************************
       
   436  *                                  *
       
   437  *          Allocation functions                *
       
   438  *                                  *
       
   439  ************************************************************************/
       
   440 
       
   441 /**
       
   442  * xmlSchemaNewSchema:
       
   443  * @ctxt:  a schema validation context
       
   444  *
       
   445  * Allocate a new Schema structure.
       
   446  *
       
   447  * Returns the newly allocated structure or NULL in case or error
       
   448  */
       
   449 static xmlSchemaPtr
       
   450 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
       
   451 {
       
   452     xmlSchemaPtr ret;
       
   453 
       
   454     ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
       
   455     if (ret == NULL) {
       
   456         xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
       
   457         return (NULL);
       
   458     }
       
   459     memset(ret, 0, sizeof(xmlSchema));
       
   460     ret->dict = ctxt->dict;
       
   461     xmlDictReference(ret->dict);
       
   462 
       
   463     return (ret);
       
   464 }
       
   465 
       
   466 /**
       
   467  * xmlSchemaNewFacet:
       
   468  *
       
   469  * Allocate a new Facet structure.
       
   470  *
       
   471  * Returns the newly allocated structure or NULL in case or error
       
   472  */
       
   473 xmlSchemaFacetPtr
       
   474 xmlSchemaNewFacet(void)
       
   475 {
       
   476     xmlSchemaFacetPtr ret;
       
   477 
       
   478     ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
       
   479     if (ret == NULL) {
       
   480         return (NULL);
       
   481     }
       
   482     memset(ret, 0, sizeof(xmlSchemaFacet));
       
   483 
       
   484     return (ret);
       
   485 }
       
   486 
       
   487 /**
       
   488  * xmlSchemaNewAnnot:
       
   489  * @ctxt:  a schema validation context
       
   490  * @node:  a node
       
   491  *
       
   492  * Allocate a new annotation structure.
       
   493  *
       
   494  * Returns the newly allocated structure or NULL in case or error
       
   495  */
       
   496 static xmlSchemaAnnotPtr
       
   497 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
       
   498 {
       
   499     xmlSchemaAnnotPtr ret;
       
   500 
       
   501     ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
       
   502     if (ret == NULL) {
       
   503         xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
       
   504         return (NULL);
       
   505     }
       
   506     memset(ret, 0, sizeof(xmlSchemaAnnot));
       
   507     ret->content = node;
       
   508     return (ret);
       
   509 }
       
   510 
       
   511 
       
   512 
       
   513 /**
       
   514  * xmlSchemaFreeImport:
       
   515  * @import:  a schema import structure
       
   516  *
       
   517  * Deallocate an import structure
       
   518  */
       
   519 static void
       
   520 xmlSchemaFreeImport(xmlSchemaImportPtr import)
       
   521 {
       
   522     if (import == NULL)
       
   523         return;
       
   524 
       
   525     xmlSchemaFree(import->schema);
       
   526     xmlFree(import);
       
   527 }
       
   528 
       
   529 /**
       
   530  * xmlSchemaFreeInclude:
       
   531  * @include:  a schema include structure
       
   532  *
       
   533  * Deallocate an include structure
       
   534  */
       
   535 static void
       
   536 xmlSchemaFreeInclude(xmlSchemaIncludePtr include)
       
   537 {
       
   538     if (include == NULL)
       
   539         return;
       
   540 
       
   541     xmlFreeDoc(include->doc);
       
   542     xmlFree(include);
       
   543 }
       
   544 
       
   545 /**
       
   546  * xmlSchemaFreeIncludeList:
       
   547  * @includes:  a schema include list
       
   548  *
       
   549  * Deallocate an include structure
       
   550  */
       
   551 static void
       
   552 xmlSchemaFreeIncludeList(xmlSchemaIncludePtr includes)
       
   553 {
       
   554     xmlSchemaIncludePtr next;
       
   555 
       
   556     while (includes != NULL) {
       
   557         next = includes->next;
       
   558     xmlSchemaFreeInclude(includes);
       
   559     includes = next;
       
   560     }
       
   561 }
       
   562 
       
   563 /**
       
   564  * xmlSchemaFreeNotation:
       
   565  * @schema:  a schema notation structure
       
   566  *
       
   567  * Deallocate a Schema Notation structure.
       
   568  */
       
   569 static void
       
   570 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
       
   571 {
       
   572     if (nota == NULL)
       
   573         return;
       
   574     xmlFree(nota);
       
   575 }
       
   576 
       
   577 /**
       
   578  * xmlSchemaFreeAttribute:
       
   579  * @schema:  a schema attribute structure
       
   580  *
       
   581  * Deallocate a Schema Attribute structure.
       
   582  */
       
   583 static void
       
   584 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
       
   585 {
       
   586     if (attr == NULL)
       
   587         return;
       
   588     xmlFree(attr);
       
   589 }
       
   590 
       
   591 /**
       
   592  * xmlSchemaFreeAttributeGroup:
       
   593  * @schema:  a schema attribute group structure
       
   594  *
       
   595  * Deallocate a Schema Attribute Group structure.
       
   596  */
       
   597 static void
       
   598 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attr)
       
   599 {
       
   600     if (attr == NULL)
       
   601         return;
       
   602     xmlFree(attr);
       
   603 }
       
   604 
       
   605 /**
       
   606  * xmlSchemaFreeElement:
       
   607  * @schema:  a schema element structure
       
   608  *
       
   609  * Deallocate a Schema Element structure.
       
   610  */
       
   611 static void
       
   612 xmlSchemaFreeElement(xmlSchemaElementPtr elem)
       
   613 {
       
   614     if (elem == NULL)
       
   615         return;
       
   616     if (elem->annot != NULL)
       
   617         xmlSchemaFreeAnnot(elem->annot);
       
   618     if (elem->contModel != NULL)
       
   619         xmlRegFreeRegexp(elem->contModel);
       
   620     xmlFree(elem);
       
   621 }
       
   622 
       
   623 /**
       
   624  * xmlSchemaFreeTypeList:
       
   625  * @type:  a schema type structure
       
   626  *
       
   627  * Deallocate a Schema Type structure.
       
   628  */
       
   629 static void
       
   630 xmlSchemaFreeTypeList(xmlSchemaTypePtr type)
       
   631 {
       
   632     xmlSchemaTypePtr next;
       
   633 
       
   634     while (type != NULL) {
       
   635         next = type->redef;
       
   636     xmlSchemaFreeType(type);
       
   637     type = next;
       
   638     }
       
   639 }
       
   640 
       
   641 /**
       
   642  * xmlSchemaFree:
       
   643  * @schema:  a schema structure
       
   644  *
       
   645  * Deallocate a Schema structure.
       
   646  */
       
   647 void
       
   648 xmlSchemaFree(xmlSchemaPtr schema)
       
   649 {
       
   650     if (schema == NULL)
       
   651         return;
       
   652 
       
   653     if (schema->notaDecl != NULL)
       
   654         xmlHashFree(schema->notaDecl,
       
   655                     (xmlHashDeallocator) xmlSchemaFreeNotation);
       
   656     if (schema->attrDecl != NULL)
       
   657         xmlHashFree(schema->attrDecl,
       
   658                     (xmlHashDeallocator) xmlSchemaFreeAttribute);
       
   659     if (schema->attrgrpDecl != NULL)
       
   660         xmlHashFree(schema->attrgrpDecl,
       
   661                     (xmlHashDeallocator) xmlSchemaFreeAttributeGroup);
       
   662     if (schema->elemDecl != NULL)
       
   663         xmlHashFree(schema->elemDecl,
       
   664                     (xmlHashDeallocator) xmlSchemaFreeElement);
       
   665     if (schema->typeDecl != NULL)
       
   666         xmlHashFree(schema->typeDecl,
       
   667                     (xmlHashDeallocator) xmlSchemaFreeTypeList);
       
   668     if (schema->groupDecl != NULL)
       
   669         xmlHashFree(schema->groupDecl,
       
   670                     (xmlHashDeallocator) xmlSchemaFreeType);
       
   671     if (schema->schemasImports != NULL)
       
   672     xmlHashFree(schema->schemasImports,
       
   673             (xmlHashDeallocator) xmlSchemaFreeImport);
       
   674     if (schema->includes != NULL) {
       
   675         xmlSchemaFreeIncludeList((xmlSchemaIncludePtr) schema->includes);
       
   676     }
       
   677     if (schema->annot != NULL)
       
   678         xmlSchemaFreeAnnot(schema->annot);
       
   679     if (schema->doc != NULL && !schema->preserve)
       
   680         xmlFreeDoc(schema->doc);
       
   681     xmlDictFree(schema->dict);
       
   682 
       
   683     xmlFree(schema);
       
   684 }
       
   685 
       
   686 /************************************************************************
       
   687  *                                  *
       
   688  *          Debug functions                 *
       
   689  *                                  *
       
   690  ************************************************************************/
       
   691 
       
   692 #ifdef LIBXML_OUTPUT_ENABLED
       
   693 
       
   694 /**
       
   695  * xmlSchemaElementDump:
       
   696  * @elem:  an element
       
   697  * @output:  the file output
       
   698  *
       
   699  * Dump the element
       
   700  */
       
   701 static void
       
   702 xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output,
       
   703                      const xmlChar * name ATTRIBUTE_UNUSED,
       
   704                      const xmlChar * context ATTRIBUTE_UNUSED,
       
   705                      const xmlChar * namespace ATTRIBUTE_UNUSED)
       
   706 {
       
   707     if (elem == NULL)
       
   708         return;
       
   709 
       
   710     fprintf(output, "Element ");
       
   711     if (elem->flags & XML_SCHEMAS_ELEM_TOPLEVEL)
       
   712         fprintf(output, "toplevel ");
       
   713     fprintf(output, ": %s ", elem->name);
       
   714     if (namespace != NULL)
       
   715         fprintf(output, "namespace '%s' ", namespace);
       
   716 
       
   717     if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
       
   718         fprintf(output, "nillable ");
       
   719     if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
       
   720         fprintf(output, "global ");
       
   721     if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
       
   722         fprintf(output, "default ");
       
   723     if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
       
   724         fprintf(output, "fixed ");
       
   725     if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
       
   726         fprintf(output, "abstract ");
       
   727     if (elem->flags & XML_SCHEMAS_ELEM_REF)
       
   728         fprintf(output, "ref '%s' ", elem->ref);
       
   729     if (elem->id != NULL)
       
   730         fprintf(output, "id '%s' ", elem->id);
       
   731     fprintf(output, "\n");
       
   732     if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
       
   733         fprintf(output, "  ");
       
   734         if (elem->minOccurs != 1)
       
   735             fprintf(output, "min: %d ", elem->minOccurs);
       
   736         if (elem->maxOccurs >= UNBOUNDED)
       
   737             fprintf(output, "max: unbounded\n");
       
   738         else if (elem->maxOccurs != 1)
       
   739             fprintf(output, "max: %d\n", elem->maxOccurs);
       
   740         else
       
   741             fprintf(output, "\n");
       
   742     }
       
   743     if (elem->namedType != NULL) {
       
   744         fprintf(output, "  type: %s", elem->namedType);
       
   745         if (elem->namedTypeNs != NULL)
       
   746             fprintf(output, " ns %s\n", elem->namedTypeNs);
       
   747         else
       
   748             fprintf(output, "\n");
       
   749     }
       
   750     if (elem->substGroup != NULL) {
       
   751         fprintf(output, "  substitutionGroup: %s", elem->substGroup);
       
   752         if (elem->substGroupNs != NULL)
       
   753             fprintf(output, " ns %s\n", elem->substGroupNs);
       
   754         else
       
   755             fprintf(output, "\n");
       
   756     }
       
   757     if (elem->value != NULL)
       
   758         fprintf(output, "  default: %s", elem->value);
       
   759 }
       
   760 
       
   761 /**
       
   762  * xmlSchemaAnnotDump:
       
   763  * @output:  the file output
       
   764  * @annot:  a annotation
       
   765  *
       
   766  * Dump the annotation
       
   767  */
       
   768 static void
       
   769 xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
       
   770 {
       
   771     xmlChar *content;
       
   772 
       
   773     if (annot == NULL)
       
   774         return;
       
   775 
       
   776     content = xmlNodeGetContent(annot->content);
       
   777     if (content != NULL) {
       
   778         fprintf(output, "  Annot: %s\n", content);
       
   779         xmlFree(content);
       
   780     } else
       
   781         fprintf(output, "  Annot: empty\n");
       
   782 }
       
   783 
       
   784 /**
       
   785  * xmlSchemaTypeDump:
       
   786  * @output:  the file output
       
   787  * @type:  a type structure
       
   788  *
       
   789  * Dump a SchemaType structure
       
   790  */
       
   791 static void
       
   792 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
       
   793 {
       
   794     if (type == NULL) {
       
   795         fprintf(output, "Type: NULL\n");
       
   796         return;
       
   797     }
       
   798     fprintf(output, "Type: ");
       
   799     if (type->name != NULL)
       
   800         fprintf(output, "%s, ", type->name);
       
   801     else
       
   802         fprintf(output, "no name");
       
   803     switch (type->type) {
       
   804         case XML_SCHEMA_TYPE_BASIC:
       
   805             fprintf(output, "basic ");
       
   806             break;
       
   807         case XML_SCHEMA_TYPE_SIMPLE:
       
   808             fprintf(output, "simple ");
       
   809             break;
       
   810         case XML_SCHEMA_TYPE_COMPLEX:
       
   811             fprintf(output, "complex ");
       
   812             break;
       
   813         case XML_SCHEMA_TYPE_SEQUENCE:
       
   814             fprintf(output, "sequence ");
       
   815             break;
       
   816         case XML_SCHEMA_TYPE_CHOICE:
       
   817             fprintf(output, "choice ");
       
   818             break;
       
   819         case XML_SCHEMA_TYPE_ALL:
       
   820             fprintf(output, "all ");
       
   821             break;
       
   822         case XML_SCHEMA_TYPE_UR:
       
   823             fprintf(output, "ur ");
       
   824             break;
       
   825         case XML_SCHEMA_TYPE_RESTRICTION:
       
   826             fprintf(output, "restriction ");
       
   827             break;
       
   828         case XML_SCHEMA_TYPE_EXTENSION:
       
   829             fprintf(output, "extension ");
       
   830             break;
       
   831         default:
       
   832             fprintf(output, "unknowntype%d ", type->type);
       
   833             break;
       
   834     }
       
   835     if (type->base != NULL) {
       
   836         fprintf(output, "base %s, ", type->base);
       
   837     }
       
   838     switch (type->contentType) {
       
   839         case XML_SCHEMA_CONTENT_UNKNOWN:
       
   840             fprintf(output, "unknown ");
       
   841             break;
       
   842         case XML_SCHEMA_CONTENT_EMPTY:
       
   843             fprintf(output, "empty ");
       
   844             break;
       
   845         case XML_SCHEMA_CONTENT_ELEMENTS:
       
   846             fprintf(output, "element ");
       
   847             break;
       
   848         case XML_SCHEMA_CONTENT_MIXED:
       
   849             fprintf(output, "mixed ");
       
   850             break;
       
   851         case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
       
   852             fprintf(output, "mixed_or_elems ");
       
   853             break;
       
   854         case XML_SCHEMA_CONTENT_BASIC:
       
   855             fprintf(output, "basic ");
       
   856             break;
       
   857         case XML_SCHEMA_CONTENT_SIMPLE:
       
   858             fprintf(output, "simple ");
       
   859             break;
       
   860         case XML_SCHEMA_CONTENT_ANY:
       
   861             fprintf(output, "any ");
       
   862             break;
       
   863     }
       
   864     fprintf(output, "\n");
       
   865     if ((type->minOccurs != 1) || (type->maxOccurs != 1)) {
       
   866         fprintf(output, "  ");
       
   867         if (type->minOccurs != 1)
       
   868             fprintf(output, "min: %d ", type->minOccurs);
       
   869         if (type->maxOccurs >= UNBOUNDED)
       
   870             fprintf(output, "max: unbounded\n");
       
   871         else if (type->maxOccurs != 1)
       
   872             fprintf(output, "max: %d\n", type->maxOccurs);
       
   873         else
       
   874             fprintf(output, "\n");
       
   875     }
       
   876     if (type->annot != NULL)
       
   877         xmlSchemaAnnotDump(output, type->annot);
       
   878     if (type->subtypes != NULL) {
       
   879         xmlSchemaTypePtr sub = type->subtypes;
       
   880 
       
   881         fprintf(output, "  subtypes: ");
       
   882         while (sub != NULL) {
       
   883             fprintf(output, "%s ", sub->name);
       
   884             sub = sub->next;
       
   885         }
       
   886         fprintf(output, "\n");
       
   887     }
       
   888 
       
   889 }
       
   890 
       
   891 /**
       
   892  * xmlSchemaDump:
       
   893  * @output:  the file output
       
   894  * @schema:  a schema structure
       
   895  *
       
   896  * Dump a Schema structure.
       
   897  */
       
   898 void
       
   899 xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
       
   900 {
       
   901     if (schema == NULL) {
       
   902         fprintf(output, "Schemas: NULL\n");
       
   903         return;
       
   904     }
       
   905     fprintf(output, "Schemas: ");
       
   906     if (schema->name != NULL)
       
   907         fprintf(output, "%s, ", schema->name);
       
   908     else
       
   909         fprintf(output, "no name, ");
       
   910     if (schema->targetNamespace != NULL)
       
   911         fprintf(output, "%s", (const char *) schema->targetNamespace);
       
   912     else
       
   913         fprintf(output, "no target namespace");
       
   914     fprintf(output, "\n");
       
   915     if (schema->annot != NULL)
       
   916         xmlSchemaAnnotDump(output, schema->annot);
       
   917 
       
   918     xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump,
       
   919                 output);
       
   920     xmlHashScanFull(schema->elemDecl,
       
   921                     (xmlHashScannerFull) xmlSchemaElementDump, output);
       
   922 }
       
   923 #endif /* LIBXML_OUTPUT_ENABLED */
       
   924 
       
   925 /************************************************************************
       
   926  *                                  *
       
   927  *          Utilities                   *
       
   928  *                                  *
       
   929  ************************************************************************/
       
   930 
       
   931 /**
       
   932  * xmlSchemaGetProp:
       
   933  * @ctxt: the parser context
       
   934  * @node: the node
       
   935  * @name: the property name
       
   936  *
       
   937  * Read a attribute value and internalize the string
       
   938  *
       
   939  * Returns the string or NULL if not present.
       
   940  */
       
   941 static const xmlChar *
       
   942 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
       
   943                  const char *name)
       
   944 {
       
   945     xmlChar *val;
       
   946     const xmlChar *ret;
       
   947 
       
   948     val = xmlGetProp(node, BAD_CAST name);
       
   949     if (val == NULL)
       
   950         return(NULL);
       
   951     ret = xmlDictLookup(ctxt->dict, val, -1);
       
   952     xmlFree(val);
       
   953     return(ret);
       
   954 }
       
   955 
       
   956 #if 0
       
   957 /**
       
   958  * xmlSchemaGetNamespace:
       
   959  * @ctxt: the parser context
       
   960  * @schema: the schemas containing the declaration
       
   961  * @node: the node
       
   962  * @qname: the QName to analyze
       
   963  *
       
   964  * Find the namespace name for the given declaration.
       
   965  *
       
   966  * Returns the local name for that declaration, as well as the namespace name
       
   967  * NOTE: This function is no longer used (Buchcik, May '04)
       
   968  */
       
   969 static const xmlChar *
       
   970 xmlSchemaGetNamespace(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
   971                   xmlNodePtr node, const xmlChar *qname,
       
   972          const xmlChar **namespace) {
       
   973     int len;
       
   974     const xmlChar *name, *prefix, *def = NULL;
       
   975     xmlNsPtr ns;
       
   976 
       
   977     *namespace = NULL;
       
   978 
       
   979     /* TODO: The following seems to be not correct here:
       
   980      * 1. The name of a declaration is a NCName, not a QName.
       
   981      * 2. The attribute "targetNamespace" is allowed for the
       
   982      *    <schema> Element Information Item only.
       
   983      * 3. One cannot evaluate the target namespace, by the type
       
   984      *    of declaration, since it is dependant on the xxxFormDefault
       
   985      *    of <schema> and the form attribute of an <element> or <attribute>.
       
   986      */
       
   987 
       
   988     if (xmlStrEqual(node->name, BAD_CAST "element") ||
       
   989         xmlStrEqual(node->name, BAD_CAST "attribute") ||
       
   990     xmlStrEqual(node->name, BAD_CAST "simpleType") ||
       
   991     xmlStrEqual(node->name, BAD_CAST "complexType")) {
       
   992     def = xmlSchemaGetProp(ctxt, node, "targetNamespace");
       
   993     }
       
   994 
       
   995 
       
   996     qname = xmlDictLookup(ctxt->dict, qname, -1); /* intern the string */
       
   997     name = xmlSplitQName3(qname, &len);
       
   998     if (name == NULL) {
       
   999         if (def == NULL) {
       
  1000         if (xmlStrEqual(node->name, BAD_CAST "element")) {
       
  1001         if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
       
  1002             *namespace = schema->targetNamespace;
       
  1003         } else if (xmlStrEqual(node->name, BAD_CAST "attribute")) {
       
  1004         if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
       
  1005             *namespace = schema->targetNamespace;
       
  1006         } else if ((xmlStrEqual(node->name, BAD_CAST "simpleType")) ||
       
  1007                    (xmlStrEqual(node->name, BAD_CAST "complexType"))) {
       
  1008         *namespace = schema->targetNamespace;
       
  1009         }
       
  1010     } else {
       
  1011         *namespace = def;
       
  1012     }
       
  1013     return(qname);
       
  1014     }
       
  1015 
       
  1016     name = xmlDictLookup(ctxt->dict, name, -1);
       
  1017     prefix = xmlDictLookup(ctxt->dict, qname, len);
       
  1018     if (def != NULL) {
       
  1019         xmlSchemaPErr(ctxt, node, XML_SCHEMAP_DEF_AND_PREFIX,
       
  1020                       "%s: presence of both prefix %s and targetNamespace\n",
       
  1021                       node->name, prefix);
       
  1022     }
       
  1023     ns = xmlSearchNs(node->doc, node, prefix);
       
  1024     if (ns == NULL) {
       
  1025         xmlSchemaPErr(ctxt, node, XML_SCHEMAP_PREFIX_UNDEFINED,
       
  1026                       "%s: the QName prefix %s is undefined\n",
       
  1027                       node->name, prefix);
       
  1028     return(name);
       
  1029     }
       
  1030     *namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
       
  1031     return(name);
       
  1032 }
       
  1033 #endif
       
  1034 
       
  1035 /************************************************************************
       
  1036  *                                  *
       
  1037  *          Parsing functions               *
       
  1038  *                                  *
       
  1039  ************************************************************************/
       
  1040 
       
  1041 /**
       
  1042  * xmlSchemaGetElem:
       
  1043  * @schema:  the schemas context
       
  1044  * @name:  the element name
       
  1045  * @ns:  the element namespace
       
  1046  * @level: how deep is the request
       
  1047  *
       
  1048  * Lookup a an element in the schemas or the accessible schemas
       
  1049  *
       
  1050  * Returns the element definition or NULL if not found.
       
  1051  */
       
  1052 static xmlSchemaElementPtr
       
  1053 xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
       
  1054                  const xmlChar * namespace, int level)
       
  1055 {
       
  1056     xmlSchemaElementPtr ret;
       
  1057     xmlSchemaImportPtr import = NULL;
       
  1058 
       
  1059     if ((name == NULL) || (schema == NULL))
       
  1060         return (NULL);
       
  1061 
       
  1062     if (namespace == NULL) {
       
  1063         ret = xmlHashLookup2(schema->elemDecl, name, namespace);
       
  1064         if ((ret != NULL) &&
       
  1065         ((level == 0) || (ret->flags & XML_SCHEMAS_ELEM_TOPLEVEL))) {
       
  1066             return (ret);
       
  1067     }
       
  1068     /*
       
  1069      * This one was removed, since top level element declarations have
       
  1070      * the target namespace specified in targetNamespace of the <schema>
       
  1071      * information element, even if elementFormDefault is "unqualified".
       
  1072      */
       
  1073 
       
  1074     /* else if ((schema->flags & XML_SCHEMAS_QUALIF_ELEM) == 0) {
       
  1075         if (xmlStrEqual(namespace, schema->targetNamespace))
       
  1076         ret = xmlHashLookup2(schema->elemDecl, name, NULL);
       
  1077     else
       
  1078         ret = xmlHashLookup2(schema->elemDecl, name, namespace);
       
  1079         if ((ret != NULL) &&
       
  1080         ((level == 0) || (ret->flags & XML_SCHEMAS_ELEM_TOPLEVEL))) {
       
  1081             return (ret);
       
  1082     }
       
  1083     */
       
  1084     } else {
       
  1085     ret = xmlHashLookup2(schema->elemDecl, name, namespace);
       
  1086         if ((ret != NULL) &&
       
  1087         ((level == 0) || (ret->flags & XML_SCHEMAS_ELEM_TOPLEVEL))) {
       
  1088             return (ret);
       
  1089     }
       
  1090     }
       
  1091     if (level > 0)
       
  1092     import = xmlHashLookup(schema->schemasImports, namespace);
       
  1093     if (import != NULL)
       
  1094     ret = xmlSchemaGetElem(import->schema, name, namespace, level + 1);
       
  1095 #ifdef DEBUG
       
  1096     if (ret == NULL) {
       
  1097         if (namespace == NULL)
       
  1098             fprintf(stderr, "Unable to lookup type %s", name);
       
  1099         else
       
  1100             fprintf(stderr, "Unable to lookup type %s:%s", name,
       
  1101                     namespace);
       
  1102     }
       
  1103 #endif
       
  1104     return (ret);
       
  1105 }
       
  1106 
       
  1107 /**
       
  1108  * xmlSchemaGetType:
       
  1109  * @schema:  the schemas context
       
  1110  * @name:  the type name
       
  1111  * @ns:  the type namespace
       
  1112  *
       
  1113  * Lookup a type in the schemas or the predefined types
       
  1114  *
       
  1115  * Returns the group definition or NULL if not found.
       
  1116  */
       
  1117 static xmlSchemaTypePtr
       
  1118 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
       
  1119                  const xmlChar * namespace)
       
  1120 {
       
  1121     xmlSchemaTypePtr ret;
       
  1122     xmlSchemaImportPtr import;
       
  1123 
       
  1124     if (name == NULL)
       
  1125         return (NULL);
       
  1126     if (schema != NULL) {
       
  1127         ret = xmlHashLookup2(schema->typeDecl, name, namespace);
       
  1128         if (ret != NULL)
       
  1129             return (ret);
       
  1130     }
       
  1131     ret = xmlSchemaGetPredefinedType(name, namespace);
       
  1132     if (ret != NULL)
       
  1133     return (ret);
       
  1134     import = xmlHashLookup(schema->schemasImports, namespace);
       
  1135     if (import != NULL)
       
  1136     ret = xmlSchemaGetType(import->schema, name, namespace);
       
  1137 #ifdef DEBUG
       
  1138     if (ret == NULL) {
       
  1139         if (namespace == NULL)
       
  1140             fprintf(stderr, "Unable to lookup type %s", name);
       
  1141         else
       
  1142             fprintf(stderr, "Unable to lookup type %s:%s", name,
       
  1143                     namespace);
       
  1144     }
       
  1145 #endif
       
  1146     return (ret);
       
  1147 }
       
  1148 
       
  1149 /************************************************************************
       
  1150  *                                  *
       
  1151  *          Parsing functions               *
       
  1152  *                                  *
       
  1153  ************************************************************************/
       
  1154 
       
  1155 #define IS_BLANK_NODE(n)                        \
       
  1156     (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content)))
       
  1157 
       
  1158 /**
       
  1159  * xmlSchemaIsBlank:
       
  1160  * @str:  a string
       
  1161  *
       
  1162  * Check if a string is ignorable
       
  1163  *
       
  1164  * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
       
  1165  */
       
  1166 static int
       
  1167 xmlSchemaIsBlank(xmlChar * str)
       
  1168 {
       
  1169     if (str == NULL)
       
  1170         return (1);
       
  1171     while (*str != 0) {
       
  1172         if (!(IS_BLANK_CH(*str)))
       
  1173             return (0);
       
  1174         str++;
       
  1175     }
       
  1176     return (1);
       
  1177 }
       
  1178 
       
  1179 /**
       
  1180  * xmlSchemaAddNotation:
       
  1181  * @ctxt:  a schema validation context
       
  1182  * @schema:  the schema being built
       
  1183  * @name:  the item name
       
  1184  *
       
  1185  * Add an XML schema Attrribute declaration
       
  1186  * *WARNING* this interface is highly subject to change
       
  1187  *
       
  1188  * Returns the new struture or NULL in case of error
       
  1189  */
       
  1190 static xmlSchemaNotationPtr
       
  1191 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  1192                      const xmlChar * name)
       
  1193 {
       
  1194     xmlSchemaNotationPtr ret = NULL;
       
  1195     int val;
       
  1196 
       
  1197     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
       
  1198         return (NULL);
       
  1199 
       
  1200     if (schema->notaDecl == NULL)
       
  1201         schema->notaDecl = xmlHashCreate(10);
       
  1202     if (schema->notaDecl == NULL)
       
  1203         return (NULL);
       
  1204 
       
  1205     ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
       
  1206     if (ret == NULL) {
       
  1207         xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
       
  1208         return (NULL);
       
  1209     }
       
  1210     memset(ret, 0, sizeof(xmlSchemaNotation));
       
  1211     ret->name = xmlDictLookup(ctxt->dict, name, -1);
       
  1212     val = xmlHashAddEntry2(schema->notaDecl, name, schema->targetNamespace,
       
  1213                            ret);
       
  1214     if (val != 0) {
       
  1215     xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
       
  1216               XML_SCHEMAP_REDEFINED_NOTATION,
       
  1217                       "Notation %s already defined\n",
       
  1218                       name, NULL);
       
  1219         xmlFree(ret);
       
  1220         return (NULL);
       
  1221     }
       
  1222     return (ret);
       
  1223 }
       
  1224 
       
  1225 
       
  1226 /**
       
  1227  * xmlSchemaAddAttribute:
       
  1228  * @ctxt:  a schema validation context
       
  1229  * @schema:  the schema being built
       
  1230  * @name:  the item name
       
  1231  * @namespace:  the namespace
       
  1232  *
       
  1233  * Add an XML schema Attrribute declaration
       
  1234  * *WARNING* this interface is highly subject to change
       
  1235  *
       
  1236  * Returns the new struture or NULL in case of error
       
  1237  */
       
  1238 static xmlSchemaAttributePtr
       
  1239 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  1240                       const xmlChar * name, const xmlChar * namespace)
       
  1241 {
       
  1242     xmlSchemaAttributePtr ret = NULL;
       
  1243     int val;
       
  1244 
       
  1245     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
       
  1246         return (NULL);
       
  1247 
       
  1248 #ifdef DEBUG
       
  1249     fprintf(stderr, "Adding attribute %s\n", name);
       
  1250     if (namespace != NULL)
       
  1251     fprintf(stderr, "  target namespace %s\n", namespace);
       
  1252 #endif
       
  1253 
       
  1254     if (schema->attrDecl == NULL)
       
  1255         schema->attrDecl = xmlHashCreate(10);
       
  1256     if (schema->attrDecl == NULL)
       
  1257         return (NULL);
       
  1258 
       
  1259     ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
       
  1260     if (ret == NULL) {
       
  1261         xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
       
  1262         return (NULL);
       
  1263     }
       
  1264     memset(ret, 0, sizeof(xmlSchemaAttribute));
       
  1265     ret->name = xmlDictLookup(ctxt->dict, name, -1);
       
  1266     ret->targetNamespace = xmlDictLookup(ctxt->dict, namespace, -1);
       
  1267     val = xmlHashAddEntry3(schema->attrDecl, name,
       
  1268                            schema->targetNamespace, ctxt->container, ret);
       
  1269     if (val != 0) {
       
  1270     xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
       
  1271               XML_SCHEMAP_REDEFINED_ATTR,
       
  1272                       "Attribute %s already defined\n",
       
  1273                       name, NULL);
       
  1274         xmlFree(ret);
       
  1275         return (NULL);
       
  1276     }
       
  1277     return (ret);
       
  1278 }
       
  1279 
       
  1280 /**
       
  1281  * xmlSchemaAddAttributeGroup:
       
  1282  * @ctxt:  a schema validation context
       
  1283  * @schema:  the schema being built
       
  1284  * @name:  the item name
       
  1285  *
       
  1286  * Add an XML schema Attrribute Group declaration
       
  1287  *
       
  1288  * Returns the new struture or NULL in case of error
       
  1289  */
       
  1290 static xmlSchemaAttributeGroupPtr
       
  1291 xmlSchemaAddAttributeGroup(xmlSchemaParserCtxtPtr ctxt,
       
  1292                            xmlSchemaPtr schema, const xmlChar * name)
       
  1293 {
       
  1294     xmlSchemaAttributeGroupPtr ret = NULL;
       
  1295     int val;
       
  1296 
       
  1297     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
       
  1298         return (NULL);
       
  1299 
       
  1300     if (schema->attrgrpDecl == NULL)
       
  1301         schema->attrgrpDecl = xmlHashCreate(10);
       
  1302     if (schema->attrgrpDecl == NULL)
       
  1303         return (NULL);
       
  1304 
       
  1305     ret =
       
  1306         (xmlSchemaAttributeGroupPtr)
       
  1307         xmlMalloc(sizeof(xmlSchemaAttributeGroup));
       
  1308     if (ret == NULL) {
       
  1309         xmlSchemaPErrMemory(ctxt, "allocating attribute group", NULL);
       
  1310         return (NULL);
       
  1311     }
       
  1312     memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
       
  1313     ret->name = xmlDictLookup(ctxt->dict, name, -1);
       
  1314     val = xmlHashAddEntry3(schema->attrgrpDecl, name,
       
  1315                            schema->targetNamespace, ctxt->container, ret);
       
  1316     if (val != 0) {
       
  1317     xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
       
  1318               XML_SCHEMAP_REDEFINED_ATTRGROUP,
       
  1319                       "Attribute group %s already defined\n",
       
  1320                       name, NULL);
       
  1321         xmlFree(ret);
       
  1322         return (NULL);
       
  1323     }
       
  1324     return (ret);
       
  1325 }
       
  1326 
       
  1327 /**
       
  1328  * xmlSchemaAddElement:
       
  1329  * @ctxt:  a schema validation context
       
  1330  * @schema:  the schema being built
       
  1331  * @name:  the type name
       
  1332  * @namespace:  the type namespace
       
  1333  *
       
  1334  * Add an XML schema Element declaration
       
  1335  * *WARNING* this interface is highly subject to change
       
  1336  *
       
  1337  * Returns the new struture or NULL in case of error
       
  1338  */
       
  1339 static xmlSchemaElementPtr
       
  1340 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  1341                     const xmlChar * name, const xmlChar * namespace)
       
  1342 {
       
  1343     xmlSchemaElementPtr ret = NULL;
       
  1344     int val;
       
  1345 
       
  1346     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
       
  1347         return (NULL);
       
  1348 
       
  1349 #ifdef DEBUG
       
  1350     fprintf(stderr, "Adding element %s\n", name);
       
  1351     if (namespace != NULL)
       
  1352     fprintf(stderr, "  target namespace %s\n", namespace);
       
  1353 #endif
       
  1354 
       
  1355     if (schema->elemDecl == NULL)
       
  1356         schema->elemDecl = xmlHashCreate(10);
       
  1357     if (schema->elemDecl == NULL)
       
  1358         return (NULL);
       
  1359 
       
  1360     ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
       
  1361     if (ret == NULL) {
       
  1362         xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
       
  1363         return (NULL);
       
  1364     }
       
  1365     memset(ret, 0, sizeof(xmlSchemaElement));
       
  1366     ret->name = xmlDictLookup(ctxt->dict, name, -1);
       
  1367     ret->targetNamespace = xmlDictLookup(ctxt->dict, namespace, -1);
       
  1368     val = xmlHashAddEntry3(schema->elemDecl, name,
       
  1369                            namespace, ctxt->container, ret);
       
  1370     if (val != 0) {
       
  1371         char buf[100];
       
  1372 
       
  1373         snprintf(buf, 99, "privatieelem %d", ctxt->counter++ + 1);
       
  1374         val = xmlHashAddEntry3(schema->elemDecl, name, (xmlChar *) buf,
       
  1375                                namespace, ret);
       
  1376         if (val != 0) {
       
  1377         xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
       
  1378               XML_SCHEMAP_REDEFINED_ELEMENT,
       
  1379               "Element %s already defined\n",
       
  1380               name, NULL);
       
  1381             xmlFree(ret);
       
  1382             return (NULL);
       
  1383         }
       
  1384     }
       
  1385     return (ret);
       
  1386 }
       
  1387 
       
  1388 /**
       
  1389  * xmlSchemaAddType:
       
  1390  * @ctxt:  a schema validation context
       
  1391  * @schema:  the schema being built
       
  1392  * @name:  the item name
       
  1393  * @namespace:  the namespace
       
  1394  *
       
  1395  * Add an XML schema Simple Type definition
       
  1396  * *WARNING* this interface is highly subject to change
       
  1397  *
       
  1398  * Returns the new struture or NULL in case of error
       
  1399  */
       
  1400 static xmlSchemaTypePtr
       
  1401 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  1402                  const xmlChar * name, const xmlChar * namespace)
       
  1403 {
       
  1404     xmlSchemaTypePtr ret = NULL;
       
  1405     int val;
       
  1406 
       
  1407     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
       
  1408         return (NULL);
       
  1409 
       
  1410 #ifdef DEBUG
       
  1411     fprintf(stderr, "Adding type %s\n", name);
       
  1412     if (namespace != NULL)
       
  1413     fprintf(stderr, "  target namespace %s\n", namespace);
       
  1414 #endif
       
  1415 
       
  1416     if (schema->typeDecl == NULL)
       
  1417         schema->typeDecl = xmlHashCreate(10);
       
  1418     if (schema->typeDecl == NULL)
       
  1419         return (NULL);
       
  1420 
       
  1421     ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
       
  1422     if (ret == NULL) {
       
  1423         xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
       
  1424         return (NULL);
       
  1425     }
       
  1426     memset(ret, 0, sizeof(xmlSchemaType));
       
  1427     ret->name = xmlDictLookup(ctxt->dict, name, -1);
       
  1428     ret->redef = NULL;
       
  1429     val = xmlHashAddEntry2(schema->typeDecl, name, namespace, ret);
       
  1430     if (val != 0) {
       
  1431         if (ctxt->includes == 0) {
       
  1432         xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
       
  1433               XML_SCHEMAP_REDEFINED_TYPE,
       
  1434               "Type %s already defined\n",
       
  1435               name, NULL);
       
  1436         xmlFree(ret);
       
  1437         return (NULL);
       
  1438     } else {
       
  1439         xmlSchemaTypePtr prev;
       
  1440 
       
  1441         prev = xmlHashLookup2(schema->typeDecl, name, namespace);
       
  1442         if (prev == NULL) {
       
  1443         xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
       
  1444                   XML_ERR_INTERNAL_ERROR,
       
  1445                   "Internal error on type %s definition\n",
       
  1446                   name, NULL);
       
  1447         xmlFree(ret);
       
  1448         return (NULL);
       
  1449         }
       
  1450         ret->redef = prev->redef;
       
  1451         prev->redef = ret;
       
  1452     }
       
  1453     }
       
  1454     ret->minOccurs = 1;
       
  1455     ret->maxOccurs = 1;
       
  1456 
       
  1457     return (ret);
       
  1458 }
       
  1459 
       
  1460 /**
       
  1461  * xmlSchemaAddGroup:
       
  1462  * @ctxt:  a schema validation context
       
  1463  * @schema:  the schema being built
       
  1464  * @name:  the group name
       
  1465  *
       
  1466  * Add an XML schema Group definition
       
  1467  *
       
  1468  * Returns the new struture or NULL in case of error
       
  1469  */
       
  1470 static xmlSchemaTypePtr
       
  1471 xmlSchemaAddGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  1472                   const xmlChar * name)
       
  1473 {
       
  1474     xmlSchemaTypePtr ret = NULL;
       
  1475     int val;
       
  1476 
       
  1477     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
       
  1478         return (NULL);
       
  1479 
       
  1480     if (schema->groupDecl == NULL)
       
  1481         schema->groupDecl = xmlHashCreate(10);
       
  1482     if (schema->groupDecl == NULL)
       
  1483         return (NULL);
       
  1484 
       
  1485     ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
       
  1486     if (ret == NULL) {
       
  1487         xmlSchemaPErrMemory(ctxt, "adding group", NULL);
       
  1488         return (NULL);
       
  1489     }
       
  1490     memset(ret, 0, sizeof(xmlSchemaType));
       
  1491     ret->name = xmlDictLookup(ctxt->dict, name, -1);
       
  1492     val =
       
  1493         xmlHashAddEntry2(schema->groupDecl, name, schema->targetNamespace,
       
  1494                          ret);
       
  1495     if (val != 0) {
       
  1496     xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
       
  1497               XML_SCHEMAP_REDEFINED_GROUP,
       
  1498                       "Group %s already defined\n",
       
  1499                       name, NULL);
       
  1500         xmlFree(ret);
       
  1501         return (NULL);
       
  1502     }
       
  1503     ret->minOccurs = 1;
       
  1504     ret->maxOccurs = 1;
       
  1505 
       
  1506     return (ret);
       
  1507 }
       
  1508 
       
  1509 /************************************************************************
       
  1510  *                                  *
       
  1511  *      Utilities for parsing                   *
       
  1512  *                                  *
       
  1513  ************************************************************************/
       
  1514 
       
  1515 /**
       
  1516  * xmlGetQNameProp:
       
  1517  * @ctxt:  a schema validation context
       
  1518  * @node:  a subtree containing XML Schema informations
       
  1519  * @name:  the attribute name
       
  1520  * @namespace:  the result namespace if any
       
  1521  *
       
  1522  * Extract a QName Attribute value
       
  1523  *
       
  1524  * Returns the NCName or NULL if not found, and also update @namespace
       
  1525  *    with the namespace URI
       
  1526  */
       
  1527 static const xmlChar *
       
  1528 xmlGetQNameProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
       
  1529                 const char *name, const xmlChar ** namespace)
       
  1530 {
       
  1531     const xmlChar *val;
       
  1532     xmlNsPtr ns;
       
  1533     const xmlChar *ret, *prefix;
       
  1534     int len;
       
  1535 
       
  1536     *namespace = NULL;
       
  1537     val = xmlSchemaGetProp(ctxt, node, name);
       
  1538     if (val == NULL)
       
  1539         return (NULL);
       
  1540 
       
  1541     if (!strchr((char *) val, ':')) {
       
  1542     ns = xmlSearchNs(node->doc, node, 0);
       
  1543     if (ns) {
       
  1544         *namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
       
  1545         return (val);
       
  1546     }
       
  1547     }
       
  1548     ret = xmlSplitQName3(val, &len);
       
  1549     if (ret == NULL) {
       
  1550         return (val);
       
  1551     }
       
  1552     ret = xmlDictLookup(ctxt->dict, ret, -1);
       
  1553     prefix = xmlDictLookup(ctxt->dict, val, len);
       
  1554 
       
  1555     ns = xmlSearchNs(node->doc, node, prefix);
       
  1556     if (ns == NULL) {
       
  1557         xmlSchemaPErr(ctxt, node, XML_SCHEMAP_PREFIX_UNDEFINED,
       
  1558                       "Attribute %s: the QName prefix %s is undefined\n",
       
  1559                       (const xmlChar *) name, prefix);
       
  1560     } else {
       
  1561         *namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
       
  1562     }
       
  1563     return (ret);
       
  1564 }
       
  1565 
       
  1566 /**
       
  1567  * xmlGetMaxOccurs:
       
  1568  * @ctxt:  a schema validation context
       
  1569  * @node:  a subtree containing XML Schema informations
       
  1570  *
       
  1571  * Get the maxOccurs property
       
  1572  *
       
  1573  * Returns the default if not found, or the value
       
  1574  */
       
  1575 static int
       
  1576 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
       
  1577 {
       
  1578     const xmlChar *val, *cur;
       
  1579     int ret = 0;
       
  1580 
       
  1581     val = xmlSchemaGetProp(ctxt, node, "maxOccurs");
       
  1582     if (val == NULL)
       
  1583         return (1);
       
  1584 
       
  1585     if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
       
  1586         return (UNBOUNDED);  /* encoding it with -1 might be another option */
       
  1587     }
       
  1588 
       
  1589     cur = val;
       
  1590     while (IS_BLANK_CH(*cur))
       
  1591         cur++;
       
  1592     while ((*cur >= '0') && (*cur <= '9')) {
       
  1593         ret = ret * 10 + (*cur - '0');
       
  1594         cur++;
       
  1595     }
       
  1596     while (IS_BLANK_CH(*cur))
       
  1597         cur++;
       
  1598     if (*cur != 0) {
       
  1599         xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_MAXOCCURS,
       
  1600                       "invalid value for maxOccurs: %s\n", val, NULL);
       
  1601         return (1);
       
  1602     }
       
  1603     return (ret);
       
  1604 }
       
  1605 
       
  1606 /**
       
  1607  * xmlGetMinOccurs:
       
  1608  * @ctxt:  a schema validation context
       
  1609  * @node:  a subtree containing XML Schema informations
       
  1610  *
       
  1611  * Get the minOccurs property
       
  1612  *
       
  1613  * Returns the default if not found, or the value
       
  1614  */
       
  1615 static int
       
  1616 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
       
  1617 {
       
  1618     const xmlChar *val, *cur;
       
  1619     int ret = 0;
       
  1620 
       
  1621     val = xmlSchemaGetProp(ctxt, node, "minOccurs");
       
  1622     if (val == NULL)
       
  1623         return (1);
       
  1624 
       
  1625     cur = val;
       
  1626     while (IS_BLANK_CH(*cur))
       
  1627         cur++;
       
  1628     while ((*cur >= '0') && (*cur <= '9')) {
       
  1629         ret = ret * 10 + (*cur - '0');
       
  1630         cur++;
       
  1631     }
       
  1632     while (IS_BLANK_CH(*cur))
       
  1633         cur++;
       
  1634     if (*cur != 0) {
       
  1635         xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_MINOCCURS,
       
  1636                       "invalid value for minOccurs: %s\n", val, NULL);
       
  1637         return (1);
       
  1638     }
       
  1639     return (ret);
       
  1640 }
       
  1641 
       
  1642 /**
       
  1643  * xmlGetBooleanProp:
       
  1644  * @ctxt:  a schema validation context
       
  1645  * @node:  a subtree containing XML Schema informations
       
  1646  * @name:  the attribute name
       
  1647  * @def:  the default value
       
  1648  *
       
  1649  * Get is a bolean property is set
       
  1650  *
       
  1651  * Returns the default if not found, 0 if found to be false,
       
  1652  *         1 if found to be true
       
  1653  */
       
  1654 static int
       
  1655 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
       
  1656                   const char *name, int def)
       
  1657 {
       
  1658     const xmlChar *val;
       
  1659 
       
  1660     val = xmlSchemaGetProp(ctxt, node, name);
       
  1661     if (val == NULL)
       
  1662         return (def);
       
  1663 
       
  1664     if (xmlStrEqual(val, BAD_CAST "true"))
       
  1665         def = 1;
       
  1666     else if (xmlStrEqual(val, BAD_CAST "false"))
       
  1667         def = 0;
       
  1668     else {
       
  1669         xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_BOOLEAN,
       
  1670                       "Attribute %s: the value %s is not boolean\n",
       
  1671                       (const xmlChar *) name, val);
       
  1672     }
       
  1673     return (def);
       
  1674 }
       
  1675 
       
  1676 /************************************************************************
       
  1677  *                                  *
       
  1678  *      Shema extraction from an Infoset            *
       
  1679  *                                  *
       
  1680  ************************************************************************/
       
  1681 static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
       
  1682                                                  ctxt, xmlSchemaPtr schema,
       
  1683                                                  xmlNodePtr node);
       
  1684 static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
       
  1685                                                   ctxt,
       
  1686                                                   xmlSchemaPtr schema,
       
  1687                                                   xmlNodePtr node);
       
  1688 static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
       
  1689                                                   ctxt,
       
  1690                                                   xmlSchemaPtr schema,
       
  1691                                                   xmlNodePtr node,
       
  1692                                                   int simple);
       
  1693 static xmlSchemaTypePtr xmlSchemaParseSequence(xmlSchemaParserCtxtPtr ctxt,
       
  1694                                                xmlSchemaPtr schema,
       
  1695                                                xmlNodePtr node);
       
  1696 static xmlSchemaTypePtr xmlSchemaParseAll(xmlSchemaParserCtxtPtr ctxt,
       
  1697                                           xmlSchemaPtr schema,
       
  1698                                           xmlNodePtr node);
       
  1699 static xmlSchemaAttributePtr xmlSchemaParseAttribute(xmlSchemaParserCtxtPtr
       
  1700                                                      ctxt,
       
  1701                                                      xmlSchemaPtr schema,
       
  1702                                                      xmlNodePtr node,
       
  1703                              int topLevel);
       
  1704 static xmlSchemaAttributeGroupPtr
       
  1705 xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt,
       
  1706                              xmlSchemaPtr schema, xmlNodePtr node);
       
  1707 static xmlSchemaTypePtr xmlSchemaParseChoice(xmlSchemaParserCtxtPtr ctxt,
       
  1708                                              xmlSchemaPtr schema,
       
  1709                                              xmlNodePtr node);
       
  1710 static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
       
  1711                                            xmlSchemaPtr schema,
       
  1712                                            xmlNodePtr node);
       
  1713 static xmlSchemaAttributePtr
       
  1714 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
       
  1715                            xmlSchemaPtr schema, xmlNodePtr node);
       
  1716 
       
  1717 /**
       
  1718  * xmlSchemaParseAttrDecls:
       
  1719  * @ctxt:  a schema validation context
       
  1720  * @schema:  the schema being built
       
  1721  * @node:  a subtree containing XML Schema informations
       
  1722  * @type:  the hosting type
       
  1723  *
       
  1724  * parse a XML schema attrDecls declaration corresponding to
       
  1725  * <!ENTITY % attrDecls
       
  1726  *       '((%attribute;| %attributeGroup;)*,(%anyAttribute;)?)'>
       
  1727  */
       
  1728 static xmlNodePtr
       
  1729 xmlSchemaParseAttrDecls(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  1730                         xmlNodePtr child, xmlSchemaTypePtr type)
       
  1731 {
       
  1732     xmlSchemaAttributePtr lastattr, attr;
       
  1733 
       
  1734     lastattr = NULL;
       
  1735     while ((IS_SCHEMA(child, "attribute")) ||
       
  1736            (IS_SCHEMA(child, "attributeGroup"))) {
       
  1737         attr = NULL;
       
  1738         if (IS_SCHEMA(child, "attribute")) {
       
  1739             attr = xmlSchemaParseAttribute(ctxt, schema, child, 0);
       
  1740         } else if (IS_SCHEMA(child, "attributeGroup")) {
       
  1741             attr = (xmlSchemaAttributePtr)
       
  1742                 xmlSchemaParseAttributeGroup(ctxt, schema, child);
       
  1743         }
       
  1744         if (attr != NULL) {
       
  1745             if (lastattr == NULL) {
       
  1746                 type->attributes = attr;
       
  1747                 lastattr = attr;
       
  1748             } else {
       
  1749                 lastattr->next = attr;
       
  1750                 lastattr = attr;
       
  1751             }
       
  1752         }
       
  1753         child = child->next;
       
  1754     }
       
  1755     if (IS_SCHEMA(child, "anyAttribute")) {
       
  1756         attr = xmlSchemaParseAnyAttribute(ctxt, schema, child);
       
  1757         if (attr != NULL) {
       
  1758             if (lastattr == NULL) {
       
  1759                 type->attributes = attr;
       
  1760                 lastattr = attr;
       
  1761             } else {
       
  1762                 lastattr->next = attr;
       
  1763                 lastattr = attr;
       
  1764             }
       
  1765         }
       
  1766         child = child->next;
       
  1767     }
       
  1768     return (child);
       
  1769 }
       
  1770 
       
  1771 /**
       
  1772  * xmlSchemaParseAnnotation:
       
  1773  * @ctxt:  a schema validation context
       
  1774  * @schema:  the schema being built
       
  1775  * @node:  a subtree containing XML Schema informations
       
  1776  *
       
  1777  * parse a XML schema Attrribute declaration
       
  1778  * *WARNING* this interface is highly subject to change
       
  1779  *
       
  1780  * Returns -1 in case of error, 0 if the declaration is improper and
       
  1781  *         1 in case of success.
       
  1782  */
       
  1783 static xmlSchemaAnnotPtr
       
  1784 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  1785                          xmlNodePtr node)
       
  1786 {
       
  1787     xmlSchemaAnnotPtr ret;
       
  1788 
       
  1789     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  1790         return (NULL);
       
  1791     ret = xmlSchemaNewAnnot(ctxt, node);
       
  1792 
       
  1793     return (ret);
       
  1794 }
       
  1795 
       
  1796 /**
       
  1797  * xmlSchemaParseFacet:
       
  1798  * @ctxt:  a schema validation context
       
  1799  * @schema:  the schema being built
       
  1800  * @node:  a subtree containing XML Schema informations
       
  1801  *
       
  1802  * parse a XML schema Facet declaration
       
  1803  * *WARNING* this interface is highly subject to change
       
  1804  *
       
  1805  * Returns the new type structure or NULL in case of error
       
  1806  */
       
  1807 static xmlSchemaFacetPtr
       
  1808 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  1809                     xmlNodePtr node)
       
  1810 {
       
  1811     xmlSchemaFacetPtr facet;
       
  1812     xmlNodePtr child = NULL;
       
  1813     const xmlChar *value;
       
  1814 
       
  1815     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  1816         return (NULL);
       
  1817 
       
  1818     facet = xmlSchemaNewFacet();
       
  1819     if (facet == NULL) {
       
  1820         xmlSchemaPErrMemory(ctxt, "allocating facet", node);
       
  1821         return (NULL);
       
  1822     }
       
  1823     facet->node = node;
       
  1824     value = xmlSchemaGetProp(ctxt, node, "value");
       
  1825     if (value == NULL) {
       
  1826         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
       
  1827                        "Facet %s has no value\n", node->name, NULL);
       
  1828         xmlSchemaFreeFacet(facet);
       
  1829         return (NULL);
       
  1830     }
       
  1831     if (IS_SCHEMA(node, "minInclusive")) {
       
  1832         facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
       
  1833     } else if (IS_SCHEMA(node, "minExclusive")) {
       
  1834         facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
       
  1835     } else if (IS_SCHEMA(node, "maxInclusive")) {
       
  1836         facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
       
  1837     } else if (IS_SCHEMA(node, "maxExclusive")) {
       
  1838         facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
       
  1839     } else if (IS_SCHEMA(node, "totalDigits")) {
       
  1840         facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
       
  1841     } else if (IS_SCHEMA(node, "fractionDigits")) {
       
  1842         facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
       
  1843     } else if (IS_SCHEMA(node, "pattern")) {
       
  1844         facet->type = XML_SCHEMA_FACET_PATTERN;
       
  1845     } else if (IS_SCHEMA(node, "enumeration")) {
       
  1846         facet->type = XML_SCHEMA_FACET_ENUMERATION;
       
  1847     } else if (IS_SCHEMA(node, "whiteSpace")) {
       
  1848         facet->type = XML_SCHEMA_FACET_WHITESPACE;
       
  1849     } else if (IS_SCHEMA(node, "length")) {
       
  1850         facet->type = XML_SCHEMA_FACET_LENGTH;
       
  1851     } else if (IS_SCHEMA(node, "maxLength")) {
       
  1852         facet->type = XML_SCHEMA_FACET_MAXLENGTH;
       
  1853     } else if (IS_SCHEMA(node, "minLength")) {
       
  1854         facet->type = XML_SCHEMA_FACET_MINLENGTH;
       
  1855     } else {
       
  1856         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
       
  1857                        "Unknown facet type %s\n", node->name, NULL);
       
  1858         xmlSchemaFreeFacet(facet);
       
  1859         return (NULL);
       
  1860     }
       
  1861     facet->id = xmlSchemaGetProp(ctxt, node, "id");
       
  1862     facet->value = value;
       
  1863     child = node->children;
       
  1864 
       
  1865     if (IS_SCHEMA(child, "annotation")) {
       
  1866         facet->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  1867         child = child->next;
       
  1868     }
       
  1869     if (child != NULL) {
       
  1870         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
       
  1871                        "Facet %s has unexpected child content\n",
       
  1872                        node->name, NULL);
       
  1873     }
       
  1874     return (facet);
       
  1875 }
       
  1876 
       
  1877 /**
       
  1878  * xmlSchemaParseAny:
       
  1879  * @ctxt:  a schema validation context
       
  1880  * @schema:  the schema being built
       
  1881  * @node:  a subtree containing XML Schema informations
       
  1882  *
       
  1883  * parse a XML schema Any declaration
       
  1884  * *WARNING* this interface is highly subject to change
       
  1885  *
       
  1886  * Returns the new type structure or NULL in case of error
       
  1887  */
       
  1888 static xmlSchemaTypePtr
       
  1889 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  1890                   xmlNodePtr node)
       
  1891 {
       
  1892     xmlSchemaTypePtr type;
       
  1893     xmlNodePtr child = NULL;
       
  1894     xmlChar name[30];
       
  1895 
       
  1896     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  1897         return (NULL);
       
  1898     snprintf((char *) name, 30, "any %d", ctxt->counter++ + 1);
       
  1899     type = xmlSchemaAddType(ctxt, schema, name, NULL);
       
  1900     if (type == NULL)
       
  1901         return (NULL);
       
  1902     type->node = node;
       
  1903     type->type = XML_SCHEMA_TYPE_ANY;
       
  1904     child = node->children;
       
  1905     type->minOccurs = xmlGetMinOccurs(ctxt, node);
       
  1906     type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
       
  1907 
       
  1908     if (IS_SCHEMA(child, "annotation")) {
       
  1909         type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  1910         child = child->next;
       
  1911     }
       
  1912     if (child != NULL) {
       
  1913         xmlSchemaPErr2(ctxt, node, child,
       
  1914                        XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD,
       
  1915                        "Sequence %s has unexpected content\n", type->name,
       
  1916                        NULL);
       
  1917     }
       
  1918 
       
  1919     return (type);
       
  1920 }
       
  1921 
       
  1922 /**
       
  1923  * xmlSchemaParseNotation:
       
  1924  * @ctxt:  a schema validation context
       
  1925  * @schema:  the schema being built
       
  1926  * @node:  a subtree containing XML Schema informations
       
  1927  *
       
  1928  * parse a XML schema Notation declaration
       
  1929  *
       
  1930  * Returns the new structure or NULL in case of error
       
  1931  */
       
  1932 static xmlSchemaNotationPtr
       
  1933 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  1934                        xmlNodePtr node)
       
  1935 {
       
  1936     const xmlChar *name;
       
  1937     xmlSchemaNotationPtr ret;
       
  1938     xmlNodePtr child = NULL;
       
  1939 
       
  1940     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  1941         return (NULL);
       
  1942     name = xmlSchemaGetProp(ctxt, node, "name");
       
  1943     if (name == NULL) {
       
  1944         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
       
  1945                        "Notation has no name\n", NULL, NULL);
       
  1946         return (NULL);
       
  1947     }
       
  1948     ret = xmlSchemaAddNotation(ctxt, schema, name);
       
  1949     if (ret == NULL) {
       
  1950         return (NULL);
       
  1951     }
       
  1952     child = node->children;
       
  1953     if (IS_SCHEMA(child, "annotation")) {
       
  1954         ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  1955         child = child->next;
       
  1956     }
       
  1957     if (child != NULL) {
       
  1958         xmlSchemaPErr2(ctxt, node, child,
       
  1959                        XML_SCHEMAP_UNKNOWN_NOTATION_CHILD,
       
  1960                        "notation %s has unexpected content\n", name, NULL);
       
  1961     }
       
  1962 
       
  1963     return (ret);
       
  1964 }
       
  1965 
       
  1966 /**
       
  1967  * xmlSchemaParseAnyAttribute:
       
  1968  * @ctxt:  a schema validation context
       
  1969  * @schema:  the schema being built
       
  1970  * @node:  a subtree containing XML Schema informations
       
  1971  *
       
  1972  * parse a XML schema AnyAttrribute declaration
       
  1973  * *WARNING* this interface is highly subject to change
       
  1974  *
       
  1975  * Returns an attribute def structure or NULL
       
  1976  */
       
  1977 static xmlSchemaAttributePtr
       
  1978 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
       
  1979                            xmlSchemaPtr schema, xmlNodePtr node)
       
  1980 {
       
  1981     const xmlChar *processContents;
       
  1982     xmlSchemaAttributePtr ret;
       
  1983     xmlNodePtr child = NULL;
       
  1984     char name[100];
       
  1985 
       
  1986 
       
  1987     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  1988         return (NULL);
       
  1989 
       
  1990     snprintf(name, 99, "anyattr %d", ctxt->counter++ + 1);
       
  1991 
       
  1992     /* local = xmlSchemaGetNamespace(ctxt, schema, node, BAD_CAST "anyattr", &ns); */
       
  1993 
       
  1994     /*
       
  1995      * TODO: namespace = ((##any | ##other) | List of (anyURI |
       
  1996      *                    (##targetNamespace | * ##local)) )  : ##any
       
  1997      */
       
  1998     ret = xmlSchemaAddAttribute(ctxt, schema, BAD_CAST name, NULL);
       
  1999     if (ret == NULL) {
       
  2000         return (NULL);
       
  2001     }
       
  2002     ret->type = XML_SCHEMA_TYPE_ANY_ATTRIBUTE;
       
  2003     ret->id = xmlSchemaGetProp(ctxt, node, "id");
       
  2004     processContents = xmlSchemaGetProp(ctxt, node, "processContents");
       
  2005     if ((processContents == NULL)
       
  2006         || (xmlStrEqual(processContents, (const xmlChar *) "strict"))) {
       
  2007         ret->occurs = XML_SCHEMAS_ANYATTR_STRICT;
       
  2008     } else if (xmlStrEqual(processContents, (const xmlChar *) "skip")) {
       
  2009         ret->occurs = XML_SCHEMAS_ANYATTR_SKIP;
       
  2010     } else if (xmlStrEqual(processContents, (const xmlChar *) "lax")) {
       
  2011         ret->occurs = XML_SCHEMAS_ANYATTR_LAX;
       
  2012     } else {
       
  2013         xmlSchemaPErr2(ctxt, node, child,
       
  2014                        XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD,
       
  2015                        "anyAttribute has unexpected content "
       
  2016                "for processContents: %s\n",
       
  2017                        processContents, NULL);
       
  2018         ret->occurs = XML_SCHEMAS_ANYATTR_STRICT;
       
  2019     }
       
  2020 
       
  2021     child = node->children;
       
  2022     if (IS_SCHEMA(child, "annotation")) {
       
  2023         ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  2024         child = child->next;
       
  2025     }
       
  2026     if (child != NULL) {
       
  2027         xmlSchemaPErr2(ctxt, node, child,
       
  2028                        XML_SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD,
       
  2029                        "anyAttribute %s has unexpected content\n",
       
  2030                        (const xmlChar *) name, NULL);
       
  2031     }
       
  2032 
       
  2033     return (ret);
       
  2034 }
       
  2035 
       
  2036 
       
  2037 /**
       
  2038  * xmlSchemaParseAttribute:
       
  2039  * @ctxt:  a schema validation context
       
  2040  * @schema:  the schema being built
       
  2041  * @node:  a subtree containing XML Schema informations
       
  2042  *
       
  2043  * parse a XML schema Attrribute declaration
       
  2044  * *WARNING* this interface is highly subject to change
       
  2045  *
       
  2046  * Returns the attribute declaration.
       
  2047  */
       
  2048 static xmlSchemaAttributePtr
       
  2049 xmlSchemaParseAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  2050                         xmlNodePtr node, int topLevel)
       
  2051 {
       
  2052     const xmlChar *name, *refNs = NULL, *ref = NULL, *attrVal;
       
  2053     xmlSchemaAttributePtr ret;
       
  2054     xmlNodePtr child = NULL;
       
  2055     char buf[100];
       
  2056     int hasRefType = 0;
       
  2057 
       
  2058     /*
       
  2059      * Note that the w3c spec assumes the schema to be validated with schema
       
  2060      * for schemas beforehand.
       
  2061      *
       
  2062      * 3.2.3 Constraints on XML Representations of Attribute Declarations
       
  2063      *
       
  2064      * TODO: Complete implementation of:
       
  2065      * 3.2.6 Schema Component Constraint: Attribute Declaration Properties
       
  2066      *       Correct
       
  2067      */
       
  2068 
       
  2069     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  2070         return (NULL);
       
  2071 
       
  2072     name = xmlSchemaGetProp(ctxt, node, "name");
       
  2073     if (name == NULL) {
       
  2074         ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
       
  2075     /* 3.2.3 : 3.1
       
  2076      * One of ref or name must be present, but not both
       
  2077      */
       
  2078         if (ref == NULL) {
       
  2079             xmlSchemaPErr(ctxt, node,
       
  2080               XML_SCHEMAP_ATTR_NONAME_NOREF,
       
  2081               "Attribute declaration has no \"name\" or \"ref\"\n",
       
  2082               NULL, NULL);
       
  2083         return (NULL);
       
  2084         }
       
  2085     hasRefType = 1;
       
  2086         snprintf(buf, 99, "anonattr %d", ctxt->counter++ + 1);
       
  2087         name = (const xmlChar *) buf;
       
  2088     ret = xmlSchemaAddAttribute(ctxt, schema, name, NULL);
       
  2089     if (!topLevel) {
       
  2090         /* 3.2.3 : 3.2
       
  2091          * If ref is present, then all of <simpleType>,
       
  2092          * form and type must be absent.
       
  2093          */
       
  2094         if (xmlSchemaGetProp(ctxt, node, "form") != NULL) {
       
  2095         xmlSchemaPErr(ctxt, node,
       
  2096                       XML_SCHEMAP_INVALID_ATTR_COMBINATION,
       
  2097                   "Attribute declaration %s has \"ref\", thus "
       
  2098                   "\"form\" must be absent\n", name, NULL);
       
  2099         }
       
  2100         if (xmlSchemaGetProp(ctxt, node, "type") != NULL) {
       
  2101         xmlSchemaPErr(ctxt, node,
       
  2102                       XML_SCHEMAP_INVALID_ATTR_COMBINATION,
       
  2103                   "Attribute declaration %s has \"ref\", thus "
       
  2104                   "\"type\" must be absent\n", name, NULL);
       
  2105         }
       
  2106     }
       
  2107     } else {
       
  2108         const xmlChar *ns = NULL;
       
  2109     /* 3.2.3 : 3.1
       
  2110      * One of ref or name must be present, but not both
       
  2111      */
       
  2112     if ((!topLevel) && (xmlSchemaGetProp(ctxt, node, "ref") != NULL)) {
       
  2113         xmlSchemaPErr(ctxt, node,
       
  2114                           XML_SCHEMAP_INVALID_ATTR_COMBINATION,
       
  2115                           "Attribute declaration has both, \"name\" and "
       
  2116               "\"ref\"\n", NULL, NULL);
       
  2117     }
       
  2118 
       
  2119         /* local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns); */
       
  2120     /* Evaluate the target namespace */
       
  2121     if (schema->targetNamespace != NULL) {
       
  2122         if (topLevel) {
       
  2123         ns = schema->targetNamespace;
       
  2124         } else if (xmlSchemaGetProp(ctxt, node, "form") != NULL) {
       
  2125         if (xmlStrEqual( xmlSchemaGetProp(ctxt, node, "form"),
       
  2126                  BAD_CAST "qualified")) {
       
  2127             ns = schema->targetNamespace;
       
  2128         }
       
  2129         } else if (schema->flags & XML_SCHEMAS_QUALIF_ATTR) {
       
  2130         ns = schema->targetNamespace;
       
  2131         }
       
  2132     }
       
  2133     ret = xmlSchemaAddAttribute(ctxt, schema, name, ns);
       
  2134 
       
  2135     /* 3.2.6 Schema Component Constraint: xmlns Not Allowed */
       
  2136     if (xmlStrEqual(name, BAD_CAST "xmlns")) {
       
  2137         xmlSchemaPErr(ctxt, node,
       
  2138                       XML_SCHEMAP_INVALID_ATTR_NAME,
       
  2139                       "The name of an attribute declaration must not match "
       
  2140               "\"xmlns\".\n", NULL, NULL);
       
  2141     }
       
  2142 
       
  2143     /* 3.2.6 Schema Component Constraint: xsi: Not Allowed */
       
  2144     if (xmlStrEqual(ret->targetNamespace, xmlSchemaInstanceNs)) {
       
  2145         xmlSchemaPErr(ctxt, node,
       
  2146                           XML_SCHEMAP_INVALID_ATTR_NAME,
       
  2147                       "The target namespace of an attribute declaration, "
       
  2148               "must not match \"http://www.w3.org/2001/"
       
  2149               "XMLSchema-instance\"", NULL, NULL);
       
  2150     }
       
  2151     }
       
  2152     if (ret == NULL) {
       
  2153         return (NULL);
       
  2154     }
       
  2155     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
       
  2156 
       
  2157     /* Handle the "use" attribute. */
       
  2158     attrVal = xmlSchemaGetProp(ctxt, node, "use");
       
  2159     if (attrVal != NULL) {
       
  2160     if (xmlStrEqual(attrVal, BAD_CAST "optional"))
       
  2161         ret->occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
       
  2162     else if (xmlStrEqual(attrVal, BAD_CAST "prohibited"))
       
  2163         ret->occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
       
  2164     else if (xmlStrEqual(attrVal, BAD_CAST "required"))
       
  2165         ret->occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
       
  2166     else
       
  2167         xmlSchemaPErr(ctxt, node,
       
  2168               XML_SCHEMAP_INVALID_ATTR_USE,
       
  2169               "Attribute declaration %s has an invalid "
       
  2170               "value for \"use\"\n", name, NULL);
       
  2171     } else
       
  2172     ret->occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
       
  2173 
       
  2174 
       
  2175     if (xmlSchemaGetProp(ctxt, node, "default") != NULL) {
       
  2176     /* 3.2.3 : 1
       
  2177      * default and fixed must not both be present.
       
  2178      */
       
  2179     if (xmlSchemaGetProp(ctxt, node, "fixed") != NULL) {
       
  2180         xmlSchemaPErr(ctxt, node,
       
  2181                           XML_SCHEMAP_INVALID_ATTR_COMBINATION,
       
  2182                           "Attribute declaration has both, \"default\" "
       
  2183               "and \"fixed\"\n", NULL, NULL);
       
  2184     }
       
  2185     /* 3.2.3 : 2
       
  2186      * If default and use are both present, use must have
       
  2187      * the actual value optional.
       
  2188      */
       
  2189     if (ret->occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL) {
       
  2190         xmlSchemaPErr(ctxt, node,
       
  2191                           XML_SCHEMAP_INVALID_ATTR_COMBINATION,
       
  2192                           "Attribute declaration has \"default\" but "
       
  2193               "\"use\" is not \"optional\"\n", NULL, NULL);
       
  2194     }
       
  2195     }
       
  2196 
       
  2197     ret->ref = ref;
       
  2198     ret->refNs = refNs;
       
  2199     /*
       
  2200      * The setting of XML_SCHEMAS_ATTR_NSDEFAULT is not needed anymore,
       
  2201      * since the target namespace was already evaluated and took
       
  2202      * attributeFormDefault into account.
       
  2203      */
       
  2204     /*
       
  2205     if ((ret->targetNamespace != NULL) &&
       
  2206         ((schema->flags & XML_SCHEMAS_QUALIF_ATTR) == 0) &&
       
  2207     (xmlStrEqual(ret->targetNamespace, schema->targetNamespace)))
       
  2208     ret->flags |= XML_SCHEMAS_ATTR_NSDEFAULT;
       
  2209     */
       
  2210     ret->typeName = xmlGetQNameProp(ctxt, node, "type", &(ret->typeNs));
       
  2211     if (ret->typeName != NULL)
       
  2212     hasRefType = 1;
       
  2213     ret->node = node;
       
  2214     child = node->children;
       
  2215     if (IS_SCHEMA(child, "annotation")) {
       
  2216         ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  2217         child = child->next;
       
  2218     }
       
  2219     if (IS_SCHEMA(child, "simpleType")) {
       
  2220     if (hasRefType) {
       
  2221         /* 3.2.3 : 4
       
  2222          * type and <simpleType> must not both be present.
       
  2223          *
       
  2224          * TODO: XML_SCHEMAP_INVALID_ATTR_COMBINATION seems not to be
       
  2225          * a proper error type here.
       
  2226          */
       
  2227         xmlSchemaPErr2(ctxt, node, child,
       
  2228                        XML_SCHEMAP_INVALID_ATTR_COMBINATION,
       
  2229                            "Attribute declaration %s has both (\"ref\" or "
       
  2230                "\"type\") and <simpleType>\n", name, NULL);
       
  2231     } else
       
  2232         ret->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child);
       
  2233         child = child->next;
       
  2234     }
       
  2235     if (child != NULL) {
       
  2236         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_ATTR_CHILD,
       
  2237                        "attribute %s has unexpected content\n", name,
       
  2238                        NULL);
       
  2239     }
       
  2240 
       
  2241     return (ret);
       
  2242 }
       
  2243 
       
  2244 /**
       
  2245  * xmlSchemaParseAttributeGroup:
       
  2246  * @ctxt:  a schema validation context
       
  2247  * @schema:  the schema being built
       
  2248  * @node:  a subtree containing XML Schema informations
       
  2249  *
       
  2250  * parse a XML schema Attribute Group declaration
       
  2251  * *WARNING* this interface is highly subject to change
       
  2252  *
       
  2253  * Returns the attribute group or NULL in case of error.
       
  2254  */
       
  2255 static xmlSchemaAttributeGroupPtr
       
  2256 xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt,
       
  2257                              xmlSchemaPtr schema, xmlNodePtr node)
       
  2258 {
       
  2259     const xmlChar *name, *refNs = NULL, *ref = NULL;
       
  2260     xmlSchemaAttributeGroupPtr ret;
       
  2261     xmlSchemaAttributePtr last = NULL, attr;
       
  2262     xmlNodePtr child = NULL;
       
  2263     const xmlChar *oldcontainer;
       
  2264     char buf[100];
       
  2265 
       
  2266     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  2267         return (NULL);
       
  2268     oldcontainer = ctxt->container;
       
  2269     name = xmlSchemaGetProp(ctxt, node, "name");
       
  2270     if (name == NULL) {
       
  2271 
       
  2272         ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
       
  2273         if (ref == NULL) {
       
  2274             xmlSchemaPErr2(ctxt, node, child,
       
  2275                            XML_SCHEMAP_ATTRGRP_NONAME_NOREF,
       
  2276                            "AttributeGroup has no name nor ref\n", NULL,
       
  2277                            NULL);
       
  2278             return (NULL);
       
  2279         }
       
  2280         snprintf(buf, 99, "anonattrgroup %d", ctxt->counter++ + 1);
       
  2281         name = (const xmlChar *) buf;
       
  2282         if (name == NULL) {
       
  2283         xmlSchemaPErrMemory(ctxt, "creating attribute group", node);
       
  2284             return (NULL);
       
  2285         }
       
  2286     }
       
  2287     ret = xmlSchemaAddAttributeGroup(ctxt, schema, name);
       
  2288     if (ret == NULL) {
       
  2289         return (NULL);
       
  2290     }
       
  2291     ret->ref = ref;
       
  2292     ret->refNs = refNs;
       
  2293     ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
       
  2294     ret->node = node;
       
  2295     child = node->children;
       
  2296     ctxt->container = name;
       
  2297     if (IS_SCHEMA(child, "annotation")) {
       
  2298         ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  2299         child = child->next;
       
  2300     }
       
  2301     while ((IS_SCHEMA(child, "attribute")) ||
       
  2302            (IS_SCHEMA(child, "attributeGroup"))) {
       
  2303         attr = NULL;
       
  2304         if (IS_SCHEMA(child, "attribute")) {
       
  2305             attr = xmlSchemaParseAttribute(ctxt, schema, child, 0);
       
  2306         } else if (IS_SCHEMA(child, "attributeGroup")) {
       
  2307             attr = (xmlSchemaAttributePtr)
       
  2308                 xmlSchemaParseAttributeGroup(ctxt, schema, child);
       
  2309         }
       
  2310         if (attr != NULL) {
       
  2311             if (last == NULL) {
       
  2312                 ret->attributes = attr;
       
  2313                 last = attr;
       
  2314             } else {
       
  2315                 last->next = attr;
       
  2316                 last = attr;
       
  2317             }
       
  2318         }
       
  2319         child = child->next;
       
  2320     }
       
  2321     if (IS_SCHEMA(child, "anyAttribute")) {
       
  2322         TODO
       
  2323     child = child->next;
       
  2324     }
       
  2325     if (child != NULL) {
       
  2326         xmlSchemaPErr2(ctxt, node, child,
       
  2327                        XML_SCHEMAP_UNKNOWN_ATTRGRP_CHILD,
       
  2328                        "attribute group %s has unexpected content\n", name,
       
  2329                        NULL);
       
  2330     }
       
  2331     ctxt->container = oldcontainer;
       
  2332     return (ret);
       
  2333 }
       
  2334 
       
  2335 /**
       
  2336  * xmlSchemaParseElement:
       
  2337  * @ctxt:  a schema validation context
       
  2338  * @schema:  the schema being built
       
  2339  * @node:  a subtree containing XML Schema informations
       
  2340  *
       
  2341  * parse a XML schema Element declaration
       
  2342  * *WARNING* this interface is highly subject to change
       
  2343  *
       
  2344  * Returns the parsed element declaration.
       
  2345  */
       
  2346 static xmlSchemaElementPtr
       
  2347 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  2348                       xmlNodePtr node, int toplevel)
       
  2349 {
       
  2350     const xmlChar *name, *fixed;
       
  2351     const xmlChar *refNs = NULL, *ref = NULL;
       
  2352     xmlSchemaElementPtr ret;
       
  2353     xmlNodePtr child = NULL;
       
  2354     const xmlChar *oldcontainer;
       
  2355     char buf[100];
       
  2356     xmlAttrPtr attr;
       
  2357 
       
  2358     /* 3.3.3 Constraints on XML Representations of Element Declarations */
       
  2359     /* TODO: Complete implementation of 3.3.6 */
       
  2360 
       
  2361     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  2362         return (NULL);
       
  2363     oldcontainer = ctxt->container;
       
  2364     name = xmlSchemaGetProp(ctxt, node, "name");
       
  2365     if (name == NULL) {
       
  2366 
       
  2367         ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
       
  2368     /* 3.3.3 : 2.1
       
  2369      * One of ref or name must be present, but not both
       
  2370      */
       
  2371         if (ref == NULL) {
       
  2372             xmlSchemaPErr(ctxt, node,
       
  2373                            XML_SCHEMAP_ELEM_NONAME_NOREF,
       
  2374                            "Element has no name nor ref\n", NULL, NULL);
       
  2375             return (NULL);
       
  2376         }
       
  2377         snprintf(buf, 99, "anonelem %d", ctxt->counter++ + 1);
       
  2378         name = (const xmlChar *) buf;
       
  2379     ret = xmlSchemaAddElement(ctxt, schema, name, NULL);
       
  2380     } else {
       
  2381     const xmlChar *ns = NULL;
       
  2382 
       
  2383     /* Evaluate the target namespace */
       
  2384     if (schema->targetNamespace != NULL) {
       
  2385         if (toplevel) {
       
  2386         ns = schema->targetNamespace;
       
  2387         } else if (xmlSchemaGetProp(ctxt, node, "form") != NULL) {
       
  2388         if (xmlStrEqual( xmlSchemaGetProp(ctxt, node, "form"),
       
  2389                  BAD_CAST "qualified")) {
       
  2390             ns = schema->targetNamespace;
       
  2391         }
       
  2392         } else if (schema->flags & XML_SCHEMAS_QUALIF_ATTR) {
       
  2393         ns = schema->targetNamespace;
       
  2394         }
       
  2395     }
       
  2396     /*local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns); */
       
  2397     ret = xmlSchemaAddElement(ctxt, schema, name, ns);
       
  2398     /* 3.3.3 : 2.1
       
  2399      * One of ref or name must be present, but not both
       
  2400      */
       
  2401     if ((!toplevel) && (xmlSchemaGetProp(ctxt, node, "ref") != NULL)) {
       
  2402         xmlSchemaPErr(ctxt, node,
       
  2403                           XML_SCHEMAP_INVALID_ATTR_COMBINATION,
       
  2404                           "Element declaration has both, \"name\" and "
       
  2405               "\"ref\"\n", NULL, NULL);
       
  2406     }
       
  2407     }
       
  2408     if (ret != NULL)
       
  2409     ret->node = node;
       
  2410     if (ret == NULL) {
       
  2411         return (NULL);
       
  2412     }
       
  2413     ret->type = XML_SCHEMA_TYPE_ELEMENT;
       
  2414     ret->ref = ref;
       
  2415     ret->refNs = refNs;
       
  2416     if (ref != NULL)
       
  2417         ret->flags |= XML_SCHEMAS_ELEM_REF;
       
  2418 
       
  2419     /* 3.3.3 : 2.2 */
       
  2420     if ((!toplevel) && (ref != NULL)) {
       
  2421     attr = node->properties;
       
  2422     while (attr != NULL) {
       
  2423         if ((attr->ns == NULL) &&
       
  2424         (!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
       
  2425         (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
       
  2426         (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
       
  2427         (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
       
  2428 
       
  2429         xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_ATTR_COMBINATION,
       
  2430                        "Element declaration %s: only minOccurs, maxOccurs "
       
  2431                "and id are allowed in addition to ref\n",
       
  2432                ret->name, NULL);
       
  2433         }
       
  2434         attr = attr->next;
       
  2435     }
       
  2436     }
       
  2437 
       
  2438     if (toplevel)
       
  2439         ret->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
       
  2440     if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
       
  2441         ret->flags |= XML_SCHEMAS_ELEM_NILLABLE;
       
  2442     if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
       
  2443         ret->flags |= XML_SCHEMAS_ELEM_NILLABLE;
       
  2444     ctxt->container = name;
       
  2445 
       
  2446     ret->id = xmlSchemaGetProp(ctxt, node, "id");
       
  2447     ret->namedType =
       
  2448         xmlGetQNameProp(ctxt, node, "type", &(ret->namedTypeNs));
       
  2449     ret->substGroup =
       
  2450         xmlGetQNameProp(ctxt, node, "substitutionGroup",
       
  2451                         &(ret->substGroupNs));
       
  2452     if ((ret->substGroup != NULL) && (!toplevel)) {
       
  2453     /* 3.3.6 : 3 */
       
  2454     /*
       
  2455      * TODO: This seems to be redundant, since the schema for schemas
       
  2456      * already prohibits the use of the "substitutionGroup" attribute
       
  2457      * in local element declarations.
       
  2458      */
       
  2459         xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_ATTR_COMBINATION,
       
  2460                   "Element declaration %s: substitutionGroup is allowed "
       
  2461               "on top-level declarations only\n", ret->name, NULL);
       
  2462 
       
  2463     }
       
  2464     fixed = xmlSchemaGetProp(ctxt, node, "fixed");
       
  2465     ret->minOccurs = xmlGetMinOccurs(ctxt, node);
       
  2466     ret->maxOccurs = xmlGetMaxOccurs(ctxt, node);
       
  2467 
       
  2468     ret->value = xmlSchemaGetProp(ctxt, node, "default");
       
  2469     if ((ret->value != NULL) && (fixed != NULL)) {
       
  2470     /* 3.3.3 : 1
       
  2471      * default and fixed must not both be present.
       
  2472      */
       
  2473         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_ELEM_DEFAULT_FIXED,
       
  2474                        "Element %s has both default and fixed\n",
       
  2475                ret->name, NULL);
       
  2476     } else if (fixed != NULL) {
       
  2477         ret->flags |= XML_SCHEMAS_ELEM_FIXED;
       
  2478         ret->value = fixed;
       
  2479     }
       
  2480 
       
  2481     child = node->children;
       
  2482     if (IS_SCHEMA(child, "annotation")) {
       
  2483         ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  2484         child = child->next;
       
  2485     }
       
  2486     if (ref != NULL) {
       
  2487     /* 3.3.3 (2.2) */
       
  2488     while (child != NULL) {
       
  2489         if ((IS_SCHEMA(child, "complexType")) ||
       
  2490         (IS_SCHEMA(child, "simpleType")) ||
       
  2491         (IS_SCHEMA(child, "unique")) ||
       
  2492             (IS_SCHEMA(child, "key")) ||
       
  2493         (IS_SCHEMA(child, "keyref"))) {
       
  2494 
       
  2495         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_REF_AND_CONTENT,
       
  2496                        "Element declaration %s: only annotation is "
       
  2497                    "allowed as content in addition to ref\n",
       
  2498                    ret->name, NULL);
       
  2499         } else {
       
  2500         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_ELEM_CHILD,
       
  2501                    "element %s has unexpected content\n", name, NULL);
       
  2502         }
       
  2503         child = child->next;
       
  2504     }
       
  2505     } else {
       
  2506     if (IS_SCHEMA(child, "complexType")) {
       
  2507         /* 3.3.3 : 3
       
  2508          * type and either <simpleType> or <complexType> are mutually
       
  2509          * exclusive
       
  2510          */
       
  2511         if (ret->namedType != NULL) {
       
  2512         xmlSchemaPErr2(ctxt, node, child,
       
  2513                    XML_SCHEMAP_INVALID_ATTR_INLINE_COMBINATION,
       
  2514                        "Element declaration %s has both \"type\" "
       
  2515                    "and a local complex type\n",
       
  2516                    ret->name, NULL);
       
  2517         } else
       
  2518         ret->subtypes = xmlSchemaParseComplexType(ctxt, schema, child);
       
  2519         child = child->next;
       
  2520     } else if (IS_SCHEMA(child, "simpleType")) {
       
  2521         /* 3.3.3 : 3
       
  2522          * type and either <simpleType> or <complexType> are
       
  2523          * mutually exclusive
       
  2524          */
       
  2525         if (ret->namedType != NULL) {
       
  2526         xmlSchemaPErr2(ctxt, node, child,
       
  2527                    XML_SCHEMAP_INVALID_ATTR_INLINE_COMBINATION,
       
  2528                        "Element declaration %s has both \"type\" "
       
  2529                    "and a local simple type\n",
       
  2530                    ret->name, NULL);
       
  2531         } else
       
  2532         ret->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child);
       
  2533         child = child->next;
       
  2534     }
       
  2535 
       
  2536     while ((IS_SCHEMA(child, "unique")) ||
       
  2537            (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
       
  2538         TODO child = child->next;
       
  2539     }
       
  2540     if (child != NULL) {
       
  2541         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_ELEM_CHILD,
       
  2542                    "element %s has unexpected content\n", name, NULL);
       
  2543     }
       
  2544     }
       
  2545 
       
  2546     ctxt->container = oldcontainer;
       
  2547     return (ret);
       
  2548 }
       
  2549 
       
  2550 /**
       
  2551  * xmlSchemaParseUnion:
       
  2552  * @ctxt:  a schema validation context
       
  2553  * @schema:  the schema being built
       
  2554  * @node:  a subtree containing XML Schema informations
       
  2555  *
       
  2556  * parse a XML schema Union definition
       
  2557  * *WARNING* this interface is highly subject to change
       
  2558  *
       
  2559  * Returns -1 in case of error, 0 if the declaration is improper and
       
  2560  *         1 in case of success.
       
  2561  */
       
  2562 static xmlSchemaTypePtr
       
  2563 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  2564                     xmlNodePtr node)
       
  2565 {
       
  2566     xmlSchemaTypePtr type, subtype, last = NULL;
       
  2567     xmlNodePtr child = NULL;
       
  2568     xmlChar name[30];
       
  2569 
       
  2570     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  2571         return (NULL);
       
  2572 
       
  2573 
       
  2574     snprintf((char *) name, 30, "union %d", ctxt->counter++ + 1);
       
  2575     type = xmlSchemaAddType(ctxt, schema, name, NULL);
       
  2576     if (type == NULL)
       
  2577         return (NULL);
       
  2578     type->node = node;
       
  2579     type->type = XML_SCHEMA_TYPE_UNION;
       
  2580     type->id = xmlSchemaGetProp(ctxt, node, "id");
       
  2581     type->ref = xmlSchemaGetProp(ctxt, node, "memberTypes");
       
  2582 
       
  2583     child = node->children;
       
  2584     if (IS_SCHEMA(child, "annotation")) {
       
  2585         type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  2586         child = child->next;
       
  2587     }
       
  2588     while (IS_SCHEMA(child, "simpleType")) {
       
  2589         subtype = (xmlSchemaTypePtr)
       
  2590             xmlSchemaParseSimpleType(ctxt, schema, child);
       
  2591         if (subtype != NULL) {
       
  2592             if (last == NULL) {
       
  2593                 type->subtypes = subtype;
       
  2594                 last = subtype;
       
  2595             } else {
       
  2596                 last->next = subtype;
       
  2597                 last = subtype;
       
  2598             }
       
  2599             last->next = NULL;
       
  2600         }
       
  2601         child = child->next;
       
  2602     }
       
  2603     if (child != NULL) {
       
  2604         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_UNION_CHILD,
       
  2605                        "Union %s has unexpected content\n", type->name,
       
  2606                        NULL);
       
  2607     }
       
  2608     return (type);
       
  2609 }
       
  2610 
       
  2611 /**
       
  2612  * xmlSchemaParseList:
       
  2613  * @ctxt:  a schema validation context
       
  2614  * @schema:  the schema being built
       
  2615  * @node:  a subtree containing XML Schema informations
       
  2616  *
       
  2617  * parse a XML schema List definition
       
  2618  * *WARNING* this interface is highly subject to change
       
  2619  *
       
  2620  * Returns -1 in case of error, 0 if the declaration is improper and
       
  2621  *         1 in case of success.
       
  2622  */
       
  2623 static xmlSchemaTypePtr
       
  2624 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  2625                    xmlNodePtr node)
       
  2626 {
       
  2627     xmlSchemaTypePtr type, subtype;
       
  2628     xmlNodePtr child = NULL;
       
  2629     xmlChar name[30];
       
  2630 
       
  2631     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  2632         return (NULL);
       
  2633 
       
  2634     snprintf((char *) name, 30, "list %d", ctxt->counter++ + 1);
       
  2635     type = xmlSchemaAddType(ctxt, schema, name, NULL);
       
  2636     if (type == NULL)
       
  2637         return (NULL);
       
  2638     type->node = node;
       
  2639     type->type = XML_SCHEMA_TYPE_LIST;
       
  2640     type->id = xmlSchemaGetProp(ctxt, node, "id");
       
  2641     type->ref = xmlGetQNameProp(ctxt, node, "ref", &(type->refNs));
       
  2642 
       
  2643     child = node->children;
       
  2644     if (IS_SCHEMA(child, "annotation")) {
       
  2645         type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  2646         child = child->next;
       
  2647     }
       
  2648 
       
  2649     subtype = NULL;
       
  2650     if (IS_SCHEMA(child, "simpleType")) {
       
  2651         subtype = (xmlSchemaTypePtr)
       
  2652             xmlSchemaParseSimpleType(ctxt, schema, child);
       
  2653         child = child->next;
       
  2654         type->subtypes = subtype;
       
  2655     }
       
  2656     if (child != NULL) {
       
  2657         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_LIST_CHILD,
       
  2658                        "List %s has unexpected content\n", type->name,
       
  2659                        NULL);
       
  2660     }
       
  2661     return (type);
       
  2662 }
       
  2663 
       
  2664 /**
       
  2665  * xmlSchemaParseSimpleType:
       
  2666  * @ctxt:  a schema validation context
       
  2667  * @schema:  the schema being built
       
  2668  * @node:  a subtree containing XML Schema informations
       
  2669  *
       
  2670  * parse a XML schema Simple Type definition
       
  2671  * *WARNING* this interface is highly subject to change
       
  2672  *
       
  2673  * Returns -1 in case of error, 0 if the declaration is improper and
       
  2674  *         1 in case of success.
       
  2675  */
       
  2676 static xmlSchemaTypePtr
       
  2677 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  2678                          xmlNodePtr node)
       
  2679 {
       
  2680     xmlSchemaTypePtr type, subtype;
       
  2681     xmlNodePtr child = NULL;
       
  2682     const xmlChar *name;
       
  2683 
       
  2684     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  2685         return (NULL);
       
  2686 
       
  2687 
       
  2688     name = xmlSchemaGetProp(ctxt, node, "name");
       
  2689     if (name == NULL) {
       
  2690         char buf[100];
       
  2691 
       
  2692         snprintf(buf, 99, "simpleType %d", ctxt->counter++ + 1);
       
  2693     type = xmlSchemaAddType(ctxt, schema, (const xmlChar *)buf, NULL);
       
  2694     } else {
       
  2695         /* local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns); */
       
  2696     type = xmlSchemaAddType(ctxt, schema, name, schema->targetNamespace);
       
  2697     }
       
  2698     if (type == NULL)
       
  2699         return (NULL);
       
  2700     type->node = node;
       
  2701     type->type = XML_SCHEMA_TYPE_SIMPLE;
       
  2702     type->id = xmlSchemaGetProp(ctxt, node, "id");
       
  2703 
       
  2704     child = node->children;
       
  2705     if (IS_SCHEMA(child, "annotation")) {
       
  2706         type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  2707         child = child->next;
       
  2708     }
       
  2709     subtype = NULL;
       
  2710     if (IS_SCHEMA(child, "restriction")) {
       
  2711         subtype = (xmlSchemaTypePtr)
       
  2712             xmlSchemaParseRestriction(ctxt, schema, child, 1);
       
  2713         child = child->next;
       
  2714     } else if (IS_SCHEMA(child, "list")) {
       
  2715         subtype = (xmlSchemaTypePtr)
       
  2716             xmlSchemaParseList(ctxt, schema, child);
       
  2717         child = child->next;
       
  2718     } else if (IS_SCHEMA(child, "union")) {
       
  2719         subtype = (xmlSchemaTypePtr)
       
  2720             xmlSchemaParseUnion(ctxt, schema, child);
       
  2721         child = child->next;
       
  2722     }
       
  2723     type->subtypes = subtype;
       
  2724     if (subtype == NULL) {
       
  2725     xmlSchemaPErr2(ctxt, node, child,
       
  2726                        XML_SCHEMAP_MISSING_SIMPLETYPE_CHILD,
       
  2727                        "SimpleType %s does not define a variety\n",
       
  2728                        type->name, NULL);
       
  2729     }
       
  2730     if (child != NULL) {
       
  2731         xmlSchemaPErr2(ctxt, node, child,
       
  2732                        XML_SCHEMAP_UNKNOWN_SIMPLETYPE_CHILD,
       
  2733                        "SimpleType %s has unexpected content\n",
       
  2734                        type->name, NULL);
       
  2735     }
       
  2736 
       
  2737     return (type);
       
  2738 }
       
  2739 
       
  2740 
       
  2741 /**
       
  2742  * xmlSchemaParseGroup:
       
  2743  * @ctxt:  a schema validation context
       
  2744  * @schema:  the schema being built
       
  2745  * @node:  a subtree containing XML Schema informations
       
  2746  *
       
  2747  * parse a XML schema Group definition
       
  2748  * *WARNING* this interface is highly subject to change
       
  2749  *
       
  2750  * Returns -1 in case of error, 0 if the declaration is improper and
       
  2751  *         1 in case of success.
       
  2752  */
       
  2753 static xmlSchemaTypePtr
       
  2754 xmlSchemaParseGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  2755                     xmlNodePtr node)
       
  2756 {
       
  2757     xmlSchemaTypePtr type, subtype;
       
  2758     xmlNodePtr child = NULL;
       
  2759     const xmlChar *name;
       
  2760     const xmlChar *ref = NULL, *refNs = NULL;
       
  2761     char buf[100];
       
  2762 
       
  2763     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  2764         return (NULL);
       
  2765 
       
  2766 
       
  2767     name = xmlSchemaGetProp(ctxt, node, "name");
       
  2768     if (name == NULL) {
       
  2769 
       
  2770         ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
       
  2771         if (ref == NULL) {
       
  2772             xmlSchemaPErr2(ctxt, node, child,
       
  2773                            XML_SCHEMAP_GROUP_NONAME_NOREF,
       
  2774                            "Group has no name nor ref\n", NULL, NULL);
       
  2775             return (NULL);
       
  2776         }
       
  2777     if (refNs == NULL)
       
  2778         refNs = schema->targetNamespace;
       
  2779         snprintf(buf, 99, "anongroup %d", ctxt->counter++ + 1);
       
  2780         name = (const xmlChar *) buf;
       
  2781     }
       
  2782     type = xmlSchemaAddGroup(ctxt, schema, name);
       
  2783     if (type == NULL)
       
  2784         return (NULL);
       
  2785 
       
  2786     type->node = node;
       
  2787     type->type = XML_SCHEMA_TYPE_GROUP;
       
  2788     type->id = xmlSchemaGetProp(ctxt, node, "id");
       
  2789     type->ref = ref;
       
  2790     type->refNs = refNs;
       
  2791     type->minOccurs = xmlGetMinOccurs(ctxt, node);
       
  2792     type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
       
  2793 
       
  2794     child = node->children;
       
  2795     if (IS_SCHEMA(child, "annotation")) {
       
  2796         type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  2797         child = child->next;
       
  2798     }
       
  2799     subtype = NULL;
       
  2800     if (IS_SCHEMA(child, "all")) {
       
  2801         subtype = (xmlSchemaTypePtr)
       
  2802             xmlSchemaParseAll(ctxt, schema, child);
       
  2803         child = child->next;
       
  2804     } else if (IS_SCHEMA(child, "choice")) {
       
  2805         subtype = xmlSchemaParseChoice(ctxt, schema, child);
       
  2806         child = child->next;
       
  2807     } else if (IS_SCHEMA(child, "sequence")) {
       
  2808         subtype = (xmlSchemaTypePtr)
       
  2809             xmlSchemaParseSequence(ctxt, schema, child);
       
  2810         child = child->next;
       
  2811     }
       
  2812     if (subtype != NULL)
       
  2813         type->subtypes = subtype;
       
  2814     if (child != NULL) {
       
  2815         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_GROUP_CHILD,
       
  2816                        "Group %s has unexpected content\n", type->name,
       
  2817                        NULL);
       
  2818     }
       
  2819 
       
  2820     return (type);
       
  2821 }
       
  2822 
       
  2823 /**
       
  2824  * xmlSchemaParseAll:
       
  2825  * @ctxt:  a schema validation context
       
  2826  * @schema:  the schema being built
       
  2827  * @node:  a subtree containing XML Schema informations
       
  2828  *
       
  2829  * parse a XML schema All definition
       
  2830  * *WARNING* this interface is highly subject to change
       
  2831  *
       
  2832  * Returns -1 in case of error, 0 if the declaration is improper and
       
  2833  *         1 in case of success.
       
  2834  */
       
  2835 static xmlSchemaTypePtr
       
  2836 xmlSchemaParseAll(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  2837                   xmlNodePtr node)
       
  2838 {
       
  2839     xmlSchemaTypePtr type, subtype, last = NULL;
       
  2840     xmlNodePtr child = NULL;
       
  2841     xmlChar name[30];
       
  2842 
       
  2843     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  2844         return (NULL);
       
  2845 
       
  2846 
       
  2847     snprintf((char *) name, 30, "all%d", ctxt->counter++ + 1);
       
  2848     type = xmlSchemaAddType(ctxt, schema, name, NULL);
       
  2849     if (type == NULL)
       
  2850         return (NULL);
       
  2851     type->node = node;
       
  2852     type->type = XML_SCHEMA_TYPE_ALL;
       
  2853     type->id = xmlSchemaGetProp(ctxt, node, "id");
       
  2854     type->minOccurs = xmlGetMinOccurs(ctxt, node);
       
  2855     if (type->minOccurs > 1)
       
  2856         xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_MINOCCURS,
       
  2857         "invalid value for minOccurs (must be 0 or 1)\n", NULL, NULL);
       
  2858     type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
       
  2859     if (type->maxOccurs > 1)
       
  2860         xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_MAXOCCURS,
       
  2861         "invalid value for maxOccurs (must be 0 or 1)\n", NULL, NULL);
       
  2862 
       
  2863     child = node->children;
       
  2864     if (IS_SCHEMA(child, "annotation")) {
       
  2865         type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  2866         child = child->next;
       
  2867     }
       
  2868     while (IS_SCHEMA(child, "element")) {
       
  2869         subtype = (xmlSchemaTypePtr)
       
  2870             xmlSchemaParseElement(ctxt, schema, child, 0);
       
  2871         if (subtype != NULL) {
       
  2872         if (subtype->minOccurs > 1)
       
  2873                 xmlSchemaPErr(ctxt, child, XML_SCHEMAP_INVALID_MINOCCURS,
       
  2874                  "invalid value for minOccurs (must be 0 or 1)\n",
       
  2875              NULL, NULL);
       
  2876         if (subtype->maxOccurs > 1)
       
  2877             xmlSchemaPErr(ctxt, child, XML_SCHEMAP_INVALID_MAXOCCURS,
       
  2878                  "invalid value for maxOccurs (must be 0 or 1)\n",
       
  2879              NULL, NULL);
       
  2880             if (last == NULL) {
       
  2881                 type->subtypes = subtype;
       
  2882                 last = subtype;
       
  2883             } else {
       
  2884                 last->next = subtype;
       
  2885                 last = subtype;
       
  2886             }
       
  2887             last->next = NULL;
       
  2888         }
       
  2889         child = child->next;
       
  2890     }
       
  2891     if (child != NULL) {
       
  2892         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_ALL_CHILD,
       
  2893                        "All %s has unexpected content\n", type->name,
       
  2894                        NULL);
       
  2895     }
       
  2896 
       
  2897     return (type);
       
  2898 }
       
  2899 
       
  2900 /**
       
  2901  * xmlSchemaImportSchema
       
  2902  *
       
  2903  * @ctxt:  a schema validation context
       
  2904  * @schemaLocation:  an URI defining where to find the imported schema
       
  2905  *
       
  2906  * import a XML schema
       
  2907  * *WARNING* this interface is highly subject to change
       
  2908  *
       
  2909  * Returns -1 in case of error and 1 in case of success.
       
  2910  */
       
  2911 static xmlSchemaImportPtr
       
  2912 xmlSchemaImportSchema(xmlSchemaParserCtxtPtr ctxt,
       
  2913                       const xmlChar *schemaLocation)
       
  2914 {
       
  2915     xmlSchemaImportPtr import;
       
  2916     xmlSchemaParserCtxtPtr newctxt;
       
  2917 
       
  2918     newctxt = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
       
  2919     if (newctxt == NULL) {
       
  2920         xmlSchemaPErrMemory(ctxt, "allocating schama parser context",
       
  2921                             NULL);
       
  2922         return (NULL);
       
  2923     }
       
  2924     memset(newctxt, 0, sizeof(xmlSchemaParserCtxt));
       
  2925     /* Keep the same dictionnary for parsing, really */
       
  2926     xmlDictReference(ctxt->dict);
       
  2927     newctxt->dict = ctxt->dict;
       
  2928     newctxt->includes = 0;
       
  2929     newctxt->URL = xmlDictLookup(newctxt->dict, schemaLocation, -1);
       
  2930 
       
  2931     xmlSchemaSetParserErrors(newctxt, ctxt->error, ctxt->warning,
       
  2932                          ctxt->userData);
       
  2933 
       
  2934     import = (xmlSchemaImport*) xmlMalloc(sizeof(xmlSchemaImport));
       
  2935     if (import == NULL) {
       
  2936         xmlSchemaPErrMemory(NULL, "allocating imported schema",
       
  2937                             NULL);
       
  2938     xmlSchemaFreeParserCtxt(newctxt);
       
  2939         return (NULL);
       
  2940     }
       
  2941 
       
  2942     memset(import, 0, sizeof(xmlSchemaImport));
       
  2943     import->schemaLocation = xmlDictLookup(ctxt->dict, schemaLocation, -1);
       
  2944     import->schema = xmlSchemaParse(newctxt);
       
  2945 
       
  2946     if (import->schema == NULL) {
       
  2947         /* FIXME use another error enum here ? */
       
  2948         xmlSchemaPErr(ctxt, NULL, XML_SCHEMAS_ERR_INTERNAL,
       
  2949                   "failed to import schema at location %s\n",
       
  2950               schemaLocation, NULL);
       
  2951 
       
  2952     xmlSchemaFreeParserCtxt(newctxt);
       
  2953     if (import->schemaLocation != NULL)
       
  2954         xmlFree((xmlChar *)import->schemaLocation);
       
  2955     xmlFree(import);
       
  2956     return NULL;
       
  2957     }
       
  2958 
       
  2959     xmlSchemaFreeParserCtxt(newctxt);
       
  2960     return import;
       
  2961 }
       
  2962 
       
  2963 
       
  2964 /**
       
  2965  * xmlSchemaParseImport:
       
  2966  * @ctxt:  a schema validation context
       
  2967  * @schema:  the schema being built
       
  2968  * @node:  a subtree containing XML Schema informations
       
  2969  *
       
  2970  * parse a XML schema Import definition
       
  2971  * *WARNING* this interface is highly subject to change
       
  2972  *
       
  2973  * Returns -1 in case of error, 0 if the declaration is improper and
       
  2974  *         1 in case of success.
       
  2975  */
       
  2976 static int
       
  2977 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  2978                      xmlNodePtr node)
       
  2979 {
       
  2980     xmlNodePtr child = NULL;
       
  2981     xmlSchemaImportPtr import = NULL;
       
  2982     const xmlChar *namespace;
       
  2983     const xmlChar *schemaLocation;
       
  2984     const xmlChar *previous;
       
  2985     xmlURIPtr check;
       
  2986 
       
  2987 
       
  2988     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  2989         return (-1);
       
  2990 
       
  2991     namespace = xmlSchemaGetProp(ctxt, node, "namespace");
       
  2992     if (namespace != NULL) {
       
  2993         check = xmlParseURI((const char *) namespace);
       
  2994         if (check == NULL) {
       
  2995             xmlSchemaPErr2(ctxt, node, child,
       
  2996                            XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI,
       
  2997                            "Import namespace attribute is not an URI: %s\n",
       
  2998                            namespace, NULL);
       
  2999             return (-1);
       
  3000         } else {
       
  3001             xmlFreeURI(check);
       
  3002         }
       
  3003     }
       
  3004     schemaLocation = xmlSchemaGetProp(ctxt, node, "schemaLocation");
       
  3005     if (schemaLocation != NULL) {
       
  3006         xmlChar *base = NULL;
       
  3007         xmlChar *URI = NULL;
       
  3008         check = xmlParseURI((const char *) schemaLocation);
       
  3009         if (check == NULL) {
       
  3010             xmlSchemaPErr2(ctxt, node, child,
       
  3011                            XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI,
       
  3012                            "Import schemaLocation attribute is not an URI: %s\n",
       
  3013                            schemaLocation, NULL);
       
  3014             return (-1);
       
  3015         } else {
       
  3016             xmlFreeURI(check);
       
  3017         }
       
  3018     base = xmlNodeGetBase(node->doc, node);
       
  3019     if (base == NULL) {
       
  3020         URI = xmlBuildURI(schemaLocation, node->doc->URL);
       
  3021     } else {
       
  3022         URI = xmlBuildURI(schemaLocation, base);
       
  3023         xmlFree(base);
       
  3024     }
       
  3025     if (URI != NULL) {
       
  3026         schemaLocation = xmlDictLookup(ctxt->dict, URI, -1);
       
  3027         xmlFree(URI);
       
  3028     }
       
  3029     }
       
  3030     if (schema->schemasImports == NULL) {
       
  3031         schema->schemasImports = xmlHashCreate(10);
       
  3032         if (schema->schemasImports == NULL) {
       
  3033             xmlSchemaPErr2(ctxt, node, child,
       
  3034                            XML_SCHEMAP_FAILED_BUILD_IMPORT,
       
  3035                            "Internal: failed to build import table\n",
       
  3036                            NULL, NULL);
       
  3037             return (-1);
       
  3038         }
       
  3039     }
       
  3040     if (namespace == NULL) {
       
  3041         import = xmlHashLookup(schema->schemasImports,
       
  3042                                    XML_SCHEMAS_DEFAULT_NAMESPACE);
       
  3043     if (import != NULL)
       
  3044             previous = import->schemaLocation;
       
  3045     else
       
  3046         previous = NULL;
       
  3047 
       
  3048         if (schemaLocation != NULL) {
       
  3049             if (previous != NULL) {
       
  3050                 if (!xmlStrEqual(schemaLocation, previous)) {
       
  3051                     xmlSchemaPErr2(ctxt, node, child,
       
  3052                                    XML_SCHEMAP_IMPORT_REDEFINE_NSNAME,
       
  3053                                    "Redefining import for default namespace "
       
  3054                    "with a different URI: %s\n",
       
  3055                                    schemaLocation, NULL);
       
  3056                 }
       
  3057             } else {
       
  3058             import = xmlSchemaImportSchema(ctxt, schemaLocation);
       
  3059         if (import == NULL) {
       
  3060             return (-1);
       
  3061         }
       
  3062                 xmlHashAddEntry(schema->schemasImports,
       
  3063                                 XML_SCHEMAS_DEFAULT_NAMESPACE,
       
  3064                                 import);
       
  3065             }
       
  3066         }
       
  3067     } else {
       
  3068         import = xmlHashLookup(schema->schemasImports, namespace);
       
  3069     if (import != NULL)
       
  3070         previous = import->schemaLocation;
       
  3071     else
       
  3072         previous = NULL;
       
  3073 
       
  3074         if (schemaLocation != NULL) {
       
  3075             if (previous != NULL) {
       
  3076                 if (!xmlStrEqual(schemaLocation, previous)) {
       
  3077                     xmlSchemaPErr2(ctxt, node, child,
       
  3078                                    XML_SCHEMAP_IMPORT_REDEFINE_NSNAME,
       
  3079                                    "Redefining import for namespace %s with "
       
  3080                    "a different URI: %s\n",
       
  3081                                    namespace, schemaLocation);
       
  3082                 }
       
  3083             } else {
       
  3084             import = xmlSchemaImportSchema(ctxt, schemaLocation);
       
  3085         if (import == NULL) {
       
  3086             return (-1);
       
  3087         }
       
  3088                 xmlHashAddEntry(schema->schemasImports,
       
  3089                                 namespace, import);
       
  3090             }
       
  3091         }
       
  3092     }
       
  3093 
       
  3094     child = node->children;
       
  3095     while (IS_SCHEMA(child, "annotation")) {
       
  3096         /*
       
  3097          * the annotations here are simply discarded ...
       
  3098          */
       
  3099         child = child->next;
       
  3100     }
       
  3101     if (child != NULL) {
       
  3102         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_IMPORT_CHILD,
       
  3103                        "Import has unexpected content\n", NULL, NULL);
       
  3104         return (-1);
       
  3105     }
       
  3106     return (1);
       
  3107 }
       
  3108 
       
  3109 /**
       
  3110  * xmlSchemaCleanupDoc:
       
  3111  * @ctxt:  a schema validation context
       
  3112  * @node:  the root of the document.
       
  3113  *
       
  3114  * removes unwanted nodes in a schemas document tree
       
  3115  */
       
  3116 static void
       
  3117 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
       
  3118 {
       
  3119     xmlNodePtr delete, cur;
       
  3120 
       
  3121     if ((ctxt == NULL) || (root == NULL)) return;
       
  3122 
       
  3123     /*
       
  3124      * Remove all the blank text nodes
       
  3125      */
       
  3126     delete = NULL;
       
  3127     cur = root;
       
  3128     while (cur != NULL) {
       
  3129         if (delete != NULL) {
       
  3130             xmlUnlinkNode(delete);
       
  3131             xmlFreeNode(delete);
       
  3132             delete = NULL;
       
  3133         }
       
  3134         if (cur->type == XML_TEXT_NODE) {
       
  3135             if (IS_BLANK_NODE(cur)) {
       
  3136                 if (xmlNodeGetSpacePreserve(cur) != 1) {
       
  3137                     delete = cur;
       
  3138                 }
       
  3139             }
       
  3140         } else if ((cur->type != XML_ELEMENT_NODE) &&
       
  3141                    (cur->type != XML_CDATA_SECTION_NODE)) {
       
  3142             delete = cur;
       
  3143             goto skip_children;
       
  3144         }
       
  3145 
       
  3146         /*
       
  3147          * Skip to next node
       
  3148          */
       
  3149         if (cur->children != NULL) {
       
  3150             if ((cur->children->type != XML_ENTITY_DECL) &&
       
  3151                 (cur->children->type != XML_ENTITY_REF_NODE) &&
       
  3152                 (cur->children->type != XML_ENTITY_NODE)) {
       
  3153                 cur = cur->children;
       
  3154                 continue;
       
  3155             }
       
  3156         }
       
  3157       skip_children:
       
  3158         if (cur->next != NULL) {
       
  3159             cur = cur->next;
       
  3160             continue;
       
  3161         }
       
  3162 
       
  3163         do {
       
  3164             cur = cur->parent;
       
  3165             if (cur == NULL)
       
  3166                 break;
       
  3167             if (cur == root) {
       
  3168                 cur = NULL;
       
  3169                 break;
       
  3170             }
       
  3171             if (cur->next != NULL) {
       
  3172                 cur = cur->next;
       
  3173                 break;
       
  3174             }
       
  3175         } while (cur != NULL);
       
  3176     }
       
  3177     if (delete != NULL) {
       
  3178         xmlUnlinkNode(delete);
       
  3179         xmlFreeNode(delete);
       
  3180         delete = NULL;
       
  3181     }
       
  3182 }
       
  3183 
       
  3184 /**
       
  3185  * xmlSchemaParseSchemaTopLevel:
       
  3186  * @ctxt:  a schema validation context
       
  3187  * @schema:  the schemas
       
  3188  * @nodes:  the list of top level nodes
       
  3189  *
       
  3190  * Returns the internal XML Schema structure built from the resource or
       
  3191  *         NULL in case of error
       
  3192  */
       
  3193 static void
       
  3194 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
       
  3195                              xmlSchemaPtr schema, xmlNodePtr nodes)
       
  3196 {
       
  3197     xmlNodePtr child;
       
  3198     xmlSchemaAnnotPtr annot;
       
  3199 
       
  3200     if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
       
  3201         return;
       
  3202 
       
  3203     child = nodes;
       
  3204     while ((IS_SCHEMA(child, "include")) ||
       
  3205        (IS_SCHEMA(child, "import")) ||
       
  3206        (IS_SCHEMA(child, "redefine")) ||
       
  3207        (IS_SCHEMA(child, "annotation"))) {
       
  3208     if (IS_SCHEMA(child, "annotation")) {
       
  3209         annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  3210         if (schema->annot == NULL)
       
  3211         schema->annot = annot;
       
  3212         else
       
  3213         xmlSchemaFreeAnnot(annot);
       
  3214     } else if (IS_SCHEMA(child, "import")) {
       
  3215         xmlSchemaParseImport(ctxt, schema, child);
       
  3216     } else if (IS_SCHEMA(child, "include")) {
       
  3217         ctxt->includes++;
       
  3218         xmlSchemaParseInclude(ctxt, schema, child);
       
  3219         ctxt->includes--;
       
  3220     } else if (IS_SCHEMA(child, "redefine")) {
       
  3221         TODO
       
  3222     }
       
  3223     child = child->next;
       
  3224     }
       
  3225     while (child != NULL) {
       
  3226     if (IS_SCHEMA(child, "complexType")) {
       
  3227         xmlSchemaParseComplexType(ctxt, schema, child);
       
  3228         child = child->next;
       
  3229     } else if (IS_SCHEMA(child, "simpleType")) {
       
  3230         xmlSchemaParseSimpleType(ctxt, schema, child);
       
  3231         child = child->next;
       
  3232     } else if (IS_SCHEMA(child, "element")) {
       
  3233         xmlSchemaParseElement(ctxt, schema, child, 1);
       
  3234         child = child->next;
       
  3235     } else if (IS_SCHEMA(child, "attribute")) {
       
  3236         xmlSchemaParseAttribute(ctxt, schema, child, 1);
       
  3237         child = child->next;
       
  3238     } else if (IS_SCHEMA(child, "attributeGroup")) {
       
  3239         xmlSchemaParseAttributeGroup(ctxt, schema, child);
       
  3240         child = child->next;
       
  3241     } else if (IS_SCHEMA(child, "group")) {
       
  3242         xmlSchemaParseGroup(ctxt, schema, child);
       
  3243         child = child->next;
       
  3244     } else if (IS_SCHEMA(child, "notation")) {
       
  3245         xmlSchemaParseNotation(ctxt, schema, child);
       
  3246         child = child->next;
       
  3247     } else {
       
  3248         xmlSchemaPErr2(ctxt, NULL, child,
       
  3249                XML_SCHEMAP_UNKNOWN_SCHEMAS_CHILD,
       
  3250                "Schemas: unexpected element %s here \n",
       
  3251                child->name, NULL);
       
  3252         child = child->next;
       
  3253     }
       
  3254     while (IS_SCHEMA(child, "annotation")) {
       
  3255         annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  3256         if (schema->annot == NULL)
       
  3257         schema->annot = annot;
       
  3258         else
       
  3259         xmlSchemaFreeAnnot(annot);
       
  3260         child = child->next;
       
  3261     }
       
  3262     }
       
  3263 }
       
  3264 
       
  3265 /**
       
  3266  * xmlSchemaParseInclude:
       
  3267  * @ctxt:  a schema validation context
       
  3268  * @schema:  the schema being built
       
  3269  * @node:  a subtree containing XML Schema informations
       
  3270  *
       
  3271  * parse a XML schema Include definition
       
  3272  *
       
  3273  * Returns -1 in case of error, 0 if the declaration is improper and
       
  3274  *         1 in case of success.
       
  3275  */
       
  3276 static int
       
  3277 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  3278                       xmlNodePtr node)
       
  3279 {
       
  3280     xmlNodePtr child = NULL;
       
  3281     const xmlChar *schemaLocation;
       
  3282     xmlURIPtr check;
       
  3283     xmlDocPtr doc;
       
  3284     xmlNodePtr root;
       
  3285     xmlSchemaIncludePtr include;
       
  3286 
       
  3287 
       
  3288     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  3289         return (-1);
       
  3290 
       
  3291     /*
       
  3292      * Preliminary step, extract the URI-Reference for the include and
       
  3293      * make an URI from the base.
       
  3294      */
       
  3295     schemaLocation = xmlSchemaGetProp(ctxt, node, "schemaLocation");
       
  3296     if (schemaLocation != NULL) {
       
  3297         xmlChar *base = NULL;
       
  3298         xmlChar *URI = NULL;
       
  3299         check = xmlParseURI((const char *) schemaLocation);
       
  3300         if (check == NULL) {
       
  3301             xmlSchemaPErr2(ctxt, node, child,
       
  3302                            XML_SCHEMAP_INCLUDE_SCHEMA_NOT_URI,
       
  3303                "Include schemaLocation attribute is not an URI: %s\n",
       
  3304                            schemaLocation, NULL);
       
  3305             return (-1);
       
  3306         } else {
       
  3307             xmlFreeURI(check);
       
  3308         }
       
  3309     base = xmlNodeGetBase(node->doc, node);
       
  3310     if (base == NULL) {
       
  3311         URI = xmlBuildURI(schemaLocation, node->doc->URL);
       
  3312     } else {
       
  3313         URI = xmlBuildURI(schemaLocation, base);
       
  3314         xmlFree(base);
       
  3315     }
       
  3316     if (URI != NULL) {
       
  3317         schemaLocation = xmlDictLookup(ctxt->dict, URI, -1);
       
  3318         xmlFree(URI);
       
  3319     }
       
  3320     } else {
       
  3321     xmlSchemaPErr2(ctxt, node, child,
       
  3322                XML_SCHEMAP_INCLUDE_SCHEMA_NO_URI,
       
  3323            "Include schemaLocation attribute missing\n",
       
  3324                NULL, NULL);
       
  3325     return (-1);
       
  3326     }
       
  3327 
       
  3328     child = node->children;
       
  3329     while (IS_SCHEMA(child, "annotation")) {
       
  3330         /*
       
  3331          * the annotations here are simply discarded ...
       
  3332          */
       
  3333         child = child->next;
       
  3334     }
       
  3335     if (child != NULL) {
       
  3336         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_INCLUDE_CHILD,
       
  3337                        "Include has unexpected content\n", NULL, NULL);
       
  3338         return (-1);
       
  3339     }
       
  3340 
       
  3341     /*
       
  3342      * First step is to parse the input document into an DOM/Infoset
       
  3343      */
       
  3344     doc = xmlReadFile((const char *) schemaLocation, NULL,
       
  3345                       SCHEMAS_PARSE_OPTIONS);
       
  3346     if (doc == NULL) {
       
  3347     xmlSchemaPErr(ctxt, NULL,
       
  3348               XML_SCHEMAP_FAILED_LOAD,
       
  3349               "xmlSchemaParse: could not load %s\n",
       
  3350               ctxt->URL, NULL);
       
  3351     return(-1);
       
  3352     }
       
  3353 
       
  3354     /*
       
  3355      * Then extract the root of the schema
       
  3356      */
       
  3357     root = xmlDocGetRootElement(doc);
       
  3358     if (root == NULL) {
       
  3359     xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
       
  3360               XML_SCHEMAP_NOROOT,
       
  3361               "schemas %s has no root", schemaLocation, NULL);
       
  3362     xmlFreeDoc(doc);
       
  3363         return (-1);
       
  3364     }
       
  3365 
       
  3366     /*
       
  3367      * Remove all the blank text nodes
       
  3368      */
       
  3369     xmlSchemaCleanupDoc(ctxt, root);
       
  3370 
       
  3371     /*
       
  3372      * Check the schemas top level element
       
  3373      */
       
  3374     if (!IS_SCHEMA(root, "schema")) {
       
  3375     xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
       
  3376               XML_SCHEMAP_NOT_SCHEMA,
       
  3377               "File %s is not a schemas", schemaLocation, NULL);
       
  3378     xmlFreeDoc(doc);
       
  3379         return (-1);
       
  3380     }
       
  3381 
       
  3382     /*
       
  3383      * register the include
       
  3384      */
       
  3385     include = (xmlSchemaIncludePtr) xmlMalloc(sizeof(xmlSchemaInclude));
       
  3386     if (include == NULL) {
       
  3387         xmlSchemaPErrMemory(ctxt, "allocating included schema", NULL);
       
  3388     xmlFreeDoc(doc);
       
  3389         return (-1);
       
  3390     }
       
  3391 
       
  3392     memset(include, 0, sizeof(xmlSchemaInclude));
       
  3393     include->schemaLocation = xmlDictLookup(ctxt->dict, schemaLocation, -1);
       
  3394     include->doc = doc;
       
  3395     include->next = schema->includes;
       
  3396     schema->includes = include;
       
  3397 
       
  3398 
       
  3399     /*
       
  3400      * parse the declarations in the included file like if they
       
  3401      * were in the original file.
       
  3402      */
       
  3403     xmlSchemaParseSchemaTopLevel(ctxt, schema, root->children);
       
  3404 
       
  3405     return (1);
       
  3406 }
       
  3407 
       
  3408 /**
       
  3409  * xmlSchemaParseChoice:
       
  3410  * @ctxt:  a schema validation context
       
  3411  * @schema:  the schema being built
       
  3412  * @node:  a subtree containing XML Schema informations
       
  3413  *
       
  3414  * parse a XML schema Choice definition
       
  3415  * *WARNING* this interface is highly subject to change
       
  3416  *
       
  3417  * Returns -1 in case of error, 0 if the declaration is improper and
       
  3418  *         1 in case of success.
       
  3419  */
       
  3420 static xmlSchemaTypePtr
       
  3421 xmlSchemaParseChoice(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  3422                      xmlNodePtr node)
       
  3423 {
       
  3424     xmlSchemaTypePtr type, subtype, last = NULL;
       
  3425     xmlNodePtr child = NULL;
       
  3426     xmlChar name[30];
       
  3427 
       
  3428     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  3429         return (NULL);
       
  3430 
       
  3431 
       
  3432     snprintf((char *) name, 30, "choice %d", ctxt->counter++ + 1);
       
  3433     type = xmlSchemaAddType(ctxt, schema, name, NULL);
       
  3434     if (type == NULL)
       
  3435         return (NULL);
       
  3436     type->node = node;
       
  3437     type->type = XML_SCHEMA_TYPE_CHOICE;
       
  3438     type->id = xmlSchemaGetProp(ctxt, node, "id");
       
  3439     type->minOccurs = xmlGetMinOccurs(ctxt, node);
       
  3440     type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
       
  3441 
       
  3442     child = node->children;
       
  3443     if (IS_SCHEMA(child, "annotation")) {
       
  3444         type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  3445         child = child->next;
       
  3446     }
       
  3447     while ((IS_SCHEMA(child, "element")) ||
       
  3448            (IS_SCHEMA(child, "group")) ||
       
  3449            (IS_SCHEMA(child, "any")) ||
       
  3450            (IS_SCHEMA(child, "choice")) ||
       
  3451            (IS_SCHEMA(child, "sequence"))) {
       
  3452         subtype = NULL;
       
  3453         if (IS_SCHEMA(child, "element")) {
       
  3454             subtype = (xmlSchemaTypePtr)
       
  3455                 xmlSchemaParseElement(ctxt, schema, child, 0);
       
  3456         } else if (IS_SCHEMA(child, "group")) {
       
  3457             subtype = xmlSchemaParseGroup(ctxt, schema, child);
       
  3458         } else if (IS_SCHEMA(child, "any")) {
       
  3459             subtype = xmlSchemaParseAny(ctxt, schema, child);
       
  3460         } else if (IS_SCHEMA(child, "sequence")) {
       
  3461             subtype = xmlSchemaParseSequence(ctxt, schema, child);
       
  3462         } else if (IS_SCHEMA(child, "choice")) {
       
  3463             subtype = xmlSchemaParseChoice(ctxt, schema, child);
       
  3464         }
       
  3465         if (subtype != NULL) {
       
  3466             if (last == NULL) {
       
  3467                 type->subtypes = subtype;
       
  3468                 last = subtype;
       
  3469             } else {
       
  3470                 last->next = subtype;
       
  3471                 last = subtype;
       
  3472             }
       
  3473             last->next = NULL;
       
  3474         }
       
  3475         child = child->next;
       
  3476     }
       
  3477     if (child != NULL) {
       
  3478         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_CHOICE_CHILD,
       
  3479                        "Choice %s has unexpected content\n", type->name,
       
  3480                        NULL);
       
  3481     }
       
  3482 
       
  3483     return (type);
       
  3484 }
       
  3485 
       
  3486 /**
       
  3487  * xmlSchemaParseSequence:
       
  3488  * @ctxt:  a schema validation context
       
  3489  * @schema:  the schema being built
       
  3490  * @node:  a subtree containing XML Schema informations
       
  3491  *
       
  3492  * parse a XML schema Sequence definition
       
  3493  * *WARNING* this interface is highly subject to change
       
  3494  *
       
  3495  * Returns -1 in case of error, 0 if the declaration is improper and
       
  3496  *         1 in case of success.
       
  3497  */
       
  3498 static xmlSchemaTypePtr
       
  3499 xmlSchemaParseSequence(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  3500                        xmlNodePtr node)
       
  3501 {
       
  3502     xmlSchemaTypePtr type, subtype, last = NULL;
       
  3503     xmlNodePtr child = NULL;
       
  3504     xmlChar name[30];
       
  3505 
       
  3506     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  3507         return (NULL);
       
  3508 
       
  3509 
       
  3510     snprintf((char *) name, 30, "sequence %d", ctxt->counter++ + 1);
       
  3511     type = xmlSchemaAddType(ctxt, schema, name, NULL);
       
  3512     if (type == NULL)
       
  3513         return (NULL);
       
  3514     type->node = node;
       
  3515     type->type = XML_SCHEMA_TYPE_SEQUENCE;
       
  3516     type->id = xmlSchemaGetProp(ctxt, node, "id");
       
  3517     type->minOccurs = xmlGetMinOccurs(ctxt, node);
       
  3518     type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
       
  3519 
       
  3520     child = node->children;
       
  3521     if (IS_SCHEMA(child, "annotation")) {
       
  3522         type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  3523         child = child->next;
       
  3524     }
       
  3525     while ((IS_SCHEMA(child, "element")) ||
       
  3526            (IS_SCHEMA(child, "group")) ||
       
  3527            (IS_SCHEMA(child, "any")) ||
       
  3528            (IS_SCHEMA(child, "choice")) ||
       
  3529            (IS_SCHEMA(child, "sequence"))) {
       
  3530         subtype = NULL;
       
  3531         if (IS_SCHEMA(child, "element")) {
       
  3532             subtype = (xmlSchemaTypePtr)
       
  3533                 xmlSchemaParseElement(ctxt, schema, child, 0);
       
  3534         } else if (IS_SCHEMA(child, "group")) {
       
  3535             subtype = xmlSchemaParseGroup(ctxt, schema, child);
       
  3536         } else if (IS_SCHEMA(child, "any")) {
       
  3537             subtype = xmlSchemaParseAny(ctxt, schema, child);
       
  3538         } else if (IS_SCHEMA(child, "choice")) {
       
  3539             subtype = xmlSchemaParseChoice(ctxt, schema, child);
       
  3540         } else if (IS_SCHEMA(child, "sequence")) {
       
  3541             subtype = xmlSchemaParseSequence(ctxt, schema, child);
       
  3542         }
       
  3543         if (subtype != NULL) {
       
  3544             if (last == NULL) {
       
  3545                 type->subtypes = subtype;
       
  3546                 last = subtype;
       
  3547             } else {
       
  3548                 last->next = subtype;
       
  3549                 last = subtype;
       
  3550             }
       
  3551             last->next = NULL;
       
  3552         }
       
  3553         child = child->next;
       
  3554     }
       
  3555     if (child != NULL) {
       
  3556         xmlSchemaPErr2(ctxt, node, child,
       
  3557                        XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD,
       
  3558                        "Sequence %s has unexpected content\n", type->name,
       
  3559                        NULL);
       
  3560     }
       
  3561 
       
  3562     return (type);
       
  3563 }
       
  3564 
       
  3565 /**
       
  3566  * xmlSchemaParseRestriction:
       
  3567  * @ctxt:  a schema validation context
       
  3568  * @schema:  the schema being built
       
  3569  * @node:  a subtree containing XML Schema informations
       
  3570  * @simple:  is that part of a simple type.
       
  3571  *
       
  3572  * parse a XML schema Restriction definition
       
  3573  * *WARNING* this interface is highly subject to change
       
  3574  *
       
  3575  * Returns the type definition or NULL in case of error
       
  3576  */
       
  3577 static xmlSchemaTypePtr
       
  3578 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  3579                           xmlNodePtr node, int simple)
       
  3580 {
       
  3581     xmlSchemaTypePtr type, subtype;
       
  3582     xmlSchemaFacetPtr facet, lastfacet = NULL;
       
  3583     xmlNodePtr child = NULL;
       
  3584     xmlChar name[30];
       
  3585     const xmlChar *oldcontainer;
       
  3586 
       
  3587     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  3588         return (NULL);
       
  3589 
       
  3590     oldcontainer = ctxt->container;
       
  3591 
       
  3592     snprintf((char *) name, 30, "restriction %d", ctxt->counter++ + 1);
       
  3593     type = xmlSchemaAddType(ctxt, schema, name, NULL);
       
  3594     if (type == NULL)
       
  3595         return (NULL);
       
  3596     type->node = node;
       
  3597     type->type = XML_SCHEMA_TYPE_RESTRICTION;
       
  3598     type->id = xmlSchemaGetProp(ctxt, node, "id");
       
  3599     type->base = xmlGetQNameProp(ctxt, node, "base", &(type->baseNs));
       
  3600     if ((!simple) && (type->base == NULL)) {
       
  3601         xmlSchemaPErr2(ctxt, node, child,
       
  3602                        XML_SCHEMAP_RESTRICTION_NONAME_NOREF,
       
  3603                        "Restriction %s has no base\n", type->name, NULL);
       
  3604     }
       
  3605     ctxt->container = name;
       
  3606 
       
  3607     child = node->children;
       
  3608     if (IS_SCHEMA(child, "annotation")) {
       
  3609         type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  3610         child = child->next;
       
  3611     }
       
  3612     subtype = NULL;
       
  3613 
       
  3614     if (IS_SCHEMA(child, "all")) {
       
  3615         subtype = (xmlSchemaTypePtr)
       
  3616             xmlSchemaParseAll(ctxt, schema, child);
       
  3617         child = child->next;
       
  3618         type->subtypes = subtype;
       
  3619     } else if (IS_SCHEMA(child, "choice")) {
       
  3620         subtype = xmlSchemaParseChoice(ctxt, schema, child);
       
  3621         child = child->next;
       
  3622         type->subtypes = subtype;
       
  3623     } else if (IS_SCHEMA(child, "sequence")) {
       
  3624         subtype = (xmlSchemaTypePtr)
       
  3625             xmlSchemaParseSequence(ctxt, schema, child);
       
  3626         child = child->next;
       
  3627         type->subtypes = subtype;
       
  3628     } else if (IS_SCHEMA(child, "group")) {
       
  3629         subtype = (xmlSchemaTypePtr)
       
  3630             xmlSchemaParseGroup(ctxt, schema, child);
       
  3631         child = child->next;
       
  3632         type->subtypes = subtype;
       
  3633     } else {
       
  3634         if (IS_SCHEMA(child, "simpleType")) {
       
  3635             subtype = (xmlSchemaTypePtr)
       
  3636                 xmlSchemaParseSimpleType(ctxt, schema, child);
       
  3637             child = child->next;
       
  3638             type->baseType = subtype;
       
  3639         }
       
  3640         /*
       
  3641          * Facets
       
  3642          */
       
  3643         while ((IS_SCHEMA(child, "minInclusive")) ||
       
  3644                (IS_SCHEMA(child, "minExclusive")) ||
       
  3645                (IS_SCHEMA(child, "maxInclusive")) ||
       
  3646                (IS_SCHEMA(child, "maxExclusive")) ||
       
  3647                (IS_SCHEMA(child, "totalDigits")) ||
       
  3648                (IS_SCHEMA(child, "fractionDigits")) ||
       
  3649                (IS_SCHEMA(child, "pattern")) ||
       
  3650                (IS_SCHEMA(child, "enumeration")) ||
       
  3651                (IS_SCHEMA(child, "whiteSpace")) ||
       
  3652                (IS_SCHEMA(child, "length")) ||
       
  3653                (IS_SCHEMA(child, "maxLength")) ||
       
  3654                (IS_SCHEMA(child, "minLength"))) {
       
  3655             facet = xmlSchemaParseFacet(ctxt, schema, child);
       
  3656             if (facet != NULL) {
       
  3657                 if (lastfacet == NULL) {
       
  3658                     type->facets = facet;
       
  3659                     lastfacet = facet;
       
  3660                 } else {
       
  3661                     lastfacet->next = facet;
       
  3662                     lastfacet = facet;
       
  3663                 }
       
  3664                 lastfacet->next = NULL;
       
  3665             }
       
  3666             child = child->next;
       
  3667         }
       
  3668     }
       
  3669     child = xmlSchemaParseAttrDecls(ctxt, schema, child, type);
       
  3670     if (child != NULL) {
       
  3671         xmlSchemaPErr2(ctxt, node, child,
       
  3672                        XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD,
       
  3673                        "Restriction %s has unexpected content\n",
       
  3674                        type->name, NULL);
       
  3675     }
       
  3676     ctxt->container = oldcontainer;
       
  3677     return (type);
       
  3678 }
       
  3679 
       
  3680 /**
       
  3681  * xmlSchemaParseExtension:
       
  3682  * @ctxt:  a schema validation context
       
  3683  * @schema:  the schema being built
       
  3684  * @node:  a subtree containing XML Schema informations
       
  3685  *
       
  3686  * parse a XML schema Extension definition
       
  3687  * *WARNING* this interface is highly subject to change
       
  3688  *
       
  3689  * Returns the type definition or NULL in case of error
       
  3690  */
       
  3691 static xmlSchemaTypePtr
       
  3692 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  3693                         xmlNodePtr node)
       
  3694 {
       
  3695     xmlSchemaTypePtr type, subtype;
       
  3696     xmlNodePtr child = NULL;
       
  3697     xmlChar name[30];
       
  3698     const xmlChar *oldcontainer;
       
  3699 
       
  3700     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  3701         return (NULL);
       
  3702 
       
  3703     oldcontainer = ctxt->container;
       
  3704 
       
  3705     snprintf((char *) name, 30, "extension %d", ctxt->counter++ + 1);
       
  3706     type = xmlSchemaAddType(ctxt, schema, name, NULL);
       
  3707     if (type == NULL)
       
  3708         return (NULL);
       
  3709     type->node = node;
       
  3710     type->type = XML_SCHEMA_TYPE_EXTENSION;
       
  3711     type->id = xmlSchemaGetProp(ctxt, node, "id");
       
  3712     ctxt->container = name;
       
  3713 
       
  3714     type->base = xmlGetQNameProp(ctxt, node, "base", &(type->baseNs));
       
  3715     if (type->base == NULL) {
       
  3716         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_EXTENSION_NO_BASE,
       
  3717                        "Extension %s has no base\n", type->name, NULL);
       
  3718     }
       
  3719     child = node->children;
       
  3720     if (IS_SCHEMA(child, "annotation")) {
       
  3721         type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  3722         child = child->next;
       
  3723     }
       
  3724     subtype = NULL;
       
  3725 
       
  3726     if (IS_SCHEMA(child, "all")) {
       
  3727         subtype = xmlSchemaParseAll(ctxt, schema, child);
       
  3728         child = child->next;
       
  3729     } else if (IS_SCHEMA(child, "choice")) {
       
  3730         subtype = xmlSchemaParseChoice(ctxt, schema, child);
       
  3731         child = child->next;
       
  3732     } else if (IS_SCHEMA(child, "sequence")) {
       
  3733         subtype = xmlSchemaParseSequence(ctxt, schema, child);
       
  3734         child = child->next;
       
  3735     } else if (IS_SCHEMA(child, "group")) {
       
  3736         subtype = xmlSchemaParseGroup(ctxt, schema, child);
       
  3737         child = child->next;
       
  3738     }
       
  3739     if (subtype != NULL)
       
  3740         type->subtypes = subtype;
       
  3741     child = xmlSchemaParseAttrDecls(ctxt, schema, child, type);
       
  3742     if (child != NULL) {
       
  3743         xmlSchemaPErr2(ctxt, node, child,
       
  3744                        XML_SCHEMAP_UNKNOWN_EXTENSION_CHILD,
       
  3745                        "Extension %s has unexpected content\n", type->name,
       
  3746                        NULL);
       
  3747     }
       
  3748     ctxt->container = oldcontainer;
       
  3749     return (type);
       
  3750 }
       
  3751 
       
  3752 /**
       
  3753  * xmlSchemaParseSimpleContent:
       
  3754  * @ctxt:  a schema validation context
       
  3755  * @schema:  the schema being built
       
  3756  * @node:  a subtree containing XML Schema informations
       
  3757  *
       
  3758  * parse a XML schema SimpleContent definition
       
  3759  * *WARNING* this interface is highly subject to change
       
  3760  *
       
  3761  * Returns the type definition or NULL in case of error
       
  3762  */
       
  3763 static xmlSchemaTypePtr
       
  3764 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
       
  3765                             xmlSchemaPtr schema, xmlNodePtr node)
       
  3766 {
       
  3767     xmlSchemaTypePtr type, subtype;
       
  3768     xmlNodePtr child = NULL;
       
  3769     xmlChar name[30];
       
  3770 
       
  3771     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  3772         return (NULL);
       
  3773 
       
  3774 
       
  3775     snprintf((char *) name, 30, "simpleContent %d", ctxt->counter++ + 1);
       
  3776     type = xmlSchemaAddType(ctxt, schema, name, NULL);
       
  3777     if (type == NULL)
       
  3778         return (NULL);
       
  3779     type->node = node;
       
  3780     type->type = XML_SCHEMA_TYPE_SIMPLE_CONTENT;
       
  3781     type->id = xmlSchemaGetProp(ctxt, node, "id");
       
  3782 
       
  3783     child = node->children;
       
  3784     if (IS_SCHEMA(child, "annotation")) {
       
  3785         type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  3786         child = child->next;
       
  3787     }
       
  3788     subtype = NULL;
       
  3789     if (IS_SCHEMA(child, "restriction")) {
       
  3790         subtype = (xmlSchemaTypePtr)
       
  3791             xmlSchemaParseRestriction(ctxt, schema, child, 0);
       
  3792         child = child->next;
       
  3793     } else if (IS_SCHEMA(child, "extension")) {
       
  3794         subtype = (xmlSchemaTypePtr)
       
  3795             xmlSchemaParseExtension(ctxt, schema, child);
       
  3796         child = child->next;
       
  3797     }
       
  3798     type->subtypes = subtype;
       
  3799     if (child != NULL) {
       
  3800         xmlSchemaPErr2(ctxt, node, child,
       
  3801                        XML_SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD,
       
  3802                        "SimpleContent %s has unexpected content\n",
       
  3803                        type->name, NULL);
       
  3804     }
       
  3805     return (type);
       
  3806 }
       
  3807 
       
  3808 /**
       
  3809  * xmlSchemaParseComplexContent:
       
  3810  * @ctxt:  a schema validation context
       
  3811  * @schema:  the schema being built
       
  3812  * @node:  a subtree containing XML Schema informations
       
  3813  *
       
  3814  * parse a XML schema ComplexContent definition
       
  3815  * *WARNING* this interface is highly subject to change
       
  3816  *
       
  3817  * Returns the type definition or NULL in case of error
       
  3818  */
       
  3819 static xmlSchemaTypePtr
       
  3820 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
       
  3821                              xmlSchemaPtr schema, xmlNodePtr node)
       
  3822 {
       
  3823     xmlSchemaTypePtr type, subtype;
       
  3824     xmlNodePtr child = NULL;
       
  3825     xmlChar name[30];
       
  3826 
       
  3827     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  3828         return (NULL);
       
  3829 
       
  3830 
       
  3831     snprintf((char *) name, 30, "complexContent %d", ctxt->counter++ + 1);
       
  3832     type = xmlSchemaAddType(ctxt, schema, name, NULL);
       
  3833     if (type == NULL)
       
  3834         return (NULL);
       
  3835     type->node = node;
       
  3836     type->type = XML_SCHEMA_TYPE_COMPLEX_CONTENT;
       
  3837     type->id = xmlSchemaGetProp(ctxt, node, "id");
       
  3838 
       
  3839     child = node->children;
       
  3840     if (IS_SCHEMA(child, "annotation")) {
       
  3841         type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  3842         child = child->next;
       
  3843     }
       
  3844     subtype = NULL;
       
  3845     if (IS_SCHEMA(child, "restriction")) {
       
  3846         subtype = (xmlSchemaTypePtr)
       
  3847             xmlSchemaParseRestriction(ctxt, schema, child, 0);
       
  3848         child = child->next;
       
  3849     } else if (IS_SCHEMA(child, "extension")) {
       
  3850         subtype = (xmlSchemaTypePtr)
       
  3851             xmlSchemaParseExtension(ctxt, schema, child);
       
  3852         child = child->next;
       
  3853     }
       
  3854     type->subtypes = subtype;
       
  3855     if (child != NULL) {
       
  3856         xmlSchemaPErr2(ctxt, node, child,
       
  3857                        XML_SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD,
       
  3858                        "ComplexContent %s has unexpected content\n",
       
  3859                        type->name, NULL);
       
  3860     }
       
  3861     return (type);
       
  3862 }
       
  3863 
       
  3864 /**
       
  3865  * xmlSchemaParseComplexType:
       
  3866  * @ctxt:  a schema validation context
       
  3867  * @schema:  the schema being built
       
  3868  * @node:  a subtree containing XML Schema informations
       
  3869  *
       
  3870  * parse a XML schema Complex Type definition
       
  3871  * *WARNING* this interface is highly subject to change
       
  3872  *
       
  3873  * Returns the type definition or NULL in case of error
       
  3874  */
       
  3875 static xmlSchemaTypePtr
       
  3876 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
       
  3877                           xmlNodePtr node)
       
  3878 {
       
  3879     xmlSchemaTypePtr type, subtype;
       
  3880     xmlNodePtr child = NULL;
       
  3881     const xmlChar *name;
       
  3882     const xmlChar *oldcontainer;
       
  3883     char buf[100];
       
  3884 
       
  3885     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
       
  3886         return (NULL);
       
  3887 
       
  3888     oldcontainer = ctxt->container;
       
  3889     name = xmlSchemaGetProp(ctxt, node, "name");
       
  3890     if (name == NULL) {
       
  3891 
       
  3892         snprintf(buf, 99, "complexType %d", ctxt->counter++ + 1);
       
  3893     name = (const xmlChar *)buf;
       
  3894     type = xmlSchemaAddType(ctxt, schema, name, NULL);
       
  3895     } else {
       
  3896 
       
  3897         /* local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns); */
       
  3898     type = xmlSchemaAddType(ctxt, schema, name, schema->targetNamespace);
       
  3899     }
       
  3900     if (type == NULL) {
       
  3901         return (NULL);
       
  3902     }
       
  3903 
       
  3904     if (xmlGetBooleanProp(ctxt, node, "mixed", 0))
       
  3905     type->flags |= XML_SCHEMAS_TYPE_MIXED;
       
  3906 
       
  3907     type->node = node;
       
  3908     type->type = XML_SCHEMA_TYPE_COMPLEX;
       
  3909     type->id = xmlSchemaGetProp(ctxt, node, "id");
       
  3910     ctxt->container = name;
       
  3911 
       
  3912     child = node->children;
       
  3913     if (IS_SCHEMA(child, "annotation")) {
       
  3914         type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
       
  3915         child = child->next;
       
  3916     }
       
  3917     if (IS_SCHEMA(child, "simpleContent")) {
       
  3918     /* 3.4.3 : 2.2
       
  3919      * Specifying mixed='true' when the <simpleContent>
       
  3920      * alternative is chosen has no effect
       
  3921      */
       
  3922     if (type->flags & XML_SCHEMAS_TYPE_MIXED)
       
  3923         type->flags ^= XML_SCHEMAS_TYPE_MIXED;
       
  3924         type->subtypes = xmlSchemaParseSimpleContent(ctxt, schema, child);
       
  3925         child = child->next;
       
  3926     } else if (IS_SCHEMA(child, "complexContent")) {
       
  3927         type->subtypes = xmlSchemaParseComplexContent(ctxt, schema, child);
       
  3928         child = child->next;
       
  3929     } else {
       
  3930         subtype = NULL;
       
  3931 
       
  3932         if (IS_SCHEMA(child, "all")) {
       
  3933             subtype = xmlSchemaParseAll(ctxt, schema, child);
       
  3934             child = child->next;
       
  3935         } else if (IS_SCHEMA(child, "choice")) {
       
  3936             subtype = xmlSchemaParseChoice(ctxt, schema, child);
       
  3937             child = child->next;
       
  3938         } else if (IS_SCHEMA(child, "sequence")) {
       
  3939             subtype = xmlSchemaParseSequence(ctxt, schema, child);
       
  3940             child = child->next;
       
  3941         } else if (IS_SCHEMA(child, "group")) {
       
  3942             subtype = xmlSchemaParseGroup(ctxt, schema, child);
       
  3943             child = child->next;
       
  3944         }
       
  3945         if (subtype != NULL)
       
  3946             type->subtypes = subtype;
       
  3947         child = xmlSchemaParseAttrDecls(ctxt, schema, child, type);
       
  3948     }
       
  3949     if (child != NULL) {
       
  3950         xmlSchemaPErr2(ctxt, node, child,
       
  3951                        XML_SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD,
       
  3952                        "ComplexType %s has unexpected content\n",
       
  3953                        type->name, NULL);
       
  3954     }
       
  3955     ctxt->container = oldcontainer;
       
  3956     return (type);
       
  3957 }
       
  3958 
       
  3959 /**
       
  3960  * xmlSchemaParseSchema:
       
  3961  * @ctxt:  a schema validation context
       
  3962  * @node:  a subtree containing XML Schema informations
       
  3963  *
       
  3964  * parse a XML schema definition from a node set
       
  3965  * *WARNING* this interface is highly subject to change
       
  3966  *
       
  3967  * Returns the internal XML Schema structure built from the resource or
       
  3968  *         NULL in case of error
       
  3969  */
       
  3970 static xmlSchemaPtr
       
  3971 xmlSchemaParseSchema(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
       
  3972 {
       
  3973     xmlSchemaPtr schema = NULL;
       
  3974     xmlNodePtr child = NULL;
       
  3975     const xmlChar *val;
       
  3976     int nberrors;
       
  3977 
       
  3978     if ((ctxt == NULL) || (node == NULL))
       
  3979         return (NULL);
       
  3980 
       
  3981     nberrors = ctxt->nberrors;
       
  3982     ctxt->nberrors = 0;
       
  3983     if (IS_SCHEMA(node, "schema")) {
       
  3984         schema = xmlSchemaNewSchema(ctxt);
       
  3985         if (schema == NULL)
       
  3986             return (NULL);
       
  3987     val = xmlSchemaGetProp(ctxt, node, "targetNamespace");
       
  3988     if (val != NULL) {
       
  3989         schema->targetNamespace = xmlDictLookup(ctxt->dict, val, -1);
       
  3990     } else {
       
  3991         schema->targetNamespace = NULL;
       
  3992     }
       
  3993         schema->id = xmlSchemaGetProp(ctxt, node, "id");
       
  3994         schema->version = xmlSchemaGetProp(ctxt, node, "version");
       
  3995         val = xmlSchemaGetProp(ctxt, node, "elementFormDefault");
       
  3996         if (val != NULL) {
       
  3997             if (xmlStrEqual(val, BAD_CAST "qualified"))
       
  3998                 schema->flags |= XML_SCHEMAS_QUALIF_ELEM;
       
  3999             else if (!xmlStrEqual(val, BAD_CAST "unqualified")) {
       
  4000                 xmlSchemaPErr2(ctxt, node, child,
       
  4001                                XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
       
  4002                                "Invalid value %s for elementFormDefault\n",
       
  4003                                val, NULL);
       
  4004             }
       
  4005         } else {
       
  4006         schema->flags |= XML_SCHEMAS_QUALIF_ELEM;
       
  4007     }
       
  4008         val = xmlSchemaGetProp(ctxt, node, "attributeFormDefault");
       
  4009         if (val != NULL) {
       
  4010             if (xmlStrEqual(val, BAD_CAST "qualified"))
       
  4011                 schema->flags |= XML_SCHEMAS_QUALIF_ATTR;
       
  4012             else if (!xmlStrEqual(val, BAD_CAST "unqualified")) {
       
  4013                 xmlSchemaPErr2(ctxt, node, child,
       
  4014                                XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
       
  4015                                "Invalid value %s for attributeFormDefault\n",
       
  4016                                val, NULL);
       
  4017             }
       
  4018         }
       
  4019 
       
  4020         xmlSchemaParseSchemaTopLevel(ctxt, schema, node->children);
       
  4021     } else {
       
  4022         xmlDocPtr doc;
       
  4023 
       
  4024     doc = node->doc;
       
  4025 
       
  4026         if ((doc != NULL) && (doc->URL != NULL)) {
       
  4027         xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
       
  4028               XML_SCHEMAP_NOT_SCHEMA,
       
  4029               "File %s is not a schemas", doc->URL, NULL);
       
  4030     } else {
       
  4031         xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
       
  4032               XML_SCHEMAP_NOT_SCHEMA,
       
  4033               "File is not a schemas", NULL, NULL);
       
  4034     }
       
  4035     return(NULL);
       
  4036     }
       
  4037     if (ctxt->nberrors != 0) {
       
  4038         if (schema != NULL) {
       
  4039             xmlSchemaFree(schema);
       
  4040             schema = NULL;
       
  4041         }
       
  4042     }
       
  4043     ctxt->nberrors = nberrors;
       
  4044 #ifdef DEBUG
       
  4045     if (schema == NULL)
       
  4046         xmlGenericError(xmlGenericErrorContext,
       
  4047                         "xmlSchemaParse() failed\n");
       
  4048 #endif
       
  4049 
       
  4050     return (schema);
       
  4051 }
       
  4052 
       
  4053 /************************************************************************
       
  4054  *                                  *
       
  4055  *          Validating using Schemas            *
       
  4056  *                                  *
       
  4057  ************************************************************************/
       
  4058 
       
  4059 /************************************************************************
       
  4060  *                                  *
       
  4061  *          Reading/Writing Schemas             *
       
  4062  *                                  *
       
  4063  ************************************************************************/
       
  4064 
       
  4065 /**
       
  4066  * xmlSchemaNewParserCtxt:
       
  4067  * @URL:  the location of the schema
       
  4068  *
       
  4069  * Create an XML Schemas parse context for that file/resource expected
       
  4070  * to contain an XML Schemas file.
       
  4071  *
       
  4072  * Returns the parser context or NULL in case of error
       
  4073  */
       
  4074 xmlSchemaParserCtxtPtr
       
  4075 xmlSchemaNewParserCtxt(const char *URL)
       
  4076 {
       
  4077     xmlSchemaParserCtxtPtr ret;
       
  4078 
       
  4079     if (URL == NULL)
       
  4080         return (NULL);
       
  4081 
       
  4082     ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
       
  4083     if (ret == NULL) {
       
  4084         xmlSchemaPErrMemory(NULL, "allocating schama parser context",
       
  4085                             NULL);
       
  4086         return (NULL);
       
  4087     }
       
  4088     memset(ret, 0, sizeof(xmlSchemaParserCtxt));
       
  4089     ret->dict = xmlDictCreate();
       
  4090     ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
       
  4091     ret->includes = 0;
       
  4092     return (ret);
       
  4093 }
       
  4094 
       
  4095 /**
       
  4096  * xmlSchemaNewMemParserCtxt:
       
  4097  * @buffer:  a pointer to a char array containing the schemas
       
  4098  * @size:  the size of the array
       
  4099  *
       
  4100  * Create an XML Schemas parse context for that memory buffer expected
       
  4101  * to contain an XML Schemas file.
       
  4102  *
       
  4103  * Returns the parser context or NULL in case of error
       
  4104  */
       
  4105 xmlSchemaParserCtxtPtr
       
  4106 xmlSchemaNewMemParserCtxt(const char *buffer, int size)
       
  4107 {
       
  4108     xmlSchemaParserCtxtPtr ret;
       
  4109 
       
  4110     if ((buffer == NULL) || (size <= 0))
       
  4111         return (NULL);
       
  4112 
       
  4113     ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
       
  4114     if (ret == NULL) {
       
  4115         xmlSchemaPErrMemory(NULL, "allocating schama parser context",
       
  4116                             NULL);
       
  4117         return (NULL);
       
  4118     }
       
  4119     memset(ret, 0, sizeof(xmlSchemaParserCtxt));
       
  4120     ret->buffer = buffer;
       
  4121     ret->size = size;
       
  4122     ret->dict = xmlDictCreate();
       
  4123     return (ret);
       
  4124 }
       
  4125 
       
  4126 /**
       
  4127  * xmlSchemaNewDocParserCtxt:
       
  4128  * @doc:  a preparsed document tree
       
  4129  *
       
  4130  * Create an XML Schemas parse context for that document.
       
  4131  * NB. The document may be modified during the parsing process.
       
  4132  *
       
  4133  * Returns the parser context or NULL in case of error
       
  4134  */
       
  4135 xmlSchemaParserCtxtPtr
       
  4136 xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
       
  4137 {
       
  4138     xmlSchemaParserCtxtPtr ret;
       
  4139 
       
  4140     if (doc == NULL)
       
  4141       return (NULL);
       
  4142 
       
  4143     ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
       
  4144     if (ret == NULL) {
       
  4145       xmlSchemaPErrMemory(NULL, "allocating schema parser context",
       
  4146               NULL);
       
  4147       return (NULL);
       
  4148     }
       
  4149     memset(ret, 0, sizeof(xmlSchemaParserCtxt));
       
  4150     ret->doc = doc;
       
  4151     ret->dict = xmlDictCreate();
       
  4152     /* The application has responsibility for the document */
       
  4153     ret->preserve = 1;
       
  4154 
       
  4155     return (ret);
       
  4156 }
       
  4157 
       
  4158 /**
       
  4159  * xmlSchemaFreeParserCtxt:
       
  4160  * @ctxt:  the schema parser context
       
  4161  *
       
  4162  * Free the resources associated to the schema parser context
       
  4163  */
       
  4164 void
       
  4165 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
       
  4166 {
       
  4167     if (ctxt == NULL)
       
  4168         return;
       
  4169     if (ctxt->doc != NULL && !ctxt->preserve)
       
  4170         xmlFreeDoc(ctxt->doc);
       
  4171     xmlDictFree(ctxt->dict);
       
  4172     xmlFree(ctxt);
       
  4173 }
       
  4174 
       
  4175 /************************************************************************
       
  4176  *                                  *
       
  4177  *          Building the content models         *
       
  4178  *                                  *
       
  4179  ************************************************************************/
       
  4180 
       
  4181 /**
       
  4182  * xmlSchemaBuildAContentModel:
       
  4183  * @type:  the schema type definition
       
  4184  * @ctxt:  the schema parser context
       
  4185  * @name:  the element name whose content is being built
       
  4186  *
       
  4187  * Generate the automata sequence needed for that type
       
  4188  */
       
  4189 static void
       
  4190 xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
       
  4191                             xmlSchemaParserCtxtPtr ctxt,
       
  4192                             const xmlChar * name)
       
  4193 {
       
  4194     if (type == NULL) {
       
  4195         xmlGenericError(xmlGenericErrorContext,
       
  4196                         "Found unexpected type = NULL in %s content model\n",
       
  4197                         name);
       
  4198         return;
       
  4199     }
       
  4200     switch (type->type) {
       
  4201         case XML_SCHEMA_TYPE_ANY:
       
  4202             /* TODO : handle the namespace too */
       
  4203             /* TODO : make that a specific transition type */
       
  4204             TODO ctxt->state =
       
  4205                 xmlAutomataNewTransition(ctxt->am, ctxt->state, NULL,
       
  4206                                          BAD_CAST "*", NULL);
       
  4207             break;
       
  4208         case XML_SCHEMA_TYPE_ELEMENT:{
       
  4209                 xmlSchemaElementPtr elem = (xmlSchemaElementPtr) type;
       
  4210 
       
  4211                 /* TODO : handle the namespace too */
       
  4212                 xmlAutomataStatePtr oldstate = ctxt->state;
       
  4213 
       
  4214                 if (elem->maxOccurs >= UNBOUNDED) {
       
  4215                     if (elem->minOccurs > 1) {
       
  4216                         xmlAutomataStatePtr tmp;
       
  4217                         int counter;
       
  4218 
       
  4219                         ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
       
  4220                                                             oldstate,
       
  4221                                                             NULL);
       
  4222                         oldstate = ctxt->state;
       
  4223 
       
  4224                         counter = xmlAutomataNewCounter(ctxt->am,
       
  4225                                                         elem->minOccurs -
       
  4226                                                         1, UNBOUNDED);
       
  4227 
       
  4228                         if (elem->refDecl != NULL) {
       
  4229                             xmlSchemaBuildAContentModel((xmlSchemaTypePtr)
       
  4230                                                         elem->refDecl,
       
  4231                                                         ctxt,
       
  4232                                                         elem->refDecl->
       
  4233                                                         name);
       
  4234                         } else {
       
  4235                             ctxt->state =
       
  4236                                 xmlAutomataNewTransition(ctxt->am,
       
  4237                                                          ctxt->state, NULL,
       
  4238                                                          elem->name, type);
       
  4239                         }
       
  4240                         tmp = ctxt->state;
       
  4241                         xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
       
  4242                                                    counter);
       
  4243                         ctxt->state =
       
  4244                             xmlAutomataNewCounterTrans(ctxt->am, tmp, NULL,
       
  4245                                                        counter);
       
  4246 
       
  4247                     } else {
       
  4248                         if (elem->refDecl != NULL) {
       
  4249                             xmlSchemaBuildAContentModel((xmlSchemaTypePtr)
       
  4250                                                         elem->refDecl,
       
  4251                                                         ctxt,
       
  4252                                                         elem->refDecl->
       
  4253                                                         name);
       
  4254                         } else {
       
  4255                             ctxt->state =
       
  4256                                 xmlAutomataNewTransition(ctxt->am,
       
  4257                                                          ctxt->state, NULL,
       
  4258                                                          elem->name, type);
       
  4259                         }
       
  4260                         xmlAutomataNewEpsilon(ctxt->am, ctxt->state,
       
  4261                                               oldstate);
       
  4262                         if (elem->minOccurs == 0) {
       
  4263                             /* basically an elem* */
       
  4264                             xmlAutomataNewEpsilon(ctxt->am, oldstate,
       
  4265                                                   ctxt->state);
       
  4266                         }
       
  4267                     }
       
  4268                 } else if ((elem->maxOccurs > 1) || (elem->minOccurs > 1)) {
       
  4269                     xmlAutomataStatePtr tmp;
       
  4270                     int counter;
       
  4271 
       
  4272                     ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
       
  4273                                                         oldstate, NULL);
       
  4274                     oldstate = ctxt->state;
       
  4275 
       
  4276                     counter = xmlAutomataNewCounter(ctxt->am,
       
  4277                                                     elem->minOccurs - 1,
       
  4278                                                     elem->maxOccurs - 1);
       
  4279 
       
  4280                     if (elem->refDecl != NULL) {
       
  4281                         xmlSchemaBuildAContentModel((xmlSchemaTypePtr)
       
  4282                                                     elem->refDecl, ctxt,
       
  4283                                                     elem->refDecl->name);
       
  4284                     } else {
       
  4285                         ctxt->state = xmlAutomataNewTransition(ctxt->am,
       
  4286                                                                ctxt->state,
       
  4287                                                                NULL,
       
  4288                                                                elem->name,
       
  4289                                                                type);
       
  4290                     }
       
  4291                     tmp = ctxt->state;
       
  4292                     xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
       
  4293                                                counter);
       
  4294                     ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, tmp,
       
  4295                                                              NULL,
       
  4296                                                              counter);
       
  4297                     if (elem->minOccurs == 0) {
       
  4298                         /* basically an elem? */
       
  4299                         xmlAutomataNewEpsilon(ctxt->am, oldstate,
       
  4300                                               ctxt->state);
       
  4301                     }
       
  4302 
       
  4303                 } else {
       
  4304                     if (elem->refDecl != NULL) {
       
  4305                         xmlSchemaBuildAContentModel((xmlSchemaTypePtr)
       
  4306                                                     elem->refDecl, ctxt,
       
  4307                                                     elem->refDecl->name);
       
  4308                     } else {
       
  4309                         ctxt->state = xmlAutomataNewTransition(ctxt->am,
       
  4310                                                                ctxt->state,
       
  4311                                                                NULL,
       
  4312                                                                elem->name,
       
  4313                                                                type);
       
  4314                     }
       
  4315                     if (elem->minOccurs == 0) {
       
  4316                         /* basically an elem? */
       
  4317                         xmlAutomataNewEpsilon(ctxt->am, oldstate,
       
  4318                                               ctxt->state);
       
  4319                     }
       
  4320                 }
       
  4321                 break;
       
  4322             }
       
  4323         case XML_SCHEMA_TYPE_SEQUENCE:{
       
  4324                 xmlSchemaTypePtr subtypes;
       
  4325 
       
  4326                 /*
       
  4327                  * If max and min occurances are default (1) then
       
  4328                  * simply iterate over the subtypes
       
  4329                  */
       
  4330                 if ((type->minOccurs == 1) && (type->maxOccurs == 1)) {
       
  4331                     subtypes = type->subtypes;
       
  4332                     while (subtypes != NULL) {
       
  4333                         xmlSchemaBuildAContentModel(subtypes, ctxt, name);
       
  4334                         subtypes = subtypes->next;
       
  4335                     }
       
  4336                 } else {
       
  4337                     xmlAutomataStatePtr oldstate = ctxt->state;
       
  4338 
       
  4339                     if (type->maxOccurs >= UNBOUNDED) {
       
  4340                         if (type->minOccurs > 1) {
       
  4341                             xmlAutomataStatePtr tmp;
       
  4342                             int counter;
       
  4343 
       
  4344                             ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
       
  4345                                                                 oldstate,
       
  4346                                                                 NULL);
       
  4347                             oldstate = ctxt->state;
       
  4348 
       
  4349                             counter = xmlAutomataNewCounter(ctxt->am,
       
  4350                                                             type->
       
  4351                                                             minOccurs - 1,
       
  4352                                                             UNBOUNDED);
       
  4353 
       
  4354                             subtypes = type->subtypes;
       
  4355                             while (subtypes != NULL) {
       
  4356                                 xmlSchemaBuildAContentModel(subtypes, ctxt,
       
  4357                                                             name);
       
  4358                                 subtypes = subtypes->next;
       
  4359                             }
       
  4360                             tmp = ctxt->state;
       
  4361                             xmlAutomataNewCountedTrans(ctxt->am, tmp,
       
  4362                                                        oldstate, counter);
       
  4363                             ctxt->state =
       
  4364                                 xmlAutomataNewCounterTrans(ctxt->am, tmp,
       
  4365                                                            NULL, counter);
       
  4366 
       
  4367                         } else {
       
  4368                             subtypes = type->subtypes;
       
  4369                             while (subtypes != NULL) {
       
  4370                                 xmlSchemaBuildAContentModel(subtypes, ctxt,
       
  4371                                                             name);
       
  4372                                 subtypes = subtypes->next;
       
  4373                             }
       
  4374                             xmlAutomataNewEpsilon(ctxt->am, ctxt->state,
       
  4375                                                   oldstate);
       
  4376                             if (type->minOccurs == 0) {
       
  4377                                 xmlAutomataNewEpsilon(ctxt->am, oldstate,
       
  4378                                                       ctxt->state);
       
  4379                             }
       
  4380                         }
       
  4381                     } else if ((type->maxOccurs > 1)
       
  4382                                || (type->minOccurs > 1)) {
       
  4383                         xmlAutomataStatePtr tmp;
       
  4384                         int counter;
       
  4385 
       
  4386                         ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
       
  4387                                                             oldstate,
       
  4388                                                             NULL);
       
  4389                         oldstate = ctxt->state;
       
  4390 
       
  4391                         counter = xmlAutomataNewCounter(ctxt->am,
       
  4392                                                         type->minOccurs -
       
  4393                                                         1,
       
  4394                                                         type->maxOccurs -
       
  4395                                                         1);
       
  4396 
       
  4397                         subtypes = type->subtypes;
       
  4398                         while (subtypes != NULL) {
       
  4399                             xmlSchemaBuildAContentModel(subtypes, ctxt,
       
  4400                                                         name);
       
  4401                             subtypes = subtypes->next;
       
  4402                         }
       
  4403                         tmp = ctxt->state;
       
  4404                         xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
       
  4405                                                    counter);
       
  4406                         ctxt->state =
       
  4407                             xmlAutomataNewCounterTrans(ctxt->am, tmp, NULL,
       
  4408                                                        counter);
       
  4409                         if (type->minOccurs == 0) {
       
  4410                             xmlAutomataNewEpsilon(ctxt->am, oldstate,
       
  4411                                                   ctxt->state);
       
  4412                         }
       
  4413 
       
  4414                     } else {
       
  4415                         subtypes = type->subtypes;
       
  4416                         while (subtypes != NULL) {
       
  4417                             xmlSchemaBuildAContentModel(subtypes, ctxt,
       
  4418                                                         name);
       
  4419                             subtypes = subtypes->next;
       
  4420                         }
       
  4421                         if (type->minOccurs == 0) {
       
  4422                             xmlAutomataNewEpsilon(ctxt->am, oldstate,
       
  4423                                                   ctxt->state);
       
  4424                         }
       
  4425                     }
       
  4426                 }
       
  4427                 break;
       
  4428             }
       
  4429         case XML_SCHEMA_TYPE_CHOICE:{
       
  4430                 xmlSchemaTypePtr subtypes;
       
  4431                 xmlAutomataStatePtr start, end;
       
  4432 
       
  4433                 start = ctxt->state;
       
  4434                 end = xmlAutomataNewState(ctxt->am);
       
  4435 
       
  4436                 /*
       
  4437                  * iterate over the subtypes and remerge the end with an
       
  4438                  * epsilon transition
       
  4439                  */
       
  4440                 if (type->maxOccurs == 1) {
       
  4441                     subtypes = type->subtypes;
       
  4442                     while (subtypes != NULL) {
       
  4443                         ctxt->state = start;
       
  4444                         xmlSchemaBuildAContentModel(subtypes, ctxt, name);
       
  4445                         xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
       
  4446                         subtypes = subtypes->next;
       
  4447                     }
       
  4448                 } else {
       
  4449                     int counter;
       
  4450                     xmlAutomataStatePtr hop;
       
  4451                     int maxOccurs = type->maxOccurs == UNBOUNDED ?
       
  4452                         UNBOUNDED : type->maxOccurs - 1;
       
  4453                     int minOccurs =
       
  4454                         type->minOccurs < 1 ? 0 : type->minOccurs - 1;
       
  4455 
       
  4456                     /*
       
  4457                      * use a counter to keep track of the number of transtions
       
  4458                      * which went through the choice.
       
  4459                      */
       
  4460                     counter =
       
  4461                         xmlAutomataNewCounter(ctxt->am, minOccurs,
       
  4462                                               maxOccurs);
       
  4463                     hop = xmlAutomataNewState(ctxt->am);
       
  4464 
       
  4465                     subtypes = type->subtypes;
       
  4466                     while (subtypes != NULL) {
       
  4467                         ctxt->state = start;
       
  4468                         xmlSchemaBuildAContentModel(subtypes, ctxt, name);
       
  4469                         xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
       
  4470                         subtypes = subtypes->next;
       
  4471                     }
       
  4472                     xmlAutomataNewCountedTrans(ctxt->am, hop, start,
       
  4473                                                counter);
       
  4474                     xmlAutomataNewCounterTrans(ctxt->am, hop, end,
       
  4475                                                counter);
       
  4476                 }
       
  4477                 if (type->minOccurs == 0) {
       
  4478                     xmlAutomataNewEpsilon(ctxt->am, start, end);
       
  4479                 }
       
  4480                 ctxt->state = end;
       
  4481                 break;
       
  4482             }
       
  4483         case XML_SCHEMA_TYPE_ALL:{
       
  4484                 xmlAutomataStatePtr start;
       
  4485                 xmlSchemaTypePtr subtypes;
       
  4486                 xmlSchemaElementPtr elem = (xmlSchemaElementPtr) type;
       
  4487                 int lax;
       
  4488 
       
  4489                 subtypes = type->subtypes;
       
  4490                 if (subtypes == NULL)
       
  4491                     break;
       
  4492                 start = ctxt->state;
       
  4493                 while (subtypes != NULL) {
       
  4494                     ctxt->state = start;
       
  4495             /*
       
  4496              * the following 'if' was needed to fix bug 139897
       
  4497              * not quite sure why it only needs to be done for
       
  4498              * elements with a 'ref', but it seems to work ok.
       
  4499              */
       
  4500             if (subtypes->ref != NULL)
       
  4501                 xmlSchemaBuildAContentModel(subtypes, ctxt, name);
       
  4502                     elem = (xmlSchemaElementPtr) subtypes;
       
  4503                     /* TODO : handle the namespace too */
       
  4504                     if ((elem->minOccurs == 1) && (elem->maxOccurs == 1)) {
       
  4505                         xmlAutomataNewOnceTrans(ctxt->am, ctxt->state,
       
  4506                                                 ctxt->state, elem->name, 1,
       
  4507                                                 1, subtypes);
       
  4508                     } else {
       
  4509                         xmlAutomataNewCountTrans(ctxt->am, ctxt->state,
       
  4510                                                  ctxt->state, elem->name,
       
  4511                                                  elem->minOccurs,
       
  4512                                                  elem->maxOccurs,
       
  4513                                                  subtypes);
       
  4514                     }
       
  4515                     subtypes = subtypes->next;
       
  4516                 }
       
  4517                 lax = type->minOccurs == 0;
       
  4518                 ctxt->state =
       
  4519                     xmlAutomataNewAllTrans(ctxt->am, ctxt->state, NULL,
       
  4520                                            lax);
       
  4521                 break;
       
  4522             }
       
  4523         case XML_SCHEMA_TYPE_RESTRICTION:
       
  4524             if (type->subtypes != NULL)
       
  4525                 xmlSchemaBuildAContentModel(type->subtypes, ctxt, name);
       
  4526             break;
       
  4527         case XML_SCHEMA_TYPE_EXTENSION:
       
  4528             if (type->baseType != NULL) {
       
  4529                 xmlSchemaTypePtr subtypes;
       
  4530 
       
  4531         if (type->recurse) {
       
  4532             xmlSchemaPErr(ctxt, type->node,
       
  4533                           XML_SCHEMAP_UNKNOWN_BASE_TYPE,
       
  4534                 "Schemas: extension type %s is recursive\n",
       
  4535                   type->name, NULL);
       
  4536             return;
       
  4537                 }
       
  4538                 type->recurse = 1;
       
  4539                 xmlSchemaBuildAContentModel(type->baseType, ctxt, name);
       
  4540                 type->recurse = 0;
       
  4541                 subtypes = type->subtypes;
       
  4542                 while (subtypes != NULL) {
       
  4543                     xmlSchemaBuildAContentModel(subtypes, ctxt, name);
       
  4544                     subtypes = subtypes->next;
       
  4545                 }
       
  4546             } else if (type->subtypes != NULL)
       
  4547                 xmlSchemaBuildAContentModel(type->subtypes, ctxt, name);
       
  4548             break;
       
  4549         case XML_SCHEMA_TYPE_GROUP:
       
  4550             if (type->subtypes == NULL) {
       
  4551             xmlSchemaTypePtr rgroup;
       
  4552         if (type->ref != NULL) {
       
  4553             rgroup = xmlHashLookup2(ctxt->schema->groupDecl, type->ref,
       
  4554                            type->refNs);
       
  4555             if (rgroup == NULL) {
       
  4556                 xmlSchemaPErr(ctxt, type->node,
       
  4557                       XML_SCHEMAP_UNKNOWN_REF,
       
  4558                 "Schemas: group %s reference %s is not found",
       
  4559                 name, type->ref);
       
  4560             return;
       
  4561             }
       
  4562             xmlSchemaBuildAContentModel(rgroup, ctxt, name);
       
  4563             break;
       
  4564         }
       
  4565             }
       
  4566         case XML_SCHEMA_TYPE_COMPLEX:
       
  4567         case XML_SCHEMA_TYPE_COMPLEX_CONTENT:
       
  4568             if (type->subtypes != NULL)
       
  4569                 xmlSchemaBuildAContentModel(type->subtypes, ctxt, name);
       
  4570             break;
       
  4571         default:
       
  4572             xmlGenericError(xmlGenericErrorContext,
       
  4573                             "Found unexpected type %d in %s content model\n",
       
  4574                             type->type, name);
       
  4575             return;
       
  4576     }
       
  4577 }
       
  4578 
       
  4579 /**
       
  4580  * xmlSchemaBuildContentModel:
       
  4581  * @elem:  the element
       
  4582  * @ctxt:  the schema parser context
       
  4583  * @name:  the element name
       
  4584  *
       
  4585  * Builds the content model of the element.
       
  4586  */
       
  4587 static void
       
  4588 xmlSchemaBuildContentModel(xmlSchemaElementPtr elem,
       
  4589                            xmlSchemaParserCtxtPtr ctxt,
       
  4590                            const xmlChar * name)
       
  4591 {
       
  4592     xmlAutomataStatePtr start;
       
  4593 
       
  4594     if (elem->contModel != NULL)
       
  4595         return;
       
  4596     if (elem->subtypes == NULL) {
       
  4597         elem->contentType = XML_SCHEMA_CONTENT_ANY;
       
  4598         return;
       
  4599     }
       
  4600     if (elem->subtypes->type != XML_SCHEMA_TYPE_COMPLEX)
       
  4601         return;
       
  4602     if ((elem->subtypes->contentType == XML_SCHEMA_CONTENT_BASIC) ||
       
  4603         (elem->subtypes->contentType == XML_SCHEMA_CONTENT_SIMPLE))
       
  4604         return;
       
  4605 
       
  4606 #ifdef DEBUG_CONTENT
       
  4607     xmlGenericError(xmlGenericErrorContext,
       
  4608                     "Building content model for %s\n", name);
       
  4609 #endif
       
  4610 
       
  4611     ctxt->am = xmlNewAutomata();
       
  4612     if (ctxt->am == NULL) {
       
  4613         xmlGenericError(xmlGenericErrorContext,
       
  4614                         "Cannot create automata for elem %s\n", name);
       
  4615         return;
       
  4616     }
       
  4617     start = ctxt->state = xmlAutomataGetInitState(ctxt->am);
       
  4618     xmlSchemaBuildAContentModel(elem->subtypes, ctxt, name);
       
  4619     xmlAutomataSetFinalState(ctxt->am, ctxt->state);
       
  4620     elem->contModel = xmlAutomataCompile(ctxt->am);
       
  4621     if (elem->contModel == NULL) {
       
  4622         xmlSchemaPErr(ctxt, elem->node, XML_SCHEMAS_ERR_INTERNAL,
       
  4623                       "failed to compile %s content model\n", name, NULL);
       
  4624     } else if (xmlRegexpIsDeterminist(elem->contModel) != 1) {
       
  4625         xmlSchemaPErr(ctxt, elem->node, XML_SCHEMAS_ERR_NOTDETERMINIST,
       
  4626                       "Content model of %s is not determinist:\n", name,
       
  4627                       NULL);
       
  4628     } else {
       
  4629 #ifdef DEBUG_CONTENT_REGEXP
       
  4630         xmlGenericError(xmlGenericErrorContext,
       
  4631                         "Content model of %s:\n", name);
       
  4632         xmlRegexpPrint(stderr, elem->contModel);
       
  4633 #endif
       
  4634     }
       
  4635     ctxt->state = NULL;
       
  4636     xmlFreeAutomata(ctxt->am);
       
  4637     ctxt->am = NULL;
       
  4638 }
       
  4639 
       
  4640 /**
       
  4641  * xmlSchemaRefFixupCallback:
       
  4642  * @elem:  the schema element context
       
  4643  * @ctxt:  the schema parser context
       
  4644  *
       
  4645  * Free the resources associated to the schema parser context
       
  4646  */
       
  4647 static void
       
  4648 xmlSchemaRefFixupCallback(xmlSchemaElementPtr elem,
       
  4649                           xmlSchemaParserCtxtPtr ctxt,
       
  4650                           const xmlChar * name,
       
  4651                           const xmlChar * context ATTRIBUTE_UNUSED,
       
  4652                           const xmlChar * namespace ATTRIBUTE_UNUSED)
       
  4653 {
       
  4654     if ((ctxt == NULL) || (elem == NULL))
       
  4655         return;
       
  4656     if (elem->ref != NULL) {
       
  4657         xmlSchemaElementPtr elemDecl;
       
  4658 
       
  4659         if (elem->subtypes != NULL) {
       
  4660             xmlSchemaPErr(ctxt, elem->node,
       
  4661                           XML_SCHEMAP_INVALID_REF_AND_SUBTYPE,
       
  4662                           "Schemas: element %s have both ref and subtype\n",
       
  4663                           name, NULL);
       
  4664             return;
       
  4665         }
       
  4666         elemDecl = xmlSchemaGetElem(ctxt->schema, elem->ref, elem->refNs, 0);
       
  4667 
       
  4668         if (elemDecl == NULL) {
       
  4669             xmlSchemaPErr(ctxt, elem->node, XML_SCHEMAP_UNKNOWN_REF,
       
  4670                           "Schemas: element %s ref to %s not found\n",
       
  4671                           name, elem->ref);
       
  4672             return;
       
  4673         }
       
  4674         elem->refDecl = elemDecl;
       
  4675     } else if (elem->namedType != NULL) {
       
  4676         xmlSchemaTypePtr typeDecl;
       
  4677 
       
  4678         if (elem->subtypes != NULL) {
       
  4679             xmlSchemaPErr(ctxt, elem->node, XML_SCHEMAP_TYPE_AND_SUBTYPE,
       
  4680                           "Schemas: element %s have both type and subtype\n",
       
  4681                           name, NULL);
       
  4682             return;
       
  4683         }
       
  4684         typeDecl = xmlSchemaGetType(ctxt->schema, elem->namedType,
       
  4685                                     elem->namedTypeNs);
       
  4686 
       
  4687         if (typeDecl == NULL) {
       
  4688             xmlSchemaPErr(ctxt, elem->node, XML_SCHEMAP_UNKNOWN_TYPE,
       
  4689                           "Schemas: element %s type %s not found\n", name,
       
  4690                           elem->namedType);
       
  4691             return;
       
  4692         }
       
  4693         elem->subtypes = typeDecl;
       
  4694     }
       
  4695 }
       
  4696 
       
  4697 /**
       
  4698  * xmlSchemaParseListRefFixup:
       
  4699  * @type:  the schema type definition
       
  4700  * @ctxt:  the schema parser context
       
  4701  *
       
  4702  * Fixup of the itemType reference of the list type.
       
  4703  */
       
  4704 static void
       
  4705 xmlSchemaParseListRefFixup(xmlSchemaTypePtr type, xmlSchemaParserCtxtPtr ctxt)
       
  4706 {
       
  4707     const xmlChar *itemType, *namespace;
       
  4708     xmlSchemaTypePtr subtype;
       
  4709 
       
  4710     /* Handle the "itemType" attribute. */
       
  4711     itemType = xmlGetQNameProp(ctxt, type->node, "itemType", &namespace);
       
  4712     if (itemType != NULL) {
       
  4713         /* Do not allow more that one item type. */
       
  4714         if (type->subtypes != NULL) {
       
  4715             xmlSchemaPErr(ctxt, type->node,
       
  4716                   XML_SCHEMAP_SUPERNUMEROUS_LIST_ITEM_TYPE,
       
  4717                           "List %s has more than one item type defined\n",
       
  4718               type->name, NULL);
       
  4719         }
       
  4720         subtype = xmlSchemaGetType(ctxt->schema, itemType, namespace);
       
  4721         if (subtype == NULL) {
       
  4722             xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_UNKNOWN_TYPE,
       
  4723                           "List %s references an unknown item type: %s\n",
       
  4724                           type->name, xmlSchemaGetProp(ctxt, type->node,
       
  4725               "itemType"));
       
  4726         } else
       
  4727             type->subtypes = subtype;
       
  4728     }
       
  4729 }
       
  4730 
       
  4731 /**
       
  4732  * xmlSchemaParseUnionRefCheck:
       
  4733  * @typeDecl:  the schema type definition
       
  4734  * @ctxt:  the schema parser context
       
  4735  *
       
  4736  * Checks the memberTypes references of the union type.
       
  4737  */
       
  4738 static void
       
  4739 xmlSchemaParseUnionRefCheck(xmlSchemaTypePtr type,
       
  4740                    xmlSchemaParserCtxtPtr ctxt)
       
  4741 {
       
  4742     const xmlChar *cur, *end, *prefix, *ncName, *namespace;
       
  4743     xmlChar *tmp;
       
  4744     xmlSchemaTypePtr subtype;
       
  4745     xmlNsPtr ns;
       
  4746     int len;
       
  4747 
       
  4748      if ((type->type != XML_SCHEMA_TYPE_UNION) || (type->ref == NULL))
       
  4749         return;
       
  4750 
       
  4751     cur = type->ref;
       
  4752     do {
       
  4753         while (IS_BLANK_CH(*cur))
       
  4754             cur++;
       
  4755         end = cur;
       
  4756         while ((*end != 0) && (!(IS_BLANK_CH(*end))))
       
  4757             end++;
       
  4758         if (end == cur)
       
  4759             break;
       
  4760         tmp = xmlStrndup(cur, end - cur);
       
  4761         ncName = xmlSplitQName3(tmp, &len);
       
  4762         if (ncName != NULL) {
       
  4763             prefix = xmlDictLookup(ctxt->dict, tmp, len);
       
  4764         } else {
       
  4765             prefix = NULL;
       
  4766             ncName = tmp;
       
  4767         }
       
  4768         ns = xmlSearchNs(type->node->doc, type->node, prefix);
       
  4769         if (ns == NULL) {
       
  4770             if (prefix != NULL) {
       
  4771                 xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_PREFIX_UNDEFINED,
       
  4772                               "Union %s: the namespace prefix of member type "
       
  4773                   "%s is undefined\n",
       
  4774                               type->name, (const xmlChar *) tmp);
       
  4775             }
       
  4776             namespace = NULL;
       
  4777         } else {
       
  4778             namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
       
  4779         }
       
  4780         /* Lookup the referenced type */
       
  4781         subtype = xmlSchemaGetType(ctxt->schema, ncName, namespace);
       
  4782         if (subtype == NULL) {
       
  4783             xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_UNKNOWN_MEMBER_TYPE,
       
  4784                        "Union %s references an unknown member type %s\n",
       
  4785                        type->name,  (const xmlChar *) tmp);
       
  4786         }
       
  4787         xmlFree(tmp);
       
  4788         cur = end;
       
  4789     } while (*cur != 0);
       
  4790 }
       
  4791 
       
  4792 /**
       
  4793  * xmlSchemaTypeFixup:
       
  4794  * @typeDecl:  the schema type definition
       
  4795  * @ctxt:  the schema parser context
       
  4796  *
       
  4797  * Fixes the content model of the type.
       
  4798  */
       
  4799 static void
       
  4800 xmlSchemaTypeFixup(xmlSchemaTypePtr typeDecl,
       
  4801                    xmlSchemaParserCtxtPtr ctxt, const xmlChar * name)
       
  4802 {
       
  4803     if (typeDecl == NULL)
       
  4804         return;
       
  4805     if (name == NULL)
       
  4806         name = typeDecl->name;
       
  4807     if (typeDecl->contentType == XML_SCHEMA_CONTENT_UNKNOWN) {
       
  4808         switch (typeDecl->type) {
       
  4809             case XML_SCHEMA_TYPE_SIMPLE_CONTENT:{
       
  4810                     xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
       
  4811                     if (typeDecl->subtypes != NULL)
       
  4812                         typeDecl->contentType =
       
  4813                             typeDecl->subtypes->contentType;
       
  4814                     break;
       
  4815                 }
       
  4816             case XML_SCHEMA_TYPE_RESTRICTION:{
       
  4817                     if (typeDecl->subtypes != NULL)
       
  4818                         xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
       
  4819 
       
  4820                     if (typeDecl->base != NULL) {
       
  4821                         xmlSchemaTypePtr baseType;
       
  4822 
       
  4823                         baseType =
       
  4824                             xmlSchemaGetType(ctxt->schema, typeDecl->base,
       
  4825                                              typeDecl->baseNs);
       
  4826                         if (baseType == NULL) {
       
  4827                 xmlSchemaPErr(ctxt, typeDecl->node,
       
  4828                               XML_SCHEMAP_UNKNOWN_BASE_TYPE,
       
  4829                 "Schemas: type %s base type %s not found\n",
       
  4830                                           name, typeDecl->base);
       
  4831                         }
       
  4832                         typeDecl->baseType = baseType;
       
  4833                     }
       
  4834             if (typeDecl->subtypes == NULL)
       
  4835             if (typeDecl->baseType != NULL) {
       
  4836                 /* The base type might be not "type fixed" yet,
       
  4837                  * so do it now. */
       
  4838                 if (typeDecl->baseType->contentType ==
       
  4839                         XML_SCHEMA_CONTENT_UNKNOWN)
       
  4840                 xmlSchemaTypeFixup(typeDecl->baseType, ctxt, NULL);
       
  4841                 typeDecl->contentType =
       
  4842                          typeDecl->baseType->contentType;
       
  4843             } else
       
  4844                             /* 1.1.1 */
       
  4845                             typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
       
  4846                     else if ((typeDecl->subtypes->subtypes == NULL) &&
       
  4847                              ((typeDecl->subtypes->type ==
       
  4848                                XML_SCHEMA_TYPE_ALL)
       
  4849                               || (typeDecl->subtypes->type ==
       
  4850                                   XML_SCHEMA_TYPE_SEQUENCE)))
       
  4851                         /* 1.1.2 */
       
  4852                         typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
       
  4853                     else if ((typeDecl->subtypes->type ==
       
  4854                               XML_SCHEMA_TYPE_CHOICE)
       
  4855                              && (typeDecl->subtypes->subtypes == NULL))
       
  4856                         /* 1.1.3 */
       
  4857                         typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
       
  4858                     else {
       
  4859                         /* 1.2 and 2.X are applied at the other layer */
       
  4860                         typeDecl->contentType =
       
  4861                             XML_SCHEMA_CONTENT_ELEMENTS;
       
  4862                     }
       
  4863                     break;
       
  4864                 }
       
  4865             case XML_SCHEMA_TYPE_EXTENSION:{
       
  4866                     xmlSchemaContentType explicitContentType;
       
  4867                     xmlSchemaTypePtr base;
       
  4868 
       
  4869                     if (typeDecl->base != NULL) {
       
  4870                         xmlSchemaTypePtr baseType;
       
  4871 
       
  4872                         baseType =
       
  4873                             xmlSchemaGetType(ctxt->schema, typeDecl->base,
       
  4874                                              typeDecl->baseNs);
       
  4875                         if (baseType == NULL) {
       
  4876                 xmlSchemaPErr(ctxt, typeDecl->node,
       
  4877                               XML_SCHEMAP_UNKNOWN_BASE_TYPE,
       
  4878                 "Schemas: type %s base type %s not found\n",
       
  4879                                           name, typeDecl->base);
       
  4880                         }
       
  4881                         typeDecl->baseType = baseType;
       
  4882                     }
       
  4883                     if (typeDecl->subtypes != NULL)
       
  4884                         xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
       
  4885 
       
  4886                     explicitContentType = XML_SCHEMA_CONTENT_ELEMENTS;
       
  4887                     if (typeDecl->subtypes == NULL)
       
  4888                         /* 1.1.1 */
       
  4889                         explicitContentType = XML_SCHEMA_CONTENT_EMPTY;
       
  4890                     else if ((typeDecl->subtypes->subtypes == NULL) &&
       
  4891                              ((typeDecl->subtypes->type ==
       
  4892                                XML_SCHEMA_TYPE_ALL)
       
  4893                               || (typeDecl->subtypes->type ==
       
  4894                                   XML_SCHEMA_TYPE_SEQUENCE)))
       
  4895                         /* 1.1.2 */
       
  4896                         explicitContentType = XML_SCHEMA_CONTENT_EMPTY;
       
  4897                     else if ((typeDecl->subtypes->type ==
       
  4898                               XML_SCHEMA_TYPE_CHOICE)
       
  4899                              && (typeDecl->subtypes->subtypes == NULL))
       
  4900                         /* 1.1.3 */
       
  4901                         explicitContentType = XML_SCHEMA_CONTENT_EMPTY;
       
  4902 
       
  4903                     base = xmlSchemaGetType(ctxt->schema, typeDecl->base,
       
  4904                                             typeDecl->baseNs);
       
  4905                     if (base == NULL) {
       
  4906                         xmlSchemaPErr(ctxt, typeDecl->node,
       
  4907                                       XML_SCHEMAP_UNKNOWN_BASE_TYPE,
       
  4908                                       "Schemas: base type %s of type %s not found\n",
       
  4909                                       typeDecl->base, name);
       
  4910                         return;
       
  4911                     }
       
  4912                     if (typeDecl->recurse) {
       
  4913                         xmlSchemaPErr(ctxt, typeDecl->node,
       
  4914                                       XML_SCHEMAP_UNKNOWN_BASE_TYPE,
       
  4915                   "Schemas: extension type %s is recursive\n",
       
  4916                                       name, NULL);
       
  4917                         return;
       
  4918             }
       
  4919             typeDecl->recurse = 1;
       
  4920                     xmlSchemaTypeFixup(base, ctxt, NULL);
       
  4921             typeDecl->recurse = 0;
       
  4922                     if (explicitContentType == XML_SCHEMA_CONTENT_EMPTY) {
       
  4923                         /* 2.1 */
       
  4924                         typeDecl->contentType = base->contentType;
       
  4925                     } else if (base->contentType ==
       
  4926                                XML_SCHEMA_CONTENT_EMPTY) {
       
  4927                         /* 2.2 imbitable ! */
       
  4928                         typeDecl->contentType =
       
  4929                             XML_SCHEMA_CONTENT_ELEMENTS;
       
  4930                     } else {
       
  4931                         /* 2.3 imbitable pareil ! */
       
  4932                         typeDecl->contentType =
       
  4933                             XML_SCHEMA_CONTENT_ELEMENTS;
       
  4934                     }
       
  4935                     break;
       
  4936                 }
       
  4937             case XML_SCHEMA_TYPE_COMPLEX:{
       
  4938                     if (typeDecl->subtypes == NULL) {
       
  4939                         typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
       
  4940 
       
  4941                         if (typeDecl->flags & XML_SCHEMAS_TYPE_MIXED)
       
  4942                             typeDecl->contentType =
       
  4943                                 XML_SCHEMA_CONTENT_MIXED;
       
  4944                     } else {
       
  4945                         if (typeDecl->flags & XML_SCHEMAS_TYPE_MIXED)
       
  4946                             typeDecl->contentType =
       
  4947                                 XML_SCHEMA_CONTENT_MIXED;
       
  4948                         else {
       
  4949                             xmlSchemaTypeFixup(typeDecl->subtypes, ctxt,
       
  4950                                                NULL);
       
  4951                             if (typeDecl->subtypes != NULL)
       
  4952                                 typeDecl->contentType =
       
  4953                                     typeDecl->subtypes->contentType;
       
  4954                         }
       
  4955             if (typeDecl->attributes == NULL)
       
  4956                 typeDecl->attributes =
       
  4957                     typeDecl->subtypes->attributes;
       
  4958                     }
       
  4959                     break;
       
  4960                 }
       
  4961             case XML_SCHEMA_TYPE_COMPLEX_CONTENT:{
       
  4962                     if (typeDecl->subtypes == NULL) {
       
  4963                         typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
       
  4964                         if (typeDecl->flags & XML_SCHEMAS_TYPE_MIXED)
       
  4965                             typeDecl->contentType =
       
  4966                                 XML_SCHEMA_CONTENT_MIXED;
       
  4967                     } else {
       
  4968                         if (typeDecl->flags & XML_SCHEMAS_TYPE_MIXED)
       
  4969                             typeDecl->contentType =
       
  4970                                 XML_SCHEMA_CONTENT_MIXED;
       
  4971                         else {
       
  4972                             xmlSchemaTypeFixup(typeDecl->subtypes, ctxt,
       
  4973                                                NULL);
       
  4974                             if (typeDecl->subtypes != NULL)
       
  4975                                 typeDecl->contentType =
       
  4976                                     typeDecl->subtypes->contentType;
       
  4977                         }
       
  4978             if (typeDecl->attributes == NULL)
       
  4979                 typeDecl->attributes =
       
  4980                     typeDecl->subtypes->attributes;
       
  4981                     }
       
  4982                     break;
       
  4983                 }
       
  4984             case XML_SCHEMA_TYPE_SEQUENCE:
       
  4985             case XML_SCHEMA_TYPE_GROUP:
       
  4986             case XML_SCHEMA_TYPE_ALL:
       
  4987             case XML_SCHEMA_TYPE_CHOICE:
       
  4988                 typeDecl->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
       
  4989                 break;
       
  4990             case XML_SCHEMA_TYPE_BASIC:
       
  4991             case XML_SCHEMA_TYPE_ANY:
       
  4992             case XML_SCHEMA_TYPE_FACET:
       
  4993             case XML_SCHEMA_TYPE_SIMPLE:
       
  4994             case XML_SCHEMA_TYPE_UR:
       
  4995             case XML_SCHEMA_TYPE_ELEMENT:
       
  4996             case XML_SCHEMA_TYPE_ATTRIBUTE:
       
  4997             case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
       
  4998             case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
       
  4999             case XML_SCHEMA_TYPE_NOTATION:
       
  5000             case XML_SCHEMA_TYPE_LIST:
       
  5001         xmlSchemaParseListRefFixup(typeDecl, ctxt);
       
  5002             case XML_SCHEMA_TYPE_UNION:
       
  5003                 xmlSchemaParseUnionRefCheck(typeDecl, ctxt);
       
  5004             case XML_SCHEMA_FACET_MININCLUSIVE:
       
  5005             case XML_SCHEMA_FACET_MINEXCLUSIVE:
       
  5006             case XML_SCHEMA_FACET_MAXINCLUSIVE:
       
  5007             case XML_SCHEMA_FACET_MAXEXCLUSIVE:
       
  5008             case XML_SCHEMA_FACET_TOTALDIGITS:
       
  5009             case XML_SCHEMA_FACET_FRACTIONDIGITS:
       
  5010             case XML_SCHEMA_FACET_PATTERN:
       
  5011             case XML_SCHEMA_FACET_ENUMERATION:
       
  5012             case XML_SCHEMA_FACET_WHITESPACE:
       
  5013             case XML_SCHEMA_FACET_LENGTH:
       
  5014             case XML_SCHEMA_FACET_MAXLENGTH:
       
  5015             case XML_SCHEMA_FACET_MINLENGTH:
       
  5016                 typeDecl->contentType = XML_SCHEMA_CONTENT_SIMPLE;
       
  5017         if (typeDecl->subtypes != NULL)
       
  5018             xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
       
  5019                 break;
       
  5020         }
       
  5021     }
       
  5022 #ifdef DEBUG_TYPE
       
  5023     if (typeDecl->node != NULL) {
       
  5024         xmlGenericError(xmlGenericErrorContext,
       
  5025                         "Type of %s : %s:%d :", name,
       
  5026                         typeDecl->node->doc->URL,
       
  5027                         xmlGetLineNo(typeDecl->node));
       
  5028     } else {
       
  5029         xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
       
  5030     }
       
  5031     switch (typeDecl->contentType) {
       
  5032         case XML_SCHEMA_CONTENT_SIMPLE:
       
  5033             xmlGenericError(xmlGenericErrorContext, "simple\n");
       
  5034             break;
       
  5035         case XML_SCHEMA_CONTENT_ELEMENTS:
       
  5036             xmlGenericError(xmlGenericErrorContext, "elements\n");
       
  5037             break;
       
  5038         case XML_SCHEMA_CONTENT_UNKNOWN:
       
  5039             xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
       
  5040             break;
       
  5041         case XML_SCHEMA_CONTENT_EMPTY:
       
  5042             xmlGenericError(xmlGenericErrorContext, "empty\n");
       
  5043             break;
       
  5044         case XML_SCHEMA_CONTENT_MIXED:
       
  5045             xmlGenericError(xmlGenericErrorContext, "mixed\n");
       
  5046             break;
       
  5047         case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
       
  5048             xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
       
  5049             break;
       
  5050         case XML_SCHEMA_CONTENT_BASIC:
       
  5051             xmlGenericError(xmlGenericErrorContext, "basic\n");
       
  5052             break;
       
  5053         default:
       
  5054             xmlGenericError(xmlGenericErrorContext,
       
  5055                             "not registered !!!\n");
       
  5056             break;
       
  5057     }
       
  5058 #endif
       
  5059 }
       
  5060 
       
  5061 ///#if defined(LIBXML_SCHEMAS_ENABLED)
       
  5062 /**
       
  5063  * xmlSchemaCheckFacet:
       
  5064  * @facet:  the facet
       
  5065  * @typeDecl:  the schema type definition
       
  5066  * @ctxt:  the schema parser context or NULL
       
  5067  * @name: name of the type
       
  5068  *
       
  5069  * Checks the default values types, especially for facets
       
  5070  *
       
  5071  * Returns 0 if okay or -1 in cae of error
       
  5072  */
       
  5073 int
       
  5074 xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
       
  5075                     xmlSchemaTypePtr typeDecl,
       
  5076                     xmlSchemaParserCtxtPtr ctxt, const xmlChar * name)
       
  5077 {
       
  5078     static xmlSchemaTypePtr nonNegativeIntegerType = NULL;
       
  5079     int ret = 0;
       
  5080 
       
  5081     if (nonNegativeIntegerType == NULL) {
       
  5082         nonNegativeIntegerType =
       
  5083             xmlSchemaGetPredefinedType(BAD_CAST "nonNegativeInteger",
       
  5084                                        xmlSchemaNs);
       
  5085     }
       
  5086     switch (facet->type) {
       
  5087         case XML_SCHEMA_FACET_MININCLUSIVE:
       
  5088         case XML_SCHEMA_FACET_MINEXCLUSIVE:
       
  5089         case XML_SCHEMA_FACET_MAXINCLUSIVE:
       
  5090         case XML_SCHEMA_FACET_MAXEXCLUSIVE:{
       
  5091                 /*
       
  5092                  * Okay we need to validate the value
       
  5093                  * at that point.
       
  5094                  */
       
  5095                 xmlSchemaValidCtxtPtr vctxt;
       
  5096 
       
  5097                 vctxt = xmlSchemaNewValidCtxt(NULL);
       
  5098                 if (vctxt == NULL)
       
  5099                     break;
       
  5100                 xmlSchemaValidateSimpleValue(vctxt, typeDecl,
       
  5101                                              facet->value);
       
  5102                 facet->val = vctxt->value;
       
  5103                 vctxt->value = NULL;
       
  5104                 if (facet->val == NULL) {
       
  5105                     /* error code */
       
  5106                     if (ctxt != NULL) {
       
  5107                         xmlSchemaPErr(ctxt, facet->node,
       
  5108                                       XML_SCHEMAP_INVALID_FACET,
       
  5109                                       "Schemas: type %s facet value %s invalid\n",
       
  5110                                       name, facet->value);
       
  5111                     }
       
  5112                     ret = -1;
       
  5113                 }
       
  5114                 xmlSchemaFreeValidCtxt(vctxt);
       
  5115                 break;
       
  5116             }
       
  5117         case XML_SCHEMA_FACET_ENUMERATION:{
       
  5118                 /*
       
  5119                  * Okay we need to validate the value
       
  5120                  * at that point.
       
  5121                  */
       
  5122                 xmlSchemaValidCtxtPtr vctxt;
       
  5123                 int tmp;
       
  5124 
       
  5125                 vctxt = xmlSchemaNewValidCtxt(NULL);
       
  5126                 if (vctxt == NULL)
       
  5127                     break;
       
  5128                 tmp = xmlSchemaValidateSimpleValue(vctxt, typeDecl,
       
  5129                                                    facet->value);
       
  5130                 if (tmp != 0) {
       
  5131                     if (ctxt != NULL) {
       
  5132                         xmlSchemaPErr(ctxt, facet->node,
       
  5133                                       XML_SCHEMAP_INVALID_ENUM,
       
  5134                                       "Schemas: type %s enumeration value %s invalid\n",
       
  5135                                       name, facet->value);
       
  5136                     }
       
  5137                     ret = -1;
       
  5138                 }
       
  5139                 xmlSchemaFreeValidCtxt(vctxt);
       
  5140                 break;
       
  5141             }
       
  5142         case XML_SCHEMA_FACET_PATTERN:
       
  5143             facet->regexp = xmlRegexpCompile(facet->value);
       
  5144             if (facet->regexp == NULL) {
       
  5145         xmlSchemaPErr(ctxt, typeDecl->node,
       
  5146                   XML_SCHEMAP_REGEXP_INVALID,
       
  5147                               "Schemas: type %s facet regexp %s invalid\n",
       
  5148                               name, facet->value);
       
  5149                 ret = -1;
       
  5150             }
       
  5151             break;
       
  5152         case XML_SCHEMA_FACET_TOTALDIGITS:
       
  5153         case XML_SCHEMA_FACET_FRACTIONDIGITS:
       
  5154         case XML_SCHEMA_FACET_LENGTH:
       
  5155         case XML_SCHEMA_FACET_MAXLENGTH:
       
  5156         case XML_SCHEMA_FACET_MINLENGTH:{
       
  5157                 int tmp;
       
  5158 
       
  5159                 tmp =
       
  5160                     xmlSchemaValidatePredefinedType(nonNegativeIntegerType,
       
  5161                                                     facet->value,
       
  5162                                                     &facet->val);
       
  5163                 if (tmp != 0) {
       
  5164                     /* error code */
       
  5165                     if (ctxt != NULL) {
       
  5166                         xmlSchemaPErr(ctxt, facet->node,
       
  5167                                       XML_SCHEMAP_INVALID_FACET_VALUE,
       
  5168                                       "Schemas: type %s facet value %s invalid\n",
       
  5169                                       name, facet->value);
       
  5170                     }
       
  5171                     ret = -1;
       
  5172                 }
       
  5173                 break;
       
  5174             }
       
  5175         case XML_SCHEMA_FACET_WHITESPACE:{
       
  5176                 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
       
  5177                     facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
       
  5178                 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
       
  5179                     facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
       
  5180                 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
       
  5181                     facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
       
  5182                 } else {
       
  5183                     if (ctxt != NULL) {
       
  5184                         xmlSchemaPErr(ctxt, facet->node,
       
  5185                                       XML_SCHEMAP_INVALID_WHITE_SPACE,
       
  5186                                       "Schemas: type %s whiteSpace value %s invalid\n",
       
  5187                                       name, facet->value);
       
  5188                     }
       
  5189                     ret = -1;
       
  5190                 }
       
  5191             }
       
  5192         default:
       
  5193             break;
       
  5194     }
       
  5195     return (ret);
       
  5196 }
       
  5197 
       
  5198 /**
       
  5199  * xmlSchemaCheckDefaults:
       
  5200  * @typeDecl:  the schema type definition
       
  5201  * @ctxt:  the schema parser context
       
  5202  *
       
  5203  * Checks the default values types, especially for facets
       
  5204  */
       
  5205 static void
       
  5206 xmlSchemaCheckDefaults(xmlSchemaTypePtr typeDecl,
       
  5207                        xmlSchemaParserCtxtPtr ctxt, const xmlChar * name)
       
  5208 {
       
  5209     if (name == NULL)
       
  5210         name = typeDecl->name;
       
  5211     if (typeDecl->type == XML_SCHEMA_TYPE_RESTRICTION) {
       
  5212         if (typeDecl->facets != NULL) {
       
  5213             xmlSchemaFacetPtr facet = typeDecl->facets;
       
  5214 
       
  5215             while (facet != NULL) {
       
  5216                 xmlSchemaCheckFacet(facet, typeDecl, ctxt, name);
       
  5217                 facet = facet->next;
       
  5218             }
       
  5219         }
       
  5220     }
       
  5221 }
       
  5222 
       
  5223 /**
       
  5224  * xmlSchemaAttrGrpFixup:
       
  5225  * @attrgrpDecl:  the schema attribute definition
       
  5226  * @ctxt:  the schema parser context
       
  5227  * @name:  the attribute name
       
  5228  *
       
  5229  * Fixes finish doing the computations on the attributes definitions
       
  5230  */
       
  5231 static void
       
  5232 xmlSchemaAttrGrpFixup(xmlSchemaAttributeGroupPtr attrgrpDecl,
       
  5233                       xmlSchemaParserCtxtPtr ctxt, const xmlChar * name)
       
  5234 {
       
  5235     if (name == NULL)
       
  5236         name = attrgrpDecl->name;
       
  5237     if (attrgrpDecl->attributes != NULL)
       
  5238         return;
       
  5239     if (attrgrpDecl->ref != NULL) {
       
  5240         xmlSchemaAttributeGroupPtr ref;
       
  5241 
       
  5242         ref = xmlHashLookup2(ctxt->schema->attrgrpDecl, attrgrpDecl->ref,
       
  5243                              attrgrpDecl->refNs);
       
  5244         if (ref == NULL) {
       
  5245             xmlSchemaPErr(ctxt, attrgrpDecl->node,
       
  5246                           XML_SCHEMAP_UNKNOWN_ATTRIBUTE_GROUP,
       
  5247                           "Schemas: attribute group %s reference %s not found\n",
       
  5248                           name, attrgrpDecl->ref);
       
  5249             return;
       
  5250         }
       
  5251         xmlSchemaAttrGrpFixup(ref, ctxt, NULL);
       
  5252         attrgrpDecl->attributes = ref->attributes;
       
  5253     } else {
       
  5254         xmlSchemaPErr(ctxt, attrgrpDecl->node, XML_SCHEMAP_NOATTR_NOREF,
       
  5255                       "Schemas: attribute %s has no attributes nor reference\n",
       
  5256                       name, NULL);
       
  5257     }
       
  5258 }
       
  5259 
       
  5260 /**
       
  5261  * xmlSchemaAttrFixup:
       
  5262  * @attrDecl:  the schema attribute definition
       
  5263  * @ctxt:  the schema parser context
       
  5264  * @name:  the attribute name
       
  5265  *
       
  5266  * Fixes finish doing the computations on the attributes definitions
       
  5267  */
       
  5268 static void
       
  5269 xmlSchemaAttrFixup(xmlSchemaAttributePtr attrDecl,
       
  5270                    xmlSchemaParserCtxtPtr ctxt, const xmlChar * name)
       
  5271 {
       
  5272     if (name == NULL)
       
  5273         name = attrDecl->name;
       
  5274     if (attrDecl->subtypes != NULL)
       
  5275         return;
       
  5276     if (attrDecl->typeName != NULL) {
       
  5277         xmlSchemaTypePtr type;
       
  5278 
       
  5279         type = xmlSchemaGetType(ctxt->schema, attrDecl->typeName,
       
  5280                                 attrDecl->typeNs);
       
  5281         if (type == NULL) {
       
  5282             xmlSchemaPErr(ctxt, attrDecl->node, XML_SCHEMAP_UNKNOWN_TYPE,
       
  5283                           "Schemas: attribute %s type %s not found\n",
       
  5284                           name, attrDecl->typeName);
       
  5285         }
       
  5286         attrDecl->subtypes = type;
       
  5287     } else if (attrDecl->ref != NULL) {
       
  5288         xmlSchemaAttributePtr ref;
       
  5289 
       
  5290         ref = xmlHashLookup2(ctxt->schema->attrDecl, attrDecl->ref,
       
  5291                              attrDecl->refNs);
       
  5292         if (ref == NULL) {
       
  5293             xmlSchemaPErr(ctxt, attrDecl->node, XML_SCHEMAP_UNKNOWN_REF,
       
  5294                           "Schemas: attribute %s reference %s not found\n",
       
  5295                           name, attrDecl->ref);
       
  5296             return;
       
  5297         }
       
  5298         xmlSchemaAttrFixup(ref, ctxt, NULL);
       
  5299         attrDecl->subtypes = ref->subtypes;
       
  5300     } else if (attrDecl->type != XML_SCHEMA_TYPE_ANY_ATTRIBUTE) {
       
  5301         xmlSchemaPErr(ctxt, attrDecl->node, XML_SCHEMAP_NOTYPE_NOREF,
       
  5302                       "Schemas: attribute %s has no type nor reference\n",
       
  5303                       name, NULL);
       
  5304     }
       
  5305 }
       
  5306 
       
  5307 /**
       
  5308  * xmlSchemaParse:
       
  5309  * @ctxt:  a schema validation context
       
  5310  *
       
  5311  * parse a schema definition resource and build an internal
       
  5312  * XML Shema struture which can be used to validate instances.
       
  5313  * *WARNING* this interface is highly subject to change
       
  5314  *
       
  5315  * Returns the internal XML Schema structure built from the resource or
       
  5316  *         NULL in case of error
       
  5317  */
       
  5318 xmlSchemaPtr
       
  5319 xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
       
  5320 {
       
  5321     xmlSchemaPtr ret = NULL;
       
  5322     xmlDocPtr doc;
       
  5323     xmlNodePtr root;
       
  5324     int nberrors;
       
  5325     int preserve = 0;
       
  5326 
       
  5327     xmlSchemaInitTypes();
       
  5328 
       
  5329     if (ctxt == NULL)
       
  5330         return (NULL);
       
  5331 
       
  5332     nberrors = ctxt->nberrors;
       
  5333     ctxt->nberrors = 0;
       
  5334     ctxt->counter = 0;
       
  5335     ctxt->container = NULL;
       
  5336 
       
  5337     /*
       
  5338      * First step is to parse the input document into an DOM/Infoset
       
  5339      */
       
  5340     if (ctxt->URL != NULL) {
       
  5341         doc = xmlReadFile((const char *) ctxt->URL, NULL,
       
  5342                       SCHEMAS_PARSE_OPTIONS);
       
  5343         if (doc == NULL) {
       
  5344         xmlSchemaPErr(ctxt, NULL,
       
  5345               XML_SCHEMAP_FAILED_LOAD,
       
  5346                           "xmlSchemaParse: could not load %s\n",
       
  5347                           ctxt->URL, NULL);
       
  5348             return (NULL);
       
  5349         }
       
  5350     } else if (ctxt->buffer != NULL) {
       
  5351         doc = xmlReadMemory(ctxt->buffer, ctxt->size, NULL, NULL,
       
  5352                         SCHEMAS_PARSE_OPTIONS);
       
  5353         if (doc == NULL) {
       
  5354         xmlSchemaPErr(ctxt, NULL,
       
  5355               XML_SCHEMAP_FAILED_PARSE,
       
  5356                           "xmlSchemaParse: could not parse\n",
       
  5357                           NULL, NULL);
       
  5358             return (NULL);
       
  5359         }
       
  5360         doc->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
       
  5361         ctxt->URL = xmlDictLookup(ctxt->dict, BAD_CAST "in_memory_buffer", -1);
       
  5362     } else if (ctxt->doc != NULL) {
       
  5363         doc = ctxt->doc;
       
  5364     preserve = 1;
       
  5365     } else {
       
  5366     xmlSchemaPErr(ctxt, NULL,
       
  5367               XML_SCHEMAP_NOTHING_TO_PARSE,
       
  5368               "xmlSchemaParse: could not parse\n",
       
  5369               NULL, NULL);
       
  5370         return (NULL);
       
  5371     }
       
  5372 
       
  5373     /*
       
  5374      * Then extract the root and Schema parse it
       
  5375      */
       
  5376     root = xmlDocGetRootElement(doc);
       
  5377     if (root == NULL) {
       
  5378     xmlSchemaPErr(ctxt, (xmlNodePtr) doc,
       
  5379               XML_SCHEMAP_NOROOT,
       
  5380               "schemas has no root", NULL, NULL);
       
  5381     if (!preserve) {
       
  5382         xmlFreeDoc(doc);
       
  5383     }
       
  5384         return (NULL);
       
  5385     }
       
  5386 
       
  5387     /*
       
  5388      * Remove all the blank text nodes
       
  5389      */
       
  5390     xmlSchemaCleanupDoc(ctxt, root);
       
  5391 
       
  5392     /*
       
  5393      * Then do the parsing for good
       
  5394      */
       
  5395     ret = xmlSchemaParseSchema(ctxt, root);
       
  5396     if (ret == NULL) {
       
  5397         if (!preserve) {
       
  5398         xmlFreeDoc(doc);
       
  5399     }
       
  5400         return (NULL);
       
  5401     }
       
  5402     ret->doc = doc;
       
  5403     ret->preserve = preserve;
       
  5404 
       
  5405     /*
       
  5406      * Then fix all the references.
       
  5407      */
       
  5408     ctxt->schema = ret;
       
  5409     xmlHashScanFull(ret->elemDecl,
       
  5410                     (xmlHashScannerFull) xmlSchemaRefFixupCallback, ctxt);
       
  5411 
       
  5412     /*
       
  5413      * Then fixup all attributes declarations
       
  5414      */
       
  5415     xmlHashScan(ret->attrDecl, (xmlHashScanner) xmlSchemaAttrFixup, ctxt);
       
  5416 
       
  5417     /*
       
  5418      * Then fixup all attributes group declarations
       
  5419      */
       
  5420     xmlHashScan(ret->attrgrpDecl, (xmlHashScanner) xmlSchemaAttrGrpFixup,
       
  5421                 ctxt);
       
  5422 
       
  5423     /*
       
  5424      * Then fixup all types properties
       
  5425      */
       
  5426     xmlHashScan(ret->typeDecl, (xmlHashScanner) xmlSchemaTypeFixup, ctxt);
       
  5427 
       
  5428     /*
       
  5429      * Then build the content model for all elements
       
  5430      */
       
  5431     xmlHashScan(ret->elemDecl,
       
  5432                 (xmlHashScanner) xmlSchemaBuildContentModel, ctxt);
       
  5433 
       
  5434     /*
       
  5435      * Then check the defaults part of the type like facets values
       
  5436      */
       
  5437     xmlHashScan(ret->typeDecl, (xmlHashScanner) xmlSchemaCheckDefaults,
       
  5438                 ctxt);
       
  5439 
       
  5440     if (ctxt->nberrors != 0) {
       
  5441         xmlSchemaFree(ret);
       
  5442         ret = NULL;
       
  5443     }
       
  5444     return (ret);
       
  5445 }
       
  5446 
       
  5447 /**
       
  5448  * xmlSchemaSetParserErrors:
       
  5449  * @ctxt:  a schema validation context
       
  5450  * @err:  the error callback
       
  5451  * @warn:  the warning callback
       
  5452  * @ctx:  contextual data for the callbacks
       
  5453  *
       
  5454  * Set the callback functions used to handle errors for a validation context
       
  5455  */
       
  5456 void
       
  5457 xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
       
  5458                          xmlSchemaValidityErrorFunc err,
       
  5459                          xmlSchemaValidityWarningFunc warn, void *ctx)
       
  5460 {
       
  5461     if (ctxt == NULL)
       
  5462         return;
       
  5463     ctxt->error = err;
       
  5464     ctxt->warning = warn;
       
  5465     ctxt->userData = ctx;
       
  5466 }
       
  5467 
       
  5468 /**
       
  5469  * xmlSchemaFacetTypeToString:
       
  5470  * @type:  the facet type
       
  5471  *
       
  5472  * Convert the xmlSchemaTypeType to a char string.
       
  5473  *
       
  5474  * Returns the char string representation of the facet type if the
       
  5475  *     type is a facet and an "Internal Error" string otherwise.
       
  5476  */
       
  5477 static const char *
       
  5478 xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
       
  5479 {
       
  5480     switch (type) {
       
  5481         case XML_SCHEMA_FACET_PATTERN:
       
  5482             return ("pattern");
       
  5483         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
       
  5484             return ("maxExclusive");
       
  5485         case XML_SCHEMA_FACET_MAXINCLUSIVE:
       
  5486             return ("maxInclusive");
       
  5487         case XML_SCHEMA_FACET_MINEXCLUSIVE:
       
  5488             return ("minExclusive");
       
  5489         case XML_SCHEMA_FACET_MININCLUSIVE:
       
  5490             return ("minInclusive");
       
  5491         case XML_SCHEMA_FACET_WHITESPACE:
       
  5492             return ("whiteSpace");
       
  5493         case XML_SCHEMA_FACET_ENUMERATION:
       
  5494             return ("enumeration");
       
  5495         case XML_SCHEMA_FACET_LENGTH:
       
  5496             return ("length");
       
  5497         case XML_SCHEMA_FACET_MAXLENGTH:
       
  5498             return ("maxLength");
       
  5499         case XML_SCHEMA_FACET_MINLENGTH:
       
  5500             return ("minLength");
       
  5501         case XML_SCHEMA_FACET_TOTALDIGITS:
       
  5502             return ("totalDigits");
       
  5503         case XML_SCHEMA_FACET_FRACTIONDIGITS:
       
  5504             return ("fractionDigits");
       
  5505         default:
       
  5506             break;
       
  5507     }
       
  5508     return ("Internal Error");
       
  5509 }
       
  5510 
       
  5511 /**
       
  5512  * xmlSchemaValidateFacetsInternal:
       
  5513  * @ctxt:  a schema validation context
       
  5514  * @base:  the base type
       
  5515  * @facets:  the list of facets to check
       
  5516  * @value:  the lexical repr of the value to validate
       
  5517  * @val:  the precomputed value
       
  5518  * @fireErrors:  if 0, only internal errors will be fired;
       
  5519  *       otherwise all errors will be fired.
       
  5520  *
       
  5521  * Check a value against all facet conditions
       
  5522  *
       
  5523  * Returns 0 if the element is schemas valid, a positive error code
       
  5524  *     number otherwise and -1 in case of internal or API error.
       
  5525  */
       
  5526 static int
       
  5527 xmlSchemaValidateFacetsInternal(xmlSchemaValidCtxtPtr ctxt,
       
  5528                         xmlSchemaTypePtr base,
       
  5529                         xmlSchemaFacetPtr facets,
       
  5530             const xmlChar * value, int fireErrors)
       
  5531 {
       
  5532     int ret = 0;
       
  5533     int tmp = 0;
       
  5534     xmlSchemaTypeType type;
       
  5535     xmlSchemaFacetPtr facet = facets;
       
  5536 
       
  5537     while (facet != NULL) {
       
  5538         type = facet->type;
       
  5539         if (type == XML_SCHEMA_FACET_ENUMERATION) {
       
  5540             tmp = 1;
       
  5541 
       
  5542             while (facet != NULL) {
       
  5543                 tmp =
       
  5544                     xmlSchemaValidateFacet(base, facet, value,
       
  5545                                            ctxt->value);
       
  5546                 if (tmp == 0) {
       
  5547                     return 0;
       
  5548                 }
       
  5549                 facet = facet->next;
       
  5550             }
       
  5551         } else
       
  5552             tmp = xmlSchemaValidateFacet(base, facet, value, ctxt->value);
       
  5553 
       
  5554         if (tmp != 0) {
       
  5555             ret = tmp;
       
  5556             if (fireErrors)
       
  5557                 xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_FACET,
       
  5558                   "Failed to validate type with facet %s\n",
       
  5559                   (const xmlChar *) xmlSchemaFacetTypeToString(type),
       
  5560                   NULL);
       
  5561         }
       
  5562         if (facet != NULL)
       
  5563             facet = facet->next;
       
  5564     }
       
  5565     return (ret);
       
  5566 }
       
  5567 
       
  5568 /**
       
  5569  * xmlSchemaValidateFacets:
       
  5570  * @ctxt:  a schema validation context
       
  5571  * @base:  the base type
       
  5572  * @facets:  the list of facets to check
       
  5573  * @value:  the lexical repr of the value to validate
       
  5574  * @val:  the precomputed value
       
  5575  *
       
  5576  * Check a value against all facet conditions
       
  5577  *
       
  5578  * Returns 0 if the element is schemas valid, a positive error code
       
  5579  *     number otherwise and -1 in case of internal or API error.
       
  5580  */
       
  5581 static int
       
  5582 xmlSchemaValidateFacets(xmlSchemaValidCtxtPtr ctxt,
       
  5583                         xmlSchemaTypePtr base,
       
  5584                         xmlSchemaFacetPtr facets, const xmlChar * value)
       
  5585 {
       
  5586     return(xmlSchemaValidateFacetsInternal(ctxt, base, facets, value, 1));
       
  5587 }
       
  5588 
       
  5589 /************************************************************************
       
  5590  *                                  *
       
  5591  *          Simple type validation              *
       
  5592  *                                  *
       
  5593  ************************************************************************/
       
  5594 
       
  5595 /**
       
  5596  * xmlSchemaValidateSimpleValueUnion:
       
  5597  * @ctxt:  a schema validation context
       
  5598  * @type:  the type declaration
       
  5599  * @value:  the value to validate
       
  5600  *
       
  5601  * Validates a value against a union.
       
  5602  *
       
  5603  * Returns 0 if the value is valid, a positive error code
       
  5604  *     number otherwise and -1 in case of internal or API error.
       
  5605  */
       
  5606 static int
       
  5607 xmlSchemaValidateSimpleValueUnion(xmlSchemaValidCtxtPtr ctxt,
       
  5608                              xmlSchemaTypePtr type, const xmlChar * value)
       
  5609 {
       
  5610     int ret = 0;
       
  5611     const xmlChar *cur, *end, *prefix, *ncName;
       
  5612     xmlChar *tmp;
       
  5613     xmlSchemaTypePtr subtype;
       
  5614     xmlNsPtr ns;
       
  5615     int len;
       
  5616 
       
  5617 
       
  5618     /* Process referenced memberTypes. */
       
  5619     cur = type->ref;
       
  5620     do {
       
  5621         while (IS_BLANK_CH(*cur))
       
  5622             cur++;
       
  5623         end = cur;
       
  5624         while ((*end != 0) && (!(IS_BLANK_CH(*end))))
       
  5625             end++;
       
  5626         if (end == cur)
       
  5627             break;
       
  5628         tmp = xmlStrndup(cur, end - cur);
       
  5629          ncName = xmlSplitQName3(tmp, &len);
       
  5630         if (ncName != NULL) {
       
  5631             prefix = xmlStrndup(tmp, len);
       
  5632             /* prefix = xmlDictLookup(ctxt->doc->dict, tmp, len); */
       
  5633         } else {
       
  5634             prefix = NULL;
       
  5635             ncName = tmp;
       
  5636         }
       
  5637         /* We won't do additional checks here,
       
  5638      * since they have been performed during parsing. */
       
  5639         ns = xmlSearchNs(type->node->doc, type->node, prefix);
       
  5640         /* namespace = xmlDictLookup(ctxt->doc->dict, ns->href, -1); */
       
  5641         subtype = xmlSchemaGetType(ctxt->schema, ncName, ns->href);
       
  5642     if (tmp != NULL)
       
  5643         xmlFree(tmp);
       
  5644     if (prefix != NULL)
       
  5645         xmlFree((void *)prefix);
       
  5646         ret = xmlSchemaValidateSimpleValueInternal(ctxt, subtype, value, 0);
       
  5647         if ((ret == 0) || (ret == -1)) {
       
  5648             return (ret);
       
  5649         }
       
  5650         cur = end;
       
  5651     } while (*cur != 0);
       
  5652 
       
  5653     if (type->subtypes != NULL) {
       
  5654         subtype = type->subtypes;
       
  5655         do {
       
  5656             ret = xmlSchemaValidateSimpleValueInternal(ctxt, subtype, value, 0);
       
  5657             if ((ret == 0) || (ret == -1)) {
       
  5658                 return (ret);
       
  5659             }
       
  5660             subtype = subtype->next;
       
  5661         } while (subtype != NULL);
       
  5662     }
       
  5663     return (ret);
       
  5664 }
       
  5665 
       
  5666 /**
       
  5667  * xmlSchemaValidateSimpleValue:
       
  5668  * @ctxt:  a schema validation context
       
  5669  * @type:  the type declaration
       
  5670  * @value:  the value to validate
       
  5671  *
       
  5672  * Validate a value against a simple type
       
  5673  *
       
  5674  * Returns 0 if the value is valid, a positive error code
       
  5675  *     number otherwise and -1 in case of internal or API error.
       
  5676  */
       
  5677 static int
       
  5678 xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
       
  5679                              xmlSchemaTypePtr type, const xmlChar * value)
       
  5680 {
       
  5681   return (xmlSchemaValidateSimpleValueInternal(ctxt, type, value, 1));
       
  5682 }
       
  5683 
       
  5684 /**
       
  5685  * xmlSchemaValidateSimpleValue:
       
  5686  * @ctxt:  a schema validation context
       
  5687  * @type:  the type declaration
       
  5688  * @value:  the value to validate
       
  5689  * @fireErrors:  if 0, only internal errors will be fired;
       
  5690  *       otherwise all errors will be fired.
       
  5691  *
       
  5692  * Validate a value against a simple type
       
  5693  *
       
  5694  * Returns 0 if the value is valid, a positive error code
       
  5695  *     number otherwise and -1 in case of internal or API error.
       
  5696  */
       
  5697 static int
       
  5698 xmlSchemaValidateSimpleValueInternal(xmlSchemaValidCtxtPtr ctxt,
       
  5699                              xmlSchemaTypePtr type,
       
  5700                  const xmlChar * value,
       
  5701                  int fireErrors)
       
  5702 {
       
  5703     int ret = 0;
       
  5704 
       
  5705     /*
       
  5706      * First normalize the value accordingly to Schema Datatype
       
  5707      * 4.3.6 whiteSpace definition of the whiteSpace facet of type
       
  5708      *
       
  5709      * Then check the normalized value against the lexical space of the
       
  5710      * type.
       
  5711      */
       
  5712     if (type->type == XML_SCHEMA_TYPE_BASIC) {
       
  5713         if (ctxt->value != NULL) {
       
  5714             xmlSchemaFreeValue(ctxt->value);
       
  5715             ctxt->value = NULL;
       
  5716         }
       
  5717         ret = xmlSchemaValPredefTypeNode(type, value, &(ctxt->value),
       
  5718                                          ctxt->cur);
       
  5719         if ((fireErrors) && (ret != 0)) {
       
  5720             xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_VALUE,
       
  5721                   "Failed to validate basic type %s\n",
       
  5722               type->name, NULL);
       
  5723         }
       
  5724     } else if (type->type == XML_SCHEMA_TYPE_RESTRICTION) {
       
  5725         xmlSchemaTypePtr base;
       
  5726         xmlSchemaFacetPtr facet;
       
  5727 
       
  5728         base = type->baseType;
       
  5729         if (base != NULL) {
       
  5730             ret = xmlSchemaValidateSimpleValueInternal(ctxt, base,
       
  5731                     value, fireErrors);
       
  5732         } else if (type->subtypes != NULL) {
       
  5733         TODO
       
  5734         }
       
  5735 
       
  5736         /*
       
  5737          * Do not validate facets or attributes when working on
       
  5738      * building the Schemas
       
  5739          */
       
  5740         if (ctxt->schema != NULL) {
       
  5741             if (ret == 0) {
       
  5742                 facet = type->facets;
       
  5743                 ret = xmlSchemaValidateFacetsInternal(ctxt, base, facet,
       
  5744                 value, fireErrors);
       
  5745             }
       
  5746         }
       
  5747     } else if (type->type == XML_SCHEMA_TYPE_SIMPLE) {
       
  5748         xmlSchemaTypePtr base;
       
  5749 
       
  5750         base = type->subtypes;
       
  5751         if (base != NULL) {
       
  5752             ret = xmlSchemaValidateSimpleValueInternal(ctxt, base,
       
  5753                     value, fireErrors);
       
  5754         } else {
       
  5755         TODO}
       
  5756     } else if (type->type == XML_SCHEMA_TYPE_LIST) {
       
  5757         xmlSchemaTypePtr base;
       
  5758         const xmlChar *cur, *end;
       
  5759     xmlChar *tmp;
       
  5760         int ret2;
       
  5761 
       
  5762         base = type->subtypes;
       
  5763         if (base == NULL) {
       
  5764         xmlSchemaVErr(ctxt, type->node, XML_SCHEMAS_ERR_INTERNAL,
       
  5765             "Internal: List type %s has no base type\n",
       
  5766             type->name, NULL);
       
  5767             return (-1);
       
  5768         }
       
  5769         cur = value;
       
  5770         do {
       
  5771             while (IS_BLANK_CH(*cur))
       
  5772                 cur++;
       
  5773             end = cur;
       
  5774             while ((*end != 0) && (!(IS_BLANK_CH(*end))))
       
  5775                 end++;
       
  5776             if (end == cur)
       
  5777                 break;
       
  5778             tmp = xmlStrndup(cur, end - cur);
       
  5779             ret2 = xmlSchemaValidateSimpleValueInternal(ctxt, base,
       
  5780                     tmp, fireErrors);
       
  5781         xmlFree(tmp);
       
  5782             if (ret2 != 0)
       
  5783                 ret = 1;
       
  5784             cur = end;
       
  5785         } while (*cur != 0);
       
  5786     }  else if (type->type == XML_SCHEMA_TYPE_UNION) {
       
  5787         ret = xmlSchemaValidateSimpleValueUnion(ctxt, type, value);
       
  5788         if ((fireErrors) && (ret != 0)) {
       
  5789             xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAS_ERR_VALUE,
       
  5790                   "Failed to validate type %s\n", type->name, NULL);
       
  5791         }
       
  5792     } else {
       
  5793         TODO
       
  5794     }
       
  5795     return (ret);
       
  5796 }
       
  5797 
       
  5798 /************************************************************************
       
  5799  *                                  *
       
  5800  *          DOM Validation code             *
       
  5801  *                                  *
       
  5802  ************************************************************************/
       
  5803 
       
  5804 static int xmlSchemaValidateContent(xmlSchemaValidCtxtPtr ctxt,
       
  5805                                     xmlNodePtr node);
       
  5806 static int xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt,
       
  5807                                        xmlNodePtr elem,
       
  5808                                        xmlSchemaAttributePtr attributes);
       
  5809 static int xmlSchemaValidateType(xmlSchemaValidCtxtPtr ctxt,
       
  5810                                  xmlNodePtr elem,
       
  5811                                  xmlSchemaElementPtr elemDecl,
       
  5812                                  xmlSchemaTypePtr type);
       
  5813 
       
  5814 /**
       
  5815  * xmlSchemaRegisterAttributes:
       
  5816  * @ctxt:  a schema validation context
       
  5817  * @attrs:  a list of attributes
       
  5818  *
       
  5819  * Register the list of attributes as the set to be validated on that element
       
  5820  *
       
  5821  * Returns -1 in case of error, 0 otherwise
       
  5822  */
       
  5823 static int
       
  5824 xmlSchemaRegisterAttributes(xmlSchemaValidCtxtPtr ctxt, xmlAttrPtr attrs)
       
  5825 {
       
  5826     while (attrs != NULL) {
       
  5827         if ((attrs->ns != NULL) &&
       
  5828             (xmlStrEqual(attrs->ns->href, xmlSchemaInstanceNs))) {
       
  5829             attrs = attrs->next;
       
  5830             continue;
       
  5831         }
       
  5832         if (ctxt->attrNr >= ctxt->attrMax) {
       
  5833             xmlSchemaAttrStatePtr tmp;
       
  5834 
       
  5835             ctxt->attrMax *= 2;
       
  5836             tmp = (xmlSchemaAttrStatePtr)
       
  5837                 xmlRealloc(ctxt->attr, ctxt->attrMax *
       
  5838                            sizeof(xmlSchemaAttrState));
       
  5839             if (tmp == NULL) {
       
  5840                 xmlSchemaVErrMemory(ctxt, "registering attributes", NULL);
       
  5841                 ctxt->attrMax /= 2;
       
  5842                 return (-1);
       
  5843             }
       
  5844             ctxt->attr = tmp;
       
  5845         }
       
  5846         ctxt->attr[ctxt->attrNr].attr = attrs;
       
  5847         ctxt->attr[ctxt->attrNr].state = XML_SCHEMAS_ATTR_UNKNOWN;
       
  5848         ctxt->attrNr++;
       
  5849         attrs = attrs->next;
       
  5850     }
       
  5851     return (0);
       
  5852 }
       
  5853 
       
  5854 /**
       
  5855  * xmlSchemaCheckAttributes:
       
  5856  * @ctxt:  a schema validation context
       
  5857  * @node:  the node carrying it.
       
  5858  *
       
  5859  * Check that the registered set of attributes on the current node
       
  5860  * has been properly validated.
       
  5861  *
       
  5862  * Returns 0 if validity constraints are met, 1 otherwise.
       
  5863  */
       
  5864 static int
       
  5865 xmlSchemaCheckAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
       
  5866 {
       
  5867     int ret = 0;
       
  5868     int i;
       
  5869 
       
  5870     for (i = ctxt->attrBase; i < ctxt->attrNr; i++) {
       
  5871         if (ctxt->attr[i].attr == NULL)
       
  5872             break;
       
  5873         if (ctxt->attr[i].state == XML_SCHEMAS_ATTR_UNKNOWN) {
       
  5874             ret = 1;
       
  5875             xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_ATTRUNKNOWN,
       
  5876                   "Attribute %s on %s is unknown\n",
       
  5877               ctxt->attr[i].attr->name, node->name);
       
  5878         }
       
  5879     }
       
  5880     return (ret);
       
  5881 }
       
  5882 
       
  5883 #if 0       /* Not currently used - remove if ever needed */
       
  5884 /**
       
  5885  * xmlSchemaValidateSimpleContent:
       
  5886  * @ctxt:  a schema validation context
       
  5887  * @elem:  an element
       
  5888  * @type:  the type declaration
       
  5889  *
       
  5890  * Validate the content of an element expected to be a simple type
       
  5891  *
       
  5892  * Returns 0 if the element is schemas valid, a positive error code
       
  5893  *     number otherwise and -1 in case of internal or API error.
       
  5894  */
       
  5895 static int
       
  5896 xmlSchemaValidateSimpleContent(xmlSchemaValidCtxtPtr ctxt,
       
  5897                                xmlNodePtr node ATTRIBUTE_UNUSED)
       
  5898 {
       
  5899     xmlNodePtr child;
       
  5900     xmlSchemaTypePtr type, base;
       
  5901     xmlChar *value;
       
  5902     int ret = 0;
       
  5903 
       
  5904     child = ctxt->node;
       
  5905     type = ctxt->type;
       
  5906 
       
  5907     /*
       
  5908      * Validation Rule: Element Locally Valid (Type): 3.1.3
       
  5909      */
       
  5910     value = xmlNodeGetContent(child);
       
  5911     /* xmlSchemaValidateSimpleValue(ctxt, type, value); */
       
  5912     switch (type->type) {
       
  5913         case XML_SCHEMA_TYPE_RESTRICTION:{
       
  5914                 xmlSchemaFacetPtr facet;
       
  5915 
       
  5916                 base = type->baseType;
       
  5917                 if (base != NULL) {
       
  5918                     ret = xmlSchemaValidateSimpleValue(ctxt, base, value);
       
  5919                 } else {
       
  5920                 TODO}
       
  5921                 if (ret == 0) {
       
  5922                     facet = type->facets;
       
  5923                     ret =
       
  5924                         xmlSchemaValidateFacets(ctxt, base, facet, value);
       
  5925                 }
       
  5926         if ((ret == 0) && (type->attributes != NULL)) {
       
  5927             ret = xmlSchemaValidateAttributes(ctxt, node,
       
  5928                                               type->attributes);
       
  5929         }
       
  5930                 break;
       
  5931             }
       
  5932         case XML_SCHEMA_TYPE_EXTENSION:{
       
  5933             TODO
       
  5934                 break;
       
  5935             }
       
  5936         default:
       
  5937         TODO
       
  5938     }
       
  5939     if (value != NULL)
       
  5940         xmlFree(value);
       
  5941 
       
  5942     return (ret);
       
  5943 }
       
  5944 #endif
       
  5945 
       
  5946 /**
       
  5947  * xmlSchemaValidateCheckNodeList
       
  5948  * @nodelist: the list of nodes
       
  5949  *
       
  5950  * Check the node list is only made of text nodes and entities pointing
       
  5951  * to text nodes
       
  5952  *
       
  5953  * Returns 1 if true, 0 if false and -1 in case of error
       
  5954  */
       
  5955 static int
       
  5956 xmlSchemaValidateCheckNodeList(xmlNodePtr nodelist)
       
  5957 {
       
  5958     while (nodelist != NULL) {
       
  5959         if (nodelist->type == XML_ENTITY_REF_NODE) {
       
  5960             TODO                /* implement recursion in the entity content */
       
  5961         }
       
  5962         if ((nodelist->type != XML_TEXT_NODE) &&
       
  5963             (nodelist->type != XML_COMMENT_NODE) &&
       
  5964             (nodelist->type != XML_PI_NODE) &&
       
  5965             (nodelist->type != XML_CDATA_SECTION_NODE)) {
       
  5966             return (0);
       
  5967         }
       
  5968         nodelist = nodelist->next;
       
  5969     }
       
  5970     return (1);
       
  5971 }
       
  5972 
       
  5973 /**
       
  5974  * xmlSchemaSkipIgnored:
       
  5975  * @ctxt:  a schema validation context
       
  5976  * @type:  the current type context
       
  5977  * @node:  the top node.
       
  5978  *
       
  5979  * Skip ignorable nodes in that context
       
  5980  *
       
  5981  * Returns the new sibling
       
  5982  *     number otherwise and -1 in case of internal or API error.
       
  5983  */
       
  5984 static xmlNodePtr
       
  5985 xmlSchemaSkipIgnored(xmlSchemaValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
       
  5986                      xmlSchemaTypePtr type, xmlNodePtr node)
       
  5987 {
       
  5988     int mixed = 0;
       
  5989 
       
  5990     /*
       
  5991      * TODO complete and handle entities
       
  5992      */
       
  5993     mixed = ((type->contentType == XML_SCHEMA_CONTENT_MIXED) ||
       
  5994              (type->contentType == XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS));
       
  5995     while ((node != NULL) &&
       
  5996            ((node->type == XML_COMMENT_NODE) ||
       
  5997             ((mixed == 1) && (node->type == XML_TEXT_NODE)) ||
       
  5998             (((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) &&
       
  5999               (node->type == XML_TEXT_NODE) && (IS_BLANK_NODE(node)))))) {
       
  6000         node = node->next;
       
  6001     }
       
  6002     return (node);
       
  6003 }
       
  6004 
       
  6005 /**
       
  6006  * xmlSchemaValidateCallback:
       
  6007  * @ctxt:  a schema validation context
       
  6008  * @name:  the name of the element detected (might be NULL)
       
  6009  * @type:  the type
       
  6010  *
       
  6011  * A transition has been made in the automata associated to an element
       
  6012  * content model
       
  6013  */
       
  6014 static void
       
  6015 xmlSchemaValidateCallback(xmlSchemaValidCtxtPtr ctxt,
       
  6016                           const xmlChar * name ATTRIBUTE_UNUSED,
       
  6017                           xmlSchemaTypePtr type, xmlNodePtr node)
       
  6018 {
       
  6019     xmlSchemaTypePtr oldtype = ctxt->type;
       
  6020     xmlNodePtr oldnode = ctxt->node;
       
  6021 
       
  6022 #ifdef DEBUG_CONTENT
       
  6023     xmlGenericError(xmlGenericErrorContext,
       
  6024                     "xmlSchemaValidateCallback: %s, %s, %s\n",
       
  6025                     name, type->name, node->name);
       
  6026 #endif
       
  6027     ctxt->type = type;
       
  6028     ctxt->node = node;
       
  6029     xmlSchemaValidateContent(ctxt, node);
       
  6030     ctxt->type = oldtype;
       
  6031     ctxt->node = oldnode;
       
  6032 }
       
  6033 
       
  6034 
       
  6035 #if 0
       
  6036 
       
  6037 /**
       
  6038  * xmlSchemaValidateSimpleRestrictionType:
       
  6039  * @ctxt:  a schema validation context
       
  6040  * @node:  the top node.
       
  6041  *
       
  6042  * Validate the content of a restriction type.
       
  6043  *
       
  6044  * Returns 0 if the element is schemas valid, a positive error code
       
  6045  *     number otherwise and -1 in case of internal or API error.
       
  6046  */
       
  6047 static int
       
  6048 xmlSchemaValidateSimpleRestrictionType(xmlSchemaValidCtxtPtr ctxt,
       
  6049                                        xmlNodePtr node)
       
  6050 {
       
  6051     xmlNodePtr child;
       
  6052     xmlSchemaTypePtr type;
       
  6053     int ret;
       
  6054 
       
  6055     child = ctxt->node;
       
  6056     type = ctxt->type;
       
  6057 
       
  6058     if ((ctxt == NULL) || (type == NULL)) {
       
  6059         xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
       
  6060               "Internal error: xmlSchemaValidateSimpleRestrictionType %s\n",
       
  6061               node->name, NULL);
       
  6062         return (-1);
       
  6063     }
       
  6064     /*
       
  6065      * Only text and text based entities references shall be found there
       
  6066      */
       
  6067     ret = xmlSchemaValidateCheckNodeList(child);
       
  6068     if (ret < 0) {
       
  6069         xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
       
  6070               "Internal error: xmlSchemaValidateSimpleType %s content\n",
       
  6071               node->name, NULL);
       
  6072         return (-1);
       
  6073     } else if (ret == 0) {
       
  6074         xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_NOTSIMPLE,
       
  6075               "Element %s content is not a simple type\n",
       
  6076               node->name, NULL);
       
  6077         return (-1);
       
  6078     }
       
  6079     ctxt->type = type->subtypes;
       
  6080     xmlSchemaValidateContent(ctxt, node);
       
  6081     ctxt->type = type;
       
  6082     return (ret);
       
  6083 }
       
  6084 #endif
       
  6085 
       
  6086 /**
       
  6087  * xmlSchemaValidateSimpleType:
       
  6088  * @ctxt:  a schema validation context
       
  6089  * @node:  the top node.
       
  6090  *
       
  6091  * Validate the content of an simple type.
       
  6092  *
       
  6093  * Returns 0 if the element is schemas valid, a positive error code
       
  6094  *     number otherwise and -1 in case of internal or API error.
       
  6095  */
       
  6096 static int
       
  6097 xmlSchemaValidateSimpleType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
       
  6098 {
       
  6099     xmlNodePtr child;
       
  6100     xmlSchemaTypePtr type, base, variety;
       
  6101     xmlAttrPtr attr;
       
  6102     int ret;
       
  6103     xmlChar *value;
       
  6104 
       
  6105 
       
  6106     child = ctxt->node;
       
  6107     type = ctxt->type;
       
  6108 
       
  6109     if ((ctxt == NULL) || (type == NULL)) {
       
  6110         xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
       
  6111               "Internal error: xmlSchemaValidateSimpleType %s\n",
       
  6112               node->name, NULL);
       
  6113         return (-1);
       
  6114     }
       
  6115     /*
       
  6116      * Only text and text based entities references shall be found there
       
  6117      */
       
  6118     ret = xmlSchemaValidateCheckNodeList(child);
       
  6119     if (ret < 0) {
       
  6120         xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
       
  6121               "Internal error: xmlSchemaValidateSimpleType %s content\n",
       
  6122               node->name, NULL);
       
  6123         return (-1);
       
  6124     } else if (ret == 0) {
       
  6125         xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_NOTSIMPLE,
       
  6126               "Element %s content is not a simple type\n",
       
  6127               node->name, NULL);
       
  6128         return (-1);
       
  6129     }
       
  6130     /*
       
  6131      * Validation Rule: Element Locally Valid (Type): 3.1.1
       
  6132      */
       
  6133 
       
  6134     attr = node->properties;
       
  6135     while (attr != NULL) {
       
  6136         if ((attr->ns == NULL) ||
       
  6137             (!xmlStrEqual(attr->ns->href, xmlSchemaInstanceNs)) ||
       
  6138             ((!xmlStrEqual(attr->name, BAD_CAST "type")) &&
       
  6139              (!xmlStrEqual(attr->name, BAD_CAST "nil")) &&
       
  6140              (!xmlStrEqual(attr->name, BAD_CAST "schemasLocation")) &&
       
  6141              (!xmlStrEqual
       
  6142               (attr->name, BAD_CAST "noNamespaceSchemaLocation")))) {
       
  6143             xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INVALIDATTR,
       
  6144                   "Element %s: attribute %s should not be present\n",
       
  6145               node->name, attr->name);
       
  6146             return (ctxt->err);
       
  6147         }
       
  6148     }
       
  6149     /* TODO:
       
  6150      * If {variety} is ·atomic· then the {variety} of {base type definition}
       
  6151      * must be ·atomic·.
       
  6152      * If {variety} is ·list· then the {variety} of {item type definition}
       
  6153      * must be either ·atomic· or ·union·.
       
  6154      * If {variety} is ·union· then {member type definitions} must be a list
       
  6155      * of datatype definitions.
       
  6156      */
       
  6157     if (type->subtypes == NULL) {
       
  6158     xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
       
  6159               "Internal error: xmlSchemaValidateSimpleType; "
       
  6160               "simple type %s does not define a variety\n",
       
  6161               node->name, NULL);
       
  6162     return (ctxt->err);
       
  6163     }
       
  6164     /* Varieties: Restriction or List or Union. */
       
  6165     variety = type->subtypes;
       
  6166     ctxt->type = variety;
       
  6167     value = xmlNodeGetContent(child);
       
  6168     switch (variety->type) {
       
  6169         case XML_SCHEMA_TYPE_RESTRICTION:{
       
  6170                 xmlSchemaFacetPtr facet;
       
  6171 
       
  6172                 base = variety->baseType;
       
  6173                 if (base != NULL) {
       
  6174                     ret = xmlSchemaValidateSimpleValue(ctxt, base, value);
       
  6175                 } else {
       
  6176                 TODO}
       
  6177                 if (ret == 0) {
       
  6178                     facet = variety->facets;
       
  6179                     ret =
       
  6180                         xmlSchemaValidateFacets(ctxt, base, facet, value);
       
  6181                 }
       
  6182         if ((ret == 0) && (variety->attributes != NULL)) {
       
  6183             ret = xmlSchemaValidateAttributes(ctxt, node,
       
  6184                     variety->attributes);
       
  6185         }
       
  6186                 break;
       
  6187             }
       
  6188         case XML_SCHEMA_TYPE_LIST:
       
  6189     case XML_SCHEMA_TYPE_UNION: {
       
  6190             ret = xmlSchemaValidateSimpleValue(ctxt, variety, value);
       
  6191                 break;
       
  6192             }
       
  6193         default:{
       
  6194         xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
       
  6195                   "Internal error: xmlSchemaValidateSimpleType; "
       
  6196                   "simple type %s defines unknown content: %s\n",
       
  6197                   variety->name, NULL);
       
  6198         ret = ctxt->err;
       
  6199         }
       
  6200     }
       
  6201     if (value != NULL)
       
  6202         xmlFree(value);
       
  6203 
       
  6204     /* This was removed, since a simple content is not a content of a
       
  6205      * simple type, but of a complex type.
       
  6206      * ret = xmlSchemaValidateSimpleContent(ctxt, node);
       
  6207      */
       
  6208     ctxt->type = type;
       
  6209     return (ret);
       
  6210 }
       
  6211 
       
  6212 /**
       
  6213  * xmlSchemaValidateElementType:
       
  6214  * @ctxt:  a schema validation context
       
  6215  * @node:  the top node.
       
  6216  *
       
  6217  * Validate the content of an element type.
       
  6218  * Validation Rule: Element Locally Valid (Complex Type)
       
  6219  *
       
  6220  * Returns 0 if the element is schemas valid, a positive error code
       
  6221  *     number otherwise and -1 in case of internal or API error.
       
  6222  */
       
  6223 static int
       
  6224 xmlSchemaValidateElementType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
       
  6225 {
       
  6226     xmlNodePtr child;
       
  6227     xmlSchemaTypePtr type;
       
  6228     xmlRegExecCtxtPtr oldregexp;        /* cont model of the parent */
       
  6229     xmlSchemaElementPtr decl;
       
  6230     int ret, attrBase;
       
  6231 
       
  6232     oldregexp = ctxt->regexp;
       
  6233 
       
  6234     child = ctxt->node;
       
  6235     type = ctxt->type;
       
  6236 
       
  6237     if ((ctxt == NULL) || (type == NULL)) {
       
  6238         xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
       
  6239               "Internal error: xmlSchemaValidateElementType\n",
       
  6240               node->name, NULL);
       
  6241         return (-1);
       
  6242     }
       
  6243     if (child == NULL) {
       
  6244         if (type->minOccurs > 0) {
       
  6245             xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_MISSING,
       
  6246                   "Element %s: missing child %s\n",
       
  6247               node->name, type->name);
       
  6248         }
       
  6249         return (ctxt->err);
       
  6250     }
       
  6251 
       
  6252     /*
       
  6253      * Verify the element matches
       
  6254      */
       
  6255     if (!xmlStrEqual(child->name, type->name)) {
       
  6256         xmlSchemaVErr3(ctxt, node, XML_SCHEMAS_ERR_WRONGELEM,
       
  6257                "Element %s: missing child %s found %s\n",
       
  6258                node->name, type->name, child->name);
       
  6259         return (ctxt->err);
       
  6260     }
       
  6261     /*
       
  6262      * Verify the attributes
       
  6263      */
       
  6264     attrBase = ctxt->attrBase;
       
  6265     ctxt->attrBase = ctxt->attrNr;
       
  6266     xmlSchemaRegisterAttributes(ctxt, child->properties);
       
  6267     xmlSchemaValidateAttributes(ctxt, child, type->attributes);
       
  6268     /*
       
  6269      * Verify the element content recursively
       
  6270      */
       
  6271     decl = (xmlSchemaElementPtr) type;
       
  6272     oldregexp = ctxt->regexp;
       
  6273     if (decl->contModel != NULL) {
       
  6274         ctxt->regexp = xmlRegNewExecCtxt(decl->contModel,
       
  6275                                          (xmlRegExecCallbacks)
       
  6276                                          xmlSchemaValidateCallback, ctxt);
       
  6277 #ifdef DEBUG_AUTOMATA
       
  6278         xmlGenericError(xmlGenericErrorContext, "====> %s\n", node->name);
       
  6279 #endif
       
  6280     }
       
  6281     xmlSchemaValidateType(ctxt, child, (xmlSchemaElementPtr) type,
       
  6282                           type->subtypes);
       
  6283 
       
  6284     if (decl->contModel != NULL) {
       
  6285         ret = xmlRegExecPushString(ctxt->regexp, NULL, NULL);
       
  6286 #ifdef DEBUG_AUTOMATA
       
  6287         xmlGenericError(xmlGenericErrorContext,
       
  6288                         "====> %s : %d\n", node->name, ret);
       
  6289 #endif
       
  6290         if (ret == 0) {
       
  6291             xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_ELEMCONT,
       
  6292                   "Element %s content check failed\n",
       
  6293               node->name, NULL);
       
  6294         } else if (ret < 0) {
       
  6295             xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_ELEMCONT,
       
  6296                   "Element %s content check failure\n",
       
  6297               node->name, NULL);
       
  6298 #ifdef DEBUG_CONTENT
       
  6299         } else {
       
  6300             xmlGenericError(xmlGenericErrorContext,
       
  6301                             "Element %s content check succeeded\n",
       
  6302                             node->name);
       
  6303 
       
  6304 #endif
       
  6305         }
       
  6306         xmlRegFreeExecCtxt(ctxt->regexp);
       
  6307     }
       
  6308     /*
       
  6309      * Verify that all attributes were Schemas-validated
       
  6310      */
       
  6311     xmlSchemaCheckAttributes(ctxt, node);
       
  6312     ctxt->attrNr = ctxt->attrBase;
       
  6313     ctxt->attrBase = attrBase;
       
  6314 
       
  6315     ctxt->regexp = oldregexp;
       
  6316 
       
  6317     ctxt->node = child;
       
  6318     ctxt->type = type;
       
  6319     return (ctxt->err);
       
  6320 }
       
  6321 
       
  6322 /**
       
  6323  * xmlSchemaValidateBasicType:
       
  6324  * @ctxt:  a schema validation context
       
  6325  * @node:  the top node.
       
  6326  *
       
  6327  * Validate the content of an element expected to be a basic type type
       
  6328  *
       
  6329  * Returns 0 if the element is schemas valid, a positive error code
       
  6330  *     number otherwise and -1 in case of internal or API error.
       
  6331  */
       
  6332 static int
       
  6333 xmlSchemaValidateBasicType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
       
  6334 {
       
  6335     int ret;
       
  6336     xmlNodePtr child, cur;
       
  6337     xmlSchemaTypePtr type;
       
  6338     xmlChar *value;             /* lexical representation */
       
  6339 
       
  6340     child = ctxt->node;
       
  6341     type = ctxt->type;
       
  6342 
       
  6343     if ((ctxt == NULL) || (type == NULL)) {
       
  6344         xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
       
  6345               "Internal error: xmlSchemaValidateBasicType\n",
       
  6346               node->name, NULL);
       
  6347         return (-1);
       
  6348     }
       
  6349     /*
       
  6350      * First check the content model of the node.
       
  6351      */
       
  6352     cur = child;
       
  6353     while (cur != NULL) {
       
  6354         switch (cur->type) {
       
  6355             case XML_TEXT_NODE:
       
  6356             case XML_CDATA_SECTION_NODE:
       
  6357             case XML_PI_NODE:
       
  6358             case XML_COMMENT_NODE:
       
  6359             case XML_XINCLUDE_START:
       
  6360             case XML_XINCLUDE_END:
       
  6361                 break;
       
  6362             case XML_ENTITY_REF_NODE:
       
  6363             case XML_ENTITY_NODE:
       
  6364                 TODO break;
       
  6365             case XML_ELEMENT_NODE:
       
  6366                 xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INVALIDELEM,
       
  6367                   "Element %s: child %s should not be present\n",
       
  6368                   node->name, cur->name);
       
  6369                 return (ctxt->err);
       
  6370             case XML_ATTRIBUTE_NODE:
       
  6371             case XML_DOCUMENT_NODE:
       
  6372             case XML_DOCUMENT_TYPE_NODE:
       
  6373             case XML_DOCUMENT_FRAG_NODE:
       
  6374             case XML_NOTATION_NODE:
       
  6375             case XML_HTML_DOCUMENT_NODE:
       
  6376             case XML_DTD_NODE:
       
  6377             case XML_ELEMENT_DECL:
       
  6378             case XML_ATTRIBUTE_DECL:
       
  6379             case XML_ENTITY_DECL:
       
  6380             case XML_NAMESPACE_DECL:
       
  6381 #ifdef LIBXML_DOCB_ENABLED
       
  6382             case XML_DOCB_DOCUMENT_NODE:
       
  6383 #endif
       
  6384                 xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INVALIDELEM,
       
  6385                   "Element %s: node type of node unexpected here\n",
       
  6386                   node->name, NULL);
       
  6387                 return (ctxt->err);
       
  6388         }
       
  6389         cur = cur->next;
       
  6390     }
       
  6391     if (child == NULL)
       
  6392         value = NULL;
       
  6393     else
       
  6394         value = xmlNodeGetContent(child->parent);
       
  6395 
       
  6396     if (ctxt->value != NULL) {
       
  6397         xmlSchemaFreeValue(ctxt->value);
       
  6398         ctxt->value = NULL;
       
  6399     }
       
  6400     ret = xmlSchemaValidatePredefinedType(type, value, &(ctxt->value));
       
  6401     if (value != NULL)
       
  6402         xmlFree(value);
       
  6403     if (ret != 0) {
       
  6404         xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_VALUE,
       
  6405               "Element %s: failed to validate basic type %s\n",
       
  6406               node->name, type->name);
       
  6407     }
       
  6408     return (ret);
       
  6409 }
       
  6410 
       
  6411 /**
       
  6412  * xmlSchemaValidateComplexType:
       
  6413  * @ctxt:  a schema validation context
       
  6414  * @node:  the top node.
       
  6415  *
       
  6416  * Validate the content of an element expected to be a complex type type
       
  6417  * xmlschema-1.html#cvc-complex-type
       
  6418  * Validation Rule: Element Locally Valid (Complex Type)
       
  6419  *
       
  6420  * Returns 0 if the element is schemas valid, a positive error code
       
  6421  *     number otherwise and -1 in case of internal or API error.
       
  6422  */
       
  6423 static int
       
  6424 xmlSchemaValidateComplexType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
       
  6425 {
       
  6426     xmlNodePtr child;
       
  6427     xmlSchemaTypePtr type, subtype;
       
  6428     int ret;
       
  6429 
       
  6430     child = ctxt->node;
       
  6431     type = ctxt->type;
       
  6432     ctxt->cur = node;
       
  6433 
       
  6434     switch (type->contentType) {
       
  6435         case XML_SCHEMA_CONTENT_EMPTY:
       
  6436         if (type->baseType != NULL) {
       
  6437         } else if (child != NULL) {
       
  6438         xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_NOTEMPTY,
       
  6439                   "Element %s is supposed to be empty\n",
       
  6440                   node->name, NULL);
       
  6441             }
       
  6442             if (type->attributes != NULL) {
       
  6443                 xmlSchemaValidateAttributes(ctxt, node, type->attributes);
       
  6444             }
       
  6445             subtype = type->subtypes;
       
  6446             while (subtype != NULL) {
       
  6447                 ctxt->type = subtype;
       
  6448                 xmlSchemaValidateComplexType(ctxt, node);
       
  6449                 subtype = subtype->next;
       
  6450             }
       
  6451             break;
       
  6452         case XML_SCHEMA_CONTENT_ELEMENTS:
       
  6453         case XML_SCHEMA_CONTENT_MIXED:
       
  6454         case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
       
  6455             /*
       
  6456              * Skip ignorable nodes in that context
       
  6457              */
       
  6458             child = xmlSchemaSkipIgnored(ctxt, type, child);
       
  6459             while (child != NULL) {
       
  6460                 if (child->type == XML_ELEMENT_NODE) {
       
  6461                     ret = xmlRegExecPushString(ctxt->regexp,
       
  6462                                                child->name, child);
       
  6463 #ifdef DEBUG_AUTOMATA
       
  6464                     if (ret < 0)
       
  6465                         xmlGenericError(xmlGenericErrorContext,
       
  6466                                         "  --> %s Error\n", child->name);
       
  6467                     else
       
  6468                         xmlGenericError(xmlGenericErrorContext,
       
  6469                                         "  --> %s\n", child->name);
       
  6470 #endif
       
  6471                 }
       
  6472                 child = child->next;
       
  6473                 /*
       
  6474                  * Skip ignorable nodes in that context
       
  6475                  */
       
  6476                 child = xmlSchemaSkipIgnored(ctxt, type, child);
       
  6477             }
       
  6478         if (((type->contentType == XML_SCHEMA_CONTENT_MIXED) ||
       
  6479         (type->contentType == XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS)) &&
       
  6480         (type->subtypes != NULL)) {
       
  6481         TODO
       
  6482         }
       
  6483 
       
  6484 
       
  6485             if (type->attributes != NULL) {
       
  6486                 xmlSchemaValidateAttributes(ctxt, node, type->attributes);
       
  6487             }
       
  6488             break;
       
  6489         case XML_SCHEMA_CONTENT_BASIC:{
       
  6490                 if (type->subtypes != NULL) {
       
  6491                     ctxt->type = type->subtypes;
       
  6492                     xmlSchemaValidateComplexType(ctxt, node);
       
  6493                 }
       
  6494                 if (type->baseType != NULL) {
       
  6495                     ctxt->type = type->baseType;
       
  6496             if (type->baseType->type == XML_SCHEMA_TYPE_BASIC)
       
  6497             xmlSchemaValidateBasicType(ctxt, node);
       
  6498             else if (type->baseType->type == XML_SCHEMA_TYPE_COMPLEX)
       
  6499             xmlSchemaValidateComplexType(ctxt, node);
       
  6500             else if (type->baseType->type == XML_SCHEMA_TYPE_SIMPLE)
       
  6501             xmlSchemaValidateSimpleType(ctxt, node);
       
  6502             else
       
  6503             xmlGenericError(xmlGenericErrorContext,
       
  6504                                  "unexpected content type of base: %d\n",
       
  6505                                  type->contentType);
       
  6506 
       
  6507                 }
       
  6508                 if (type->attributes != NULL) {
       
  6509                     xmlSchemaValidateAttributes(ctxt, node,
       
  6510                                                 type->attributes);
       
  6511                 }
       
  6512                 ctxt->type = type;
       
  6513                 break;
       
  6514             }
       
  6515         case XML_SCHEMA_CONTENT_SIMPLE:{
       
  6516                 if (type->subtypes != NULL) {
       
  6517                     ctxt->type = type->subtypes;
       
  6518                     xmlSchemaValidateComplexType(ctxt, node);
       
  6519                 }
       
  6520                 if (type->baseType != NULL) {
       
  6521                     ctxt->type = type->baseType;
       
  6522                     xmlSchemaValidateComplexType(ctxt, node);
       
  6523                 }
       
  6524                 if (type->attributes != NULL) {
       
  6525                     xmlSchemaValidateAttributes(ctxt, node,
       
  6526                                                 type->attributes);
       
  6527                 }
       
  6528                 ctxt->type = type;
       
  6529                 break;
       
  6530     }
       
  6531         default:
       
  6532             TODO xmlGenericError(xmlGenericErrorContext,
       
  6533                                  "unimplemented content type %d\n",
       
  6534                                  type->contentType);
       
  6535     }
       
  6536     return (ctxt->err);
       
  6537 }
       
  6538 
       
  6539 /**
       
  6540  * xmlSchemaValidateContent:
       
  6541  * @ctxt:  a schema validation context
       
  6542  * @elem:  an element
       
  6543  * @type:  the type declaration
       
  6544  *
       
  6545  * Validate the content of an element against the type.
       
  6546  *
       
  6547  * Returns 0 if the element is schemas valid, a positive error code
       
  6548  *     number otherwise and -1 in case of internal or API error.
       
  6549  */
       
  6550 static int
       
  6551 xmlSchemaValidateContent(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
       
  6552 {
       
  6553     xmlNodePtr child;
       
  6554     xmlSchemaTypePtr type;
       
  6555 
       
  6556     child = ctxt->node;
       
  6557     type = ctxt->type;
       
  6558     ctxt->cur = node;
       
  6559 
       
  6560     xmlSchemaValidateAttributes(ctxt, node, type->attributes);
       
  6561     ctxt->cur = node;
       
  6562 
       
  6563     switch (type->type) {
       
  6564         case XML_SCHEMA_TYPE_ANY:
       
  6565             /* Any type will do it, fine */
       
  6566             TODO                /* handle recursivity */
       
  6567                 break;
       
  6568         case XML_SCHEMA_TYPE_COMPLEX:
       
  6569             xmlSchemaValidateComplexType(ctxt, node);
       
  6570             break;
       
  6571         case XML_SCHEMA_TYPE_ELEMENT:{
       
  6572                 xmlSchemaElementPtr decl = (xmlSchemaElementPtr) type;
       
  6573 
       
  6574                 /*
       
  6575                  * Handle element reference here
       
  6576                  */
       
  6577                 if (decl->ref != NULL) {
       
  6578                     if (decl->refDecl == NULL) {
       
  6579                         xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_INTERNAL,
       
  6580                       "Internal error: element reference %s "
       
  6581                       "not resolved\n", decl->ref, NULL);
       
  6582                         return (-1);
       
  6583                     }
       
  6584                     ctxt->type = (xmlSchemaTypePtr) decl->refDecl;
       
  6585                     decl = decl->refDecl;
       
  6586                 }
       
  6587         /* TODO: Should "xmlSchemaValidateElement" be called instead? */
       
  6588                 xmlSchemaValidateElementType(ctxt, node);
       
  6589                 ctxt->type = type;
       
  6590                 break;
       
  6591             }
       
  6592         case XML_SCHEMA_TYPE_BASIC:
       
  6593             xmlSchemaValidateBasicType(ctxt, node);
       
  6594             break;
       
  6595         case XML_SCHEMA_TYPE_FACET:
       
  6596             TODO break;
       
  6597         case XML_SCHEMA_TYPE_SIMPLE:
       
  6598             xmlSchemaValidateSimpleType(ctxt, node);
       
  6599             break;
       
  6600         case XML_SCHEMA_TYPE_SEQUENCE:
       
  6601             TODO break;
       
  6602         case XML_SCHEMA_TYPE_CHOICE:
       
  6603             TODO break;
       
  6604         case XML_SCHEMA_TYPE_ALL:
       
  6605             TODO break;
       
  6606         case XML_SCHEMA_TYPE_SIMPLE_CONTENT:
       
  6607             TODO break;
       
  6608         case XML_SCHEMA_TYPE_COMPLEX_CONTENT:
       
  6609             TODO break;
       
  6610         case XML_SCHEMA_TYPE_UR:
       
  6611             TODO break;
       
  6612         case XML_SCHEMA_TYPE_RESTRICTION:
       
  6613             /*xmlSchemaValidateRestrictionType(ctxt, node); */
       
  6614             TODO break;
       
  6615         case XML_SCHEMA_TYPE_EXTENSION:
       
  6616             TODO break;
       
  6617         case XML_SCHEMA_TYPE_ATTRIBUTE:
       
  6618             TODO break;
       
  6619         case XML_SCHEMA_TYPE_GROUP:
       
  6620             TODO break;
       
  6621         case XML_SCHEMA_TYPE_NOTATION:
       
  6622             TODO break;
       
  6623         case XML_SCHEMA_TYPE_LIST:
       
  6624             TODO break;
       
  6625         case XML_SCHEMA_TYPE_UNION:
       
  6626             TODO break;
       
  6627         case XML_SCHEMA_FACET_MININCLUSIVE:
       
  6628             TODO break;
       
  6629         case XML_SCHEMA_FACET_MINEXCLUSIVE:
       
  6630             TODO break;
       
  6631         case XML_SCHEMA_FACET_MAXINCLUSIVE:
       
  6632             TODO break;
       
  6633         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
       
  6634             TODO break;
       
  6635         case XML_SCHEMA_FACET_TOTALDIGITS:
       
  6636             TODO break;
       
  6637         case XML_SCHEMA_FACET_FRACTIONDIGITS:
       
  6638             TODO break;
       
  6639         case XML_SCHEMA_FACET_PATTERN:
       
  6640             TODO break;
       
  6641         case XML_SCHEMA_FACET_ENUMERATION:
       
  6642             TODO break;
       
  6643         case XML_SCHEMA_FACET_WHITESPACE:
       
  6644             TODO break;
       
  6645         case XML_SCHEMA_FACET_LENGTH:
       
  6646             TODO break;
       
  6647         case XML_SCHEMA_FACET_MAXLENGTH:
       
  6648             TODO break;
       
  6649         case XML_SCHEMA_FACET_MINLENGTH:
       
  6650             TODO break;
       
  6651         case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
       
  6652             TODO break;
       
  6653         case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
       
  6654             TODO break;
       
  6655     }
       
  6656     xmlSchemaValidateAttributes(ctxt, node, type->attributes);
       
  6657 
       
  6658     if (ctxt->node == NULL)
       
  6659         return (ctxt->err);
       
  6660     ctxt->node = ctxt->node->next;
       
  6661     ctxt->type = type->next;
       
  6662     return (ctxt->err);
       
  6663 }
       
  6664 
       
  6665 /**
       
  6666  * xmlSchemaValidateType:
       
  6667  * @ctxt:  a schema validation context
       
  6668  * @elem:  an element
       
  6669  * @type:  the list of type declarations
       
  6670  *
       
  6671  * Validate the content of an element against the types.
       
  6672  *
       
  6673  * Returns 0 if the element is schemas valid, a positive error code
       
  6674  *     number otherwise and -1 in case of internal or API error.
       
  6675  */
       
  6676 static int
       
  6677 xmlSchemaValidateType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem,
       
  6678                       xmlSchemaElementPtr elemDecl, xmlSchemaTypePtr type)
       
  6679 {
       
  6680     xmlChar *nil;
       
  6681 
       
  6682     if ((elem == NULL) || (type == NULL) || (elemDecl == NULL))
       
  6683         return (0);
       
  6684 
       
  6685     /*
       
  6686      * 3.3.4 : 2
       
  6687      */
       
  6688     if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
       
  6689         xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_ISABSTRACT,
       
  6690               "Element declaration %s is abstract\n",
       
  6691               elemDecl->name, NULL);
       
  6692     /* Changed, since the element declaration is abstract and not
       
  6693      * the element itself. */
       
  6694     /* xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_ISABSTRACT,
       
  6695              "Element %s is abstract\n", elem->name, NULL); */
       
  6696         return (ctxt->err);
       
  6697     }
       
  6698     /*
       
  6699      * 3.3.4: 3
       
  6700      */
       
  6701     nil = xmlGetNsProp(elem, BAD_CAST "nil", xmlSchemaInstanceNs);
       
  6702     if (elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) {
       
  6703         /* 3.3.4: 3.2 */
       
  6704         if (xmlStrEqual(nil, BAD_CAST "true")) {
       
  6705             if (elem->children != NULL) {
       
  6706                 xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_NOTEMPTY,
       
  6707                   "Element %s is not empty\n", elem->name, NULL);
       
  6708                 return (ctxt->err);
       
  6709             }
       
  6710             if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
       
  6711                 (elemDecl->value != NULL)) {
       
  6712                 xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_HAVEDEFAULT,
       
  6713                   "Empty element %s cannot get a fixed value\n",
       
  6714                   elem->name, NULL);
       
  6715                 return (ctxt->err);
       
  6716             }
       
  6717         }
       
  6718     } else {
       
  6719         /* 3.3.4: 3.1 */
       
  6720         if (nil != NULL) {
       
  6721             xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_NOTNILLABLE,
       
  6722                   "Element %s with xs:nil but not nillable\n",
       
  6723               elem->name, NULL);
       
  6724             xmlFree(nil);
       
  6725             return (ctxt->err);
       
  6726         }
       
  6727     }
       
  6728 
       
  6729     /* TODO 3.3.4: 4 if the element carries xs:type */
       
  6730 
       
  6731     ctxt->type = elemDecl->subtypes;
       
  6732     ctxt->node = elem->children;
       
  6733     xmlSchemaValidateContent(ctxt, elem);
       
  6734     xmlSchemaValidateAttributes(ctxt, elem, elemDecl->attributes);
       
  6735 
       
  6736     return (ctxt->err);
       
  6737 }
       
  6738 
       
  6739 
       
  6740 /**
       
  6741  * xmlSchemaValidateAttributes:
       
  6742  * @ctxt:  a schema validation context
       
  6743  * @elem:  an element
       
  6744  * @attributes:  the list of attribute declarations
       
  6745  *
       
  6746  * Validate the attributes of an element.
       
  6747  *
       
  6748  * Returns 0 if the element is schemas valid, a positive error code
       
  6749  *     number otherwise and -1 in case of internal or API error.
       
  6750  */
       
  6751 static int
       
  6752 xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem,
       
  6753                             xmlSchemaAttributePtr attributes)
       
  6754 {
       
  6755     int i, ret;
       
  6756     xmlAttrPtr attr;
       
  6757     xmlChar *value;
       
  6758     xmlSchemaAttributeGroupPtr group = NULL;
       
  6759     int found;
       
  6760 
       
  6761     if (attributes == NULL)
       
  6762         return (0);
       
  6763     while (attributes != NULL) {
       
  6764         found = 0;
       
  6765         /*
       
  6766          * Handle attribute groups
       
  6767          */
       
  6768         if (attributes->type == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
       
  6769             group = (xmlSchemaAttributeGroupPtr) attributes;
       
  6770             xmlSchemaValidateAttributes(ctxt, elem, group->attributes);
       
  6771             attributes = group->next;
       
  6772             continue;
       
  6773         }
       
  6774         for (i = ctxt->attrBase; i < ctxt->attrNr; i++) {
       
  6775             attr = ctxt->attr[i].attr;
       
  6776             if (attr == NULL)
       
  6777                 continue;
       
  6778             if (attributes->ref != NULL) {
       
  6779                 if (!xmlStrEqual(attr->name, attributes->ref))
       
  6780                     continue;
       
  6781                 if (attr->ns != NULL) {
       
  6782                     if ((attributes->refNs == NULL) ||
       
  6783                         (!xmlStrEqual(attr->ns->href, attributes->refNs)))
       
  6784                         continue;
       
  6785                 } else if (attributes->refNs != NULL) {
       
  6786                     continue;
       
  6787                 }
       
  6788             } else {
       
  6789                 if (!xmlStrEqual(attr->name, attributes->name))
       
  6790                     continue;
       
  6791                 /*
       
  6792                  * handle the namespaces checks here
       
  6793                  */
       
  6794                 if (attr->ns == NULL) {
       
  6795             /*
       
  6796              * accept an unqualified attribute only if the target
       
  6797              * namespace of the declaration is absent.
       
  6798              */
       
  6799             if (attributes->targetNamespace != NULL)
       
  6800             /*
       
  6801              * This check was removed, since the target namespace
       
  6802              * was evaluated during parsing and already took
       
  6803              * "attributeFormDefault" into account.
       
  6804              */
       
  6805                 /* ((attributes->flags & XML_SCHEMAS_ATTR_NSDEFAULT) == 0)) */
       
  6806                 continue;
       
  6807         } else {
       
  6808             if (attributes->targetNamespace == NULL)
       
  6809                 continue;
       
  6810             if (!xmlStrEqual(attributes->targetNamespace,
       
  6811                              attr->ns->href))
       
  6812             continue;
       
  6813         }
       
  6814             }
       
  6815             found = 1;
       
  6816             ctxt->cur = (xmlNodePtr) attributes;
       
  6817 
       
  6818             if (attributes->subtypes == NULL) {
       
  6819                 xmlSchemaVErr(ctxt, (xmlNodePtr) attr, XML_SCHEMAS_ERR_INTERNAL,
       
  6820                   "Internal error: attribute %s type not resolved\n",
       
  6821                   attr->name, NULL);
       
  6822                 continue;
       
  6823             }
       
  6824 
       
  6825             if (attributes->occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
       
  6826                 xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_INVALIDATTR,
       
  6827                   "attribute %s on %s is prohibited\n",
       
  6828                   attributes->name, elem->name);
       
  6829                 /* Setting the state to XML_SCHEMAS_ATTR_CHECKED seems
       
  6830          * not very logical but it suppresses the
       
  6831          * "attribute is unknown" error report. Please change
       
  6832          * this if you know better */
       
  6833                 ctxt->attr[i].state = XML_SCHEMAS_ATTR_CHECKED;
       
  6834                 break;
       
  6835             }
       
  6836 
       
  6837             value = xmlNodeListGetString(elem->doc, attr->children, 1);
       
  6838             ret = xmlSchemaValidateSimpleValue(ctxt, attributes->subtypes,
       
  6839                                                value);
       
  6840             if (ret != 0) {
       
  6841                 xmlSchemaVErr(ctxt, (xmlNodePtr) attr,
       
  6842                   XML_SCHEMAS_ERR_ATTRINVALID,
       
  6843                   "attribute %s on %s does not match type\n",
       
  6844                   attr->name, elem->name);
       
  6845             } else {
       
  6846                 ctxt->attr[i].state = XML_SCHEMAS_ATTR_CHECKED;
       
  6847             }
       
  6848             if (value != NULL) {
       
  6849                 xmlFree(value);
       
  6850             }
       
  6851         }
       
  6852         if ((!found) && (attributes->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED)) {
       
  6853             xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_MISSING,
       
  6854                   "required attribute %s on %s is missing\n",
       
  6855                   attributes->name, elem->name);
       
  6856         }
       
  6857         attributes = attributes->next;
       
  6858     }
       
  6859     return (ctxt->err);
       
  6860 }
       
  6861 
       
  6862 /**
       
  6863  * xmlSchemaValidateElement:
       
  6864  * @ctxt:  a schema validation context
       
  6865  * @elem:  an element
       
  6866  *
       
  6867  * Validate an element in a tree
       
  6868  *
       
  6869  * Returns 0 if the element is schemas valid, a positive error code
       
  6870  *     number otherwise and -1 in case of internal or API error.
       
  6871  */
       
  6872 static int
       
  6873 xmlSchemaValidateElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
       
  6874 {
       
  6875     xmlSchemaElementPtr elemDecl;
       
  6876     int ret, attrBase;
       
  6877 
       
  6878     if (elem->ns != NULL) {
       
  6879         elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
       
  6880                                   elem->name, elem->ns->href, NULL);
       
  6881     } else {
       
  6882         elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
       
  6883                                   elem->name, NULL, NULL);
       
  6884     }
       
  6885     /*
       
  6886      * special case whe elementFormDefault is unqualified for top-level elem.
       
  6887      */
       
  6888     /*
       
  6889      * This was removed, since elementFormDefault does not apply to top-level
       
  6890      * element declarations.
       
  6891      */
       
  6892     /*
       
  6893     if ((elemDecl == NULL) && (elem->ns != NULL) &&
       
  6894         (elem->parent != NULL) && (elem->parent->type != XML_ELEMENT_NODE) &&
       
  6895         (xmlStrEqual(ctxt->schema->targetNamespace, elem->ns->href)) &&
       
  6896     ((ctxt->schema->flags & XML_SCHEMAS_QUALIF_ELEM) == 0)) {
       
  6897         elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
       
  6898                                   elem->name, NULL, NULL);
       
  6899     }
       
  6900     */
       
  6901 
       
  6902     /*
       
  6903      * 3.3.4 : 1
       
  6904      */
       
  6905     if (elemDecl == NULL) {
       
  6906         xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_UNDECLAREDELEM,
       
  6907               "Element %s not declared\n", elem->name, NULL);
       
  6908         return (ctxt->err);
       
  6909     }
       
  6910     if (elemDecl->subtypes == NULL) {
       
  6911         xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_NOTYPE,
       
  6912               "Element %s has no type\n", elem->name, NULL);
       
  6913         return (ctxt->err);
       
  6914     }
       
  6915     /*
       
  6916      * Verify the attributes
       
  6917      */
       
  6918     attrBase = ctxt->attrBase;
       
  6919     ctxt->attrBase = ctxt->attrNr;
       
  6920     xmlSchemaRegisterAttributes(ctxt, elem->properties);
       
  6921     xmlSchemaValidateAttributes(ctxt, elem, elemDecl->attributes);
       
  6922     /*
       
  6923      * Verify the element content recursively
       
  6924      */
       
  6925     if (elemDecl->contModel != NULL) {
       
  6926         ctxt->regexp = xmlRegNewExecCtxt(elemDecl->contModel,
       
  6927                                          (xmlRegExecCallbacks)
       
  6928                                          xmlSchemaValidateCallback, ctxt);
       
  6929 #ifdef DEBUG_AUTOMATA
       
  6930         xmlGenericError(xmlGenericErrorContext, "====> %s\n", elem->name);
       
  6931 #endif
       
  6932     }
       
  6933     xmlSchemaValidateType(ctxt, elem, elemDecl, elemDecl->subtypes);
       
  6934     if (elemDecl->contModel != NULL) {
       
  6935         ret = xmlRegExecPushString(ctxt->regexp, NULL, NULL);
       
  6936 #ifdef DEBUG_AUTOMATA
       
  6937         xmlGenericError(xmlGenericErrorContext,
       
  6938                         "====> %s : %d\n", elem->name, ret);
       
  6939 #endif
       
  6940         if (ret == 0) {
       
  6941             xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_ELEMCONT,
       
  6942                   "Element %s content check failed\n",
       
  6943               elem->name, NULL);
       
  6944         } else if (ret < 0) {
       
  6945             xmlSchemaVErr(ctxt, elem, XML_SCHEMAS_ERR_ELEMCONT,
       
  6946                   "Element %s content check failed\n",
       
  6947               elem->name, NULL);
       
  6948 #ifdef DEBUG_CONTENT
       
  6949         } else {
       
  6950             xmlGenericError(xmlGenericErrorContext,
       
  6951                             "Element %s content check succeeded\n",
       
  6952                             elem->name);
       
  6953 
       
  6954 #endif
       
  6955         }
       
  6956         xmlRegFreeExecCtxt(ctxt->regexp);
       
  6957     }
       
  6958     /*
       
  6959      * Verify that all attributes were Schemas-validated
       
  6960      */
       
  6961     xmlSchemaCheckAttributes(ctxt, elem);
       
  6962     ctxt->attrNr = ctxt->attrBase;
       
  6963     ctxt->attrBase = attrBase;
       
  6964 
       
  6965     return (ctxt->err);
       
  6966 }
       
  6967 
       
  6968 /**
       
  6969  * xmlSchemaValidateDocument:
       
  6970  * @ctxt:  a schema validation context
       
  6971  * @doc:  a parsed document tree
       
  6972  *
       
  6973  * Validate a document tree in memory.
       
  6974  *
       
  6975  * Returns 0 if the document is schemas valid, a positive error code
       
  6976  *     number otherwise and -1 in case of internal or API error.
       
  6977  */
       
  6978 static int
       
  6979 xmlSchemaValidateDocument(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
       
  6980 {
       
  6981     xmlNodePtr root;
       
  6982     xmlSchemaElementPtr elemDecl;
       
  6983 
       
  6984     root = xmlDocGetRootElement(doc);
       
  6985     if (root == NULL) {
       
  6986         xmlSchemaVErr(ctxt, (xmlNodePtr) doc, XML_SCHEMAS_ERR_NOROOT,
       
  6987               "document has no root\n", NULL, NULL);
       
  6988         return (ctxt->err);
       
  6989     }
       
  6990 
       
  6991     if (root->ns != NULL)
       
  6992         elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
       
  6993                                   root->name, root->ns->href, NULL);
       
  6994     else
       
  6995         elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
       
  6996                                   root->name, NULL, NULL);
       
  6997     /*
       
  6998      * special case whe elementFormDefault is unqualified for top-level elem.
       
  6999      */
       
  7000     if ((elemDecl == NULL) && (root->ns != NULL) &&
       
  7001         (xmlStrEqual(ctxt->schema->targetNamespace, root->ns->href)) &&
       
  7002     ((ctxt->schema->flags & XML_SCHEMAS_QUALIF_ELEM) == 0)) {
       
  7003         elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
       
  7004                                   root->name, NULL, NULL);
       
  7005     }
       
  7006 
       
  7007     if (elemDecl == NULL) {
       
  7008         xmlSchemaVErr(ctxt, root, XML_SCHEMAS_ERR_UNDECLAREDELEM,
       
  7009               "Element %s not declared\n", root->name, NULL);
       
  7010     } else if ((elemDecl->flags & XML_SCHEMAS_ELEM_TOPLEVEL) == 0) {
       
  7011         xmlSchemaVErr(ctxt, root, XML_SCHEMAS_ERR_NOTTOPLEVEL,
       
  7012               "Root element %s not toplevel\n", root->name, NULL);
       
  7013     }
       
  7014     /*
       
  7015      * Okay, start the recursive validation
       
  7016      */
       
  7017     xmlSchemaValidateElement(ctxt, root);
       
  7018 
       
  7019     return (ctxt->err);
       
  7020 }
       
  7021 
       
  7022 /************************************************************************
       
  7023  *                                  *
       
  7024  *          SAX Validation code             *
       
  7025  *                                  *
       
  7026  ************************************************************************/
       
  7027 
       
  7028 /************************************************************************
       
  7029  *                                  *
       
  7030  *          Validation interfaces               *
       
  7031  *                                  *
       
  7032  ************************************************************************/
       
  7033 
       
  7034 /**
       
  7035  * xmlSchemaNewValidCtxt:
       
  7036  * @schema:  a precompiled XML Schemas
       
  7037  *
       
  7038  * Create an XML Schemas validation context based on the given schema
       
  7039  *
       
  7040  * Returns the validation context or NULL in case of error
       
  7041  */
       
  7042 xmlSchemaValidCtxtPtr
       
  7043 xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
       
  7044 {
       
  7045     xmlSchemaValidCtxtPtr ret;
       
  7046 
       
  7047     ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
       
  7048     if (ret == NULL) {
       
  7049         xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
       
  7050         return (NULL);
       
  7051     }
       
  7052     memset(ret, 0, sizeof(xmlSchemaValidCtxt));
       
  7053     ret->schema = schema;
       
  7054     ret->attrNr = 0;
       
  7055     ret->attrMax = 10;
       
  7056     ret->attr = (xmlSchemaAttrStatePtr) xmlMalloc(ret->attrMax *
       
  7057                                                   sizeof
       
  7058                                                   (xmlSchemaAttrState));
       
  7059     if (ret->attr == NULL) {
       
  7060         xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
       
  7061         free(ret);
       
  7062         return (NULL);
       
  7063     }
       
  7064     memset(ret->attr, 0, ret->attrMax * sizeof(xmlSchemaAttrState));
       
  7065     return (ret);
       
  7066 }
       
  7067 
       
  7068 /**
       
  7069  * xmlSchemaFreeValidCtxt:
       
  7070  * @ctxt:  the schema validation context
       
  7071  *
       
  7072  * Free the resources associated to the schema validation context
       
  7073  */
       
  7074 void
       
  7075 xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
       
  7076 {
       
  7077     if (ctxt == NULL)
       
  7078         return;
       
  7079     if (ctxt->attr != NULL)
       
  7080         xmlFree(ctxt->attr);
       
  7081     if (ctxt->value != NULL)
       
  7082         xmlSchemaFreeValue(ctxt->value);
       
  7083     xmlFree(ctxt);
       
  7084 }
       
  7085 
       
  7086 /**
       
  7087  * xmlSchemaSetValidErrors:
       
  7088  * @ctxt:  a schema validation context
       
  7089  * @err:  the error function
       
  7090  * @warn: the warning function
       
  7091  * @ctx: the functions context
       
  7092  *
       
  7093  * Set the error and warning callback informations
       
  7094  */
       
  7095 void
       
  7096 xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
       
  7097                         xmlSchemaValidityErrorFunc err,
       
  7098                         xmlSchemaValidityWarningFunc warn, void *ctx)
       
  7099 {
       
  7100     if (ctxt == NULL)
       
  7101         return;
       
  7102     ctxt->error = err;
       
  7103     ctxt->warning = warn;
       
  7104     ctxt->userData = ctx;
       
  7105 }
       
  7106 
       
  7107 /**
       
  7108  * xmlSchemaValidateDoc:
       
  7109  * @ctxt:  a schema validation context
       
  7110  * @doc:  a parsed document tree
       
  7111  *
       
  7112  * Validate a document tree in memory.
       
  7113  *
       
  7114  * Returns 0 if the document is schemas valid, a positive error code
       
  7115  *     number otherwise and -1 in case of internal or API error.
       
  7116  */
       
  7117 int
       
  7118 xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
       
  7119 {
       
  7120     int ret;
       
  7121 
       
  7122     if ((ctxt == NULL) || (doc == NULL))
       
  7123         return (-1);
       
  7124 
       
  7125     ctxt->doc = doc;
       
  7126     ret = xmlSchemaValidateDocument(ctxt, doc);
       
  7127     return (ret);
       
  7128 }
       
  7129 
       
  7130 /**
       
  7131  * xmlSchemaValidateStream:
       
  7132  * @ctxt:  a schema validation context
       
  7133  * @input:  the input to use for reading the data
       
  7134  * @enc:  an optional encoding information
       
  7135  * @sax:  a SAX handler for the resulting events
       
  7136  * @user_data:  the context to provide to the SAX handler.
       
  7137  *
       
  7138  * Validate a document tree in memory.
       
  7139  *
       
  7140  * Returns 0 if the document is schemas valid, a positive error code
       
  7141  *     number otherwise and -1 in case of internal or API error.
       
  7142  */
       
  7143 int
       
  7144 xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
       
  7145                         xmlParserInputBufferPtr input, xmlCharEncoding enc,
       
  7146                         xmlSAXHandlerPtr sax, void *user_data)
       
  7147 {
       
  7148     if ((ctxt == NULL) || (input == NULL))
       
  7149         return (-1);
       
  7150     ctxt->input = input;
       
  7151     ctxt->enc = enc;
       
  7152     ctxt->sax = sax;
       
  7153     ctxt->user_data = user_data;
       
  7154     TODO return (0);
       
  7155 }
       
  7156 
       
  7157 #endif /* LIBXML_SCHEMAS_ENABLED */