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