2002-04-16 19:50:10 +04:00
/*
* schemas . c : implementation of the XML Schema handling and
* schema validity checking
*
* See Copyright for the status of this software .
*
* Daniel Veillard < veillard @ redhat . com >
*/
2003-12-24 02:30:53 +03:00
/*
* TODO :
* - when types are redefined in includes , check that all
* types in the redef list are equal
* - > need a type equality operation .
*/
2002-04-16 19:50:10 +04:00
# define IN_LIBXML
# include "libxml.h"
# ifdef LIBXML_SCHEMAS_ENABLED
# include <string.h>
# include <libxml/xmlmemory.h>
# include <libxml/parser.h>
# include <libxml/parserInternals.h>
# include <libxml/hash.h>
2002-05-22 10:40:27 +04:00
# include <libxml/uri.h>
2002-04-16 19:50:10 +04:00
# include <libxml/xmlschemas.h>
# include <libxml/schemasInternals.h>
# include <libxml/xmlschemastypes.h>
# include <libxml/xmlautomata.h>
# include <libxml/xmlregexp.h>
2003-11-22 23:37:51 +03:00
# include <libxml/dict.h>
2002-04-16 19:50:10 +04:00
2003-06-02 20:58:46 +04:00
/* #define DEBUG 1 */
2003-10-10 04:49:42 +04:00
2003-05-12 00:16:09 +04:00
/* #define DEBUG_CONTENT 1 */
2003-10-10 04:49:42 +04:00
2003-05-12 00:16:09 +04:00
/* #define DEBUG_TYPE 1 */
2003-10-10 04:49:42 +04:00
2002-09-24 18:13:13 +04:00
/* #define DEBUG_CONTENT_REGEXP 1 */
2003-10-10 04:49:42 +04:00
2002-04-16 19:50:10 +04:00
/* #define DEBUG_AUTOMATA 1 */
# define UNBOUNDED (1 << 30)
# define TODO \
xmlGenericError ( xmlGenericErrorContext , \
" Unimplemented block at %s:%d \n " , \
__FILE__ , __LINE__ ) ;
2002-05-22 10:40:27 +04:00
# define XML_SCHEMAS_DEFAULT_NAMESPACE (const xmlChar *)"the default namespace"
2002-04-16 19:50:10 +04:00
/*
* The XML Schemas namespaces
*/
static const xmlChar * xmlSchemaNs = ( const xmlChar * )
" http://www.w3.org/2001/XMLSchema " ;
static const xmlChar * xmlSchemaInstanceNs = ( const xmlChar * )
" http://www.w3.org/2001/XMLSchema-instance " ;
# define IS_SCHEMA(node, type) \
( ( node ! = NULL ) & & ( node - > ns ! = NULL ) & & \
( xmlStrEqual ( node - > name , ( const xmlChar * ) type ) ) & & \
( xmlStrEqual ( node - > ns - > href , xmlSchemaNs ) ) )
# define XML_SCHEMAS_PARSE_ERROR 1
2003-11-25 18:38:59 +03:00
# define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
2002-04-16 19:50:10 +04:00
struct _xmlSchemaParserCtxt {
2003-10-10 04:49:42 +04:00
void * userData ; /* user specific data block */
xmlSchemaValidityErrorFunc error ; /* the callback in case of errors */
xmlSchemaValidityWarningFunc warning ; /* the callback in case of warning */
2002-04-22 20:01:24 +04:00
xmlSchemaValidError err ;
2003-10-10 04:49:42 +04:00
int nberrors ;
2003-10-10 18:10:40 +04:00
xmlStructuredErrorFunc serror ;
2002-04-16 19:50:10 +04:00
2003-11-22 23:37:51 +03:00
xmlSchemaPtr topschema ; /* The main schema */
xmlHashTablePtr namespaces ; /* Hash table of namespaces to schemas */
2003-10-10 04:49:42 +04:00
xmlSchemaPtr schema ; /* The schema in use */
2003-11-22 23:37:51 +03:00
const xmlChar * container ; /* the current element, group, ... */
2002-04-16 19:50:10 +04:00
int counter ;
2003-11-22 23:37:51 +03:00
const xmlChar * URL ;
2003-10-10 04:49:42 +04:00
xmlDocPtr doc ;
2004-01-24 11:31:30 +03:00
int preserve ; /* Whether the doc should be freed */
2002-04-16 19:50:10 +04:00
2003-10-10 04:49:42 +04:00
const char * buffer ;
int size ;
2002-10-10 01:13:59 +04:00
2002-04-16 19:50:10 +04:00
/*
* Used to build complex element content models
*/
2003-10-10 04:49:42 +04:00
xmlAutomataPtr am ;
2002-04-16 19:50:10 +04:00
xmlAutomataStatePtr start ;
xmlAutomataStatePtr end ;
xmlAutomataStatePtr state ;
2003-11-22 23:37:51 +03:00
xmlDictPtr dict ; /* dictionnary for interned string names */
2003-12-24 02:30:53 +03:00
int includes ; /* the inclusion level, 0 for root or imports */
2002-04-16 19:50:10 +04:00
} ;
# define XML_SCHEMAS_ATTR_UNKNOWN 1
# define XML_SCHEMAS_ATTR_CHECKED 2
typedef struct _xmlSchemaAttrState xmlSchemaAttrState ;
typedef xmlSchemaAttrState * xmlSchemaAttrStatePtr ;
struct _xmlSchemaAttrState {
2003-10-10 04:49:42 +04:00
xmlAttrPtr attr ;
int state ;
2002-04-16 19:50:10 +04:00
} ;
/**
* xmlSchemaValidCtxt :
*
* A Schemas validation context
*/
struct _xmlSchemaValidCtxt {
2003-10-10 04:49:42 +04:00
void * userData ; /* user specific data block */
xmlSchemaValidityErrorFunc error ; /* the callback in case of errors */
xmlSchemaValidityWarningFunc warning ; /* the callback in case of warning */
2003-10-10 18:10:40 +04:00
xmlStructuredErrorFunc serror ;
2002-04-16 19:50:10 +04:00
2003-10-10 04:49:42 +04:00
xmlSchemaPtr schema ; /* The schema in use */
xmlDocPtr doc ;
2002-04-16 19:50:10 +04:00
xmlParserInputBufferPtr input ;
2003-10-10 04:49:42 +04:00
xmlCharEncoding enc ;
xmlSAXHandlerPtr sax ;
void * user_data ;
2002-04-16 19:50:10 +04:00
2003-10-10 04:49:42 +04:00
xmlDocPtr myDoc ;
int err ;
int nberrors ;
2002-04-16 19:50:10 +04:00
2003-10-10 04:49:42 +04:00
xmlNodePtr node ;
xmlNodePtr cur ;
xmlSchemaTypePtr type ;
2002-04-16 19:50:10 +04:00
2003-10-10 04:49:42 +04:00
xmlRegExecCtxtPtr regexp ;
xmlSchemaValPtr value ;
2002-04-16 19:50:10 +04:00
2003-10-10 04:49:42 +04:00
int attrNr ;
int attrBase ;
int attrMax ;
xmlSchemaAttrStatePtr attr ;
2002-04-16 19:50:10 +04:00
} ;
2003-11-21 03:28:39 +03:00
/*
* These are the entries in the schemas importSchemas hash table
*/
typedef struct _xmlSchemaImport xmlSchemaImport ;
typedef xmlSchemaImport * xmlSchemaImportPtr ;
struct _xmlSchemaImport {
const xmlChar * schemaLocation ;
xmlSchemaPtr schema ;
} ;
2002-04-16 19:50:10 +04:00
2003-11-25 18:38:59 +03:00
/*
* These are the entries associated to includes in a schemas
*/
typedef struct _xmlSchemaInclude xmlSchemaInclude ;
typedef xmlSchemaInclude * xmlSchemaIncludePtr ;
struct _xmlSchemaInclude {
xmlSchemaIncludePtr next ;
const xmlChar * schemaLocation ;
xmlDocPtr doc ;
} ;
2002-04-16 19:50:10 +04:00
/************************************************************************
* *
* Some predeclarations *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-10-10 04:49:42 +04:00
static int xmlSchemaValidateSimpleValue ( xmlSchemaValidCtxtPtr ctxt ,
xmlSchemaTypePtr type ,
2003-11-22 23:37:51 +03:00
const xmlChar * value ) ;
2003-10-10 04:49:42 +04:00
2003-11-25 18:38:59 +03:00
static int xmlSchemaParseInclude ( xmlSchemaParserCtxtPtr ctxt ,
xmlSchemaPtr schema ,
xmlNodePtr node ) ;
2004-04-17 18:58:15 +04:00
static int
xmlSchemaValidateSimpleValueInternal ( xmlSchemaValidCtxtPtr ctxt ,
xmlSchemaTypePtr type ,
const xmlChar * value ,
int fireErrors ) ;
2003-10-10 04:49:42 +04:00
/************************************************************************
* *
* Datatype error handlers *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlSchemaPErrMemory :
* @ node : a context node
* @ extra : extra informations
*
* Handle an out of memory condition
*/
static void
xmlSchemaPErrMemory ( xmlSchemaParserCtxtPtr ctxt ,
const char * extra , xmlNodePtr node )
{
if ( ctxt ! = NULL )
ctxt - > nberrors + + ;
__xmlSimpleError ( XML_FROM_SCHEMASP , XML_ERR_NO_MEMORY , node , NULL ,
extra ) ;
}
/**
* xmlSchemaPErr :
* @ ctxt : the parsing context
* @ node : the context node
* @ error : the error code
* @ msg : the error message
* @ str1 : extra data
* @ str2 : extra data
*
* Handle a parser error
*/
static void
xmlSchemaPErr ( xmlSchemaParserCtxtPtr ctxt , xmlNodePtr node , int error ,
const char * msg , const xmlChar * str1 , const xmlChar * str2 )
{
xmlGenericErrorFunc channel = NULL ;
2003-10-10 18:10:40 +04:00
xmlStructuredErrorFunc schannel = NULL ;
2003-10-10 04:49:42 +04:00
void * data = NULL ;
if ( ctxt ! = NULL ) {
ctxt - > nberrors + + ;
channel = ctxt - > error ;
data = ctxt - > userData ;
2003-10-10 18:10:40 +04:00
schannel = ctxt - > serror ;
2003-10-10 04:49:42 +04:00
}
2003-10-10 18:10:40 +04:00
__xmlRaiseError ( schannel , channel , data , ctxt , node , XML_FROM_SCHEMASP ,
2003-10-10 04:49:42 +04:00
error , XML_ERR_ERROR , NULL , 0 ,
( const char * ) str1 , ( const char * ) str2 , NULL , 0 , 0 ,
msg , str1 , str2 ) ;
}
/**
* xmlSchemaPErr2 :
* @ ctxt : the parsing context
* @ node : the context node
* @ node : the current child
* @ error : the error code
* @ msg : the error message
* @ str1 : extra data
* @ str2 : extra data
*
* Handle a parser error
*/
static void
xmlSchemaPErr2 ( xmlSchemaParserCtxtPtr ctxt , xmlNodePtr node ,
xmlNodePtr child , int error ,
const char * msg , const xmlChar * str1 , const xmlChar * str2 )
{
if ( child ! = NULL )
xmlSchemaPErr ( ctxt , child , error , msg , str1 , str2 ) ;
else
xmlSchemaPErr ( ctxt , node , error , msg , str1 , str2 ) ;
}
/**
* xmlSchemaVTypeErrMemory :
* @ node : a context node
* @ extra : extra informations
*
* Handle an out of memory condition
*/
static void
xmlSchemaVErrMemory ( xmlSchemaValidCtxtPtr ctxt ,
const char * extra , xmlNodePtr node )
{
if ( ctxt ! = NULL ) {
ctxt - > nberrors + + ;
ctxt - > err = XML_SCHEMAS_ERR_INTERNAL ;
}
__xmlSimpleError ( XML_FROM_SCHEMASV , XML_ERR_NO_MEMORY , node , NULL ,
extra ) ;
}
/**
* xmlSchemaVErr3 :
* @ ctxt : the validation context
* @ node : the context node
* @ error : the error code
* @ msg : the error message
* @ str1 : extra data
* @ str2 : extra data
* @ str3 : extra data
*
* Handle a validation error
*/
static void
xmlSchemaVErr3 ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr node , int error ,
const char * msg , const xmlChar * str1 , const xmlChar * str2 ,
const xmlChar * str3 )
{
2003-10-10 18:10:40 +04:00
xmlStructuredErrorFunc schannel = NULL ;
2003-10-10 04:49:42 +04:00
xmlGenericErrorFunc channel = NULL ;
void * data = NULL ;
if ( ctxt ! = NULL ) {
ctxt - > nberrors + + ;
ctxt - > err = error ;
channel = ctxt - > error ;
2003-10-10 18:10:40 +04:00
schannel = ctxt - > serror ;
2003-10-10 04:49:42 +04:00
data = ctxt - > userData ;
}
/* reajust to global error numbers */
error + = XML_SCHEMAV_NOROOT - XML_SCHEMAS_ERR_NOROOT ;
2003-10-10 18:10:40 +04:00
__xmlRaiseError ( schannel , channel , data , ctxt , node , XML_FROM_SCHEMASV ,
2003-10-10 04:49:42 +04:00
error , XML_ERR_ERROR , NULL , 0 ,
( const char * ) str1 , ( const char * ) str2 ,
( const char * ) str3 , 0 , 0 ,
msg , str1 , str2 , str3 ) ;
}
/**
* xmlSchemaVErr :
* @ ctxt : the validation context
* @ node : the context node
* @ error : the error code
* @ msg : the error message
* @ str1 : extra data
* @ str2 : extra data
*
* Handle a validation error
*/
static void
xmlSchemaVErr ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr node , int error ,
const char * msg , const xmlChar * str1 , const xmlChar * str2 )
{
2003-10-10 18:10:40 +04:00
xmlStructuredErrorFunc schannel = NULL ;
2003-10-10 04:49:42 +04:00
xmlGenericErrorFunc channel = NULL ;
void * data = NULL ;
if ( ctxt ! = NULL ) {
ctxt - > nberrors + + ;
ctxt - > err = error ;
channel = ctxt - > error ;
data = ctxt - > userData ;
2003-10-10 18:10:40 +04:00
schannel = ctxt - > serror ;
2003-10-10 04:49:42 +04:00
}
/* reajust to global error numbers */
error + = XML_SCHEMAV_NOROOT - XML_SCHEMAS_ERR_NOROOT ;
2003-10-10 18:10:40 +04:00
__xmlRaiseError ( schannel , channel , data , ctxt , node , XML_FROM_SCHEMASV ,
2003-10-10 04:49:42 +04:00
error , XML_ERR_ERROR , NULL , 0 ,
( const char * ) str1 , ( const char * ) str2 , NULL , 0 , 0 ,
msg , str1 , str2 ) ;
}
2002-04-16 19:50:10 +04:00
/************************************************************************
* *
* Allocation functions *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlSchemaNewSchema :
2003-12-29 05:52:11 +03:00
* @ ctxt : a schema validation context
2002-04-16 19:50:10 +04:00
*
* Allocate a new Schema structure .
*
* Returns the newly allocated structure or NULL in case or error
*/
static xmlSchemaPtr
xmlSchemaNewSchema ( xmlSchemaParserCtxtPtr ctxt )
{
xmlSchemaPtr ret ;
ret = ( xmlSchemaPtr ) xmlMalloc ( sizeof ( xmlSchema ) ) ;
if ( ret = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErrMemory ( ctxt , " allocating schema " , NULL ) ;
2002-04-16 19:50:10 +04:00
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchema ) ) ;
2003-11-22 23:37:51 +03:00
ret - > dict = ctxt - > dict ;
2004-03-22 18:22:58 +03:00
xmlDictReference ( ret - > dict ) ;
2002-04-16 19:50:10 +04:00
return ( ret ) ;
}
/**
* xmlSchemaNewFacet :
*
* Allocate a new Facet structure .
*
* Returns the newly allocated structure or NULL in case or error
*/
2003-02-27 20:42:22 +03:00
xmlSchemaFacetPtr
xmlSchemaNewFacet ( void )
2002-04-16 19:50:10 +04:00
{
xmlSchemaFacetPtr ret ;
ret = ( xmlSchemaFacetPtr ) xmlMalloc ( sizeof ( xmlSchemaFacet ) ) ;
if ( ret = = NULL ) {
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaFacet ) ) ;
return ( ret ) ;
}
/**
* xmlSchemaNewAnnot :
2003-12-29 05:52:11 +03:00
* @ ctxt : a schema validation context
2002-04-16 19:50:10 +04:00
* @ node : a node
*
* Allocate a new annotation structure .
*
* Returns the newly allocated structure or NULL in case or error
*/
static xmlSchemaAnnotPtr
xmlSchemaNewAnnot ( xmlSchemaParserCtxtPtr ctxt , xmlNodePtr node )
{
xmlSchemaAnnotPtr ret ;
ret = ( xmlSchemaAnnotPtr ) xmlMalloc ( sizeof ( xmlSchemaAnnot ) ) ;
if ( ret = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErrMemory ( ctxt , " allocating annotation " , node ) ;
2002-04-16 19:50:10 +04:00
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaAnnot ) ) ;
ret - > content = node ;
return ( ret ) ;
}
2002-07-02 01:52:03 +04:00
/**
* xmlSchemaFreeAnnot :
* @ annot : a schema type structure
*
* Deallocate a annotation structure
*/
static void
xmlSchemaFreeAnnot ( xmlSchemaAnnotPtr annot )
{
if ( annot = = NULL )
return ;
xmlFree ( annot ) ;
}
2003-11-21 03:28:39 +03:00
/**
* xmlSchemaFreeImport :
* @ import : a schema import structure
*
* Deallocate an import structure
*/
static void
xmlSchemaFreeImport ( xmlSchemaImportPtr import )
{
if ( import = = NULL )
return ;
xmlSchemaFree ( import - > schema ) ;
xmlFree ( import ) ;
}
2003-11-25 18:38:59 +03:00
/**
* xmlSchemaFreeInclude :
* @ include : a schema include structure
*
* Deallocate an include structure
*/
static void
xmlSchemaFreeInclude ( xmlSchemaIncludePtr include )
{
if ( include = = NULL )
return ;
xmlFreeDoc ( include - > doc ) ;
xmlFree ( include ) ;
}
/**
* xmlSchemaFreeIncludeList :
* @ includes : a schema include list
*
* Deallocate an include structure
*/
static void
xmlSchemaFreeIncludeList ( xmlSchemaIncludePtr includes )
{
xmlSchemaIncludePtr next ;
while ( includes ! = NULL ) {
next = includes - > next ;
xmlSchemaFreeInclude ( includes ) ;
includes = next ;
}
}
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaFreeNotation :
* @ schema : a schema notation structure
*
* Deallocate a Schema Notation structure .
*/
static void
xmlSchemaFreeNotation ( xmlSchemaNotationPtr nota )
{
if ( nota = = NULL )
return ;
xmlFree ( nota ) ;
}
/**
* xmlSchemaFreeAttribute :
* @ schema : a schema attribute structure
*
* Deallocate a Schema Attribute structure .
*/
static void
xmlSchemaFreeAttribute ( xmlSchemaAttributePtr attr )
{
if ( attr = = NULL )
return ;
xmlFree ( attr ) ;
}
/**
* xmlSchemaFreeAttributeGroup :
* @ schema : a schema attribute group structure
*
* Deallocate a Schema Attribute Group structure .
*/
static void
xmlSchemaFreeAttributeGroup ( xmlSchemaAttributeGroupPtr attr )
{
if ( attr = = NULL )
return ;
xmlFree ( attr ) ;
}
/**
* xmlSchemaFreeElement :
* @ schema : a schema element structure
*
* Deallocate a Schema Element structure .
*/
static void
xmlSchemaFreeElement ( xmlSchemaElementPtr elem )
{
if ( elem = = NULL )
return ;
2002-10-16 18:08:14 +04:00
if ( elem - > annot ! = NULL )
xmlSchemaFreeAnnot ( elem - > annot ) ;
2002-04-16 19:50:10 +04:00
if ( elem - > contModel ! = NULL )
2003-10-10 04:49:42 +04:00
xmlRegFreeRegexp ( elem - > contModel ) ;
2002-04-16 19:50:10 +04:00
xmlFree ( elem ) ;
}
/**
* xmlSchemaFreeFacet :
* @ facet : a schema facet structure
*
* Deallocate a Schema Facet structure .
*/
2003-02-27 20:42:22 +03:00
void
2002-04-16 19:50:10 +04:00
xmlSchemaFreeFacet ( xmlSchemaFacetPtr facet )
{
if ( facet = = NULL )
return ;
if ( facet - > val ! = NULL )
2003-10-10 04:49:42 +04:00
xmlSchemaFreeValue ( facet - > val ) ;
2002-04-16 19:50:10 +04:00
if ( facet - > regexp ! = NULL )
2003-10-10 04:49:42 +04:00
xmlRegFreeRegexp ( facet - > regexp ) ;
2002-07-02 01:52:03 +04:00
if ( facet - > annot ! = NULL )
2003-10-10 04:49:42 +04:00
xmlSchemaFreeAnnot ( facet - > annot ) ;
2002-04-16 19:50:10 +04:00
xmlFree ( facet ) ;
}
/**
* xmlSchemaFreeType :
* @ type : a schema type structure
*
* Deallocate a Schema Type structure .
*/
void
xmlSchemaFreeType ( xmlSchemaTypePtr type )
{
if ( type = = NULL )
return ;
if ( type - > annot ! = NULL )
2002-10-16 18:08:14 +04:00
xmlSchemaFreeAnnot ( type - > annot ) ;
2002-04-16 19:50:10 +04:00
if ( type - > facets ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaFacetPtr facet , next ;
2002-04-16 19:50:10 +04:00
2003-10-10 04:49:42 +04:00
facet = type - > facets ;
while ( facet ! = NULL ) {
next = facet - > next ;
xmlSchemaFreeFacet ( facet ) ;
facet = next ;
}
2002-04-16 19:50:10 +04:00
}
xmlFree ( type ) ;
}
2003-12-24 02:30:53 +03:00
/**
* xmlSchemaFreeTypeList :
* @ type : a schema type structure
*
* Deallocate a Schema Type structure .
*/
static void
xmlSchemaFreeTypeList ( xmlSchemaTypePtr type )
{
xmlSchemaTypePtr next ;
while ( type ! = NULL ) {
next = type - > redef ;
xmlSchemaFreeType ( type ) ;
type = next ;
}
}
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaFree :
* @ schema : a schema structure
*
* Deallocate a Schema structure .
*/
void
xmlSchemaFree ( xmlSchemaPtr schema )
{
if ( schema = = NULL )
return ;
if ( schema - > notaDecl ! = NULL )
xmlHashFree ( schema - > notaDecl ,
( xmlHashDeallocator ) xmlSchemaFreeNotation ) ;
if ( schema - > attrDecl ! = NULL )
xmlHashFree ( schema - > attrDecl ,
( xmlHashDeallocator ) xmlSchemaFreeAttribute ) ;
if ( schema - > attrgrpDecl ! = NULL )
xmlHashFree ( schema - > attrgrpDecl ,
( xmlHashDeallocator ) xmlSchemaFreeAttributeGroup ) ;
if ( schema - > elemDecl ! = NULL )
xmlHashFree ( schema - > elemDecl ,
( xmlHashDeallocator ) xmlSchemaFreeElement ) ;
if ( schema - > typeDecl ! = NULL )
xmlHashFree ( schema - > typeDecl ,
2003-12-24 02:30:53 +03:00
( xmlHashDeallocator ) xmlSchemaFreeTypeList ) ;
2003-06-02 20:58:46 +04:00
if ( schema - > groupDecl ! = NULL )
xmlHashFree ( schema - > groupDecl ,
( xmlHashDeallocator ) xmlSchemaFreeType ) ;
2003-11-21 03:28:39 +03:00
if ( schema - > schemasImports ! = NULL )
xmlHashFree ( schema - > schemasImports ,
( xmlHashDeallocator ) xmlSchemaFreeImport ) ;
2003-11-25 18:38:59 +03:00
if ( schema - > includes ! = NULL ) {
xmlSchemaFreeIncludeList ( ( xmlSchemaIncludePtr ) schema - > includes ) ;
}
2002-04-16 19:50:10 +04:00
if ( schema - > annot ! = NULL )
2003-10-10 04:49:42 +04:00
xmlSchemaFreeAnnot ( schema - > annot ) ;
2004-01-24 11:31:30 +03:00
if ( schema - > doc ! = NULL & & ! schema - > preserve )
2003-10-10 04:49:42 +04:00
xmlFreeDoc ( schema - > doc ) ;
2003-11-22 23:37:51 +03:00
xmlDictFree ( schema - > dict ) ;
2002-04-16 19:50:10 +04:00
xmlFree ( schema ) ;
}
/************************************************************************
* *
* Debug functions *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2003-10-10 04:49:42 +04:00
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaElementDump :
* @ elem : an element
* @ output : the file output
*
* Dump the element
*/
static void
xmlSchemaElementDump ( xmlSchemaElementPtr elem , FILE * output ,
2003-10-10 04:49:42 +04:00
const xmlChar * name ATTRIBUTE_UNUSED ,
const xmlChar * context ATTRIBUTE_UNUSED ,
const xmlChar * namespace ATTRIBUTE_UNUSED )
2002-04-16 19:50:10 +04:00
{
if ( elem = = NULL )
return ;
fprintf ( output , " Element " ) ;
if ( elem - > flags & XML_SCHEMAS_ELEM_TOPLEVEL )
2003-10-10 04:49:42 +04:00
fprintf ( output , " toplevel " ) ;
2002-04-16 19:50:10 +04:00
fprintf ( output , " : %s " , elem - > name ) ;
if ( namespace ! = NULL )
2003-10-10 04:49:42 +04:00
fprintf ( output , " namespace '%s' " , namespace ) ;
2002-04-16 19:50:10 +04:00
if ( elem - > flags & XML_SCHEMAS_ELEM_NILLABLE )
2003-10-10 04:49:42 +04:00
fprintf ( output , " nillable " ) ;
2002-04-16 19:50:10 +04:00
if ( elem - > flags & XML_SCHEMAS_ELEM_GLOBAL )
2003-10-10 04:49:42 +04:00
fprintf ( output , " global " ) ;
2002-04-16 19:50:10 +04:00
if ( elem - > flags & XML_SCHEMAS_ELEM_DEFAULT )
2003-10-10 04:49:42 +04:00
fprintf ( output , " default " ) ;
2002-04-16 19:50:10 +04:00
if ( elem - > flags & XML_SCHEMAS_ELEM_FIXED )
2003-10-10 04:49:42 +04:00
fprintf ( output , " fixed " ) ;
2002-04-16 19:50:10 +04:00
if ( elem - > flags & XML_SCHEMAS_ELEM_ABSTRACT )
2003-10-10 04:49:42 +04:00
fprintf ( output , " abstract " ) ;
2002-04-16 19:50:10 +04:00
if ( elem - > flags & XML_SCHEMAS_ELEM_REF )
2003-10-10 04:49:42 +04:00
fprintf ( output , " ref '%s' " , elem - > ref ) ;
2002-04-16 19:50:10 +04:00
if ( elem - > id ! = NULL )
2003-10-10 04:49:42 +04:00
fprintf ( output , " id '%s' " , elem - > id ) ;
2002-04-16 19:50:10 +04:00
fprintf ( output , " \n " ) ;
if ( ( elem - > minOccurs ! = 1 ) | | ( elem - > maxOccurs ! = 1 ) ) {
2003-10-10 04:49:42 +04:00
fprintf ( output , " " ) ;
if ( elem - > minOccurs ! = 1 )
fprintf ( output , " min: %d " , elem - > minOccurs ) ;
if ( elem - > maxOccurs > = UNBOUNDED )
fprintf ( output , " max: unbounded \n " ) ;
else if ( elem - > maxOccurs ! = 1 )
fprintf ( output , " max: %d \n " , elem - > maxOccurs ) ;
else
fprintf ( output , " \n " ) ;
2002-04-16 19:50:10 +04:00
}
if ( elem - > namedType ! = NULL ) {
2003-10-10 04:49:42 +04:00
fprintf ( output , " type: %s " , elem - > namedType ) ;
if ( elem - > namedTypeNs ! = NULL )
fprintf ( output , " ns %s \n " , elem - > namedTypeNs ) ;
else
fprintf ( output , " \n " ) ;
2002-04-16 19:50:10 +04:00
}
if ( elem - > substGroup ! = NULL ) {
2003-10-10 04:49:42 +04:00
fprintf ( output , " substitutionGroup: %s " , elem - > substGroup ) ;
if ( elem - > substGroupNs ! = NULL )
fprintf ( output , " ns %s \n " , elem - > substGroupNs ) ;
else
fprintf ( output , " \n " ) ;
2002-04-16 19:50:10 +04:00
}
if ( elem - > value ! = NULL )
2003-10-10 04:49:42 +04:00
fprintf ( output , " default: %s " , elem - > value ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaAnnotDump :
* @ output : the file output
* @ annot : a annotation
*
* Dump the annotation
*/
static void
xmlSchemaAnnotDump ( FILE * output , xmlSchemaAnnotPtr annot )
{
xmlChar * content ;
if ( annot = = NULL )
return ;
content = xmlNodeGetContent ( annot - > content ) ;
if ( content ! = NULL ) {
fprintf ( output , " Annot: %s \n " , content ) ;
xmlFree ( content ) ;
} else
fprintf ( output , " Annot: empty \n " ) ;
}
/**
* xmlSchemaTypeDump :
* @ output : the file output
* @ type : a type structure
*
* Dump a SchemaType structure
*/
static void
xmlSchemaTypeDump ( xmlSchemaTypePtr type , FILE * output )
{
if ( type = = NULL ) {
fprintf ( output , " Type: NULL \n " ) ;
return ;
}
fprintf ( output , " Type: " ) ;
if ( type - > name ! = NULL )
fprintf ( output , " %s, " , type - > name ) ;
else
fprintf ( output , " no name " ) ;
switch ( type - > type ) {
case XML_SCHEMA_TYPE_BASIC :
fprintf ( output , " basic " ) ;
break ;
case XML_SCHEMA_TYPE_SIMPLE :
fprintf ( output , " simple " ) ;
break ;
case XML_SCHEMA_TYPE_COMPLEX :
fprintf ( output , " complex " ) ;
break ;
case XML_SCHEMA_TYPE_SEQUENCE :
fprintf ( output , " sequence " ) ;
break ;
case XML_SCHEMA_TYPE_CHOICE :
fprintf ( output , " choice " ) ;
break ;
case XML_SCHEMA_TYPE_ALL :
fprintf ( output , " all " ) ;
break ;
case XML_SCHEMA_TYPE_UR :
fprintf ( output , " ur " ) ;
break ;
case XML_SCHEMA_TYPE_RESTRICTION :
fprintf ( output , " restriction " ) ;
break ;
case XML_SCHEMA_TYPE_EXTENSION :
fprintf ( output , " extension " ) ;
break ;
default :
fprintf ( output , " unknowntype%d " , type - > type ) ;
break ;
}
if ( type - > base ! = NULL ) {
2003-10-10 04:49:42 +04:00
fprintf ( output , " base %s, " , type - > base ) ;
2002-04-16 19:50:10 +04:00
}
switch ( type - > contentType ) {
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_CONTENT_UNKNOWN :
fprintf ( output , " unknown " ) ;
break ;
case XML_SCHEMA_CONTENT_EMPTY :
fprintf ( output , " empty " ) ;
break ;
case XML_SCHEMA_CONTENT_ELEMENTS :
fprintf ( output , " element " ) ;
break ;
case XML_SCHEMA_CONTENT_MIXED :
fprintf ( output , " mixed " ) ;
break ;
case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS :
fprintf ( output , " mixed_or_elems " ) ;
break ;
case XML_SCHEMA_CONTENT_BASIC :
fprintf ( output , " basic " ) ;
break ;
case XML_SCHEMA_CONTENT_SIMPLE :
fprintf ( output , " simple " ) ;
break ;
case XML_SCHEMA_CONTENT_ANY :
fprintf ( output , " any " ) ;
break ;
2002-04-16 19:50:10 +04:00
}
fprintf ( output , " \n " ) ;
if ( ( type - > minOccurs ! = 1 ) | | ( type - > maxOccurs ! = 1 ) ) {
2003-10-10 04:49:42 +04:00
fprintf ( output , " " ) ;
if ( type - > minOccurs ! = 1 )
fprintf ( output , " min: %d " , type - > minOccurs ) ;
if ( type - > maxOccurs > = UNBOUNDED )
fprintf ( output , " max: unbounded \n " ) ;
else if ( type - > maxOccurs ! = 1 )
fprintf ( output , " max: %d \n " , type - > maxOccurs ) ;
else
fprintf ( output , " \n " ) ;
2002-04-16 19:50:10 +04:00
}
if ( type - > annot ! = NULL )
xmlSchemaAnnotDump ( output , type - > annot ) ;
if ( type - > subtypes ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaTypePtr sub = type - > subtypes ;
2002-04-16 19:50:10 +04:00
2003-10-10 04:49:42 +04:00
fprintf ( output , " subtypes: " ) ;
while ( sub ! = NULL ) {
fprintf ( output , " %s " , sub - > name ) ;
sub = sub - > next ;
}
fprintf ( output , " \n " ) ;
2002-04-16 19:50:10 +04:00
}
}
/**
* xmlSchemaDump :
* @ output : the file output
* @ schema : a schema structure
*
* Dump a Schema structure .
*/
void
xmlSchemaDump ( FILE * output , xmlSchemaPtr schema )
{
if ( schema = = NULL ) {
fprintf ( output , " Schemas: NULL \n " ) ;
return ;
}
fprintf ( output , " Schemas: " ) ;
if ( schema - > name ! = NULL )
fprintf ( output , " %s, " , schema - > name ) ;
else
fprintf ( output , " no name, " ) ;
if ( schema - > targetNamespace ! = NULL )
2003-03-22 00:22:48 +03:00
fprintf ( output , " %s " , ( const char * ) schema - > targetNamespace ) ;
2002-04-16 19:50:10 +04:00
else
fprintf ( output , " no target namespace " ) ;
fprintf ( output , " \n " ) ;
if ( schema - > annot ! = NULL )
xmlSchemaAnnotDump ( output , schema - > annot ) ;
xmlHashScan ( schema - > typeDecl , ( xmlHashScanner ) xmlSchemaTypeDump ,
output ) ;
xmlHashScanFull ( schema - > elemDecl ,
2003-10-10 04:49:42 +04:00
( xmlHashScannerFull ) xmlSchemaElementDump , output ) ;
2002-04-16 19:50:10 +04:00
}
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2002-04-16 19:50:10 +04:00
2003-11-22 23:37:51 +03:00
/************************************************************************
* *
* Utilities *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlSchemaGetProp :
* @ ctxt : the parser context
* @ node : the node
* @ name : the property name
*
* Read a attribute value and internalize the string
*
* Returns the string or NULL if not present .
*/
static const xmlChar *
xmlSchemaGetProp ( xmlSchemaParserCtxtPtr ctxt , xmlNodePtr node ,
const char * name )
{
xmlChar * val ;
const xmlChar * ret ;
val = xmlGetProp ( node , BAD_CAST name ) ;
if ( val = = NULL )
return ( NULL ) ;
ret = xmlDictLookup ( ctxt - > dict , val , - 1 ) ;
xmlFree ( val ) ;
return ( ret ) ;
}
/**
* xmlSchemaGetNamespace :
* @ ctxt : the parser context
* @ schema : the schemas containing the declaration
* @ node : the node
* @ qname : the QName to analyze
*
* Find the namespace name for the given declaration .
*
* Returns the local name for that declaration , as well as the namespace name
*/
static const xmlChar *
xmlSchemaGetNamespace ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
xmlNodePtr node , const xmlChar * qname ,
const xmlChar * * namespace ) {
int len ;
const xmlChar * name , * prefix , * def = NULL ;
xmlNsPtr ns ;
* namespace = NULL ;
if ( xmlStrEqual ( node - > name , BAD_CAST " element " ) | |
xmlStrEqual ( node - > name , BAD_CAST " attribute " ) | |
xmlStrEqual ( node - > name , BAD_CAST " simpleType " ) | |
xmlStrEqual ( node - > name , BAD_CAST " complexType " ) ) {
def = xmlSchemaGetProp ( ctxt , node , " targetNamespace " ) ;
}
qname = xmlDictLookup ( ctxt - > dict , qname , - 1 ) ; /* intern the string */
name = xmlSplitQName3 ( qname , & len ) ;
if ( name = = NULL ) {
if ( def = = NULL ) {
if ( xmlStrEqual ( node - > name , BAD_CAST " element " ) ) {
if ( schema - > flags & XML_SCHEMAS_QUALIF_ELEM )
* namespace = schema - > targetNamespace ;
} else if ( xmlStrEqual ( node - > name , BAD_CAST " attribute " ) ) {
if ( schema - > flags & XML_SCHEMAS_QUALIF_ATTR )
* namespace = schema - > targetNamespace ;
} else if ( ( xmlStrEqual ( node - > name , BAD_CAST " simpleType " ) ) | |
( xmlStrEqual ( node - > name , BAD_CAST " complexType " ) ) ) {
* namespace = schema - > targetNamespace ;
}
} else {
* namespace = def ;
}
return ( qname ) ;
}
name = xmlDictLookup ( ctxt - > dict , name , - 1 ) ;
prefix = xmlDictLookup ( ctxt - > dict , qname , len ) ;
if ( def ! = NULL ) {
xmlSchemaPErr ( ctxt , node , XML_SCHEMAP_DEF_AND_PREFIX ,
" %s: presence of both prefix %s and targetNamespace \n " ,
node - > name , prefix ) ;
}
ns = xmlSearchNs ( node - > doc , node , prefix ) ;
if ( ns = = NULL ) {
xmlSchemaPErr ( ctxt , node , XML_SCHEMAP_PREFIX_UNDEFINED ,
" %s: the QName prefix %s is undefined \n " ,
node - > name , prefix ) ;
return ( name ) ;
}
* namespace = xmlDictLookup ( ctxt - > dict , ns - > href , - 1 ) ;
return ( name ) ;
}
2002-04-16 19:50:10 +04:00
/************************************************************************
* *
* Parsing functions *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-11-22 23:37:51 +03:00
/**
* xmlSchemaGetElem :
* @ schema : the schemas context
* @ name : the element name
* @ ns : the element namespace
2003-11-24 16:04:35 +03:00
* @ level : how deep is the request
2003-11-22 23:37:51 +03:00
*
* Lookup a an element in the schemas or the accessible schemas
*
* Returns the element definition or NULL if not found .
*/
static xmlSchemaElementPtr
xmlSchemaGetElem ( xmlSchemaPtr schema , const xmlChar * name ,
2003-11-24 16:04:35 +03:00
const xmlChar * namespace , int level )
2003-11-22 23:37:51 +03:00
{
xmlSchemaElementPtr ret ;
2003-11-24 16:04:35 +03:00
xmlSchemaImportPtr import = NULL ;
2003-11-22 23:37:51 +03:00
if ( ( name = = NULL ) | | ( schema = = NULL ) )
return ( NULL ) ;
if ( namespace = = NULL ) {
ret = xmlHashLookup2 ( schema - > elemDecl , name , namespace ) ;
2003-11-24 16:04:35 +03:00
if ( ( ret ! = NULL ) & &
( ( level = = 0 ) | | ( ret - > flags & XML_SCHEMAS_ELEM_TOPLEVEL ) ) ) {
2003-11-22 23:37:51 +03:00
return ( ret ) ;
2003-11-24 16:04:35 +03:00
}
2003-11-22 23:37:51 +03:00
} else if ( ( schema - > flags & XML_SCHEMAS_QUALIF_ELEM ) = = 0 ) {
if ( xmlStrEqual ( namespace , schema - > targetNamespace ) )
ret = xmlHashLookup2 ( schema - > elemDecl , name , NULL ) ;
else
ret = xmlHashLookup2 ( schema - > elemDecl , name , namespace ) ;
2003-11-24 16:04:35 +03:00
if ( ( ret ! = NULL ) & &
( ( level = = 0 ) | | ( ret - > flags & XML_SCHEMAS_ELEM_TOPLEVEL ) ) ) {
2003-11-22 23:37:51 +03:00
return ( ret ) ;
2003-11-24 16:04:35 +03:00
}
2003-11-22 23:37:51 +03:00
} else {
ret = xmlHashLookup2 ( schema - > elemDecl , name , namespace ) ;
2003-11-24 16:04:35 +03:00
if ( ( ret ! = NULL ) & &
( ( level = = 0 ) | | ( ret - > flags & XML_SCHEMAS_ELEM_TOPLEVEL ) ) ) {
2003-11-22 23:37:51 +03:00
return ( ret ) ;
2003-11-24 16:04:35 +03:00
}
2003-11-22 23:37:51 +03:00
}
2003-11-24 16:04:35 +03:00
if ( level > 0 )
2003-11-22 23:37:51 +03:00
import = xmlHashLookup ( schema - > schemasImports , namespace ) ;
if ( import ! = NULL )
2003-11-24 16:04:35 +03:00
ret = xmlSchemaGetElem ( import - > schema , name , namespace , level + 1 ) ;
2003-11-22 23:37:51 +03:00
# ifdef DEBUG
if ( ret = = NULL ) {
if ( namespace = = NULL )
fprintf ( stderr , " Unable to lookup type %s " , name ) ;
else
fprintf ( stderr , " Unable to lookup type %s:%s " , name ,
namespace ) ;
}
# endif
return ( ret ) ;
}
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaGetType :
* @ schema : the schemas context
* @ name : the type name
* @ ns : the type namespace
*
* Lookup a type in the schemas or the predefined types
*
2003-06-02 20:58:46 +04:00
* Returns the group definition or NULL if not found .
2002-04-16 19:50:10 +04:00
*/
static xmlSchemaTypePtr
xmlSchemaGetType ( xmlSchemaPtr schema , const xmlChar * name ,
2003-10-10 04:49:42 +04:00
const xmlChar * namespace )
{
2002-04-16 19:50:10 +04:00
xmlSchemaTypePtr ret ;
2003-11-21 03:28:39 +03:00
xmlSchemaImportPtr import ;
2002-04-16 19:50:10 +04:00
if ( name = = NULL )
2003-10-10 04:49:42 +04:00
return ( NULL ) ;
2002-04-16 19:50:10 +04:00
if ( schema ! = NULL ) {
2003-10-10 04:49:42 +04:00
ret = xmlHashLookup2 ( schema - > typeDecl , name , namespace ) ;
if ( ret ! = NULL )
return ( ret ) ;
2002-04-16 19:50:10 +04:00
}
ret = xmlSchemaGetPredefinedType ( name , namespace ) ;
2003-11-21 03:28:39 +03:00
if ( ret ! = NULL )
return ( ret ) ;
import = xmlHashLookup ( schema - > schemasImports , namespace ) ;
if ( import ! = NULL )
ret = xmlSchemaGetType ( import - > schema , name , namespace ) ;
2002-04-16 19:50:10 +04:00
# ifdef DEBUG
if ( ret = = NULL ) {
2003-10-10 04:49:42 +04:00
if ( namespace = = NULL )
fprintf ( stderr , " Unable to lookup type %s " , name ) ;
else
fprintf ( stderr , " Unable to lookup type %s:%s " , name ,
namespace ) ;
2002-04-16 19:50:10 +04:00
}
# endif
2003-10-10 04:49:42 +04:00
return ( ret ) ;
2002-04-16 19:50:10 +04:00
}
/************************************************************************
* *
* Parsing functions *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define IS_BLANK_NODE(n) \
( ( ( n ) - > type = = XML_TEXT_NODE ) & & ( xmlSchemaIsBlank ( ( n ) - > content ) ) )
/**
* xmlSchemaIsBlank :
* @ str : a string
*
* Check if a string is ignorable
*
* Returns 1 if the string is NULL or made of blanks chars , 0 otherwise
*/
static int
2003-10-10 04:49:42 +04:00
xmlSchemaIsBlank ( xmlChar * str )
{
2002-04-16 19:50:10 +04:00
if ( str = = NULL )
2003-10-10 04:49:42 +04:00
return ( 1 ) ;
2002-04-16 19:50:10 +04:00
while ( * str ! = 0 ) {
2003-10-18 20:20:14 +04:00
if ( ! ( IS_BLANK_CH ( * str ) ) )
2003-10-10 04:49:42 +04:00
return ( 0 ) ;
str + + ;
2002-04-16 19:50:10 +04:00
}
2003-10-10 04:49:42 +04:00
return ( 1 ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaAddNotation :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ name : the item name
*
* Add an XML schema Attrribute declaration
* * WARNING * this interface is highly subject to change
*
* Returns the new struture or NULL in case of error
*/
static xmlSchemaNotationPtr
xmlSchemaAddNotation ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
2003-10-10 04:49:42 +04:00
const xmlChar * name )
2002-04-16 19:50:10 +04:00
{
xmlSchemaNotationPtr ret = NULL ;
int val ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( name = = NULL ) )
return ( NULL ) ;
if ( schema - > notaDecl = = NULL )
schema - > notaDecl = xmlHashCreate ( 10 ) ;
if ( schema - > notaDecl = = NULL )
return ( NULL ) ;
ret = ( xmlSchemaNotationPtr ) xmlMalloc ( sizeof ( xmlSchemaNotation ) ) ;
if ( ret = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErrMemory ( ctxt , " add annotation " , NULL ) ;
2002-04-16 19:50:10 +04:00
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaNotation ) ) ;
2003-11-22 23:37:51 +03:00
ret - > name = xmlDictLookup ( ctxt - > dict , name , - 1 ) ;
2002-04-16 19:50:10 +04:00
val = xmlHashAddEntry2 ( schema - > notaDecl , name , schema - > targetNamespace ,
ret ) ;
if ( val ! = 0 ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr ( ctxt , ( xmlNodePtr ) ctxt - > doc ,
XML_SCHEMAP_REDEFINED_NOTATION ,
" Notation %s already defined \n " ,
name , NULL ) ;
2002-04-16 19:50:10 +04:00
xmlFree ( ret ) ;
return ( NULL ) ;
}
return ( ret ) ;
}
/**
* xmlSchemaAddAttribute :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ name : the item name
2003-11-22 23:37:51 +03:00
* @ namespace : the namespace
2002-04-16 19:50:10 +04:00
*
* Add an XML schema Attrribute declaration
* * WARNING * this interface is highly subject to change
*
* Returns the new struture or NULL in case of error
*/
static xmlSchemaAttributePtr
xmlSchemaAddAttribute ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
2003-11-22 23:37:51 +03:00
const xmlChar * name , const xmlChar * namespace )
2002-04-16 19:50:10 +04:00
{
xmlSchemaAttributePtr ret = NULL ;
int val ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( name = = NULL ) )
return ( NULL ) ;
2003-11-22 23:37:51 +03:00
# ifdef DEBUG
fprintf ( stderr , " Adding attribute %s \n " , name ) ;
if ( namespace ! = NULL )
fprintf ( stderr , " target namespace %s \n " , namespace ) ;
# endif
2002-04-16 19:50:10 +04:00
if ( schema - > attrDecl = = NULL )
schema - > attrDecl = xmlHashCreate ( 10 ) ;
if ( schema - > attrDecl = = NULL )
return ( NULL ) ;
ret = ( xmlSchemaAttributePtr ) xmlMalloc ( sizeof ( xmlSchemaAttribute ) ) ;
if ( ret = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErrMemory ( ctxt , " allocating attribute " , NULL ) ;
2002-04-16 19:50:10 +04:00
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaAttribute ) ) ;
2003-11-22 23:37:51 +03:00
ret - > name = xmlDictLookup ( ctxt - > dict , name , - 1 ) ;
ret - > targetNamespace = xmlDictLookup ( ctxt - > dict , namespace , - 1 ) ;
2002-04-16 19:50:10 +04:00
val = xmlHashAddEntry3 ( schema - > attrDecl , name ,
2003-10-10 04:49:42 +04:00
schema - > targetNamespace , ctxt - > container , ret ) ;
2002-04-16 19:50:10 +04:00
if ( val ! = 0 ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr ( ctxt , ( xmlNodePtr ) ctxt - > doc ,
XML_SCHEMAP_REDEFINED_ATTR ,
" Attribute %s already defined \n " ,
name , NULL ) ;
2002-04-16 19:50:10 +04:00
xmlFree ( ret ) ;
return ( NULL ) ;
}
return ( ret ) ;
}
/**
* xmlSchemaAddAttributeGroup :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ name : the item name
*
* Add an XML schema Attrribute Group declaration
*
* Returns the new struture or NULL in case of error
*/
static xmlSchemaAttributeGroupPtr
2003-10-10 04:49:42 +04:00
xmlSchemaAddAttributeGroup ( xmlSchemaParserCtxtPtr ctxt ,
xmlSchemaPtr schema , const xmlChar * name )
2002-04-16 19:50:10 +04:00
{
xmlSchemaAttributeGroupPtr ret = NULL ;
int val ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( name = = NULL ) )
return ( NULL ) ;
if ( schema - > attrgrpDecl = = NULL )
schema - > attrgrpDecl = xmlHashCreate ( 10 ) ;
if ( schema - > attrgrpDecl = = NULL )
return ( NULL ) ;
2003-10-10 04:49:42 +04:00
ret =
( xmlSchemaAttributeGroupPtr )
xmlMalloc ( sizeof ( xmlSchemaAttributeGroup ) ) ;
2002-04-16 19:50:10 +04:00
if ( ret = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErrMemory ( ctxt , " allocating attribute group " , NULL ) ;
2002-04-16 19:50:10 +04:00
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaAttributeGroup ) ) ;
2003-11-22 23:37:51 +03:00
ret - > name = xmlDictLookup ( ctxt - > dict , name , - 1 ) ;
2002-04-16 19:50:10 +04:00
val = xmlHashAddEntry3 ( schema - > attrgrpDecl , name ,
2003-10-10 04:49:42 +04:00
schema - > targetNamespace , ctxt - > container , ret ) ;
2002-04-16 19:50:10 +04:00
if ( val ! = 0 ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr ( ctxt , ( xmlNodePtr ) ctxt - > doc ,
XML_SCHEMAP_REDEFINED_ATTRGROUP ,
" Attribute group %s already defined \n " ,
name , NULL ) ;
2002-04-16 19:50:10 +04:00
xmlFree ( ret ) ;
return ( NULL ) ;
}
return ( ret ) ;
}
/**
* xmlSchemaAddElement :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ name : the type name
* @ namespace : the type namespace
*
* Add an XML schema Element declaration
* * WARNING * this interface is highly subject to change
*
* Returns the new struture or NULL in case of error
*/
static xmlSchemaElementPtr
xmlSchemaAddElement ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
const xmlChar * name , const xmlChar * namespace )
{
xmlSchemaElementPtr ret = NULL ;
int val ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( name = = NULL ) )
return ( NULL ) ;
2003-11-22 23:37:51 +03:00
# ifdef DEBUG
fprintf ( stderr , " Adding element %s \n " , name ) ;
if ( namespace ! = NULL )
fprintf ( stderr , " target namespace %s \n " , namespace ) ;
# endif
2002-04-16 19:50:10 +04:00
if ( schema - > elemDecl = = NULL )
schema - > elemDecl = xmlHashCreate ( 10 ) ;
if ( schema - > elemDecl = = NULL )
return ( NULL ) ;
ret = ( xmlSchemaElementPtr ) xmlMalloc ( sizeof ( xmlSchemaElement ) ) ;
if ( ret = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErrMemory ( ctxt , " allocating element " , NULL ) ;
2002-04-16 19:50:10 +04:00
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaElement ) ) ;
2003-11-22 23:37:51 +03:00
ret - > name = xmlDictLookup ( ctxt - > dict , name , - 1 ) ;
ret - > targetNamespace = xmlDictLookup ( ctxt - > dict , namespace , - 1 ) ;
2002-04-16 19:50:10 +04:00
val = xmlHashAddEntry3 ( schema - > elemDecl , name ,
2003-10-10 04:49:42 +04:00
namespace , ctxt - > container , ret ) ;
2002-04-16 19:50:10 +04:00
if ( val ! = 0 ) {
2003-10-10 04:49:42 +04:00
char buf [ 100 ] ;
2003-11-22 23:37:51 +03:00
snprintf ( buf , 99 , " privatieelem %d " , ctxt - > counter + + + 1 ) ;
2003-10-10 04:49:42 +04:00
val = xmlHashAddEntry3 ( schema - > elemDecl , name , ( xmlChar * ) buf ,
namespace , ret ) ;
if ( val ! = 0 ) {
xmlSchemaPErr ( ctxt , ( xmlNodePtr ) ctxt - > doc ,
XML_SCHEMAP_REDEFINED_ELEMENT ,
" Element %s already defined \n " ,
name , NULL ) ;
xmlFree ( ret ) ;
return ( NULL ) ;
}
2002-04-16 19:50:10 +04:00
}
return ( ret ) ;
}
/**
* xmlSchemaAddType :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ name : the item name
2003-11-22 23:37:51 +03:00
* @ namespace : the namespace
2002-04-16 19:50:10 +04:00
*
* Add an XML schema Simple Type definition
* * WARNING * this interface is highly subject to change
*
* Returns the new struture or NULL in case of error
*/
static xmlSchemaTypePtr
xmlSchemaAddType ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
2003-11-22 23:37:51 +03:00
const xmlChar * name , const xmlChar * namespace )
2002-04-16 19:50:10 +04:00
{
xmlSchemaTypePtr ret = NULL ;
int val ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( name = = NULL ) )
return ( NULL ) ;
2003-11-22 23:37:51 +03:00
# ifdef DEBUG
fprintf ( stderr , " Adding type %s \n " , name ) ;
if ( namespace ! = NULL )
fprintf ( stderr , " target namespace %s \n " , namespace ) ;
# endif
2002-04-16 19:50:10 +04:00
if ( schema - > typeDecl = = NULL )
schema - > typeDecl = xmlHashCreate ( 10 ) ;
if ( schema - > typeDecl = = NULL )
return ( NULL ) ;
ret = ( xmlSchemaTypePtr ) xmlMalloc ( sizeof ( xmlSchemaType ) ) ;
if ( ret = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErrMemory ( ctxt , " allocating type " , NULL ) ;
2002-04-16 19:50:10 +04:00
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaType ) ) ;
2003-11-22 23:37:51 +03:00
ret - > name = xmlDictLookup ( ctxt - > dict , name , - 1 ) ;
2003-12-24 02:30:53 +03:00
ret - > redef = NULL ;
2003-11-22 23:37:51 +03:00
val = xmlHashAddEntry2 ( schema - > typeDecl , name , namespace , ret ) ;
2002-04-16 19:50:10 +04:00
if ( val ! = 0 ) {
2003-12-24 02:30:53 +03:00
if ( ctxt - > includes = = 0 ) {
xmlSchemaPErr ( ctxt , ( xmlNodePtr ) ctxt - > doc ,
XML_SCHEMAP_REDEFINED_TYPE ,
" Type %s already defined \n " ,
name , NULL ) ;
xmlFree ( ret ) ;
return ( NULL ) ;
} else {
xmlSchemaTypePtr prev ;
prev = xmlHashLookup2 ( schema - > typeDecl , name , namespace ) ;
if ( prev = = NULL ) {
xmlSchemaPErr ( ctxt , ( xmlNodePtr ) ctxt - > doc ,
XML_ERR_INTERNAL_ERROR ,
" Internal error on type %s definition \n " ,
name , NULL ) ;
xmlFree ( ret ) ;
return ( NULL ) ;
}
ret - > redef = prev - > redef ;
prev - > redef = ret ;
}
2003-06-02 20:58:46 +04:00
}
ret - > minOccurs = 1 ;
ret - > maxOccurs = 1 ;
return ( ret ) ;
}
/**
* xmlSchemaAddGroup :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ name : the group name
*
* Add an XML schema Group definition
*
* Returns the new struture or NULL in case of error
*/
static xmlSchemaTypePtr
xmlSchemaAddGroup ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
2003-10-10 04:49:42 +04:00
const xmlChar * name )
2003-06-02 20:58:46 +04:00
{
xmlSchemaTypePtr ret = NULL ;
int val ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( name = = NULL ) )
return ( NULL ) ;
if ( schema - > groupDecl = = NULL )
schema - > groupDecl = xmlHashCreate ( 10 ) ;
if ( schema - > groupDecl = = NULL )
return ( NULL ) ;
ret = ( xmlSchemaTypePtr ) xmlMalloc ( sizeof ( xmlSchemaType ) ) ;
if ( ret = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErrMemory ( ctxt , " adding group " , NULL ) ;
2003-06-02 20:58:46 +04:00
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaType ) ) ;
2003-11-22 23:37:51 +03:00
ret - > name = xmlDictLookup ( ctxt - > dict , name , - 1 ) ;
2003-10-10 04:49:42 +04:00
val =
xmlHashAddEntry2 ( schema - > groupDecl , name , schema - > targetNamespace ,
ret ) ;
2003-06-02 20:58:46 +04:00
if ( val ! = 0 ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr ( ctxt , ( xmlNodePtr ) ctxt - > doc ,
XML_SCHEMAP_REDEFINED_GROUP ,
" Group %s already defined \n " ,
name , NULL ) ;
2002-04-16 19:50:10 +04:00
xmlFree ( ret ) ;
return ( NULL ) ;
}
ret - > minOccurs = 1 ;
ret - > maxOccurs = 1 ;
return ( ret ) ;
}
/************************************************************************
* *
* Utilities for parsing *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlGetQNameProp :
* @ ctxt : a schema validation context
* @ node : a subtree containing XML Schema informations
* @ name : the attribute name
* @ namespace : the result namespace if any
*
* Extract a QName Attribute value
*
* Returns the NCName or NULL if not found , and also update @ namespace
* with the namespace URI
*/
2003-11-22 23:37:51 +03:00
static const xmlChar *
2002-04-16 19:50:10 +04:00
xmlGetQNameProp ( xmlSchemaParserCtxtPtr ctxt , xmlNodePtr node ,
2003-11-22 23:37:51 +03:00
const char * name , const xmlChar * * namespace )
2003-10-10 04:49:42 +04:00
{
2003-11-22 23:37:51 +03:00
const xmlChar * val ;
2002-04-16 19:50:10 +04:00
xmlNsPtr ns ;
2003-11-22 23:37:51 +03:00
const xmlChar * ret , * prefix ;
int len ;
2002-04-16 19:50:10 +04:00
2003-11-22 23:37:51 +03:00
* namespace = NULL ;
val = xmlSchemaGetProp ( ctxt , node , name ) ;
2002-04-16 19:50:10 +04:00
if ( val = = NULL )
2003-10-10 04:49:42 +04:00
return ( NULL ) ;
2002-04-16 19:50:10 +04:00
2004-04-01 14:42:31 +04:00
if ( ! strchr ( ( char * ) val , ' : ' ) ) {
2004-03-05 03:15:50 +03:00
ns = xmlSearchNs ( node - > doc , node , 0 ) ;
if ( ns ) {
* namespace = xmlDictLookup ( ctxt - > dict , ns - > href , - 1 ) ;
return ( val ) ;
}
}
2003-11-22 23:37:51 +03:00
ret = xmlSplitQName3 ( val , & len ) ;
if ( ret = = NULL ) {
2003-10-10 04:49:42 +04:00
return ( val ) ;
2003-11-22 23:37:51 +03:00
}
ret = xmlDictLookup ( ctxt - > dict , ret , - 1 ) ;
prefix = xmlDictLookup ( ctxt - > dict , val , len ) ;
2002-04-16 19:50:10 +04:00
ns = xmlSearchNs ( node - > doc , node , prefix ) ;
if ( ns = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr ( ctxt , node , XML_SCHEMAP_PREFIX_UNDEFINED ,
" Attribute %s: the QName prefix %s is undefined \n " ,
( const xmlChar * ) name , prefix ) ;
2002-04-16 19:50:10 +04:00
} else {
2003-11-22 23:37:51 +03:00
* namespace = xmlDictLookup ( ctxt - > dict , ns - > href , - 1 ) ;
2002-04-16 19:50:10 +04:00
}
2003-10-10 04:49:42 +04:00
return ( ret ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlGetMaxOccurs :
* @ ctxt : a schema validation context
* @ node : a subtree containing XML Schema informations
*
* Get the maxOccurs property
*
* Returns the default if not found , or the value
*/
static int
2003-10-10 04:49:42 +04:00
xmlGetMaxOccurs ( xmlSchemaParserCtxtPtr ctxt , xmlNodePtr node )
{
2003-11-22 23:37:51 +03:00
const xmlChar * val , * cur ;
2002-04-16 19:50:10 +04:00
int ret = 0 ;
2003-11-22 23:37:51 +03:00
val = xmlSchemaGetProp ( ctxt , node , " maxOccurs " ) ;
2002-04-16 19:50:10 +04:00
if ( val = = NULL )
2003-10-10 04:49:42 +04:00
return ( 1 ) ;
2002-04-16 19:50:10 +04:00
if ( xmlStrEqual ( val , ( const xmlChar * ) " unbounded " ) ) {
2003-11-22 23:37:51 +03:00
return ( UNBOUNDED ) ; /* encoding it with -1 might be another option */
2002-04-16 19:50:10 +04:00
}
cur = val ;
2003-10-18 20:20:14 +04:00
while ( IS_BLANK_CH ( * cur ) )
2003-10-10 04:49:42 +04:00
cur + + ;
2002-04-16 19:50:10 +04:00
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
2003-10-10 04:49:42 +04:00
ret = ret * 10 + ( * cur - ' 0 ' ) ;
cur + + ;
2002-04-16 19:50:10 +04:00
}
2003-10-18 20:20:14 +04:00
while ( IS_BLANK_CH ( * cur ) )
2003-10-10 04:49:42 +04:00
cur + + ;
2002-04-16 19:50:10 +04:00
if ( * cur ! = 0 ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr ( ctxt , node , XML_SCHEMAP_INVALID_MAXOCCURS ,
" invalid value for maxOccurs: %s \n " , val , NULL ) ;
return ( 1 ) ;
2002-04-16 19:50:10 +04:00
}
2003-10-10 04:49:42 +04:00
return ( ret ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlGetMinOccurs :
* @ ctxt : a schema validation context
* @ node : a subtree containing XML Schema informations
*
* Get the minOccurs property
*
* Returns the default if not found , or the value
*/
static int
2003-10-10 04:49:42 +04:00
xmlGetMinOccurs ( xmlSchemaParserCtxtPtr ctxt , xmlNodePtr node )
{
2003-11-22 23:37:51 +03:00
const xmlChar * val , * cur ;
2002-04-16 19:50:10 +04:00
int ret = 0 ;
2003-11-22 23:37:51 +03:00
val = xmlSchemaGetProp ( ctxt , node , " minOccurs " ) ;
2002-04-16 19:50:10 +04:00
if ( val = = NULL )
2003-10-10 04:49:42 +04:00
return ( 1 ) ;
2002-04-16 19:50:10 +04:00
cur = val ;
2003-10-18 20:20:14 +04:00
while ( IS_BLANK_CH ( * cur ) )
2003-10-10 04:49:42 +04:00
cur + + ;
2002-04-16 19:50:10 +04:00
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
2003-10-10 04:49:42 +04:00
ret = ret * 10 + ( * cur - ' 0 ' ) ;
cur + + ;
2002-04-16 19:50:10 +04:00
}
2003-10-18 20:20:14 +04:00
while ( IS_BLANK_CH ( * cur ) )
2003-10-10 04:49:42 +04:00
cur + + ;
2002-04-16 19:50:10 +04:00
if ( * cur ! = 0 ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr ( ctxt , node , XML_SCHEMAP_INVALID_MINOCCURS ,
" invalid value for minOccurs: %s \n " , val , NULL ) ;
return ( 1 ) ;
2002-04-16 19:50:10 +04:00
}
2003-10-10 04:49:42 +04:00
return ( ret ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlGetBooleanProp :
* @ ctxt : a schema validation context
* @ node : a subtree containing XML Schema informations
* @ name : the attribute name
* @ def : the default value
*
* Get is a bolean property is set
*
* Returns the default if not found , 0 if found to be false ,
* 1 if found to be true
*/
static int
xmlGetBooleanProp ( xmlSchemaParserCtxtPtr ctxt , xmlNodePtr node ,
2003-10-10 04:49:42 +04:00
const char * name , int def )
{
2003-11-22 23:37:51 +03:00
const xmlChar * val ;
2002-04-16 19:50:10 +04:00
2003-11-22 23:37:51 +03:00
val = xmlSchemaGetProp ( ctxt , node , name ) ;
2002-04-16 19:50:10 +04:00
if ( val = = NULL )
2003-10-10 04:49:42 +04:00
return ( def ) ;
2002-04-16 19:50:10 +04:00
2003-10-10 04:49:42 +04:00
if ( xmlStrEqual ( val , BAD_CAST " true " ) )
def = 1 ;
else if ( xmlStrEqual ( val , BAD_CAST " false " ) )
def = 0 ;
2002-04-16 19:50:10 +04:00
else {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr ( ctxt , node , XML_SCHEMAP_INVALID_BOOLEAN ,
" Attribute %s: the value %s is not boolean \n " ,
( const xmlChar * ) name , val ) ;
2002-04-16 19:50:10 +04:00
}
2003-10-10 04:49:42 +04:00
return ( def ) ;
2002-04-16 19:50:10 +04:00
}
/************************************************************************
* *
* Shema extraction from an Infoset *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static xmlSchemaTypePtr xmlSchemaParseSimpleType ( xmlSchemaParserCtxtPtr
ctxt , xmlSchemaPtr schema ,
xmlNodePtr node ) ;
2003-10-10 04:49:42 +04:00
static xmlSchemaTypePtr xmlSchemaParseComplexType ( xmlSchemaParserCtxtPtr
ctxt ,
2002-04-16 19:50:10 +04:00
xmlSchemaPtr schema ,
xmlNodePtr node ) ;
2003-10-10 04:49:42 +04:00
static xmlSchemaTypePtr xmlSchemaParseRestriction ( xmlSchemaParserCtxtPtr
ctxt ,
2002-04-16 19:50:10 +04:00
xmlSchemaPtr schema ,
xmlNodePtr node ,
2003-10-10 04:49:42 +04:00
int simple ) ;
2002-04-16 19:50:10 +04:00
static xmlSchemaTypePtr xmlSchemaParseSequence ( xmlSchemaParserCtxtPtr ctxt ,
xmlSchemaPtr schema ,
xmlNodePtr node ) ;
static xmlSchemaTypePtr xmlSchemaParseAll ( xmlSchemaParserCtxtPtr ctxt ,
xmlSchemaPtr schema ,
xmlNodePtr node ) ;
static xmlSchemaAttributePtr xmlSchemaParseAttribute ( xmlSchemaParserCtxtPtr
ctxt ,
xmlSchemaPtr schema ,
xmlNodePtr node ) ;
static xmlSchemaAttributeGroupPtr
xmlSchemaParseAttributeGroup ( xmlSchemaParserCtxtPtr ctxt ,
xmlSchemaPtr schema , xmlNodePtr node ) ;
static xmlSchemaTypePtr xmlSchemaParseChoice ( xmlSchemaParserCtxtPtr ctxt ,
xmlSchemaPtr schema ,
xmlNodePtr node ) ;
static xmlSchemaTypePtr xmlSchemaParseList ( xmlSchemaParserCtxtPtr ctxt ,
xmlSchemaPtr schema ,
xmlNodePtr node ) ;
static xmlSchemaAttributePtr
2003-10-10 04:49:42 +04:00
xmlSchemaParseAnyAttribute ( xmlSchemaParserCtxtPtr ctxt ,
xmlSchemaPtr schema , xmlNodePtr node ) ;
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaParseAttrDecls :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
* @ type : the hosting type
*
* parse a XML schema attrDecls declaration corresponding to
* < ! ENTITY % attrDecls
* ' ( ( % attribute ; | % attributeGroup ; ) * , ( % anyAttribute ; ) ? ) ' >
*/
static xmlNodePtr
xmlSchemaParseAttrDecls ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
xmlNodePtr child , xmlSchemaTypePtr type )
{
xmlSchemaAttributePtr lastattr , attr ;
lastattr = NULL ;
while ( ( IS_SCHEMA ( child , " attribute " ) ) | |
2003-10-10 04:49:42 +04:00
( IS_SCHEMA ( child , " attributeGroup " ) ) ) {
attr = NULL ;
if ( IS_SCHEMA ( child , " attribute " ) ) {
attr = xmlSchemaParseAttribute ( ctxt , schema , child ) ;
} else if ( IS_SCHEMA ( child , " attributeGroup " ) ) {
attr = ( xmlSchemaAttributePtr )
xmlSchemaParseAttributeGroup ( ctxt , schema , child ) ;
}
if ( attr ! = NULL ) {
if ( lastattr = = NULL ) {
type - > attributes = attr ;
lastattr = attr ;
} else {
lastattr - > next = attr ;
lastattr = attr ;
}
}
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( IS_SCHEMA ( child , " anyAttribute " ) ) {
2003-10-10 04:49:42 +04:00
attr = xmlSchemaParseAnyAttribute ( ctxt , schema , child ) ;
if ( attr ! = NULL ) {
if ( lastattr = = NULL ) {
type - > attributes = attr ;
lastattr = attr ;
} else {
lastattr - > next = attr ;
lastattr = attr ;
}
}
child = child - > next ;
}
return ( child ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaParseAnnotation :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema Attrribute declaration
* * WARNING * this interface is highly subject to change
*
* Returns - 1 in case of error , 0 if the declaration is inproper and
* 1 in case of success .
*/
static xmlSchemaAnnotPtr
xmlSchemaParseAnnotation ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
xmlNodePtr node )
{
xmlSchemaAnnotPtr ret ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
ret = xmlSchemaNewAnnot ( ctxt , node ) ;
return ( ret ) ;
}
/**
* xmlSchemaParseFacet :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema Facet declaration
* * WARNING * this interface is highly subject to change
*
* Returns the new type structure or NULL in case of error
*/
static xmlSchemaFacetPtr
xmlSchemaParseFacet ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
2003-10-10 04:49:42 +04:00
xmlNodePtr node )
2002-04-16 19:50:10 +04:00
{
xmlSchemaFacetPtr facet ;
xmlNodePtr child = NULL ;
2003-11-22 23:37:51 +03:00
const xmlChar * value ;
2002-04-16 19:50:10 +04:00
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
2003-02-27 20:42:22 +03:00
facet = xmlSchemaNewFacet ( ) ;
2003-10-10 04:49:42 +04:00
if ( facet = = NULL ) {
xmlSchemaPErrMemory ( ctxt , " allocating facet " , node ) ;
return ( NULL ) ;
}
2002-04-16 19:50:10 +04:00
facet - > node = node ;
2003-11-22 23:37:51 +03:00
value = xmlSchemaGetProp ( ctxt , node , " value " ) ;
2002-04-16 19:50:10 +04:00
if ( value = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child , XML_SCHEMAP_FACET_NO_VALUE ,
" Facet %s has no value \n " , node - > name , NULL ) ;
xmlSchemaFreeFacet ( facet ) ;
2002-04-16 19:50:10 +04:00
return ( NULL ) ;
}
2003-10-10 04:49:42 +04:00
if ( IS_SCHEMA ( node , " minInclusive " ) ) {
2002-04-16 19:50:10 +04:00
facet - > type = XML_SCHEMA_FACET_MININCLUSIVE ;
2003-10-10 04:49:42 +04:00
} else if ( IS_SCHEMA ( node , " minExclusive " ) ) {
2002-04-16 19:50:10 +04:00
facet - > type = XML_SCHEMA_FACET_MINEXCLUSIVE ;
2003-10-10 04:49:42 +04:00
} else if ( IS_SCHEMA ( node , " maxInclusive " ) ) {
2002-04-16 19:50:10 +04:00
facet - > type = XML_SCHEMA_FACET_MAXINCLUSIVE ;
2003-10-10 04:49:42 +04:00
} else if ( IS_SCHEMA ( node , " maxExclusive " ) ) {
2002-04-16 19:50:10 +04:00
facet - > type = XML_SCHEMA_FACET_MAXEXCLUSIVE ;
2003-10-10 04:49:42 +04:00
} else if ( IS_SCHEMA ( node , " totalDigits " ) ) {
2002-04-16 19:50:10 +04:00
facet - > type = XML_SCHEMA_FACET_TOTALDIGITS ;
2003-10-10 04:49:42 +04:00
} else if ( IS_SCHEMA ( node , " fractionDigits " ) ) {
2002-04-16 19:50:10 +04:00
facet - > type = XML_SCHEMA_FACET_FRACTIONDIGITS ;
2003-10-10 04:49:42 +04:00
} else if ( IS_SCHEMA ( node , " pattern " ) ) {
2002-04-16 19:50:10 +04:00
facet - > type = XML_SCHEMA_FACET_PATTERN ;
2003-10-10 04:49:42 +04:00
} else if ( IS_SCHEMA ( node , " enumeration " ) ) {
2002-04-16 19:50:10 +04:00
facet - > type = XML_SCHEMA_FACET_ENUMERATION ;
2003-10-10 04:49:42 +04:00
} else if ( IS_SCHEMA ( node , " whiteSpace " ) ) {
2002-04-16 19:50:10 +04:00
facet - > type = XML_SCHEMA_FACET_WHITESPACE ;
2003-10-10 04:49:42 +04:00
} else if ( IS_SCHEMA ( node , " length " ) ) {
2002-04-16 19:50:10 +04:00
facet - > type = XML_SCHEMA_FACET_LENGTH ;
2003-10-10 04:49:42 +04:00
} else if ( IS_SCHEMA ( node , " maxLength " ) ) {
2002-04-16 19:50:10 +04:00
facet - > type = XML_SCHEMA_FACET_MAXLENGTH ;
} else if ( IS_SCHEMA ( node , " minLength " ) ) {
facet - > type = XML_SCHEMA_FACET_MINLENGTH ;
} else {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child , XML_SCHEMAP_UNKNOWN_FACET_TYPE ,
" Unknown facet type %s \n " , node - > name , NULL ) ;
xmlSchemaFreeFacet ( facet ) ;
return ( NULL ) ;
2002-04-16 19:50:10 +04:00
}
2003-11-22 23:37:51 +03:00
facet - > id = xmlSchemaGetProp ( ctxt , node , " id " ) ;
2002-04-16 19:50:10 +04:00
facet - > value = value ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
facet - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child , XML_SCHEMAP_UNKNOWN_FACET_CHILD ,
" Facet %s has unexpected child content \n " ,
node - > name , NULL ) ;
2002-04-16 19:50:10 +04:00
}
return ( facet ) ;
}
/**
* xmlSchemaParseAny :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema Any declaration
* * WARNING * this interface is highly subject to change
*
* Returns the new type structure or NULL in case of error
*/
static xmlSchemaTypePtr
xmlSchemaParseAny ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
xmlNodePtr node )
{
xmlSchemaTypePtr type ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
2003-10-10 04:49:42 +04:00
snprintf ( ( char * ) name , 30 , " any %d " , ctxt - > counter + + + 1 ) ;
2003-11-22 23:37:51 +03:00
type = xmlSchemaAddType ( ctxt , schema , name , NULL ) ;
2002-04-16 19:50:10 +04:00
if ( type = = NULL )
2003-10-10 04:49:42 +04:00
return ( NULL ) ;
2002-04-16 19:50:10 +04:00
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_ANY ;
child = node - > children ;
type - > minOccurs = xmlGetMinOccurs ( ctxt , node ) ;
type - > maxOccurs = xmlGetMaxOccurs ( ctxt , node ) ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD ,
" Sequence %s has unexpected content \n " , type - > name ,
NULL ) ;
2002-04-16 19:50:10 +04:00
}
return ( type ) ;
}
/**
* xmlSchemaParseNotation :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema Notation declaration
*
* Returns the new structure or NULL in case of error
*/
static xmlSchemaNotationPtr
xmlSchemaParseNotation ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
2003-10-10 04:49:42 +04:00
xmlNodePtr node )
2002-04-16 19:50:10 +04:00
{
2003-11-22 23:37:51 +03:00
const xmlChar * name ;
2002-04-16 19:50:10 +04:00
xmlSchemaNotationPtr ret ;
xmlNodePtr child = NULL ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
2003-11-22 23:37:51 +03:00
name = xmlSchemaGetProp ( ctxt , node , " name " ) ;
2002-04-16 19:50:10 +04:00
if ( name = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child , XML_SCHEMAP_NOTATION_NO_NAME ,
" Notation has no name \n " , NULL , NULL ) ;
2002-04-16 19:50:10 +04:00
return ( NULL ) ;
}
ret = xmlSchemaAddNotation ( ctxt , schema , name ) ;
if ( ret = = NULL ) {
return ( NULL ) ;
}
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
ret - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_UNKNOWN_NOTATION_CHILD ,
" notation %s has unexpected content \n " , name , NULL ) ;
2002-04-16 19:50:10 +04:00
}
return ( ret ) ;
}
/**
* xmlSchemaParseAnyAttribute :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema AnyAttrribute declaration
* * WARNING * this interface is highly subject to change
*
* Returns an attribute def structure or NULL
*/
static xmlSchemaAttributePtr
2003-10-10 04:49:42 +04:00
xmlSchemaParseAnyAttribute ( xmlSchemaParserCtxtPtr ctxt ,
xmlSchemaPtr schema , xmlNodePtr node )
2002-04-16 19:50:10 +04:00
{
2003-11-22 23:37:51 +03:00
const xmlChar * processContents ;
2002-04-16 19:50:10 +04:00
xmlSchemaAttributePtr ret ;
xmlNodePtr child = NULL ;
char name [ 100 ] ;
2003-11-22 23:37:51 +03:00
const xmlChar * local , * ns ;
2002-04-16 19:50:10 +04:00
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
snprintf ( name , 99 , " anyattr %d " , ctxt - > counter + + + 1 ) ;
2003-11-22 23:37:51 +03:00
local = xmlSchemaGetNamespace ( ctxt , schema , node , BAD_CAST " anyattr " , & ns ) ;
ret = xmlSchemaAddAttribute ( ctxt , schema , BAD_CAST name , ns ) ;
2002-04-16 19:50:10 +04:00
if ( ret = = NULL ) {
return ( NULL ) ;
}
2003-11-22 23:37:51 +03:00
ret - > id = xmlSchemaGetProp ( ctxt , node , " id " ) ;
processContents = xmlSchemaGetProp ( ctxt , node , " processContents " ) ;
2003-10-10 04:49:42 +04:00
if ( ( processContents = = NULL )
| | ( xmlStrEqual ( processContents , ( const xmlChar * ) " strict " ) ) ) {
ret - > occurs = XML_SCHEMAS_ANYATTR_STRICT ;
} else if ( xmlStrEqual ( processContents , ( const xmlChar * ) " skip " ) ) {
ret - > occurs = XML_SCHEMAS_ANYATTR_SKIP ;
} else if ( xmlStrEqual ( processContents , ( const xmlChar * ) " lax " ) ) {
ret - > occurs = XML_SCHEMAS_ANYATTR_LAX ;
2002-04-16 19:50:10 +04:00
} else {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD ,
" anyAttribute has unexpected content for processContents: %s \n " ,
processContents , NULL ) ;
ret - > occurs = XML_SCHEMAS_ANYATTR_STRICT ;
2002-04-16 19:50:10 +04:00
}
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
ret - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD ,
" anyAttribute %s has unexpected content \n " ,
( const xmlChar * ) name , NULL ) ;
2002-04-16 19:50:10 +04:00
}
return ( ret ) ;
}
/**
* xmlSchemaParseAttribute :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema Attrribute declaration
* * WARNING * this interface is highly subject to change
*
* Returns - 1 in case of error , 0 if the declaration is inproper and
* 1 in case of success .
*/
static xmlSchemaAttributePtr
xmlSchemaParseAttribute ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
xmlNodePtr node )
{
2004-04-16 20:46:51 +04:00
const xmlChar * name , * refNs = NULL , * ref = NULL , * attrVal ;
2002-04-16 19:50:10 +04:00
xmlSchemaAttributePtr ret ;
xmlNodePtr child = NULL ;
2003-11-22 23:37:51 +03:00
char buf [ 100 ] ;
2002-04-16 19:50:10 +04:00
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
2003-11-22 23:37:51 +03:00
name = xmlSchemaGetProp ( ctxt , node , " name " ) ;
2002-04-16 19:50:10 +04:00
if ( name = = NULL ) {
2003-10-10 04:49:42 +04:00
ref = xmlGetQNameProp ( ctxt , node , " ref " , & refNs ) ;
if ( ref = = NULL ) {
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_ATTR_NONAME_NOREF ,
" Attribute has no name nor ref \n " , NULL , NULL ) ;
return ( NULL ) ;
}
2003-11-22 23:37:51 +03:00
snprintf ( buf , 99 , " anonattr %d " , ctxt - > counter + + + 1 ) ;
name = ( const xmlChar * ) buf ;
ret = xmlSchemaAddAttribute ( ctxt , schema , name , NULL ) ;
} else {
const xmlChar * local , * ns ;
local = xmlSchemaGetNamespace ( ctxt , schema , node , name , & ns ) ;
ret = xmlSchemaAddAttribute ( ctxt , schema , local , ns ) ;
2002-04-16 19:50:10 +04:00
}
if ( ret = = NULL ) {
return ( NULL ) ;
}
2004-04-16 20:46:51 +04:00
/* Read the "use" attribute. */
attrVal = xmlSchemaGetProp ( ctxt , node , " use " ) ;
if ( attrVal ! = NULL ) {
if ( xmlStrEqual ( attrVal , BAD_CAST " optional " ) )
ret - > occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL ;
else if ( xmlStrEqual ( attrVal , BAD_CAST " prohibited " ) )
ret - > occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED ;
else if ( xmlStrEqual ( attrVal , BAD_CAST " required " ) )
ret - > occurs = XML_SCHEMAS_ATTR_USE_REQUIRED ;
else
xmlSchemaPErr ( ctxt , node ,
XML_SCHEMAP_INVALID_ATTR_USE ,
" attribute %s has an invalid value for \" use \" \n " , name , NULL ) ;
} else
ret - > occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL ;
2002-04-16 19:50:10 +04:00
ret - > ref = ref ;
ret - > refNs = refNs ;
2003-11-22 23:37:51 +03:00
if ( ( ret - > targetNamespace ! = NULL ) & &
( ( schema - > flags & XML_SCHEMAS_QUALIF_ATTR ) = = 0 ) & &
( xmlStrEqual ( ret - > targetNamespace , schema - > targetNamespace ) ) )
ret - > flags | = XML_SCHEMAS_ATTR_NSDEFAULT ;
2002-04-16 19:50:10 +04:00
ret - > typeName = xmlGetQNameProp ( ctxt , node , " type " , & ( ret - > typeNs ) ) ;
2003-05-12 19:25:56 +04:00
ret - > node = node ;
2002-04-16 19:50:10 +04:00
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
ret - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( IS_SCHEMA ( child , " simpleType " ) ) {
2003-10-10 04:49:42 +04:00
ret - > subtypes = xmlSchemaParseSimpleType ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child , XML_SCHEMAP_UNKNOWN_ATTR_CHILD ,
" attribute %s has unexpected content \n " , name ,
NULL ) ;
2002-04-16 19:50:10 +04:00
}
return ( ret ) ;
}
/**
* xmlSchemaParseAttributeGroup :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema Attribute Group declaration
* * WARNING * this interface is highly subject to change
*
* Returns the attribute group or NULL in case of error .
*/
static xmlSchemaAttributeGroupPtr
2003-10-10 04:49:42 +04:00
xmlSchemaParseAttributeGroup ( xmlSchemaParserCtxtPtr ctxt ,
xmlSchemaPtr schema , xmlNodePtr node )
2002-04-16 19:50:10 +04:00
{
2003-11-22 23:37:51 +03:00
const xmlChar * name , * refNs = NULL , * ref = NULL ;
2002-04-16 19:50:10 +04:00
xmlSchemaAttributeGroupPtr ret ;
xmlSchemaAttributePtr last = NULL , attr ;
xmlNodePtr child = NULL ;
2003-11-22 23:37:51 +03:00
const xmlChar * oldcontainer ;
char buf [ 100 ] ;
2002-04-16 19:50:10 +04:00
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
oldcontainer = ctxt - > container ;
2003-11-22 23:37:51 +03:00
name = xmlSchemaGetProp ( ctxt , node , " name " ) ;
2002-04-16 19:50:10 +04:00
if ( name = = NULL ) {
2003-10-10 04:49:42 +04:00
ref = xmlGetQNameProp ( ctxt , node , " ref " , & refNs ) ;
if ( ref = = NULL ) {
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_ATTRGRP_NONAME_NOREF ,
" AttributeGroup has no name nor ref \n " , NULL ,
NULL ) ;
return ( NULL ) ;
}
2003-11-22 23:37:51 +03:00
snprintf ( buf , 99 , " anonattrgroup %d " , ctxt - > counter + + + 1 ) ;
name = ( const xmlChar * ) buf ;
2003-10-10 04:49:42 +04:00
if ( name = = NULL ) {
xmlSchemaPErrMemory ( ctxt , " creating attribute group " , node ) ;
return ( NULL ) ;
}
2002-04-16 19:50:10 +04:00
}
ret = xmlSchemaAddAttributeGroup ( ctxt , schema , name ) ;
if ( ret = = NULL ) {
return ( NULL ) ;
}
ret - > ref = ref ;
ret - > refNs = refNs ;
2002-04-23 21:51:29 +04:00
ret - > type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP ;
2003-05-12 19:25:56 +04:00
ret - > node = node ;
2002-04-16 19:50:10 +04:00
child = node - > children ;
ctxt - > container = name ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
ret - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
while ( ( IS_SCHEMA ( child , " attribute " ) ) | |
2003-10-10 04:49:42 +04:00
( IS_SCHEMA ( child , " attributeGroup " ) ) ) {
attr = NULL ;
if ( IS_SCHEMA ( child , " attribute " ) ) {
attr = xmlSchemaParseAttribute ( ctxt , schema , child ) ;
} else if ( IS_SCHEMA ( child , " attributeGroup " ) ) {
attr = ( xmlSchemaAttributePtr )
xmlSchemaParseAttributeGroup ( ctxt , schema , child ) ;
}
if ( attr ! = NULL ) {
if ( last = = NULL ) {
ret - > attributes = attr ;
last = attr ;
} else {
last - > next = attr ;
last = attr ;
}
}
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( IS_SCHEMA ( child , " anyAttribute " ) ) {
2003-11-22 23:37:51 +03:00
TODO
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_UNKNOWN_ATTRGRP_CHILD ,
" attribute group %s has unexpected content \n " , name ,
NULL ) ;
2002-04-16 19:50:10 +04:00
}
ctxt - > container = oldcontainer ;
return ( ret ) ;
}
/**
* xmlSchemaParseElement :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema Element declaration
* * WARNING * this interface is highly subject to change
*
* Returns - 1 in case of error , 0 if the declaration is inproper and
* 1 in case of success .
*/
static xmlSchemaElementPtr
xmlSchemaParseElement ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
xmlNodePtr node , int toplevel )
{
2003-11-22 23:37:51 +03:00
const xmlChar * name , * fixed ;
const xmlChar * refNs = NULL , * ref = NULL ;
2002-04-16 19:50:10 +04:00
xmlSchemaElementPtr ret ;
xmlNodePtr child = NULL ;
2003-11-22 23:37:51 +03:00
const xmlChar * oldcontainer ;
char buf [ 100 ] ;
2002-04-16 19:50:10 +04:00
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
oldcontainer = ctxt - > container ;
2003-11-22 23:37:51 +03:00
name = xmlSchemaGetProp ( ctxt , node , " name " ) ;
2002-04-16 19:50:10 +04:00
if ( name = = NULL ) {
2003-10-10 04:49:42 +04:00
ref = xmlGetQNameProp ( ctxt , node , " ref " , & refNs ) ;
if ( ref = = NULL ) {
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_ELEM_NONAME_NOREF ,
" Element has no name nor ref \n " , NULL , NULL ) ;
return ( NULL ) ;
}
2003-11-22 23:37:51 +03:00
snprintf ( buf , 99 , " anonelem %d " , ctxt - > counter + + + 1 ) ;
name = ( const xmlChar * ) buf ;
ret = xmlSchemaAddElement ( ctxt , schema , name , NULL ) ;
} else {
const xmlChar * local , * ns ;
local = xmlSchemaGetNamespace ( ctxt , schema , node , name , & ns ) ;
ret = xmlSchemaAddElement ( ctxt , schema , local , ns ) ;
}
if ( ret ! = NULL )
ret - > node = node ;
2002-04-16 19:50:10 +04:00
if ( ret = = NULL ) {
return ( NULL ) ;
}
ret - > type = XML_SCHEMA_TYPE_ELEMENT ;
ret - > ref = ref ;
ret - > refNs = refNs ;
if ( ref ! = NULL )
ret - > flags | = XML_SCHEMAS_ELEM_REF ;
if ( toplevel )
ret - > flags | = XML_SCHEMAS_ELEM_TOPLEVEL ;
if ( xmlGetBooleanProp ( ctxt , node , " nillable " , 0 ) )
ret - > flags | = XML_SCHEMAS_ELEM_NILLABLE ;
if ( xmlGetBooleanProp ( ctxt , node , " abstract " , 0 ) )
ret - > flags | = XML_SCHEMAS_ELEM_NILLABLE ;
ctxt - > container = name ;
2003-11-22 23:37:51 +03:00
ret - > id = xmlSchemaGetProp ( ctxt , node , " id " ) ;
2003-10-10 04:49:42 +04:00
ret - > namedType =
xmlGetQNameProp ( ctxt , node , " type " , & ( ret - > namedTypeNs ) ) ;
ret - > substGroup =
xmlGetQNameProp ( ctxt , node , " substitutionGroup " ,
& ( ret - > substGroupNs ) ) ;
2003-11-22 23:37:51 +03:00
fixed = xmlSchemaGetProp ( ctxt , node , " fixed " ) ;
2002-04-16 19:50:10 +04:00
ret - > minOccurs = xmlGetMinOccurs ( ctxt , node ) ;
ret - > maxOccurs = xmlGetMaxOccurs ( ctxt , node ) ;
2003-10-10 04:49:42 +04:00
2003-11-22 23:37:51 +03:00
ret - > value = xmlSchemaGetProp ( ctxt , node , " default " ) ;
2002-04-16 19:50:10 +04:00
if ( ( ret - > value ! = NULL ) & & ( fixed ! = NULL ) ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child , XML_SCHEMAP_ELEM_DEFAULT_FIXED ,
" Element %s has both default and fixed \n " ,
ret - > name , NULL ) ;
2002-04-16 19:50:10 +04:00
} else if ( fixed ! = NULL ) {
ret - > flags | = XML_SCHEMAS_ELEM_FIXED ;
2003-10-10 04:49:42 +04:00
ret - > value = fixed ;
2002-04-16 19:50:10 +04:00
}
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
ret - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( IS_SCHEMA ( child , " complexType " ) ) {
2003-10-10 04:49:42 +04:00
ret - > subtypes = xmlSchemaParseComplexType ( ctxt , schema , child ) ;
2002-04-16 19:50:10 +04:00
child = child - > next ;
} else if ( IS_SCHEMA ( child , " simpleType " ) ) {
2003-10-10 04:49:42 +04:00
ret - > subtypes = xmlSchemaParseSimpleType ( ctxt , schema , child ) ;
2002-04-16 19:50:10 +04:00
child = child - > next ;
}
while ( ( IS_SCHEMA ( child , " unique " ) ) | |
2003-10-10 04:49:42 +04:00
( IS_SCHEMA ( child , " key " ) ) | | ( IS_SCHEMA ( child , " keyref " ) ) ) {
TODO child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child , XML_SCHEMAP_UNKNOWN_ELEM_CHILD ,
" element %s has unexpected content \n " , name , NULL ) ;
2002-04-16 19:50:10 +04:00
}
ctxt - > container = oldcontainer ;
return ( ret ) ;
}
/**
* xmlSchemaParseUnion :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema Union definition
* * WARNING * this interface is highly subject to change
*
* Returns - 1 in case of error , 0 if the declaration is inproper and
* 1 in case of success .
*/
static xmlSchemaTypePtr
xmlSchemaParseUnion ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
2003-10-10 04:49:42 +04:00
xmlNodePtr node )
2002-04-16 19:50:10 +04:00
{
xmlSchemaTypePtr type , subtype , last = NULL ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
2003-10-10 04:49:42 +04:00
snprintf ( ( char * ) name , 30 , " union %d " , ctxt - > counter + + + 1 ) ;
2003-11-22 23:37:51 +03:00
type = xmlSchemaAddType ( ctxt , schema , name , NULL ) ;
2002-04-16 19:50:10 +04:00
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
2004-04-16 20:30:05 +04:00
type - > type = XML_SCHEMA_TYPE_UNION ;
2003-11-22 23:37:51 +03:00
type - > id = xmlSchemaGetProp ( ctxt , node , " id " ) ;
type - > ref = xmlSchemaGetProp ( ctxt , node , " memberTypes " ) ;
2002-04-16 19:50:10 +04:00
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
while ( IS_SCHEMA ( child , " simpleType " ) ) {
2003-10-10 04:49:42 +04:00
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseSimpleType ( ctxt , schema , child ) ;
if ( subtype ! = NULL ) {
if ( last = = NULL ) {
type - > subtypes = subtype ;
last = subtype ;
} else {
last - > next = subtype ;
last = subtype ;
}
last - > next = NULL ;
}
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child , XML_SCHEMAP_UNKNOWN_UNION_CHILD ,
" Union %s has unexpected content \n " , type - > name ,
NULL ) ;
2002-04-16 19:50:10 +04:00
}
return ( type ) ;
}
/**
* xmlSchemaParseList :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema List definition
* * WARNING * this interface is highly subject to change
*
* Returns - 1 in case of error , 0 if the declaration is inproper and
* 1 in case of success .
*/
static xmlSchemaTypePtr
xmlSchemaParseList ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
2003-10-10 04:49:42 +04:00
xmlNodePtr node )
2002-04-16 19:50:10 +04:00
{
xmlSchemaTypePtr type , subtype ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
2003-10-10 04:49:42 +04:00
snprintf ( ( char * ) name , 30 , " list %d " , ctxt - > counter + + + 1 ) ;
2003-11-22 23:37:51 +03:00
type = xmlSchemaAddType ( ctxt , schema , name , NULL ) ;
2002-04-16 19:50:10 +04:00
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_LIST ;
2003-11-22 23:37:51 +03:00
type - > id = xmlSchemaGetProp ( ctxt , node , " id " ) ;
2002-04-16 19:50:10 +04:00
type - > ref = xmlGetQNameProp ( ctxt , node , " ref " , & ( type - > refNs ) ) ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
subtype = NULL ;
if ( IS_SCHEMA ( child , " simpleType " ) ) {
2003-10-10 04:49:42 +04:00
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseSimpleType ( ctxt , schema , child ) ;
child = child - > next ;
type - > subtypes = subtype ;
2002-04-16 19:50:10 +04:00
}
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child , XML_SCHEMAP_UNKNOWN_LIST_CHILD ,
" List %s has unexpected content \n " , type - > name ,
NULL ) ;
2002-04-16 19:50:10 +04:00
}
return ( type ) ;
}
2003-10-10 04:49:42 +04:00
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaParseSimpleType :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema Simple Type definition
* * WARNING * this interface is highly subject to change
*
* Returns - 1 in case of error , 0 if the declaration is inproper and
* 1 in case of success .
*/
static xmlSchemaTypePtr
xmlSchemaParseSimpleType ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
xmlNodePtr node )
{
xmlSchemaTypePtr type , subtype ;
xmlNodePtr child = NULL ;
2003-11-22 23:37:51 +03:00
const xmlChar * name ;
2002-04-16 19:50:10 +04:00
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
2003-11-22 23:37:51 +03:00
name = xmlSchemaGetProp ( ctxt , node , " name " ) ;
2002-04-16 19:50:10 +04:00
if ( name = = NULL ) {
2003-10-10 04:49:42 +04:00
char buf [ 100 ] ;
2002-04-16 19:50:10 +04:00
2003-11-22 23:37:51 +03:00
snprintf ( buf , 99 , " simpletype %d " , ctxt - > counter + + + 1 ) ;
type = xmlSchemaAddType ( ctxt , schema , ( const xmlChar * ) buf , NULL ) ;
} else {
const xmlChar * local , * ns ;
local = xmlSchemaGetNamespace ( ctxt , schema , node , name , & ns ) ;
type = xmlSchemaAddType ( ctxt , schema , local , ns ) ;
2002-04-16 19:50:10 +04:00
}
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_SIMPLE ;
2003-11-22 23:37:51 +03:00
type - > id = xmlSchemaGetProp ( ctxt , node , " id " ) ;
2002-04-16 19:50:10 +04:00
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
subtype = NULL ;
if ( IS_SCHEMA ( child , " restriction " ) ) {
2003-10-10 04:49:42 +04:00
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseRestriction ( ctxt , schema , child , 1 ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
} else if ( IS_SCHEMA ( child , " list " ) ) {
2003-10-10 04:49:42 +04:00
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseList ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
} else if ( IS_SCHEMA ( child , " union " ) ) {
2003-10-10 04:49:42 +04:00
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseUnion ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
type - > subtypes = subtype ;
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_UNKNOWN_SIMPLETYPE_CHILD ,
" SimpleType %s has unexpected content \n " ,
type - > name , NULL ) ;
2002-04-16 19:50:10 +04:00
}
return ( type ) ;
}
/**
* xmlSchemaParseGroup :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema Group definition
* * WARNING * this interface is highly subject to change
*
* Returns - 1 in case of error , 0 if the declaration is inproper and
* 1 in case of success .
*/
static xmlSchemaTypePtr
xmlSchemaParseGroup ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
2003-10-10 04:49:42 +04:00
xmlNodePtr node )
2002-04-16 19:50:10 +04:00
{
xmlSchemaTypePtr type , subtype ;
xmlNodePtr child = NULL ;
2003-11-22 23:37:51 +03:00
const xmlChar * name ;
const xmlChar * ref = NULL , * refNs = NULL ;
char buf [ 100 ] ;
2002-04-16 19:50:10 +04:00
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
2003-11-22 23:37:51 +03:00
name = xmlSchemaGetProp ( ctxt , node , " name " ) ;
2002-04-16 19:50:10 +04:00
if ( name = = NULL ) {
2003-10-10 04:49:42 +04:00
ref = xmlGetQNameProp ( ctxt , node , " ref " , & refNs ) ;
if ( ref = = NULL ) {
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_GROUP_NONAME_NOREF ,
" Group has no name nor ref \n " , NULL , NULL ) ;
return ( NULL ) ;
}
2003-11-22 23:37:51 +03:00
if ( refNs = = NULL )
refNs = schema - > targetNamespace ;
snprintf ( buf , 99 , " anongroup %d " , ctxt - > counter + + + 1 ) ;
name = ( const xmlChar * ) buf ;
2002-04-16 19:50:10 +04:00
}
2003-06-02 20:58:46 +04:00
type = xmlSchemaAddGroup ( ctxt , schema , name ) ;
2002-04-16 19:50:10 +04:00
if ( type = = NULL )
return ( NULL ) ;
2003-11-21 03:28:39 +03:00
2002-04-16 19:50:10 +04:00
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_GROUP ;
2003-11-22 23:37:51 +03:00
type - > id = xmlSchemaGetProp ( ctxt , node , " id " ) ;
2002-04-16 19:50:10 +04:00
type - > ref = ref ;
type - > refNs = refNs ;
type - > minOccurs = xmlGetMinOccurs ( ctxt , node ) ;
type - > maxOccurs = xmlGetMaxOccurs ( ctxt , node ) ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
subtype = NULL ;
if ( IS_SCHEMA ( child , " all " ) ) {
2003-10-10 04:49:42 +04:00
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseAll ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
} else if ( IS_SCHEMA ( child , " choice " ) ) {
2003-10-10 04:49:42 +04:00
subtype = xmlSchemaParseChoice ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
} else if ( IS_SCHEMA ( child , " sequence " ) ) {
2003-10-10 04:49:42 +04:00
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseSequence ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( subtype ! = NULL )
2003-10-10 04:49:42 +04:00
type - > subtypes = subtype ;
2002-04-16 19:50:10 +04:00
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child , XML_SCHEMAP_UNKNOWN_GROUP_CHILD ,
" Group %s has unexpected content \n " , type - > name ,
NULL ) ;
2002-04-16 19:50:10 +04:00
}
return ( type ) ;
}
/**
* xmlSchemaParseAll :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema All definition
* * WARNING * this interface is highly subject to change
*
* Returns - 1 in case of error , 0 if the declaration is inproper and
* 1 in case of success .
*/
static xmlSchemaTypePtr
xmlSchemaParseAll ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
2003-10-10 04:49:42 +04:00
xmlNodePtr node )
2002-04-16 19:50:10 +04:00
{
xmlSchemaTypePtr type , subtype , last = NULL ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
2003-10-10 04:49:42 +04:00
snprintf ( ( char * ) name , 30 , " all%d " , ctxt - > counter + + + 1 ) ;
2003-11-22 23:37:51 +03:00
type = xmlSchemaAddType ( ctxt , schema , name , NULL ) ;
2002-04-16 19:50:10 +04:00
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
2002-04-20 10:41:40 +04:00
type - > type = XML_SCHEMA_TYPE_ALL ;
2003-11-22 23:37:51 +03:00
type - > id = xmlSchemaGetProp ( ctxt , node , " id " ) ;
2002-04-16 19:50:10 +04:00
type - > minOccurs = xmlGetMinOccurs ( ctxt , node ) ;
2003-12-27 07:34:42 +03:00
if ( type - > minOccurs > 1 )
xmlSchemaPErr ( ctxt , node , XML_SCHEMAP_INVALID_MINOCCURS ,
" invalid value for minOccurs (must be 0 or 1) \n " , NULL , NULL ) ;
2002-04-16 19:50:10 +04:00
type - > maxOccurs = xmlGetMaxOccurs ( ctxt , node ) ;
2003-12-27 07:34:42 +03:00
if ( type - > maxOccurs > 1 )
xmlSchemaPErr ( ctxt , node , XML_SCHEMAP_INVALID_MAXOCCURS ,
" invalid value for maxOccurs (must be 0 or 1) \n " , NULL , NULL ) ;
2002-04-16 19:50:10 +04:00
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
while ( IS_SCHEMA ( child , " element " ) ) {
2003-10-10 04:49:42 +04:00
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseElement ( ctxt , schema , child , 0 ) ;
if ( subtype ! = NULL ) {
2003-12-27 07:34:42 +03:00
if ( subtype - > minOccurs > 1 )
xmlSchemaPErr ( ctxt , child , XML_SCHEMAP_INVALID_MINOCCURS ,
" invalid value for minOccurs (must be 0 or 1) \n " ,
NULL , NULL ) ;
if ( subtype - > maxOccurs > 1 )
xmlSchemaPErr ( ctxt , child , XML_SCHEMAP_INVALID_MAXOCCURS ,
" invalid value for maxOccurs (must be 0 or 1) \n " ,
NULL , NULL ) ;
2003-10-10 04:49:42 +04:00
if ( last = = NULL ) {
type - > subtypes = subtype ;
last = subtype ;
} else {
last - > next = subtype ;
last = subtype ;
}
last - > next = NULL ;
}
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child , XML_SCHEMAP_UNKNOWN_ALL_CHILD ,
" All %s has unexpected content \n " , type - > name ,
NULL ) ;
2002-04-16 19:50:10 +04:00
}
return ( type ) ;
}
2003-11-21 03:28:39 +03:00
/**
* xmlSchemaImportSchema
*
* @ ctxt : a schema validation context
* @ schemaLocation : an URI defining where to find the imported schema
*
* import a XML schema
* * WARNING * this interface is highly subject to change
*
* Returns - 1 in case of error and 1 in case of success .
*/
static xmlSchemaImportPtr
xmlSchemaImportSchema ( xmlSchemaParserCtxtPtr ctxt ,
const xmlChar * schemaLocation )
{
xmlSchemaImportPtr import ;
xmlSchemaParserCtxtPtr newctxt ;
2003-11-25 18:38:59 +03:00
newctxt = ( xmlSchemaParserCtxtPtr ) xmlMalloc ( sizeof ( xmlSchemaParserCtxt ) ) ;
2003-11-21 03:28:39 +03:00
if ( newctxt = = NULL ) {
2003-11-25 18:38:59 +03:00
xmlSchemaPErrMemory ( ctxt , " allocating schama parser context " ,
2003-11-21 03:28:39 +03:00
NULL ) ;
return ( NULL ) ;
}
2003-11-25 18:38:59 +03:00
memset ( newctxt , 0 , sizeof ( xmlSchemaParserCtxt ) ) ;
/* Keep the same dictionnary for parsing, really */
xmlDictReference ( ctxt - > dict ) ;
newctxt - > dict = ctxt - > dict ;
2003-12-24 02:30:53 +03:00
newctxt - > includes = 0 ;
2003-11-25 18:38:59 +03:00
newctxt - > URL = xmlDictLookup ( newctxt - > dict , schemaLocation , - 1 ) ;
2003-11-21 03:28:39 +03:00
xmlSchemaSetParserErrors ( newctxt , ctxt - > error , ctxt - > warning ,
ctxt - > userData ) ;
import = ( xmlSchemaImport * ) xmlMalloc ( sizeof ( xmlSchemaImport ) ) ;
if ( import = = NULL ) {
xmlSchemaPErrMemory ( NULL , " allocating imported schema " ,
NULL ) ;
xmlSchemaFreeParserCtxt ( newctxt ) ;
return ( NULL ) ;
}
memset ( import , 0 , sizeof ( xmlSchemaImport ) ) ;
2003-11-22 23:37:51 +03:00
import - > schemaLocation = xmlDictLookup ( ctxt - > dict , schemaLocation , - 1 ) ;
2003-11-21 03:28:39 +03:00
import - > schema = xmlSchemaParse ( newctxt ) ;
if ( import - > schema = = NULL ) {
/* FIXME use another error enum here ? */
xmlSchemaPErr ( ctxt , NULL , XML_SCHEMAS_ERR_INTERNAL ,
" failed to import schema at location %s \n " ,
schemaLocation , NULL ) ;
xmlSchemaFreeParserCtxt ( newctxt ) ;
if ( import - > schemaLocation ! = NULL )
xmlFree ( ( xmlChar * ) import - > schemaLocation ) ;
xmlFree ( import ) ;
return NULL ;
}
xmlSchemaFreeParserCtxt ( newctxt ) ;
return import ;
}
2002-05-22 10:40:27 +04:00
/**
* xmlSchemaParseImport :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema Import definition
* * WARNING * this interface is highly subject to change
*
* Returns - 1 in case of error , 0 if the declaration is inproper and
* 1 in case of success .
*/
static int
xmlSchemaParseImport ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
2003-10-10 04:49:42 +04:00
xmlNodePtr node )
2002-05-22 10:40:27 +04:00
{
xmlNodePtr child = NULL ;
2003-11-21 03:28:39 +03:00
xmlSchemaImportPtr import = NULL ;
2003-11-22 23:37:51 +03:00
const xmlChar * namespace ;
const xmlChar * schemaLocation ;
2003-11-21 03:28:39 +03:00
const xmlChar * previous ;
2002-05-22 10:40:27 +04:00
xmlURIPtr check ;
2003-11-21 03:28:39 +03:00
2002-05-22 10:40:27 +04:00
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( - 1 ) ;
2003-11-22 23:37:51 +03:00
namespace = xmlSchemaGetProp ( ctxt , node , " namespace " ) ;
2002-05-22 10:40:27 +04:00
if ( namespace ! = NULL ) {
2003-10-10 04:49:42 +04:00
check = xmlParseURI ( ( const char * ) namespace ) ;
if ( check = = NULL ) {
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI ,
" Import namespace attribute is not an URI: %s \n " ,
namespace , NULL ) ;
return ( - 1 ) ;
} else {
xmlFreeURI ( check ) ;
}
2002-05-22 10:40:27 +04:00
}
2003-11-22 23:37:51 +03:00
schemaLocation = xmlSchemaGetProp ( ctxt , node , " schemaLocation " ) ;
2002-05-22 10:40:27 +04:00
if ( schemaLocation ! = NULL ) {
2003-11-21 03:28:39 +03:00
xmlChar * base = NULL ;
xmlChar * URI = NULL ;
2003-10-10 04:49:42 +04:00
check = xmlParseURI ( ( const char * ) schemaLocation ) ;
if ( check = = NULL ) {
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI ,
" Import schemaLocation attribute is not an URI: %s \n " ,
schemaLocation , NULL ) ;
return ( - 1 ) ;
} else {
xmlFreeURI ( check ) ;
}
2003-11-21 03:28:39 +03:00
base = xmlNodeGetBase ( node - > doc , node ) ;
if ( base = = NULL ) {
URI = xmlBuildURI ( schemaLocation , node - > doc - > URL ) ;
} else {
URI = xmlBuildURI ( schemaLocation , base ) ;
2003-11-22 23:37:51 +03:00
xmlFree ( base ) ;
2003-11-21 03:28:39 +03:00
}
if ( URI ! = NULL ) {
2003-11-22 23:37:51 +03:00
schemaLocation = xmlDictLookup ( ctxt - > dict , URI , - 1 ) ;
xmlFree ( URI ) ;
2003-11-21 03:28:39 +03:00
}
2002-05-22 10:40:27 +04:00
}
if ( schema - > schemasImports = = NULL ) {
2003-10-10 04:49:42 +04:00
schema - > schemasImports = xmlHashCreate ( 10 ) ;
if ( schema - > schemasImports = = NULL ) {
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_FAILED_BUILD_IMPORT ,
" Internal: failed to build import table \n " ,
NULL , NULL ) ;
return ( - 1 ) ;
}
2002-05-22 10:40:27 +04:00
}
if ( namespace = = NULL ) {
2003-11-21 03:28:39 +03:00
import = xmlHashLookup ( schema - > schemasImports ,
XML_SCHEMAS_DEFAULT_NAMESPACE ) ;
if ( import ! = NULL )
previous = import - > schemaLocation ;
else
previous = NULL ;
2003-10-10 04:49:42 +04:00
if ( schemaLocation ! = NULL ) {
if ( previous ! = NULL ) {
if ( ! xmlStrEqual ( schemaLocation , previous ) ) {
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_IMPORT_REDEFINE_NSNAME ,
" Redefining import for default namespace with a different URI: %s \n " ,
schemaLocation , NULL ) ;
}
} else {
2003-11-21 03:28:39 +03:00
import = xmlSchemaImportSchema ( ctxt , schemaLocation ) ;
if ( import = = NULL ) {
return ( - 1 ) ;
}
2003-10-10 04:49:42 +04:00
xmlHashAddEntry ( schema - > schemasImports ,
XML_SCHEMAS_DEFAULT_NAMESPACE ,
2003-11-21 03:28:39 +03:00
import ) ;
2003-10-10 04:49:42 +04:00
}
}
2002-05-22 10:40:27 +04:00
} else {
2003-11-21 03:28:39 +03:00
import = xmlHashLookup ( schema - > schemasImports , namespace ) ;
if ( import ! = NULL )
previous = import - > schemaLocation ;
else
previous = NULL ;
2003-10-10 04:49:42 +04:00
if ( schemaLocation ! = NULL ) {
if ( previous ! = NULL ) {
if ( ! xmlStrEqual ( schemaLocation , previous ) ) {
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_IMPORT_REDEFINE_NSNAME ,
" Redefining import for namespace %s with a different URI: %s \n " ,
namespace , schemaLocation ) ;
}
} else {
2003-11-21 03:28:39 +03:00
import = xmlSchemaImportSchema ( ctxt , schemaLocation ) ;
if ( import = = NULL ) {
return ( - 1 ) ;
}
2003-10-10 04:49:42 +04:00
xmlHashAddEntry ( schema - > schemasImports ,
2003-11-21 03:28:39 +03:00
namespace , import ) ;
2003-10-10 04:49:42 +04:00
}
}
2002-05-22 10:40:27 +04:00
}
child = node - > children ;
while ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
/*
* the annotations here are simply discarded . . .
*/
child = child - > next ;
2002-05-22 10:40:27 +04:00
}
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child , XML_SCHEMAP_UNKNOWN_IMPORT_CHILD ,
" Import has unexpected content \n " , NULL , NULL ) ;
return ( - 1 ) ;
2002-05-22 10:40:27 +04:00
}
2003-10-10 04:49:42 +04:00
return ( 1 ) ;
2002-05-22 10:40:27 +04:00
}
2003-11-25 18:38:59 +03:00
/**
* xmlSchemaCleanupDoc :
* @ ctxt : a schema validation context
* @ node : the root of the document .
*
* removes unwanted nodes in a schemas document tree
*/
static void
xmlSchemaCleanupDoc ( xmlSchemaParserCtxtPtr ctxt , xmlNodePtr root )
{
xmlNodePtr delete , cur ;
if ( ( ctxt = = NULL ) | | ( root = = NULL ) ) return ;
/*
* Remove all the blank text nodes
*/
delete = NULL ;
cur = root ;
while ( cur ! = NULL ) {
if ( delete ! = NULL ) {
xmlUnlinkNode ( delete ) ;
xmlFreeNode ( delete ) ;
delete = NULL ;
}
if ( cur - > type = = XML_TEXT_NODE ) {
if ( IS_BLANK_NODE ( cur ) ) {
if ( xmlNodeGetSpacePreserve ( cur ) ! = 1 ) {
delete = cur ;
}
}
} else if ( ( cur - > type ! = XML_ELEMENT_NODE ) & &
( cur - > type ! = XML_CDATA_SECTION_NODE ) ) {
delete = cur ;
goto skip_children ;
}
/*
* Skip to next node
*/
if ( cur - > children ! = NULL ) {
if ( ( cur - > children - > type ! = XML_ENTITY_DECL ) & &
( cur - > children - > type ! = XML_ENTITY_REF_NODE ) & &
( cur - > children - > type ! = XML_ENTITY_NODE ) ) {
cur = cur - > children ;
continue ;
}
}
skip_children :
if ( cur - > next ! = NULL ) {
cur = cur - > next ;
continue ;
}
do {
cur = cur - > parent ;
if ( cur = = NULL )
break ;
if ( cur = = root ) {
cur = NULL ;
break ;
}
if ( cur - > next ! = NULL ) {
cur = cur - > next ;
break ;
}
} while ( cur ! = NULL ) ;
}
if ( delete ! = NULL ) {
xmlUnlinkNode ( delete ) ;
xmlFreeNode ( delete ) ;
delete = NULL ;
}
}
/**
* xmlSchemaParseSchemaTopLevel :
* @ ctxt : a schema validation context
* @ schema : the schemas
* @ nodes : the list of top level nodes
*
* Returns the internal XML Schema structure built from the resource or
* NULL in case of error
*/
static void
xmlSchemaParseSchemaTopLevel ( xmlSchemaParserCtxtPtr ctxt ,
xmlSchemaPtr schema , xmlNodePtr nodes )
{
xmlNodePtr child ;
xmlSchemaAnnotPtr annot ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( nodes = = NULL ) )
return ;
child = nodes ;
while ( ( IS_SCHEMA ( child , " include " ) ) | |
( IS_SCHEMA ( child , " import " ) ) | |
( IS_SCHEMA ( child , " redefine " ) ) | |
( IS_SCHEMA ( child , " annotation " ) ) ) {
if ( IS_SCHEMA ( child , " annotation " ) ) {
annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
if ( schema - > annot = = NULL )
schema - > annot = annot ;
else
xmlSchemaFreeAnnot ( annot ) ;
} else if ( IS_SCHEMA ( child , " import " ) ) {
xmlSchemaParseImport ( ctxt , schema , child ) ;
} else if ( IS_SCHEMA ( child , " include " ) ) {
2003-12-24 02:30:53 +03:00
ctxt - > includes + + ;
2003-11-25 18:38:59 +03:00
xmlSchemaParseInclude ( ctxt , schema , child ) ;
2003-12-24 02:30:53 +03:00
ctxt - > includes - - ;
2003-11-25 18:38:59 +03:00
} else if ( IS_SCHEMA ( child , " redefine " ) ) {
TODO
}
child = child - > next ;
}
while ( child ! = NULL ) {
if ( IS_SCHEMA ( child , " complexType " ) ) {
xmlSchemaParseComplexType ( ctxt , schema , child ) ;
child = child - > next ;
} else if ( IS_SCHEMA ( child , " simpleType " ) ) {
xmlSchemaParseSimpleType ( ctxt , schema , child ) ;
child = child - > next ;
} else if ( IS_SCHEMA ( child , " element " ) ) {
xmlSchemaParseElement ( ctxt , schema , child , 1 ) ;
child = child - > next ;
} else if ( IS_SCHEMA ( child , " attribute " ) ) {
xmlSchemaParseAttribute ( ctxt , schema , child ) ;
child = child - > next ;
} else if ( IS_SCHEMA ( child , " attributeGroup " ) ) {
xmlSchemaParseAttributeGroup ( ctxt , schema , child ) ;
child = child - > next ;
} else if ( IS_SCHEMA ( child , " group " ) ) {
xmlSchemaParseGroup ( ctxt , schema , child ) ;
child = child - > next ;
} else if ( IS_SCHEMA ( child , " notation " ) ) {
xmlSchemaParseNotation ( ctxt , schema , child ) ;
child = child - > next ;
} else {
xmlSchemaPErr2 ( ctxt , NULL , child ,
XML_SCHEMAP_UNKNOWN_SCHEMAS_CHILD ,
" Schemas: unexpected element %s here \n " ,
child - > name , NULL ) ;
child = child - > next ;
}
while ( IS_SCHEMA ( child , " annotation " ) ) {
annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
if ( schema - > annot = = NULL )
schema - > annot = annot ;
else
xmlSchemaFreeAnnot ( annot ) ;
child = child - > next ;
}
}
}
/**
* xmlSchemaParseInclude :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema Include definition
*
* Returns - 1 in case of error , 0 if the declaration is inproper and
* 1 in case of success .
*/
static int
xmlSchemaParseInclude ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
xmlNodePtr node )
{
xmlNodePtr child = NULL ;
const xmlChar * schemaLocation ;
xmlURIPtr check ;
xmlDocPtr doc ;
xmlNodePtr root ;
xmlSchemaIncludePtr include ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( - 1 ) ;
/*
* Preliminary step , extract the URI - Reference for the include and
* make an URI from the base .
*/
schemaLocation = xmlSchemaGetProp ( ctxt , node , " schemaLocation " ) ;
if ( schemaLocation ! = NULL ) {
xmlChar * base = NULL ;
xmlChar * URI = NULL ;
check = xmlParseURI ( ( const char * ) schemaLocation ) ;
if ( check = = NULL ) {
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_INCLUDE_SCHEMA_NOT_URI ,
" Include schemaLocation attribute is not an URI: %s \n " ,
schemaLocation , NULL ) ;
return ( - 1 ) ;
} else {
xmlFreeURI ( check ) ;
}
base = xmlNodeGetBase ( node - > doc , node ) ;
if ( base = = NULL ) {
URI = xmlBuildURI ( schemaLocation , node - > doc - > URL ) ;
} else {
URI = xmlBuildURI ( schemaLocation , base ) ;
xmlFree ( base ) ;
}
if ( URI ! = NULL ) {
schemaLocation = xmlDictLookup ( ctxt - > dict , URI , - 1 ) ;
xmlFree ( URI ) ;
}
} else {
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_INCLUDE_SCHEMA_NO_URI ,
" Include schemaLocation attribute missing \n " ,
NULL , NULL ) ;
return ( - 1 ) ;
}
child = node - > children ;
while ( IS_SCHEMA ( child , " annotation " ) ) {
/*
* the annotations here are simply discarded . . .
*/
child = child - > next ;
}
if ( child ! = NULL ) {
xmlSchemaPErr2 ( ctxt , node , child , XML_SCHEMAP_UNKNOWN_INCLUDE_CHILD ,
" Include has unexpected content \n " , NULL , NULL ) ;
return ( - 1 ) ;
}
/*
* First step is to parse the input document into an DOM / Infoset
*/
doc = xmlReadFile ( ( const char * ) schemaLocation , NULL ,
SCHEMAS_PARSE_OPTIONS ) ;
if ( doc = = NULL ) {
xmlSchemaPErr ( ctxt , NULL ,
XML_SCHEMAP_FAILED_LOAD ,
" xmlSchemaParse: could not load %s \n " ,
ctxt - > URL , NULL ) ;
return ( - 1 ) ;
}
/*
* Then extract the root of the schema
*/
root = xmlDocGetRootElement ( doc ) ;
if ( root = = NULL ) {
xmlSchemaPErr ( ctxt , ( xmlNodePtr ) doc ,
XML_SCHEMAP_NOROOT ,
" schemas %s has no root " , schemaLocation , NULL ) ;
xmlFreeDoc ( doc ) ;
return ( - 1 ) ;
}
/*
* Remove all the blank text nodes
*/
xmlSchemaCleanupDoc ( ctxt , root ) ;
/*
* Check the schemas top level element
*/
if ( ! IS_SCHEMA ( root , " schema " ) ) {
xmlSchemaPErr ( ctxt , ( xmlNodePtr ) doc ,
XML_SCHEMAP_NOT_SCHEMA ,
" File %s is not a schemas " , schemaLocation , NULL ) ;
xmlFreeDoc ( doc ) ;
return ( - 1 ) ;
}
/*
* register the include
*/
include = ( xmlSchemaIncludePtr ) xmlMalloc ( sizeof ( xmlSchemaInclude ) ) ;
if ( include = = NULL ) {
xmlSchemaPErrMemory ( ctxt , " allocating included schema " , NULL ) ;
xmlFreeDoc ( doc ) ;
return ( - 1 ) ;
}
memset ( include , 0 , sizeof ( xmlSchemaInclude ) ) ;
include - > schemaLocation = xmlDictLookup ( ctxt - > dict , schemaLocation , - 1 ) ;
include - > doc = doc ;
include - > next = schema - > includes ;
schema - > includes = include ;
/*
* parse the declarations in the included file like if they
* were in the original file .
*/
xmlSchemaParseSchemaTopLevel ( ctxt , schema , root - > children ) ;
return ( 1 ) ;
}
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaParseChoice :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema Choice definition
* * WARNING * this interface is highly subject to change
*
* Returns - 1 in case of error , 0 if the declaration is inproper and
* 1 in case of success .
*/
static xmlSchemaTypePtr
xmlSchemaParseChoice ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
2003-10-10 04:49:42 +04:00
xmlNodePtr node )
2002-04-16 19:50:10 +04:00
{
xmlSchemaTypePtr type , subtype , last = NULL ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
2003-10-10 04:49:42 +04:00
snprintf ( ( char * ) name , 30 , " choice %d " , ctxt - > counter + + + 1 ) ;
2003-11-22 23:37:51 +03:00
type = xmlSchemaAddType ( ctxt , schema , name , NULL ) ;
2002-04-16 19:50:10 +04:00
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_CHOICE ;
2003-11-22 23:37:51 +03:00
type - > id = xmlSchemaGetProp ( ctxt , node , " id " ) ;
2002-04-16 19:50:10 +04:00
type - > minOccurs = xmlGetMinOccurs ( ctxt , node ) ;
type - > maxOccurs = xmlGetMaxOccurs ( ctxt , node ) ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
while ( ( IS_SCHEMA ( child , " element " ) ) | |
2003-10-10 04:49:42 +04:00
( IS_SCHEMA ( child , " group " ) ) | |
( IS_SCHEMA ( child , " any " ) ) | |
( IS_SCHEMA ( child , " choice " ) ) | |
( IS_SCHEMA ( child , " sequence " ) ) ) {
subtype = NULL ;
if ( IS_SCHEMA ( child , " element " ) ) {
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseElement ( ctxt , schema , child , 0 ) ;
} else if ( IS_SCHEMA ( child , " group " ) ) {
subtype = xmlSchemaParseGroup ( ctxt , schema , child ) ;
} else if ( IS_SCHEMA ( child , " any " ) ) {
subtype = xmlSchemaParseAny ( ctxt , schema , child ) ;
} else if ( IS_SCHEMA ( child , " sequence " ) ) {
subtype = xmlSchemaParseSequence ( ctxt , schema , child ) ;
} else if ( IS_SCHEMA ( child , " choice " ) ) {
subtype = xmlSchemaParseChoice ( ctxt , schema , child ) ;
}
if ( subtype ! = NULL ) {
if ( last = = NULL ) {
type - > subtypes = subtype ;
last = subtype ;
} else {
last - > next = subtype ;
last = subtype ;
}
last - > next = NULL ;
}
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child , XML_SCHEMAP_UNKNOWN_CHOICE_CHILD ,
" Choice %s has unexpected content \n " , type - > name ,
NULL ) ;
2002-04-16 19:50:10 +04:00
}
return ( type ) ;
}
/**
* xmlSchemaParseSequence :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema Sequence definition
* * WARNING * this interface is highly subject to change
*
* Returns - 1 in case of error , 0 if the declaration is inproper and
* 1 in case of success .
*/
static xmlSchemaTypePtr
xmlSchemaParseSequence ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
2003-10-10 04:49:42 +04:00
xmlNodePtr node )
2002-04-16 19:50:10 +04:00
{
xmlSchemaTypePtr type , subtype , last = NULL ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
2003-10-10 04:49:42 +04:00
snprintf ( ( char * ) name , 30 , " sequence %d " , ctxt - > counter + + + 1 ) ;
2003-11-22 23:37:51 +03:00
type = xmlSchemaAddType ( ctxt , schema , name , NULL ) ;
2002-04-16 19:50:10 +04:00
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_SEQUENCE ;
2003-11-22 23:37:51 +03:00
type - > id = xmlSchemaGetProp ( ctxt , node , " id " ) ;
2002-04-16 19:50:10 +04:00
type - > minOccurs = xmlGetMinOccurs ( ctxt , node ) ;
type - > maxOccurs = xmlGetMaxOccurs ( ctxt , node ) ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
while ( ( IS_SCHEMA ( child , " element " ) ) | |
2003-10-10 04:49:42 +04:00
( IS_SCHEMA ( child , " group " ) ) | |
( IS_SCHEMA ( child , " any " ) ) | |
( IS_SCHEMA ( child , " choice " ) ) | |
( IS_SCHEMA ( child , " sequence " ) ) ) {
subtype = NULL ;
if ( IS_SCHEMA ( child , " element " ) ) {
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseElement ( ctxt , schema , child , 0 ) ;
} else if ( IS_SCHEMA ( child , " group " ) ) {
subtype = xmlSchemaParseGroup ( ctxt , schema , child ) ;
} else if ( IS_SCHEMA ( child , " any " ) ) {
subtype = xmlSchemaParseAny ( ctxt , schema , child ) ;
} else if ( IS_SCHEMA ( child , " choice " ) ) {
subtype = xmlSchemaParseChoice ( ctxt , schema , child ) ;
} else if ( IS_SCHEMA ( child , " sequence " ) ) {
subtype = xmlSchemaParseSequence ( ctxt , schema , child ) ;
}
if ( subtype ! = NULL ) {
if ( last = = NULL ) {
type - > subtypes = subtype ;
last = subtype ;
} else {
last - > next = subtype ;
last = subtype ;
}
last - > next = NULL ;
}
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD ,
" Sequence %s has unexpected content \n " , type - > name ,
NULL ) ;
2002-04-16 19:50:10 +04:00
}
return ( type ) ;
}
/**
* xmlSchemaParseRestriction :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
* @ simple : is that part of a simple type .
*
* parse a XML schema Restriction definition
* * WARNING * this interface is highly subject to change
*
* Returns the type definition or NULL in case of error
*/
static xmlSchemaTypePtr
xmlSchemaParseRestriction ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
xmlNodePtr node , int simple )
{
xmlSchemaTypePtr type , subtype ;
xmlSchemaFacetPtr facet , lastfacet = NULL ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
2003-11-22 23:37:51 +03:00
const xmlChar * oldcontainer ;
2002-04-16 19:50:10 +04:00
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
oldcontainer = ctxt - > container ;
2003-10-10 04:49:42 +04:00
snprintf ( ( char * ) name , 30 , " restriction %d " , ctxt - > counter + + + 1 ) ;
2003-11-22 23:37:51 +03:00
type = xmlSchemaAddType ( ctxt , schema , name , NULL ) ;
2002-04-16 19:50:10 +04:00
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_RESTRICTION ;
2003-11-22 23:37:51 +03:00
type - > id = xmlSchemaGetProp ( ctxt , node , " id " ) ;
2002-04-16 19:50:10 +04:00
type - > base = xmlGetQNameProp ( ctxt , node , " base " , & ( type - > baseNs ) ) ;
if ( ( ! simple ) & & ( type - > base = = NULL ) ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_RESTRICTION_NONAME_NOREF ,
" Restriction %s has no base \n " , type - > name , NULL ) ;
2002-04-16 19:50:10 +04:00
}
ctxt - > container = name ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
subtype = NULL ;
if ( IS_SCHEMA ( child , " all " ) ) {
2003-10-10 04:49:42 +04:00
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseAll ( ctxt , schema , child ) ;
child = child - > next ;
type - > subtypes = subtype ;
2002-04-16 19:50:10 +04:00
} else if ( IS_SCHEMA ( child , " choice " ) ) {
2003-10-10 04:49:42 +04:00
subtype = xmlSchemaParseChoice ( ctxt , schema , child ) ;
child = child - > next ;
type - > subtypes = subtype ;
2002-04-16 19:50:10 +04:00
} else if ( IS_SCHEMA ( child , " sequence " ) ) {
2003-10-10 04:49:42 +04:00
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseSequence ( ctxt , schema , child ) ;
child = child - > next ;
type - > subtypes = subtype ;
2002-04-16 19:50:10 +04:00
} else if ( IS_SCHEMA ( child , " group " ) ) {
2003-10-10 04:49:42 +04:00
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseGroup ( ctxt , schema , child ) ;
child = child - > next ;
type - > subtypes = subtype ;
2002-04-16 19:50:10 +04:00
} else {
2003-10-10 04:49:42 +04:00
if ( IS_SCHEMA ( child , " simpleType " ) ) {
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseSimpleType ( ctxt , schema , child ) ;
child = child - > next ;
type - > baseType = subtype ;
}
/*
* Facets
*/
2002-04-16 19:50:10 +04:00
while ( ( IS_SCHEMA ( child , " minInclusive " ) ) | |
2003-10-10 04:49:42 +04:00
( IS_SCHEMA ( child , " minExclusive " ) ) | |
( IS_SCHEMA ( child , " maxInclusive " ) ) | |
( IS_SCHEMA ( child , " maxExclusive " ) ) | |
( IS_SCHEMA ( child , " totalDigits " ) ) | |
( IS_SCHEMA ( child , " fractionDigits " ) ) | |
( IS_SCHEMA ( child , " pattern " ) ) | |
( IS_SCHEMA ( child , " enumeration " ) ) | |
( IS_SCHEMA ( child , " whiteSpace " ) ) | |
( IS_SCHEMA ( child , " length " ) ) | |
( IS_SCHEMA ( child , " maxLength " ) ) | |
( IS_SCHEMA ( child , " minLength " ) ) ) {
facet = xmlSchemaParseFacet ( ctxt , schema , child ) ;
if ( facet ! = NULL ) {
if ( lastfacet = = NULL ) {
type - > facets = facet ;
lastfacet = facet ;
} else {
lastfacet - > next = facet ;
lastfacet = facet ;
}
lastfacet - > next = NULL ;
}
child = child - > next ;
}
2002-04-16 19:50:10 +04:00
}
child = xmlSchemaParseAttrDecls ( ctxt , schema , child , type ) ;
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD ,
" Restriction %s has unexpected content \n " ,
type - > name , NULL ) ;
2002-04-16 19:50:10 +04:00
}
ctxt - > container = oldcontainer ;
return ( type ) ;
}
/**
* xmlSchemaParseExtension :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema Extension definition
* * WARNING * this interface is highly subject to change
*
* Returns the type definition or NULL in case of error
*/
static xmlSchemaTypePtr
xmlSchemaParseExtension ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
2003-10-10 04:49:42 +04:00
xmlNodePtr node )
2002-04-16 19:50:10 +04:00
{
xmlSchemaTypePtr type , subtype ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
2003-11-22 23:37:51 +03:00
const xmlChar * oldcontainer ;
2002-04-16 19:50:10 +04:00
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
oldcontainer = ctxt - > container ;
2003-10-10 04:49:42 +04:00
snprintf ( ( char * ) name , 30 , " extension %d " , ctxt - > counter + + + 1 ) ;
2003-11-22 23:37:51 +03:00
type = xmlSchemaAddType ( ctxt , schema , name , NULL ) ;
2002-04-16 19:50:10 +04:00
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_EXTENSION ;
2003-11-22 23:37:51 +03:00
type - > id = xmlSchemaGetProp ( ctxt , node , " id " ) ;
2002-04-16 19:50:10 +04:00
ctxt - > container = name ;
type - > base = xmlGetQNameProp ( ctxt , node , " base " , & ( type - > baseNs ) ) ;
if ( type - > base = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child , XML_SCHEMAP_EXTENSION_NO_BASE ,
" Extension %s has no base \n " , type - > name , NULL ) ;
2002-04-16 19:50:10 +04:00
}
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
subtype = NULL ;
if ( IS_SCHEMA ( child , " all " ) ) {
2003-10-10 04:49:42 +04:00
subtype = xmlSchemaParseAll ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
} else if ( IS_SCHEMA ( child , " choice " ) ) {
2003-10-10 04:49:42 +04:00
subtype = xmlSchemaParseChoice ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
} else if ( IS_SCHEMA ( child , " sequence " ) ) {
2003-10-10 04:49:42 +04:00
subtype = xmlSchemaParseSequence ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
} else if ( IS_SCHEMA ( child , " group " ) ) {
2003-10-10 04:49:42 +04:00
subtype = xmlSchemaParseGroup ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( subtype ! = NULL )
2003-10-10 04:49:42 +04:00
type - > subtypes = subtype ;
2002-04-16 19:50:10 +04:00
child = xmlSchemaParseAttrDecls ( ctxt , schema , child , type ) ;
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_UNKNOWN_EXTENSION_CHILD ,
" Extension %s has unexpected content \n " , type - > name ,
NULL ) ;
2002-04-16 19:50:10 +04:00
}
ctxt - > container = oldcontainer ;
return ( type ) ;
}
/**
* xmlSchemaParseSimpleContent :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema SimpleContent definition
* * WARNING * this interface is highly subject to change
*
* Returns the type definition or NULL in case of error
*/
static xmlSchemaTypePtr
2003-10-10 04:49:42 +04:00
xmlSchemaParseSimpleContent ( xmlSchemaParserCtxtPtr ctxt ,
xmlSchemaPtr schema , xmlNodePtr node )
2002-04-16 19:50:10 +04:00
{
xmlSchemaTypePtr type , subtype ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
2003-10-10 04:49:42 +04:00
snprintf ( ( char * ) name , 30 , " complexContent %d " , ctxt - > counter + + + 1 ) ;
2003-11-22 23:37:51 +03:00
type = xmlSchemaAddType ( ctxt , schema , name , NULL ) ;
2002-04-16 19:50:10 +04:00
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_SIMPLE_CONTENT ;
2003-11-22 23:37:51 +03:00
type - > id = xmlSchemaGetProp ( ctxt , node , " id " ) ;
2002-04-16 19:50:10 +04:00
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
subtype = NULL ;
if ( IS_SCHEMA ( child , " restriction " ) ) {
2003-10-10 04:49:42 +04:00
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseRestriction ( ctxt , schema , child , 0 ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
} else if ( IS_SCHEMA ( child , " extension " ) ) {
2003-10-10 04:49:42 +04:00
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseExtension ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
type - > subtypes = subtype ;
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD ,
" SimpleContent %s has unexpected content \n " ,
type - > name , NULL ) ;
2002-04-16 19:50:10 +04:00
}
return ( type ) ;
}
/**
* xmlSchemaParseComplexContent :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema ComplexContent definition
* * WARNING * this interface is highly subject to change
*
* Returns the type definition or NULL in case of error
*/
static xmlSchemaTypePtr
2003-10-10 04:49:42 +04:00
xmlSchemaParseComplexContent ( xmlSchemaParserCtxtPtr ctxt ,
xmlSchemaPtr schema , xmlNodePtr node )
2002-04-16 19:50:10 +04:00
{
xmlSchemaTypePtr type , subtype ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
2003-10-10 04:49:42 +04:00
snprintf ( ( char * ) name , 30 , " complexContent %d " , ctxt - > counter + + + 1 ) ;
2003-11-22 23:37:51 +03:00
type = xmlSchemaAddType ( ctxt , schema , name , NULL ) ;
2002-04-16 19:50:10 +04:00
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_COMPLEX_CONTENT ;
2003-11-22 23:37:51 +03:00
type - > id = xmlSchemaGetProp ( ctxt , node , " id " ) ;
2002-04-16 19:50:10 +04:00
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
subtype = NULL ;
if ( IS_SCHEMA ( child , " restriction " ) ) {
2003-10-10 04:49:42 +04:00
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseRestriction ( ctxt , schema , child , 0 ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
} else if ( IS_SCHEMA ( child , " extension " ) ) {
2003-10-10 04:49:42 +04:00
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseExtension ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
type - > subtypes = subtype ;
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD ,
" ComplexContent %s has unexpected content \n " ,
type - > name , NULL ) ;
2002-04-16 19:50:10 +04:00
}
return ( type ) ;
}
/**
* xmlSchemaParseComplexType :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema Complex Type definition
* * WARNING * this interface is highly subject to change
*
* Returns the type definition or NULL in case of error
*/
static xmlSchemaTypePtr
xmlSchemaParseComplexType ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
xmlNodePtr node )
{
xmlSchemaTypePtr type , subtype ;
xmlNodePtr child = NULL ;
2003-11-22 23:37:51 +03:00
const xmlChar * name ;
const xmlChar * oldcontainer ;
2004-03-04 14:40:48 +03:00
const xmlChar * mixed ;
2003-11-22 23:37:51 +03:00
char buf [ 100 ] ;
2002-04-16 19:50:10 +04:00
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
oldcontainer = ctxt - > container ;
2003-11-22 23:37:51 +03:00
name = xmlSchemaGetProp ( ctxt , node , " name " ) ;
2002-04-16 19:50:10 +04:00
if ( name = = NULL ) {
2003-11-22 23:37:51 +03:00
snprintf ( buf , 99 , " anontype %d " , ctxt - > counter + + + 1 ) ;
name = ( const xmlChar * ) buf ;
type = xmlSchemaAddType ( ctxt , schema , name , NULL ) ;
} else {
const xmlChar * local , * ns ;
local = xmlSchemaGetNamespace ( ctxt , schema , node , name , & ns ) ;
type = xmlSchemaAddType ( ctxt , schema , local , ns ) ;
2002-04-16 19:50:10 +04:00
}
if ( type = = NULL ) {
return ( NULL ) ;
}
2004-03-04 14:40:48 +03:00
mixed = xmlSchemaGetProp ( ctxt , node , " mixed " ) ;
if ( mixed ! = NULL )
type - > flags | = XML_SCHEMAS_TYPE_MIXED ;
2002-04-16 19:50:10 +04:00
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_COMPLEX ;
2003-11-22 23:37:51 +03:00
type - > id = xmlSchemaGetProp ( ctxt , node , " id " ) ;
2002-04-16 19:50:10 +04:00
ctxt - > container = name ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
2003-10-10 04:49:42 +04:00
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
}
if ( IS_SCHEMA ( child , " simpleContent " ) ) {
2003-10-10 04:49:42 +04:00
type - > subtypes = xmlSchemaParseSimpleContent ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
} else if ( IS_SCHEMA ( child , " complexContent " ) ) {
2003-10-10 04:49:42 +04:00
type - > subtypes = xmlSchemaParseComplexContent ( ctxt , schema , child ) ;
child = child - > next ;
2002-04-16 19:50:10 +04:00
} else {
2003-10-10 04:49:42 +04:00
subtype = NULL ;
if ( IS_SCHEMA ( child , " all " ) ) {
subtype = xmlSchemaParseAll ( ctxt , schema , child ) ;
child = child - > next ;
} else if ( IS_SCHEMA ( child , " choice " ) ) {
subtype = xmlSchemaParseChoice ( ctxt , schema , child ) ;
child = child - > next ;
} else if ( IS_SCHEMA ( child , " sequence " ) ) {
subtype = xmlSchemaParseSequence ( ctxt , schema , child ) ;
child = child - > next ;
} else if ( IS_SCHEMA ( child , " group " ) ) {
subtype = xmlSchemaParseGroup ( ctxt , schema , child ) ;
child = child - > next ;
}
if ( subtype ! = NULL )
type - > subtypes = subtype ;
child = xmlSchemaParseAttrDecls ( ctxt , schema , child , type ) ;
2002-04-16 19:50:10 +04:00
}
if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD ,
" ComplexType %s has unexpected content \n " ,
type - > name , NULL ) ;
2002-04-16 19:50:10 +04:00
}
ctxt - > container = oldcontainer ;
return ( type ) ;
}
/**
* xmlSchemaParseSchema :
* @ ctxt : a schema validation context
* @ node : a subtree containing XML Schema informations
*
* parse a XML schema definition from a node set
* * WARNING * this interface is highly subject to change
*
* Returns the internal XML Schema structure built from the resource or
* NULL in case of error
*/
static xmlSchemaPtr
xmlSchemaParseSchema ( xmlSchemaParserCtxtPtr ctxt , xmlNodePtr node )
{
xmlSchemaPtr schema = NULL ;
xmlNodePtr child = NULL ;
2003-11-22 23:37:51 +03:00
const xmlChar * val ;
2003-05-12 19:25:56 +04:00
int nberrors ;
2002-04-16 19:50:10 +04:00
if ( ( ctxt = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
2003-05-12 19:25:56 +04:00
nberrors = ctxt - > nberrors ;
ctxt - > nberrors = 0 ;
2002-04-16 19:50:10 +04:00
if ( IS_SCHEMA ( node , " schema " ) ) {
schema = xmlSchemaNewSchema ( ctxt ) ;
2003-10-10 04:49:42 +04:00
if ( schema = = NULL )
return ( NULL ) ;
2003-11-22 23:37:51 +03:00
val = xmlSchemaGetProp ( ctxt , node , " targetNamespace " ) ;
if ( val ! = NULL ) {
schema - > targetNamespace = xmlDictLookup ( ctxt - > dict , val , - 1 ) ;
} else {
schema - > targetNamespace = NULL ;
}
schema - > id = xmlSchemaGetProp ( ctxt , node , " id " ) ;
schema - > version = xmlSchemaGetProp ( ctxt , node , " version " ) ;
val = xmlSchemaGetProp ( ctxt , node , " elementFormDefault " ) ;
2003-10-10 04:49:42 +04:00
if ( val ! = NULL ) {
if ( xmlStrEqual ( val , BAD_CAST " qualified " ) )
schema - > flags | = XML_SCHEMAS_QUALIF_ELEM ;
else if ( ! xmlStrEqual ( val , BAD_CAST " unqualified " ) ) {
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_ELEMFORMDEFAULT_VALUE ,
" Invalid value %s for elementFormDefault \n " ,
val , NULL ) ;
}
2003-11-22 23:37:51 +03:00
} else {
schema - > flags | = XML_SCHEMAS_QUALIF_ELEM ;
}
val = xmlSchemaGetProp ( ctxt , node , " attributeFormDefault " ) ;
2003-10-10 04:49:42 +04:00
if ( val ! = NULL ) {
if ( xmlStrEqual ( val , BAD_CAST " qualified " ) )
schema - > flags | = XML_SCHEMAS_QUALIF_ATTR ;
else if ( ! xmlStrEqual ( val , BAD_CAST " unqualified " ) ) {
xmlSchemaPErr2 ( ctxt , node , child ,
XML_SCHEMAP_ATTRFORMDEFAULT_VALUE ,
" Invalid value %s for attributeFormDefault \n " ,
val , NULL ) ;
}
2003-11-22 23:37:51 +03:00
}
2002-04-16 19:50:10 +04:00
2003-11-25 18:38:59 +03:00
xmlSchemaParseSchemaTopLevel ( ctxt , schema , node - > children ) ;
} else {
xmlDocPtr doc ;
doc = node - > doc ;
if ( ( doc ! = NULL ) & & ( doc - > URL ! = NULL ) ) {
xmlSchemaPErr ( ctxt , ( xmlNodePtr ) doc ,
XML_SCHEMAP_NOT_SCHEMA ,
" File %s is not a schemas " , doc - > URL , NULL ) ;
} else {
xmlSchemaPErr ( ctxt , ( xmlNodePtr ) doc ,
XML_SCHEMAP_NOT_SCHEMA ,
" File is not a schemas " , NULL , NULL ) ;
}
return ( NULL ) ;
2002-04-16 19:50:10 +04:00
}
2003-05-12 19:25:56 +04:00
if ( ctxt - > nberrors ! = 0 ) {
if ( schema ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaFree ( schema ) ;
schema = NULL ;
}
2003-05-12 19:25:56 +04:00
}
ctxt - > nberrors = nberrors ;
2002-04-16 19:50:10 +04:00
# ifdef DEBUG
if ( schema = = NULL )
xmlGenericError ( xmlGenericErrorContext ,
" xmlSchemaParse() failed \n " ) ;
# endif
return ( schema ) ;
}
/************************************************************************
* *
* Validating using Schemas *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/************************************************************************
* *
* Reading / Writing Schemas *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlSchemaNewParserCtxt :
* @ URL : the location of the schema
*
* Create an XML Schemas parse context for that file / resource expected
* to contain an XML Schemas file .
*
* Returns the parser context or NULL in case of error
*/
xmlSchemaParserCtxtPtr
2003-10-10 04:49:42 +04:00
xmlSchemaNewParserCtxt ( const char * URL )
{
2002-04-16 19:50:10 +04:00
xmlSchemaParserCtxtPtr ret ;
if ( URL = = NULL )
2003-10-10 04:49:42 +04:00
return ( NULL ) ;
2002-04-16 19:50:10 +04:00
ret = ( xmlSchemaParserCtxtPtr ) xmlMalloc ( sizeof ( xmlSchemaParserCtxt ) ) ;
if ( ret = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErrMemory ( NULL , " allocating schama parser context " ,
NULL ) ;
2002-04-16 19:50:10 +04:00
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaParserCtxt ) ) ;
2003-11-22 23:37:51 +03:00
ret - > dict = xmlDictCreate ( ) ;
ret - > URL = xmlDictLookup ( ret - > dict , ( const xmlChar * ) URL , - 1 ) ;
2003-12-24 02:30:53 +03:00
ret - > includes = 0 ;
2002-04-16 19:50:10 +04:00
return ( ret ) ;
}
2002-10-10 01:13:59 +04:00
/**
* xmlSchemaNewMemParserCtxt :
* @ buffer : a pointer to a char array containing the schemas
* @ size : the size of the array
*
* Create an XML Schemas parse context for that memory buffer expected
* to contain an XML Schemas file .
*
* Returns the parser context or NULL in case of error
*/
xmlSchemaParserCtxtPtr
2003-10-10 04:49:42 +04:00
xmlSchemaNewMemParserCtxt ( const char * buffer , int size )
{
2002-10-10 01:13:59 +04:00
xmlSchemaParserCtxtPtr ret ;
if ( ( buffer = = NULL ) | | ( size < = 0 ) )
2003-10-10 04:49:42 +04:00
return ( NULL ) ;
2002-10-10 01:13:59 +04:00
ret = ( xmlSchemaParserCtxtPtr ) xmlMalloc ( sizeof ( xmlSchemaParserCtxt ) ) ;
if ( ret = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErrMemory ( NULL , " allocating schama parser context " ,
NULL ) ;
2002-10-10 01:13:59 +04:00
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaParserCtxt ) ) ;
ret - > buffer = buffer ;
ret - > size = size ;
2003-12-25 16:24:05 +03:00
ret - > dict = xmlDictCreate ( ) ;
2002-10-10 01:13:59 +04:00
return ( ret ) ;
}
2003-10-29 16:21:47 +03:00
/**
* xmlSchemaNewDocParserCtxt :
* @ doc : a preparsed document tree
*
* Create an XML Schemas parse context for that document .
* NB . The document may be modified during the parsing process .
*
* Returns the parser context or NULL in case of error
*/
xmlSchemaParserCtxtPtr
xmlSchemaNewDocParserCtxt ( xmlDocPtr doc )
{
xmlSchemaParserCtxtPtr ret ;
if ( doc = = NULL )
return ( NULL ) ;
ret = ( xmlSchemaParserCtxtPtr ) xmlMalloc ( sizeof ( xmlSchemaParserCtxt ) ) ;
if ( ret = = NULL ) {
xmlSchemaPErrMemory ( NULL , " allocating schema parser context " ,
NULL ) ;
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaParserCtxt ) ) ;
ret - > doc = doc ;
2003-12-25 16:24:05 +03:00
ret - > dict = xmlDictCreate ( ) ;
2004-01-24 11:31:30 +03:00
/* The application has responsibility for the document */
ret - > preserve = 1 ;
2003-10-29 16:21:47 +03:00
return ( ret ) ;
}
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaFreeParserCtxt :
* @ ctxt : the schema parser context
*
* Free the resources associated to the schema parser context
*/
void
2003-10-10 04:49:42 +04:00
xmlSchemaFreeParserCtxt ( xmlSchemaParserCtxtPtr ctxt )
{
2002-04-16 19:50:10 +04:00
if ( ctxt = = NULL )
2003-10-10 04:49:42 +04:00
return ;
2004-01-24 11:31:30 +03:00
if ( ctxt - > doc ! = NULL & & ! ctxt - > preserve )
2003-10-10 04:49:42 +04:00
xmlFreeDoc ( ctxt - > doc ) ;
2003-11-22 23:37:51 +03:00
xmlDictFree ( ctxt - > dict ) ;
2002-04-16 19:50:10 +04:00
xmlFree ( ctxt ) ;
}
/************************************************************************
* *
* Building the content models *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-10-10 04:49:42 +04:00
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaBuildAContentModel :
* @ type : the schema type definition
* @ ctxt : the schema parser context
* @ name : the element name whose content is being built
*
* Generate the automata sequence needed for that type
*/
static void
xmlSchemaBuildAContentModel ( xmlSchemaTypePtr type ,
2003-10-10 04:49:42 +04:00
xmlSchemaParserCtxtPtr ctxt ,
const xmlChar * name )
{
2002-04-16 19:50:10 +04:00
if ( type = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" Found unexpected type = NULL in %s content model \n " ,
name ) ;
return ;
2002-04-16 19:50:10 +04:00
}
switch ( type - > type ) {
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_TYPE_ANY :
/* TODO : handle the namespace too */
/* TODO : make that a specific transition type */
TODO ctxt - > state =
xmlAutomataNewTransition ( ctxt - > am , ctxt - > state , NULL ,
BAD_CAST " * " , NULL ) ;
break ;
case XML_SCHEMA_TYPE_ELEMENT : {
xmlSchemaElementPtr elem = ( xmlSchemaElementPtr ) type ;
/* TODO : handle the namespace too */
xmlAutomataStatePtr oldstate = ctxt - > state ;
if ( elem - > maxOccurs > = UNBOUNDED ) {
if ( elem - > minOccurs > 1 ) {
xmlAutomataStatePtr tmp ;
int counter ;
ctxt - > state = xmlAutomataNewEpsilon ( ctxt - > am ,
oldstate ,
NULL ) ;
oldstate = ctxt - > state ;
counter = xmlAutomataNewCounter ( ctxt - > am ,
elem - > minOccurs -
1 , UNBOUNDED ) ;
if ( elem - > refDecl ! = NULL ) {
xmlSchemaBuildAContentModel ( ( xmlSchemaTypePtr )
elem - > refDecl ,
ctxt ,
elem - > refDecl - >
name ) ;
} else {
ctxt - > state =
xmlAutomataNewTransition ( ctxt - > am ,
ctxt - > state , NULL ,
elem - > name , type ) ;
}
tmp = ctxt - > state ;
xmlAutomataNewCountedTrans ( ctxt - > am , tmp , oldstate ,
counter ) ;
ctxt - > state =
xmlAutomataNewCounterTrans ( ctxt - > am , tmp , NULL ,
counter ) ;
} else {
if ( elem - > refDecl ! = NULL ) {
xmlSchemaBuildAContentModel ( ( xmlSchemaTypePtr )
elem - > refDecl ,
ctxt ,
elem - > refDecl - >
name ) ;
} else {
ctxt - > state =
xmlAutomataNewTransition ( ctxt - > am ,
ctxt - > state , NULL ,
elem - > name , type ) ;
}
xmlAutomataNewEpsilon ( ctxt - > am , ctxt - > state ,
oldstate ) ;
if ( elem - > minOccurs = = 0 ) {
/* basically an elem* */
xmlAutomataNewEpsilon ( ctxt - > am , oldstate ,
ctxt - > state ) ;
}
}
} else if ( ( elem - > maxOccurs > 1 ) | | ( elem - > minOccurs > 1 ) ) {
xmlAutomataStatePtr tmp ;
int counter ;
ctxt - > state = xmlAutomataNewEpsilon ( ctxt - > am ,
oldstate , NULL ) ;
oldstate = ctxt - > state ;
counter = xmlAutomataNewCounter ( ctxt - > am ,
elem - > minOccurs - 1 ,
elem - > maxOccurs - 1 ) ;
if ( elem - > refDecl ! = NULL ) {
xmlSchemaBuildAContentModel ( ( xmlSchemaTypePtr )
elem - > refDecl , ctxt ,
elem - > refDecl - > name ) ;
} else {
ctxt - > state = xmlAutomataNewTransition ( ctxt - > am ,
ctxt - > state ,
NULL ,
elem - > name ,
type ) ;
}
tmp = ctxt - > state ;
xmlAutomataNewCountedTrans ( ctxt - > am , tmp , oldstate ,
counter ) ;
ctxt - > state = xmlAutomataNewCounterTrans ( ctxt - > am , tmp ,
NULL ,
counter ) ;
if ( elem - > minOccurs = = 0 ) {
/* basically an elem? */
xmlAutomataNewEpsilon ( ctxt - > am , oldstate ,
ctxt - > state ) ;
}
} else {
if ( elem - > refDecl ! = NULL ) {
xmlSchemaBuildAContentModel ( ( xmlSchemaTypePtr )
elem - > refDecl , ctxt ,
elem - > refDecl - > name ) ;
} else {
ctxt - > state = xmlAutomataNewTransition ( ctxt - > am ,
ctxt - > state ,
NULL ,
elem - > name ,
type ) ;
}
if ( elem - > minOccurs = = 0 ) {
/* basically an elem? */
xmlAutomataNewEpsilon ( ctxt - > am , oldstate ,
ctxt - > state ) ;
}
}
break ;
}
case XML_SCHEMA_TYPE_SEQUENCE : {
xmlSchemaTypePtr subtypes ;
/*
* If max and min occurances are default ( 1 ) then
* simply iterate over the subtypes
*/
if ( ( type - > minOccurs = = 1 ) & & ( type - > maxOccurs = = 1 ) ) {
subtypes = type - > subtypes ;
while ( subtypes ! = NULL ) {
xmlSchemaBuildAContentModel ( subtypes , ctxt , name ) ;
subtypes = subtypes - > next ;
}
} else {
xmlAutomataStatePtr oldstate = ctxt - > state ;
if ( type - > maxOccurs > = UNBOUNDED ) {
if ( type - > minOccurs > 1 ) {
xmlAutomataStatePtr tmp ;
int counter ;
ctxt - > state = xmlAutomataNewEpsilon ( ctxt - > am ,
oldstate ,
NULL ) ;
oldstate = ctxt - > state ;
counter = xmlAutomataNewCounter ( ctxt - > am ,
type - >
minOccurs - 1 ,
UNBOUNDED ) ;
subtypes = type - > subtypes ;
while ( subtypes ! = NULL ) {
xmlSchemaBuildAContentModel ( subtypes , ctxt ,
name ) ;
subtypes = subtypes - > next ;
}
tmp = ctxt - > state ;
xmlAutomataNewCountedTrans ( ctxt - > am , tmp ,
oldstate , counter ) ;
ctxt - > state =
xmlAutomataNewCounterTrans ( ctxt - > am , tmp ,
NULL , counter ) ;
} else {
subtypes = type - > subtypes ;
while ( subtypes ! = NULL ) {
xmlSchemaBuildAContentModel ( subtypes , ctxt ,
name ) ;
subtypes = subtypes - > next ;
}
xmlAutomataNewEpsilon ( ctxt - > am , ctxt - > state ,
oldstate ) ;
if ( type - > minOccurs = = 0 ) {
xmlAutomataNewEpsilon ( ctxt - > am , oldstate ,
ctxt - > state ) ;
}
}
} else if ( ( type - > maxOccurs > 1 )
| | ( type - > minOccurs > 1 ) ) {
xmlAutomataStatePtr tmp ;
int counter ;
ctxt - > state = xmlAutomataNewEpsilon ( ctxt - > am ,
oldstate ,
NULL ) ;
oldstate = ctxt - > state ;
counter = xmlAutomataNewCounter ( ctxt - > am ,
type - > minOccurs -
1 ,
type - > maxOccurs -
1 ) ;
subtypes = type - > subtypes ;
while ( subtypes ! = NULL ) {
xmlSchemaBuildAContentModel ( subtypes , ctxt ,
name ) ;
subtypes = subtypes - > next ;
}
tmp = ctxt - > state ;
xmlAutomataNewCountedTrans ( ctxt - > am , tmp , oldstate ,
counter ) ;
ctxt - > state =
xmlAutomataNewCounterTrans ( ctxt - > am , tmp , NULL ,
counter ) ;
if ( type - > minOccurs = = 0 ) {
xmlAutomataNewEpsilon ( ctxt - > am , oldstate ,
ctxt - > state ) ;
}
} else {
subtypes = type - > subtypes ;
while ( subtypes ! = NULL ) {
xmlSchemaBuildAContentModel ( subtypes , ctxt ,
name ) ;
subtypes = subtypes - > next ;
}
if ( type - > minOccurs = = 0 ) {
xmlAutomataNewEpsilon ( ctxt - > am , oldstate ,
ctxt - > state ) ;
}
}
}
break ;
}
case XML_SCHEMA_TYPE_CHOICE : {
xmlSchemaTypePtr subtypes ;
xmlAutomataStatePtr start , end ;
start = ctxt - > state ;
end = xmlAutomataNewState ( ctxt - > am ) ;
/*
* iterate over the subtypes and remerge the end with an
* epsilon transition
*/
if ( type - > maxOccurs = = 1 ) {
subtypes = type - > subtypes ;
while ( subtypes ! = NULL ) {
ctxt - > state = start ;
xmlSchemaBuildAContentModel ( subtypes , ctxt , name ) ;
xmlAutomataNewEpsilon ( ctxt - > am , ctxt - > state , end ) ;
subtypes = subtypes - > next ;
}
} else {
int counter ;
xmlAutomataStatePtr hop ;
int maxOccurs = type - > maxOccurs = = UNBOUNDED ?
UNBOUNDED : type - > maxOccurs - 1 ;
int minOccurs =
type - > minOccurs < 1 ? 0 : type - > minOccurs - 1 ;
/*
* use a counter to keep track of the number of transtions
* which went through the choice .
*/
counter =
xmlAutomataNewCounter ( ctxt - > am , minOccurs ,
maxOccurs ) ;
hop = xmlAutomataNewState ( ctxt - > am ) ;
subtypes = type - > subtypes ;
while ( subtypes ! = NULL ) {
ctxt - > state = start ;
xmlSchemaBuildAContentModel ( subtypes , ctxt , name ) ;
xmlAutomataNewEpsilon ( ctxt - > am , ctxt - > state , hop ) ;
subtypes = subtypes - > next ;
}
xmlAutomataNewCountedTrans ( ctxt - > am , hop , start ,
counter ) ;
xmlAutomataNewCounterTrans ( ctxt - > am , hop , end ,
counter ) ;
}
if ( type - > minOccurs = = 0 ) {
xmlAutomataNewEpsilon ( ctxt - > am , start , end ) ;
}
ctxt - > state = end ;
break ;
}
case XML_SCHEMA_TYPE_ALL : {
xmlAutomataStatePtr start ;
xmlSchemaTypePtr subtypes ;
xmlSchemaElementPtr elem = ( xmlSchemaElementPtr ) type ;
int lax ;
subtypes = type - > subtypes ;
if ( subtypes = = NULL )
break ;
start = ctxt - > state ;
while ( subtypes ! = NULL ) {
ctxt - > state = start ;
elem = ( xmlSchemaElementPtr ) subtypes ;
/* TODO : handle the namespace too */
if ( ( elem - > minOccurs = = 1 ) & & ( elem - > maxOccurs = = 1 ) ) {
xmlAutomataNewOnceTrans ( ctxt - > am , ctxt - > state ,
ctxt - > state , elem - > name , 1 ,
1 , subtypes ) ;
} else {
xmlAutomataNewCountTrans ( ctxt - > am , ctxt - > state ,
ctxt - > state , elem - > name ,
elem - > minOccurs ,
elem - > maxOccurs ,
subtypes ) ;
}
subtypes = subtypes - > next ;
}
lax = type - > minOccurs = = 0 ;
ctxt - > state =
xmlAutomataNewAllTrans ( ctxt - > am , ctxt - > state , NULL ,
lax ) ;
break ;
}
case XML_SCHEMA_TYPE_RESTRICTION :
if ( type - > subtypes ! = NULL )
xmlSchemaBuildAContentModel ( type - > subtypes , ctxt , name ) ;
break ;
case XML_SCHEMA_TYPE_EXTENSION :
if ( type - > baseType ! = NULL ) {
xmlSchemaTypePtr subtypes ;
xmlSchemaBuildAContentModel ( type - > baseType , ctxt , name ) ;
subtypes = type - > subtypes ;
while ( subtypes ! = NULL ) {
xmlSchemaBuildAContentModel ( subtypes , ctxt , name ) ;
subtypes = subtypes - > next ;
}
} else if ( type - > subtypes ! = NULL )
xmlSchemaBuildAContentModel ( type - > subtypes , ctxt , name ) ;
break ;
case XML_SCHEMA_TYPE_GROUP :
if ( type - > subtypes = = NULL ) {
}
case XML_SCHEMA_TYPE_COMPLEX :
case XML_SCHEMA_TYPE_COMPLEX_CONTENT :
if ( type - > subtypes ! = NULL )
xmlSchemaBuildAContentModel ( type - > subtypes , ctxt , name ) ;
break ;
default :
xmlGenericError ( xmlGenericErrorContext ,
" Found unexpected type %d in %s content model \n " ,
type - > type , name ) ;
return ;
2002-04-16 19:50:10 +04:00
}
}
2003-10-10 04:49:42 +04:00
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaBuildContentModel :
2003-06-02 20:58:46 +04:00
* @ elem : the element
2002-04-16 19:50:10 +04:00
* @ ctxt : the schema parser context
2003-06-02 20:58:46 +04:00
* @ name : the element name
2002-04-16 19:50:10 +04:00
*
2003-06-02 20:58:46 +04:00
* Builds the content model of the element .
2002-04-16 19:50:10 +04:00
*/
static void
xmlSchemaBuildContentModel ( xmlSchemaElementPtr elem ,
2003-10-10 04:49:42 +04:00
xmlSchemaParserCtxtPtr ctxt ,
const xmlChar * name )
{
2002-04-16 19:50:10 +04:00
xmlAutomataStatePtr start ;
if ( elem - > contModel ! = NULL )
2003-10-10 04:49:42 +04:00
return ;
2002-04-23 11:12:20 +04:00
if ( elem - > subtypes = = NULL ) {
2003-10-10 04:49:42 +04:00
elem - > contentType = XML_SCHEMA_CONTENT_ANY ;
return ;
2002-04-23 11:12:20 +04:00
}
2002-04-16 19:50:10 +04:00
if ( elem - > subtypes - > type ! = XML_SCHEMA_TYPE_COMPLEX )
2003-10-10 04:49:42 +04:00
return ;
2003-11-22 23:37:51 +03:00
if ( ( elem - > subtypes - > contentType = = XML_SCHEMA_CONTENT_BASIC ) | |
( elem - > subtypes - > contentType = = XML_SCHEMA_CONTENT_SIMPLE ) )
2003-10-10 04:49:42 +04:00
return ;
2002-04-18 18:41:51 +04:00
# ifdef DEBUG_CONTENT
xmlGenericError ( xmlGenericErrorContext ,
2003-10-10 04:49:42 +04:00
" Building content model for %s \n " , name ) ;
2002-04-18 18:41:51 +04:00
# endif
2002-04-16 19:50:10 +04:00
ctxt - > am = xmlNewAutomata ( ) ;
if ( ctxt - > am = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" Cannot create automata for elem %s \n " , name ) ;
return ;
2002-04-16 19:50:10 +04:00
}
start = ctxt - > state = xmlAutomataGetInitState ( ctxt - > am ) ;
xmlSchemaBuildAContentModel ( elem - > subtypes , ctxt , name ) ;
xmlAutomataSetFinalState ( ctxt - > am , ctxt - > state ) ;
2002-09-12 20:02:56 +04:00
elem - > contModel = xmlAutomataCompile ( ctxt - > am ) ;
2003-06-02 20:58:46 +04:00
if ( elem - > contModel = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr ( ctxt , elem - > node , XML_SCHEMAS_ERR_INTERNAL ,
" failed to compile %s content model \n " , name , NULL ) ;
2003-06-02 20:58:46 +04:00
} else if ( xmlRegexpIsDeterminist ( elem - > contModel ) ! = 1 ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr ( ctxt , elem - > node , XML_SCHEMAS_ERR_NOTDETERMINIST ,
" Content model of %s is not determinist: \n " , name ,
NULL ) ;
2002-04-22 20:01:24 +04:00
} else {
2002-09-24 18:13:13 +04:00
# ifdef DEBUG_CONTENT_REGEXP
2003-10-10 04:49:42 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" Content model of %s: \n " , name ) ;
xmlRegexpPrint ( stderr , elem - > contModel ) ;
2002-04-16 19:50:10 +04:00
# endif
2002-04-22 20:01:24 +04:00
}
2003-06-02 20:58:46 +04:00
ctxt - > state = NULL ;
2002-04-16 19:50:10 +04:00
xmlFreeAutomata ( ctxt - > am ) ;
ctxt - > am = NULL ;
}
/**
* xmlSchemaRefFixupCallback :
* @ elem : the schema element context
* @ ctxt : the schema parser context
*
* Free the resources associated to the schema parser context
*/
static void
xmlSchemaRefFixupCallback ( xmlSchemaElementPtr elem ,
2003-10-10 04:49:42 +04:00
xmlSchemaParserCtxtPtr ctxt ,
const xmlChar * name ,
const xmlChar * context ATTRIBUTE_UNUSED ,
const xmlChar * namespace ATTRIBUTE_UNUSED )
2002-04-16 19:50:10 +04:00
{
if ( ( ctxt = = NULL ) | | ( elem = = NULL ) )
2003-10-10 04:49:42 +04:00
return ;
2002-04-16 19:50:10 +04:00
if ( elem - > ref ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaElementPtr elemDecl ;
if ( elem - > subtypes ! = NULL ) {
xmlSchemaPErr ( ctxt , elem - > node ,
XML_SCHEMAP_INVALID_REF_AND_SUBTYPE ,
" Schemas: element %s have both ref and subtype \n " ,
name , NULL ) ;
return ;
}
2003-11-24 16:04:35 +03:00
elemDecl = xmlSchemaGetElem ( ctxt - > schema , elem - > ref , elem - > refNs , 0 ) ;
2002-04-16 19:50:10 +04:00
if ( elemDecl = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr ( ctxt , elem - > node , XML_SCHEMAP_UNKNOWN_REF ,
" Schemas: element %s ref to %s not found \n " ,
name , elem - > ref ) ;
return ;
}
elem - > refDecl = elemDecl ;
2002-04-16 19:50:10 +04:00
} else if ( elem - > namedType ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaTypePtr typeDecl ;
if ( elem - > subtypes ! = NULL ) {
xmlSchemaPErr ( ctxt , elem - > node , XML_SCHEMAP_TYPE_AND_SUBTYPE ,
" Schemas: element %s have both type and subtype \n " ,
name , NULL ) ;
return ;
}
typeDecl = xmlSchemaGetType ( ctxt - > schema , elem - > namedType ,
elem - > namedTypeNs ) ;
2002-04-16 19:50:10 +04:00
if ( typeDecl = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr ( ctxt , elem - > node , XML_SCHEMAP_UNKNOWN_TYPE ,
" Schemas: element %s type %s not found \n " , name ,
elem - > namedType ) ;
return ;
}
elem - > subtypes = typeDecl ;
2002-04-16 19:50:10 +04:00
}
}
2004-04-16 20:30:05 +04:00
static void
xmlSchemaParseUnionRefCheck ( xmlSchemaTypePtr typeDecl ,
xmlSchemaParserCtxtPtr ctxt )
{
const xmlChar * cur , * end , * prefix , * ncName , * namespace ;
xmlChar * tmp ;
xmlSchemaTypePtr subtype ;
xmlNsPtr ns ;
int len ;
if ( ( typeDecl - > type ! = XML_SCHEMA_TYPE_UNION ) | | ( typeDecl - > ref = = NULL ) )
return ;
cur = typeDecl - > ref ;
do {
while ( IS_BLANK_CH ( * cur ) )
cur + + ;
end = cur ;
while ( ( * end ! = 0 ) & & ( ! ( IS_BLANK_CH ( * end ) ) ) )
end + + ;
if ( end = = cur )
break ;
tmp = xmlStrndup ( cur , end - cur ) ;
ncName = xmlSplitQName3 ( tmp , & len ) ;
if ( ncName ! = NULL ) {
prefix = xmlDictLookup ( ctxt - > dict , tmp , len ) ;
} else {
prefix = NULL ;
ncName = tmp ;
}
ns = xmlSearchNs ( typeDecl - > node - > doc , typeDecl - > node , prefix ) ;
if ( ns = = NULL ) {
xmlSchemaPErr ( ctxt , typeDecl - > node , XML_SCHEMAP_PREFIX_UNDEFINED ,
" Union %s: the namespace of member type %s is undefined \n " ,
2004-04-17 18:58:15 +04:00
typeDecl - > name , ( const xmlChar * ) tmp ) ;
namespace = NULL ;
2004-04-16 20:30:05 +04:00
} else {
namespace = xmlDictLookup ( ctxt - > dict , ns - > href , - 1 ) ;
}
/* Lookup the referenced type */
subtype = xmlSchemaGetType ( ctxt - > schema , ncName , namespace ) ;
if ( subtype = = NULL ) {
xmlSchemaPErr ( ctxt , typeDecl - > node , XML_SCHEMAP_UNKNOWN_MEMBER_TYPE ,
" Union %s references an unknown member type >%s< \n " ,
2004-04-17 18:58:15 +04:00
typeDecl - > name , ( const xmlChar * ) tmp ) ;
2004-04-16 20:30:05 +04:00
}
xmlFree ( tmp ) ;
cur = end ;
} while ( * cur ! = 0 ) ;
}
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaTypeFixup :
* @ typeDecl : the schema type definition
* @ ctxt : the schema parser context
*
* Fixes the content model of the type .
*/
static void
xmlSchemaTypeFixup ( xmlSchemaTypePtr typeDecl ,
2003-10-10 04:49:42 +04:00
xmlSchemaParserCtxtPtr ctxt , const xmlChar * name )
2002-04-16 19:50:10 +04:00
{
2003-05-12 00:16:09 +04:00
if ( typeDecl = = NULL )
return ;
2002-04-16 19:50:10 +04:00
if ( name = = NULL )
2003-10-10 04:49:42 +04:00
name = typeDecl - > name ;
2002-04-16 19:50:10 +04:00
if ( typeDecl - > contentType = = XML_SCHEMA_CONTENT_UNKNOWN ) {
2003-10-10 04:49:42 +04:00
switch ( typeDecl - > type ) {
case XML_SCHEMA_TYPE_SIMPLE_CONTENT : {
xmlSchemaTypeFixup ( typeDecl - > subtypes , ctxt , NULL ) ;
if ( typeDecl - > subtypes ! = NULL )
typeDecl - > contentType =
typeDecl - > subtypes - > contentType ;
break ;
}
case XML_SCHEMA_TYPE_RESTRICTION : {
if ( typeDecl - > subtypes ! = NULL )
xmlSchemaTypeFixup ( typeDecl - > subtypes , ctxt , NULL ) ;
if ( typeDecl - > base ! = NULL ) {
xmlSchemaTypePtr baseType ;
baseType =
xmlSchemaGetType ( ctxt - > schema , typeDecl - > base ,
typeDecl - > baseNs ) ;
if ( baseType = = NULL ) {
xmlSchemaPErr ( ctxt , typeDecl - > node ,
XML_SCHEMAP_UNKNOWN_BASE_TYPE ,
2002-04-16 19:50:10 +04:00
" Schemas: type %s base type %s not found \n " ,
2003-10-10 04:49:42 +04:00
name , typeDecl - > base ) ;
}
typeDecl - > baseType = baseType ;
}
2003-11-22 23:37:51 +03:00
if ( typeDecl - > subtypes = = NULL )
if ( typeDecl - > baseType ! = NULL )
typeDecl - > contentType =
typeDecl - > baseType - > contentType ;
else
/* 1.1.1 */
typeDecl - > contentType = XML_SCHEMA_CONTENT_EMPTY ;
2003-10-10 04:49:42 +04:00
else if ( ( typeDecl - > subtypes - > subtypes = = NULL ) & &
( ( typeDecl - > subtypes - > type = =
XML_SCHEMA_TYPE_ALL )
| | ( typeDecl - > subtypes - > type = =
XML_SCHEMA_TYPE_SEQUENCE ) ) )
/* 1.1.2 */
typeDecl - > contentType = XML_SCHEMA_CONTENT_EMPTY ;
else if ( ( typeDecl - > subtypes - > type = =
XML_SCHEMA_TYPE_CHOICE )
& & ( typeDecl - > subtypes - > subtypes = = NULL ) )
/* 1.1.3 */
typeDecl - > contentType = XML_SCHEMA_CONTENT_EMPTY ;
else {
/* 1.2 and 2.X are applied at the other layer */
typeDecl - > contentType =
XML_SCHEMA_CONTENT_ELEMENTS ;
}
break ;
}
case XML_SCHEMA_TYPE_EXTENSION : {
xmlSchemaContentType explicitContentType ;
xmlSchemaTypePtr base ;
if ( typeDecl - > base ! = NULL ) {
xmlSchemaTypePtr baseType ;
baseType =
xmlSchemaGetType ( ctxt - > schema , typeDecl - > base ,
typeDecl - > baseNs ) ;
if ( baseType = = NULL ) {
xmlSchemaPErr ( ctxt , typeDecl - > node ,
XML_SCHEMAP_UNKNOWN_BASE_TYPE ,
2002-04-16 19:50:10 +04:00
" Schemas: type %s base type %s not found \n " ,
2003-10-10 04:49:42 +04:00
name , typeDecl - > base ) ;
}
typeDecl - > baseType = baseType ;
}
if ( typeDecl - > subtypes ! = NULL )
xmlSchemaTypeFixup ( typeDecl - > subtypes , ctxt , NULL ) ;
explicitContentType = XML_SCHEMA_CONTENT_ELEMENTS ;
if ( typeDecl - > subtypes = = NULL )
/* 1.1.1 */
explicitContentType = XML_SCHEMA_CONTENT_EMPTY ;
else if ( ( typeDecl - > subtypes - > subtypes = = NULL ) & &
( ( typeDecl - > subtypes - > type = =
XML_SCHEMA_TYPE_ALL )
| | ( typeDecl - > subtypes - > type = =
XML_SCHEMA_TYPE_SEQUENCE ) ) )
/* 1.1.2 */
explicitContentType = XML_SCHEMA_CONTENT_EMPTY ;
else if ( ( typeDecl - > subtypes - > type = =
XML_SCHEMA_TYPE_CHOICE )
& & ( typeDecl - > subtypes - > subtypes = = NULL ) )
/* 1.1.3 */
explicitContentType = XML_SCHEMA_CONTENT_EMPTY ;
base = xmlSchemaGetType ( ctxt - > schema , typeDecl - > base ,
typeDecl - > baseNs ) ;
if ( base = = NULL ) {
xmlSchemaPErr ( ctxt , typeDecl - > node ,
XML_SCHEMAP_UNKNOWN_BASE_TYPE ,
" Schemas: base type %s of type %s not found \n " ,
typeDecl - > base , name ) ;
return ;
}
2004-04-18 23:49:46 +04:00
if ( typeDecl - > recurse ) {
xmlSchemaPErr ( ctxt , typeDecl - > node ,
XML_SCHEMAP_UNKNOWN_BASE_TYPE ,
" Schemas: extension type %s is recursive \n " ,
name , NULL ) ;
return ;
}
typeDecl - > recurse = 1 ;
2003-10-10 04:49:42 +04:00
xmlSchemaTypeFixup ( base , ctxt , NULL ) ;
2004-04-18 23:49:46 +04:00
typeDecl - > recurse = 0 ;
2003-10-10 04:49:42 +04:00
if ( explicitContentType = = XML_SCHEMA_CONTENT_EMPTY ) {
/* 2.1 */
typeDecl - > contentType = base - > contentType ;
} else if ( base - > contentType = =
XML_SCHEMA_CONTENT_EMPTY ) {
/* 2.2 imbitable ! */
typeDecl - > contentType =
XML_SCHEMA_CONTENT_ELEMENTS ;
} else {
/* 2.3 imbitable pareil ! */
typeDecl - > contentType =
XML_SCHEMA_CONTENT_ELEMENTS ;
}
break ;
}
case XML_SCHEMA_TYPE_COMPLEX : {
if ( typeDecl - > subtypes = = NULL ) {
typeDecl - > contentType = XML_SCHEMA_CONTENT_EMPTY ;
2004-03-04 14:40:48 +03:00
if ( typeDecl - > flags & XML_SCHEMAS_TYPE_MIXED )
typeDecl - > contentType =
XML_SCHEMA_CONTENT_MIXED ;
2003-10-10 04:49:42 +04:00
} else {
if ( typeDecl - > flags & XML_SCHEMAS_TYPE_MIXED )
typeDecl - > contentType =
XML_SCHEMA_CONTENT_MIXED ;
else {
xmlSchemaTypeFixup ( typeDecl - > subtypes , ctxt ,
NULL ) ;
if ( typeDecl - > subtypes ! = NULL )
typeDecl - > contentType =
typeDecl - > subtypes - > contentType ;
}
2003-11-24 16:04:35 +03:00
if ( typeDecl - > attributes = = NULL )
typeDecl - > attributes =
typeDecl - > subtypes - > attributes ;
2003-10-10 04:49:42 +04:00
}
break ;
}
case XML_SCHEMA_TYPE_COMPLEX_CONTENT : {
if ( typeDecl - > subtypes = = NULL ) {
typeDecl - > contentType = XML_SCHEMA_CONTENT_EMPTY ;
2004-03-04 14:40:48 +03:00
if ( typeDecl - > flags & XML_SCHEMAS_TYPE_MIXED )
typeDecl - > contentType =
XML_SCHEMA_CONTENT_MIXED ;
2003-10-10 04:49:42 +04:00
} else {
if ( typeDecl - > flags & XML_SCHEMAS_TYPE_MIXED )
typeDecl - > contentType =
XML_SCHEMA_CONTENT_MIXED ;
else {
xmlSchemaTypeFixup ( typeDecl - > subtypes , ctxt ,
NULL ) ;
if ( typeDecl - > subtypes ! = NULL )
typeDecl - > contentType =
typeDecl - > subtypes - > contentType ;
}
2003-11-24 16:04:35 +03:00
if ( typeDecl - > attributes = = NULL )
typeDecl - > attributes =
typeDecl - > subtypes - > attributes ;
2003-10-10 04:49:42 +04:00
}
break ;
}
case XML_SCHEMA_TYPE_SEQUENCE :
case XML_SCHEMA_TYPE_GROUP :
case XML_SCHEMA_TYPE_ALL :
case XML_SCHEMA_TYPE_CHOICE :
typeDecl - > contentType = XML_SCHEMA_CONTENT_ELEMENTS ;
break ;
case XML_SCHEMA_TYPE_BASIC :
case XML_SCHEMA_TYPE_ANY :
case XML_SCHEMA_TYPE_FACET :
case XML_SCHEMA_TYPE_SIMPLE :
case XML_SCHEMA_TYPE_UR :
case XML_SCHEMA_TYPE_ELEMENT :
case XML_SCHEMA_TYPE_ATTRIBUTE :
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP :
case XML_SCHEMA_TYPE_NOTATION :
case XML_SCHEMA_TYPE_LIST :
case XML_SCHEMA_TYPE_UNION :
2004-04-16 20:30:05 +04:00
xmlSchemaParseUnionRefCheck ( typeDecl , ctxt ) ;
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_FACET_MININCLUSIVE :
case XML_SCHEMA_FACET_MINEXCLUSIVE :
case XML_SCHEMA_FACET_MAXINCLUSIVE :
case XML_SCHEMA_FACET_MAXEXCLUSIVE :
case XML_SCHEMA_FACET_TOTALDIGITS :
case XML_SCHEMA_FACET_FRACTIONDIGITS :
case XML_SCHEMA_FACET_PATTERN :
case XML_SCHEMA_FACET_ENUMERATION :
case XML_SCHEMA_FACET_WHITESPACE :
case XML_SCHEMA_FACET_LENGTH :
case XML_SCHEMA_FACET_MAXLENGTH :
case XML_SCHEMA_FACET_MINLENGTH :
typeDecl - > contentType = XML_SCHEMA_CONTENT_SIMPLE ;
2003-11-22 23:37:51 +03:00
if ( typeDecl - > subtypes ! = NULL )
xmlSchemaTypeFixup ( typeDecl - > subtypes , ctxt , NULL ) ;
2003-10-10 04:49:42 +04:00
break ;
}
}
2002-04-17 13:06:27 +04:00
# ifdef DEBUG_TYPE
2002-04-18 18:41:51 +04:00
if ( typeDecl - > node ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" Type of %s : %s:%d : " , name ,
typeDecl - > node - > doc - > URL ,
xmlGetLineNo ( typeDecl - > node ) ) ;
2002-04-18 18:41:51 +04:00
} else {
2003-10-10 04:49:42 +04:00
xmlGenericError ( xmlGenericErrorContext , " Type of %s : " , name ) ;
2002-04-18 18:41:51 +04:00
}
2002-04-17 13:06:27 +04:00
switch ( typeDecl - > contentType ) {
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_CONTENT_SIMPLE :
xmlGenericError ( xmlGenericErrorContext , " simple \n " ) ;
break ;
case XML_SCHEMA_CONTENT_ELEMENTS :
xmlGenericError ( xmlGenericErrorContext , " elements \n " ) ;
break ;
2002-04-17 13:06:27 +04:00
case XML_SCHEMA_CONTENT_UNKNOWN :
2003-10-10 04:49:42 +04:00
xmlGenericError ( xmlGenericErrorContext , " unknown !!! \n " ) ;
break ;
2002-04-17 13:06:27 +04:00
case XML_SCHEMA_CONTENT_EMPTY :
2003-10-10 04:49:42 +04:00
xmlGenericError ( xmlGenericErrorContext , " empty \n " ) ;
break ;
2002-04-17 13:06:27 +04:00
case XML_SCHEMA_CONTENT_MIXED :
2003-10-10 04:49:42 +04:00
xmlGenericError ( xmlGenericErrorContext , " mixed \n " ) ;
break ;
2002-04-17 13:06:27 +04:00
case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS :
2003-10-10 04:49:42 +04:00
xmlGenericError ( xmlGenericErrorContext , " mixed or elems \n " ) ;
break ;
2002-04-17 13:06:27 +04:00
case XML_SCHEMA_CONTENT_BASIC :
2003-10-10 04:49:42 +04:00
xmlGenericError ( xmlGenericErrorContext , " basic \n " ) ;
break ;
default :
xmlGenericError ( xmlGenericErrorContext ,
" not registered !!! \n " ) ;
break ;
2002-04-17 13:06:27 +04:00
}
# endif
2002-04-16 19:50:10 +04:00
}
2003-02-27 20:42:22 +03:00
/**
* xmlSchemaCheckFacet :
* @ facet : the facet
* @ typeDecl : the schema type definition
* @ ctxt : the schema parser context or NULL
* @ name : name of the type
*
* Checks the default values types , especially for facets
*
* Returns 0 if okay or - 1 in cae of error
*/
int
xmlSchemaCheckFacet ( xmlSchemaFacetPtr facet ,
2003-10-10 04:49:42 +04:00
xmlSchemaTypePtr typeDecl ,
xmlSchemaParserCtxtPtr ctxt , const xmlChar * name )
2003-02-27 20:42:22 +03:00
{
static xmlSchemaTypePtr nonNegativeIntegerType = NULL ;
int ret = 0 ;
if ( nonNegativeIntegerType = = NULL ) {
2003-10-10 04:49:42 +04:00
nonNegativeIntegerType =
xmlSchemaGetPredefinedType ( BAD_CAST " nonNegativeInteger " ,
xmlSchemaNs ) ;
2003-02-27 20:42:22 +03:00
}
switch ( facet - > type ) {
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_FACET_MININCLUSIVE :
case XML_SCHEMA_FACET_MINEXCLUSIVE :
case XML_SCHEMA_FACET_MAXINCLUSIVE :
case XML_SCHEMA_FACET_MAXEXCLUSIVE : {
/*
* Okay we need to validate the value
* at that point .
*/
xmlSchemaValidCtxtPtr vctxt ;
vctxt = xmlSchemaNewValidCtxt ( NULL ) ;
if ( vctxt = = NULL )
break ;
xmlSchemaValidateSimpleValue ( vctxt , typeDecl ,
facet - > value ) ;
facet - > val = vctxt - > value ;
vctxt - > value = NULL ;
if ( facet - > val = = NULL ) {
/* error code */
if ( ctxt ! = NULL ) {
xmlSchemaPErr ( ctxt , facet - > node ,
XML_SCHEMAP_INVALID_FACET ,
" Schemas: type %s facet value %s invalid \n " ,
name , facet - > value ) ;
}
ret = - 1 ;
}
xmlSchemaFreeValidCtxt ( vctxt ) ;
break ;
}
case XML_SCHEMA_FACET_ENUMERATION : {
/*
* Okay we need to validate the value
* at that point .
*/
xmlSchemaValidCtxtPtr vctxt ;
int tmp ;
vctxt = xmlSchemaNewValidCtxt ( NULL ) ;
if ( vctxt = = NULL )
break ;
tmp = xmlSchemaValidateSimpleValue ( vctxt , typeDecl ,
facet - > value ) ;
if ( tmp ! = 0 ) {
if ( ctxt ! = NULL ) {
xmlSchemaPErr ( ctxt , facet - > node ,
XML_SCHEMAP_INVALID_ENUM ,
" Schemas: type %s enumeration value %s invalid \n " ,
name , facet - > value ) ;
}
ret = - 1 ;
}
xmlSchemaFreeValidCtxt ( vctxt ) ;
break ;
}
case XML_SCHEMA_FACET_PATTERN :
facet - > regexp = xmlRegexpCompile ( facet - > value ) ;
if ( facet - > regexp = = NULL ) {
xmlSchemaPErr ( ctxt , typeDecl - > node ,
XML_SCHEMAP_REGEXP_INVALID ,
" Schemas: type %s facet regexp %s invalid \n " ,
name , facet - > value ) ;
ret = - 1 ;
}
break ;
case XML_SCHEMA_FACET_TOTALDIGITS :
case XML_SCHEMA_FACET_FRACTIONDIGITS :
case XML_SCHEMA_FACET_LENGTH :
case XML_SCHEMA_FACET_MAXLENGTH :
case XML_SCHEMA_FACET_MINLENGTH : {
int tmp ;
tmp =
xmlSchemaValidatePredefinedType ( nonNegativeIntegerType ,
facet - > value ,
& facet - > val ) ;
if ( tmp ! = 0 ) {
/* error code */
if ( ctxt ! = NULL ) {
xmlSchemaPErr ( ctxt , facet - > node ,
XML_SCHEMAP_INVALID_FACET_VALUE ,
" Schemas: type %s facet value %s invalid \n " ,
name , facet - > value ) ;
}
ret = - 1 ;
}
break ;
}
case XML_SCHEMA_FACET_WHITESPACE : {
if ( xmlStrEqual ( facet - > value , BAD_CAST " preserve " ) ) {
facet - > whitespace = XML_SCHEMAS_FACET_PRESERVE ;
} else if ( xmlStrEqual ( facet - > value , BAD_CAST " replace " ) ) {
facet - > whitespace = XML_SCHEMAS_FACET_REPLACE ;
} else if ( xmlStrEqual ( facet - > value , BAD_CAST " collapse " ) ) {
facet - > whitespace = XML_SCHEMAS_FACET_COLLAPSE ;
} else {
if ( ctxt ! = NULL ) {
xmlSchemaPErr ( ctxt , facet - > node ,
XML_SCHEMAP_INVALID_WHITE_SPACE ,
" Schemas: type %s whiteSpace value %s invalid \n " ,
name , facet - > value ) ;
}
ret = - 1 ;
}
}
default :
break ;
}
return ( ret ) ;
2003-02-27 20:42:22 +03:00
}
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaCheckDefaults :
* @ typeDecl : the schema type definition
* @ ctxt : the schema parser context
*
* Checks the default values types , especially for facets
*/
static void
xmlSchemaCheckDefaults ( xmlSchemaTypePtr typeDecl ,
2003-10-10 04:49:42 +04:00
xmlSchemaParserCtxtPtr ctxt , const xmlChar * name )
2002-04-16 19:50:10 +04:00
{
if ( name = = NULL )
2003-10-10 04:49:42 +04:00
name = typeDecl - > name ;
2002-04-16 19:50:10 +04:00
if ( typeDecl - > type = = XML_SCHEMA_TYPE_RESTRICTION ) {
2003-10-10 04:49:42 +04:00
if ( typeDecl - > facets ! = NULL ) {
xmlSchemaFacetPtr facet = typeDecl - > facets ;
while ( facet ! = NULL ) {
xmlSchemaCheckFacet ( facet , typeDecl , ctxt , name ) ;
facet = facet - > next ;
}
}
2002-04-16 19:50:10 +04:00
}
}
2002-04-23 21:51:29 +04:00
/**
* xmlSchemaAttrGrpFixup :
* @ attrgrpDecl : the schema attribute definition
* @ ctxt : the schema parser context
* @ name : the attribute name
*
* Fixes finish doing the computations on the attributes definitions
*/
static void
xmlSchemaAttrGrpFixup ( xmlSchemaAttributeGroupPtr attrgrpDecl ,
2003-10-10 04:49:42 +04:00
xmlSchemaParserCtxtPtr ctxt , const xmlChar * name )
2002-04-23 21:51:29 +04:00
{
if ( name = = NULL )
2003-10-10 04:49:42 +04:00
name = attrgrpDecl - > name ;
2002-04-23 21:51:29 +04:00
if ( attrgrpDecl - > attributes ! = NULL )
2003-10-10 04:49:42 +04:00
return ;
2002-04-23 21:51:29 +04:00
if ( attrgrpDecl - > ref ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaAttributeGroupPtr ref ;
ref = xmlHashLookup2 ( ctxt - > schema - > attrgrpDecl , attrgrpDecl - > ref ,
attrgrpDecl - > refNs ) ;
if ( ref = = NULL ) {
xmlSchemaPErr ( ctxt , attrgrpDecl - > node ,
XML_SCHEMAP_UNKNOWN_ATTRIBUTE_GROUP ,
" Schemas: attribute group %s reference %s not found \n " ,
name , attrgrpDecl - > ref ) ;
return ;
}
xmlSchemaAttrGrpFixup ( ref , ctxt , NULL ) ;
attrgrpDecl - > attributes = ref - > attributes ;
2002-04-23 21:51:29 +04:00
} else {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr ( ctxt , attrgrpDecl - > node , XML_SCHEMAP_NOATTR_NOREF ,
" Schemas: attribute %s has no attributes nor reference \n " ,
name , NULL ) ;
2002-04-23 21:51:29 +04:00
}
}
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaAttrFixup :
* @ attrDecl : the schema attribute definition
* @ ctxt : the schema parser context
* @ name : the attribute name
*
* Fixes finish doing the computations on the attributes definitions
*/
static void
xmlSchemaAttrFixup ( xmlSchemaAttributePtr attrDecl ,
2003-10-10 04:49:42 +04:00
xmlSchemaParserCtxtPtr ctxt , const xmlChar * name )
2002-04-16 19:50:10 +04:00
{
if ( name = = NULL )
2003-10-10 04:49:42 +04:00
name = attrDecl - > name ;
2002-04-16 19:50:10 +04:00
if ( attrDecl - > subtypes ! = NULL )
2003-10-10 04:49:42 +04:00
return ;
2002-04-16 19:50:10 +04:00
if ( attrDecl - > typeName ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaTypePtr type ;
type = xmlSchemaGetType ( ctxt - > schema , attrDecl - > typeName ,
attrDecl - > typeNs ) ;
if ( type = = NULL ) {
xmlSchemaPErr ( ctxt , attrDecl - > node , XML_SCHEMAP_UNKNOWN_TYPE ,
" Schemas: attribute %s type %s not found \n " ,
name , attrDecl - > typeName ) ;
}
attrDecl - > subtypes = type ;
2002-04-16 19:50:10 +04:00
} else if ( attrDecl - > ref ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaAttributePtr ref ;
ref = xmlHashLookup2 ( ctxt - > schema - > attrDecl , attrDecl - > ref ,
attrDecl - > refNs ) ;
if ( ref = = NULL ) {
xmlSchemaPErr ( ctxt , attrDecl - > node , XML_SCHEMAP_UNKNOWN_REF ,
" Schemas: attribute %s reference %s not found \n " ,
name , attrDecl - > ref ) ;
return ;
}
xmlSchemaAttrFixup ( ref , ctxt , NULL ) ;
attrDecl - > subtypes = ref - > subtypes ;
2002-04-16 19:50:10 +04:00
} else {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr ( ctxt , attrDecl - > node , XML_SCHEMAP_NOTYPE_NOREF ,
" Schemas: attribute %s has no type nor reference \n " ,
name , NULL ) ;
2002-04-16 19:50:10 +04:00
}
}
/**
* xmlSchemaParse :
* @ ctxt : a schema validation context
*
2002-12-10 18:19:08 +03:00
* parse a schema definition resource and build an internal
2002-04-16 19:50:10 +04:00
* XML Shema struture which can be used to validate instances .
* * WARNING * this interface is highly subject to change
*
* Returns the internal XML Schema structure built from the resource or
* NULL in case of error
*/
xmlSchemaPtr
xmlSchemaParse ( xmlSchemaParserCtxtPtr ctxt )
{
xmlSchemaPtr ret = NULL ;
xmlDocPtr doc ;
2003-11-25 18:38:59 +03:00
xmlNodePtr root ;
2003-05-12 19:25:56 +04:00
int nberrors ;
2004-01-24 11:31:30 +03:00
int preserve = 0 ;
2002-04-16 19:50:10 +04:00
xmlSchemaInitTypes ( ) ;
2002-10-10 01:13:59 +04:00
if ( ctxt = = NULL )
2002-04-16 19:50:10 +04:00
return ( NULL ) ;
2003-05-12 19:25:56 +04:00
nberrors = ctxt - > nberrors ;
ctxt - > nberrors = 0 ;
2002-04-16 19:50:10 +04:00
ctxt - > counter = 0 ;
ctxt - > container = NULL ;
/*
* First step is to parse the input document into an DOM / Infoset
*/
2002-10-10 01:13:59 +04:00
if ( ctxt - > URL ! = NULL ) {
2003-11-25 18:38:59 +03:00
doc = xmlReadFile ( ( const char * ) ctxt - > URL , NULL ,
SCHEMAS_PARSE_OPTIONS ) ;
2003-10-10 04:49:42 +04:00
if ( doc = = NULL ) {
xmlSchemaPErr ( ctxt , NULL ,
XML_SCHEMAP_FAILED_LOAD ,
" xmlSchemaParse: could not load %s \n " ,
ctxt - > URL , NULL ) ;
return ( NULL ) ;
}
2002-10-10 01:13:59 +04:00
} else if ( ctxt - > buffer ! = NULL ) {
2003-11-25 18:38:59 +03:00
doc = xmlReadMemory ( ctxt - > buffer , ctxt - > size , NULL , NULL ,
SCHEMAS_PARSE_OPTIONS ) ;
2003-10-10 04:49:42 +04:00
if ( doc = = NULL ) {
xmlSchemaPErr ( ctxt , NULL ,
XML_SCHEMAP_FAILED_PARSE ,
" xmlSchemaParse: could not parse \n " ,
NULL , NULL ) ;
return ( NULL ) ;
}
doc - > URL = xmlStrdup ( BAD_CAST " in_memory_buffer " ) ;
2004-01-08 19:59:30 +03:00
ctxt - > URL = xmlDictLookup ( ctxt - > dict , BAD_CAST " in_memory_buffer " , - 1 ) ;
2003-10-29 16:21:47 +03:00
} else if ( ctxt - > doc ! = NULL ) {
doc = ctxt - > doc ;
2004-01-24 11:31:30 +03:00
preserve = 1 ;
2002-10-10 01:13:59 +04:00
} else {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr ( ctxt , NULL ,
XML_SCHEMAP_NOTHING_TO_PARSE ,
" xmlSchemaParse: could not parse \n " ,
NULL , NULL ) ;
return ( NULL ) ;
2002-04-16 19:50:10 +04:00
}
/*
* Then extract the root and Schema parse it
*/
root = xmlDocGetRootElement ( doc ) ;
if ( root = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaPErr ( ctxt , ( xmlNodePtr ) doc ,
XML_SCHEMAP_NOROOT ,
" schemas has no root " , NULL , NULL ) ;
2004-01-24 11:31:30 +03:00
if ( ! preserve ) {
xmlFreeDoc ( doc ) ;
}
2002-04-16 19:50:10 +04:00
return ( NULL ) ;
}
/*
* Remove all the blank text nodes
*/
2003-11-25 18:38:59 +03:00
xmlSchemaCleanupDoc ( ctxt , root ) ;
2002-04-16 19:50:10 +04:00
/*
* Then do the parsing for good
*/
ret = xmlSchemaParseSchema ( ctxt , root ) ;
2003-11-21 03:28:39 +03:00
if ( ret = = NULL ) {
2004-01-24 11:31:30 +03:00
if ( ! preserve ) {
xmlFreeDoc ( doc ) ;
}
2003-10-10 04:49:42 +04:00
return ( NULL ) ;
2003-11-21 03:28:39 +03:00
}
2002-04-16 19:50:10 +04:00
ret - > doc = doc ;
2004-01-24 11:31:30 +03:00
ret - > preserve = preserve ;
2002-04-16 19:50:10 +04:00
/*
* Then fix all the references .
*/
ctxt - > schema = ret ;
xmlHashScanFull ( ret - > elemDecl ,
2003-10-10 04:49:42 +04:00
( xmlHashScannerFull ) xmlSchemaRefFixupCallback , ctxt ) ;
2002-04-16 19:50:10 +04:00
2003-11-24 16:04:35 +03:00
/*
* Then fixup all attributes declarations
*/
xmlHashScan ( ret - > attrDecl , ( xmlHashScanner ) xmlSchemaAttrFixup , ctxt ) ;
/*
* Then fixup all attributes group declarations
*/
xmlHashScan ( ret - > attrgrpDecl , ( xmlHashScanner ) xmlSchemaAttrGrpFixup ,
ctxt ) ;
2002-04-16 19:50:10 +04:00
/*
* Then fixup all types properties
*/
xmlHashScan ( ret - > typeDecl , ( xmlHashScanner ) xmlSchemaTypeFixup , ctxt ) ;
/*
* Then build the content model for all elements
*/
xmlHashScan ( ret - > elemDecl ,
2003-10-10 04:49:42 +04:00
( xmlHashScanner ) xmlSchemaBuildContentModel , ctxt ) ;
2002-04-16 19:50:10 +04:00
/*
* Then check the defaults part of the type like facets values
*/
2003-10-10 04:49:42 +04:00
xmlHashScan ( ret - > typeDecl , ( xmlHashScanner ) xmlSchemaCheckDefaults ,
ctxt ) ;
2002-04-16 19:50:10 +04:00
2003-05-12 19:25:56 +04:00
if ( ctxt - > nberrors ! = 0 ) {
xmlSchemaFree ( ret ) ;
2003-10-10 04:49:42 +04:00
ret = NULL ;
2003-05-12 19:25:56 +04:00
}
2002-04-16 19:50:10 +04:00
return ( ret ) ;
}
2003-10-10 04:49:42 +04:00
2002-04-16 19:50:10 +04:00
/**
2002-12-10 18:19:08 +03:00
* xmlSchemaSetParserErrors :
2002-04-16 19:50:10 +04:00
* @ ctxt : a schema validation context
2002-12-10 18:19:08 +03:00
* @ err : the error callback
* @ warn : the warning callback
* @ ctx : contextual data for the callbacks
2002-04-16 19:50:10 +04:00
*
2002-12-10 18:19:08 +03:00
* Set the callback functions used to handle errors for a validation context
2002-04-16 19:50:10 +04:00
*/
void
xmlSchemaSetParserErrors ( xmlSchemaParserCtxtPtr ctxt ,
2003-10-10 04:49:42 +04:00
xmlSchemaValidityErrorFunc err ,
xmlSchemaValidityWarningFunc warn , void * ctx )
{
2002-04-16 19:50:10 +04:00
if ( ctxt = = NULL )
2003-10-10 04:49:42 +04:00
return ;
2002-04-16 19:50:10 +04:00
ctxt - > error = err ;
ctxt - > warning = warn ;
ctxt - > userData = ctx ;
}
2003-04-09 15:24:17 +04:00
/**
* xmlSchemaFacetTypeToString :
* @ type : the facet type
*
* Convert the xmlSchemaTypeType to a char string .
*
* Returns the char string representation of the facet type if the
* type is a facet and an " Internal Error " string otherwise .
*/
static const char *
xmlSchemaFacetTypeToString ( xmlSchemaTypeType type )
{
switch ( type ) {
case XML_SCHEMA_FACET_PATTERN :
return ( " pattern " ) ;
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_FACET_MAXEXCLUSIVE :
2003-04-09 15:24:17 +04:00
return ( " maxExclusive " ) ;
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_FACET_MAXINCLUSIVE :
2003-04-09 15:24:17 +04:00
return ( " maxInclusive " ) ;
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_FACET_MINEXCLUSIVE :
2003-04-09 15:24:17 +04:00
return ( " minExclusive " ) ;
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_FACET_MININCLUSIVE :
2003-04-09 15:24:17 +04:00
return ( " minInclusive " ) ;
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_FACET_WHITESPACE :
2003-04-09 15:24:17 +04:00
return ( " whiteSpace " ) ;
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_FACET_ENUMERATION :
2003-04-09 15:24:17 +04:00
return ( " enumeration " ) ;
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_FACET_LENGTH :
2003-04-09 15:24:17 +04:00
return ( " length " ) ;
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_FACET_MAXLENGTH :
2003-04-09 15:24:17 +04:00
return ( " maxLength " ) ;
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_FACET_MINLENGTH :
2003-04-09 15:24:17 +04:00
return ( " minLength " ) ;
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_FACET_TOTALDIGITS :
2003-04-09 15:24:17 +04:00
return ( " totalDigits " ) ;
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_FACET_FRACTIONDIGITS :
2003-04-09 15:24:17 +04:00
return ( " fractionDigits " ) ;
default :
break ;
}
return ( " Internal Error " ) ;
}
2004-04-16 20:30:05 +04:00
/**
* xmlSchemaValidateFacetsInternal :
* @ ctxt : a schema validation context
* @ base : the base type
* @ facets : the list of facets to check
* @ value : the lexical repr of the value to validate
* @ val : the precomputed value
* @ fireErrors : if 0 , only internal errors will be fired ; otherwise all errors will be fired .
*
* Check a value against all facet conditions
*
* Returns 0 if the element is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
static int
xmlSchemaValidateFacetsInternal ( xmlSchemaValidCtxtPtr ctxt ,
xmlSchemaTypePtr base ,
xmlSchemaFacetPtr facets , const xmlChar * value , int fireErrors )
2003-10-10 04:49:42 +04:00
{
2003-04-09 15:24:17 +04:00
int ret = 0 ;
int tmp = 0 ;
xmlSchemaTypeType type ;
xmlSchemaFacetPtr facet = facets ;
while ( facet ! = NULL ) {
type = facet - > type ;
if ( type = = XML_SCHEMA_FACET_ENUMERATION ) {
2003-10-10 04:49:42 +04:00
tmp = 1 ;
2003-04-09 15:24:17 +04:00
2003-10-10 04:49:42 +04:00
while ( facet ! = NULL ) {
tmp =
xmlSchemaValidateFacet ( base , facet , value ,
ctxt - > value ) ;
if ( tmp = = 0 ) {
2003-04-09 15:24:17 +04:00
return 0 ;
2003-10-10 04:49:42 +04:00
}
facet = facet - > next ;
}
2003-04-09 15:24:17 +04:00
} else
2003-10-10 04:49:42 +04:00
tmp = xmlSchemaValidateFacet ( base , facet , value , ctxt - > value ) ;
2003-04-09 15:24:17 +04:00
if ( tmp ! = 0 ) {
ret = tmp ;
2004-04-16 20:30:05 +04:00
if ( fireErrors )
xmlSchemaVErr ( ctxt , ctxt - > cur , XML_SCHEMAS_ERR_FACET , " Failed to validate type with facet %s \n " , ( const xmlChar * ) xmlSchemaFacetTypeToString ( type ) , NULL ) ;
2003-04-09 15:24:17 +04:00
}
if ( facet ! = NULL )
facet = facet - > next ;
}
return ( ret ) ;
}
2004-04-17 18:58:15 +04:00
/**
* xmlSchemaValidateFacets :
* @ ctxt : a schema validation context
* @ base : the base type
* @ facets : the list of facets to check
* @ value : the lexical repr of the value to validate
* @ val : the precomputed value
*
* Check a value against all facet conditions
*
* Returns 0 if the element is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
static int
xmlSchemaValidateFacets ( xmlSchemaValidCtxtPtr ctxt ,
xmlSchemaTypePtr base ,
xmlSchemaFacetPtr facets , const xmlChar * value )
{
return ( xmlSchemaValidateFacetsInternal ( ctxt , base , facets , value , 1 ) ) ;
}
2002-04-16 19:50:10 +04:00
/************************************************************************
* *
* Simple type validation *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-04-16 20:30:05 +04:00
/**
* xmlSchemaValidateSimpleValueUnion :
* @ ctxt : a schema validation context
* @ type : the type declaration
* @ value : the value to validate
*
* Validates a value against a union .
*
* Returns 0 if the value is valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
static int
xmlSchemaValidateSimpleValueUnion ( xmlSchemaValidCtxtPtr ctxt ,
xmlSchemaTypePtr type , const xmlChar * value )
{
int ret = 0 ;
const xmlChar * cur , * end , * prefix , * ncName ;
xmlChar * tmp ;
xmlSchemaTypePtr subtype ;
xmlNsPtr ns ;
int len ;
/* Process referenced memberTypes. */
cur = type - > ref ;
do {
while ( IS_BLANK_CH ( * cur ) )
cur + + ;
end = cur ;
while ( ( * end ! = 0 ) & & ( ! ( IS_BLANK_CH ( * end ) ) ) )
end + + ;
if ( end = = cur )
break ;
tmp = xmlStrndup ( cur , end - cur ) ;
ncName = xmlSplitQName3 ( tmp , & len ) ;
if ( ncName ! = NULL ) {
prefix = xmlStrndup ( tmp , len ) ;
/* prefix = xmlDictLookup(ctxt->doc->dict, tmp, len); */
} else {
prefix = NULL ;
ncName = tmp ;
}
/* We won't do additional checks here, since they have been performed during parsing. */
ns = xmlSearchNs ( type - > node - > doc , type - > node , prefix ) ;
/* namespace = xmlDictLookup(ctxt->doc->dict, ns->href, -1); */
subtype = xmlSchemaGetType ( ctxt - > schema , ncName , ns - > href ) ;
if ( tmp ! = NULL )
xmlFree ( tmp ) ;
if ( prefix ! = NULL )
2004-04-17 18:58:15 +04:00
xmlFree ( ( void * ) prefix ) ;
2004-04-16 20:30:05 +04:00
ret = xmlSchemaValidateSimpleValueInternal ( ctxt , subtype , value , 0 ) ;
if ( ( ret = = 0 ) | | ( ret = = - 1 ) ) {
return ( ret ) ;
}
cur = end ;
} while ( * cur ! = 0 ) ;
if ( type - > subtypes ! = NULL ) {
subtype = type - > subtypes ;
do {
ret = xmlSchemaValidateSimpleValueInternal ( ctxt , subtype , value , 0 ) ;
if ( ( ret = = 0 ) | | ( ret = = - 1 ) ) {
return ( ret ) ;
}
subtype = subtype - > next ;
} while ( subtype ! = NULL ) ;
}
return ( ret ) ;
}
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaValidateSimpleValue :
* @ ctxt : a schema validation context
* @ type : the type declaration
* @ value : the value to validate
*
* Validate a value against a simple type
*
* Returns 0 if the value is valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
static int
2003-10-10 04:49:42 +04:00
xmlSchemaValidateSimpleValue ( xmlSchemaValidCtxtPtr ctxt ,
2003-11-22 23:37:51 +03:00
xmlSchemaTypePtr type , const xmlChar * value )
2004-04-16 20:30:05 +04:00
{
return ( xmlSchemaValidateSimpleValueInternal ( ctxt , type , value , 1 ) ) ;
}
/**
* xmlSchemaValidateSimpleValue :
* @ ctxt : a schema validation context
* @ type : the type declaration
* @ value : the value to validate
* @ fireErrors : if 0 , only internal errors will be fired ; otherwise all errors will be fired .
*
* Validate a value against a simple type
*
* Returns 0 if the value is valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
static int
xmlSchemaValidateSimpleValueInternal ( xmlSchemaValidCtxtPtr ctxt ,
xmlSchemaTypePtr type , const xmlChar * value , int fireErrors )
2003-10-10 04:49:42 +04:00
{
2002-04-16 19:50:10 +04:00
int ret = 0 ;
2003-10-10 04:49:42 +04:00
2002-04-16 19:50:10 +04:00
/*
* First normalize the value accordingly to Schema Datatype
* 4.3 .6 whiteSpace definition of the whiteSpace facet of type
*/
/*
* Then check the normalized value against the lexical space of the
* type .
*/
if ( type - > type = = XML_SCHEMA_TYPE_BASIC ) {
2003-10-10 04:49:42 +04:00
if ( ctxt - > value ! = NULL ) {
xmlSchemaFreeValue ( ctxt - > value ) ;
ctxt - > value = NULL ;
}
ret = xmlSchemaValPredefTypeNode ( type , value , & ( ctxt - > value ) ,
ctxt - > cur ) ;
2004-04-16 20:30:05 +04:00
if ( ( fireErrors ) & & ( ret ! = 0 ) ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , ctxt - > cur , XML_SCHEMAS_ERR_VALUE , " Failed to validate basic type %s \n " , type - > name , NULL ) ;
2003-04-09 15:24:17 +04:00
}
2002-04-16 19:50:10 +04:00
} else if ( type - > type = = XML_SCHEMA_TYPE_RESTRICTION ) {
2003-10-10 04:49:42 +04:00
xmlSchemaTypePtr base ;
xmlSchemaFacetPtr facet ;
base = type - > baseType ;
if ( base ! = NULL ) {
2004-04-16 20:30:05 +04:00
ret = xmlSchemaValidateSimpleValueInternal ( ctxt , base , value , fireErrors ) ;
2003-10-10 04:49:42 +04:00
} else if ( type - > subtypes ! = NULL ) {
2003-11-22 23:37:51 +03:00
TODO
2003-10-10 04:49:42 +04:00
}
2003-11-22 23:37:51 +03:00
2003-10-10 04:49:42 +04:00
/*
2003-11-24 16:04:35 +03:00
* Do not validate facets or attributes when working on
* building the Schemas
2003-10-10 04:49:42 +04:00
*/
if ( ctxt - > schema ! = NULL ) {
if ( ret = = 0 ) {
facet = type - > facets ;
2004-04-16 20:30:05 +04:00
ret = xmlSchemaValidateFacetsInternal ( ctxt , base , facet , value , fireErrors ) ;
2003-10-10 04:49:42 +04:00
}
}
2002-04-16 19:50:10 +04:00
} else if ( type - > type = = XML_SCHEMA_TYPE_SIMPLE ) {
2003-10-10 04:49:42 +04:00
xmlSchemaTypePtr base ;
base = type - > subtypes ;
if ( base ! = NULL ) {
2004-04-16 20:30:05 +04:00
ret = xmlSchemaValidateSimpleValueInternal ( ctxt , base , value , fireErrors ) ;
2003-10-10 04:49:42 +04:00
} else {
TODO }
2002-04-16 19:50:10 +04:00
} else if ( type - > type = = XML_SCHEMA_TYPE_LIST ) {
2003-10-10 04:49:42 +04:00
xmlSchemaTypePtr base ;
2003-11-22 23:37:51 +03:00
const xmlChar * cur , * end ;
xmlChar * tmp ;
2003-10-10 04:49:42 +04:00
int ret2 ;
base = type - > subtypes ;
if ( base = = NULL ) {
xmlSchemaVErr ( ctxt , type - > node , XML_SCHEMAS_ERR_INTERNAL ,
" Internal: List type %s has no base type \n " ,
type - > name , NULL ) ;
return ( - 1 ) ;
}
cur = value ;
do {
2003-10-18 20:20:14 +04:00
while ( IS_BLANK_CH ( * cur ) )
2003-10-10 04:49:42 +04:00
cur + + ;
end = cur ;
2003-10-18 20:20:14 +04:00
while ( ( * end ! = 0 ) & & ( ! ( IS_BLANK_CH ( * end ) ) ) )
2003-10-10 04:49:42 +04:00
end + + ;
if ( end = = cur )
break ;
2003-11-22 23:37:51 +03:00
tmp = xmlStrndup ( cur , end - cur ) ;
2004-04-16 20:30:05 +04:00
ret2 = xmlSchemaValidateSimpleValueInternal ( ctxt , base , tmp , fireErrors ) ;
2003-11-22 23:37:51 +03:00
xmlFree ( tmp ) ;
2003-10-10 04:49:42 +04:00
if ( ret2 ! = 0 )
ret = 1 ;
cur = end ;
} while ( * cur ! = 0 ) ;
2004-04-16 20:30:05 +04:00
} else if ( type - > type = = XML_SCHEMA_TYPE_UNION ) {
ret = xmlSchemaValidateSimpleValueUnion ( ctxt , type , value ) ;
if ( ( fireErrors ) & & ( ret ! = 0 ) ) {
xmlSchemaVErr ( ctxt , ctxt - > cur , XML_SCHEMAS_ERR_VALUE , " Failed to validate type %s \n " , type - > name , NULL ) ;
}
2002-04-16 19:50:10 +04:00
} else {
2003-11-22 23:37:51 +03:00
TODO
}
2003-10-10 04:49:42 +04:00
return ( ret ) ;
2002-04-16 19:50:10 +04:00
}
/************************************************************************
* *
* DOM Validation code *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int xmlSchemaValidateContent ( xmlSchemaValidCtxtPtr ctxt ,
2003-10-10 04:49:42 +04:00
xmlNodePtr node ) ;
2002-04-16 19:50:10 +04:00
static int xmlSchemaValidateAttributes ( xmlSchemaValidCtxtPtr ctxt ,
2003-10-10 04:49:42 +04:00
xmlNodePtr elem ,
xmlSchemaAttributePtr attributes ) ;
2002-04-16 19:50:10 +04:00
static int xmlSchemaValidateType ( xmlSchemaValidCtxtPtr ctxt ,
2003-10-10 04:49:42 +04:00
xmlNodePtr elem ,
xmlSchemaElementPtr elemDecl ,
xmlSchemaTypePtr type ) ;
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaRegisterAttributes :
* @ ctxt : a schema validation context
* @ attrs : a list of attributes
*
* Register the list of attributes as the set to be validated on that element
*
* Returns - 1 in case of error , 0 otherwise
*/
static int
2003-10-10 04:49:42 +04:00
xmlSchemaRegisterAttributes ( xmlSchemaValidCtxtPtr ctxt , xmlAttrPtr attrs )
{
2002-04-16 19:50:10 +04:00
while ( attrs ! = NULL ) {
2003-10-10 04:49:42 +04:00
if ( ( attrs - > ns ! = NULL ) & &
( xmlStrEqual ( attrs - > ns - > href , xmlSchemaInstanceNs ) ) ) {
attrs = attrs - > next ;
continue ;
}
if ( ctxt - > attrNr > = ctxt - > attrMax ) {
xmlSchemaAttrStatePtr tmp ;
ctxt - > attrMax * = 2 ;
tmp = ( xmlSchemaAttrStatePtr )
xmlRealloc ( ctxt - > attr , ctxt - > attrMax *
sizeof ( xmlSchemaAttrState ) ) ;
if ( tmp = = NULL ) {
xmlSchemaVErrMemory ( ctxt , " registering attributes " , NULL ) ;
ctxt - > attrMax / = 2 ;
return ( - 1 ) ;
}
ctxt - > attr = tmp ;
}
ctxt - > attr [ ctxt - > attrNr ] . attr = attrs ;
ctxt - > attr [ ctxt - > attrNr ] . state = XML_SCHEMAS_ATTR_UNKNOWN ;
ctxt - > attrNr + + ;
attrs = attrs - > next ;
}
return ( 0 ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaCheckAttributes :
* @ ctxt : a schema validation context
* @ node : the node carrying it .
*
* Check that the registered set of attributes on the current node
* has been properly validated .
*
* Returns 0 if validity constraints are met , 1 otherwise .
*/
static int
2003-10-10 04:49:42 +04:00
xmlSchemaCheckAttributes ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr node )
{
2002-04-16 19:50:10 +04:00
int ret = 0 ;
int i ;
2003-10-10 04:49:42 +04:00
for ( i = ctxt - > attrBase ; i < ctxt - > attrNr ; i + + ) {
if ( ctxt - > attr [ i ] . attr = = NULL )
break ;
if ( ctxt - > attr [ i ] . state = = XML_SCHEMAS_ATTR_UNKNOWN ) {
ret = 1 ;
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_ATTRUNKNOWN , " Attribute %s on %s is unknown \n " , ctxt - > attr [ i ] . attr - > name , node - > name ) ;
}
}
return ( ret ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaValidateSimpleContent :
* @ ctxt : a schema validation context
* @ elem : an element
* @ type : the type declaration
*
* Validate the content of an element expected to be a simple type
*
* Returns 0 if the element is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
static int
xmlSchemaValidateSimpleContent ( xmlSchemaValidCtxtPtr ctxt ,
2003-10-10 04:49:42 +04:00
xmlNodePtr node ATTRIBUTE_UNUSED )
{
2002-04-16 19:50:10 +04:00
xmlNodePtr child ;
xmlSchemaTypePtr type , base ;
xmlChar * value ;
2003-04-09 15:24:17 +04:00
int ret = 0 ;
2002-04-16 19:50:10 +04:00
child = ctxt - > node ;
type = ctxt - > type ;
/*
* Validation Rule : Element Locally Valid ( Type ) : 3.1 .3
*/
value = xmlNodeGetContent ( child ) ;
/* xmlSchemaValidateSimpleValue(ctxt, type, value); */
switch ( type - > type ) {
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_TYPE_RESTRICTION : {
xmlSchemaFacetPtr facet ;
base = type - > baseType ;
if ( base ! = NULL ) {
ret = xmlSchemaValidateSimpleValue ( ctxt , base , value ) ;
} else {
TODO }
if ( ret = = 0 ) {
facet = type - > facets ;
ret =
xmlSchemaValidateFacets ( ctxt , base , facet , value ) ;
}
2003-11-24 16:04:35 +03:00
if ( ( ret = = 0 ) & & ( type - > attributes ! = NULL ) ) {
ret = xmlSchemaValidateAttributes ( ctxt , node ,
type - > attributes ) ;
}
2003-10-10 04:49:42 +04:00
break ;
}
2003-11-22 23:37:51 +03:00
case XML_SCHEMA_TYPE_EXTENSION : {
TODO
break ;
}
2003-10-10 04:49:42 +04:00
default :
2003-11-22 23:37:51 +03:00
TODO
}
2002-04-16 19:50:10 +04:00
if ( value ! = NULL )
2003-10-10 04:49:42 +04:00
xmlFree ( value ) ;
2002-04-16 19:50:10 +04:00
2003-10-10 04:49:42 +04:00
return ( ret ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaValidateCheckNodeList
* @ nodelist : the list of nodes
*
* Check the node list is only made of text nodes and entities pointing
* to text nodes
*
* Returns 1 if true , 0 if false and - 1 in case of error
*/
static int
2003-10-10 04:49:42 +04:00
xmlSchemaValidateCheckNodeList ( xmlNodePtr nodelist )
{
2002-04-16 19:50:10 +04:00
while ( nodelist ! = NULL ) {
2003-10-10 04:49:42 +04:00
if ( nodelist - > type = = XML_ENTITY_REF_NODE ) {
TODO /* implement recursion in the entity content */
}
if ( ( nodelist - > type ! = XML_TEXT_NODE ) & &
( nodelist - > type ! = XML_COMMENT_NODE ) & &
( nodelist - > type ! = XML_PI_NODE ) & &
( nodelist - > type ! = XML_PI_NODE ) ) {
return ( 0 ) ;
}
nodelist = nodelist - > next ;
}
return ( 1 ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaSkipIgnored :
* @ ctxt : a schema validation context
* @ type : the current type context
* @ node : the top node .
*
* Skip ignorable nodes in that context
*
* Returns the new sibling
* number otherwise and - 1 in case of internal or API error .
*/
static xmlNodePtr
2002-09-26 13:47:36 +04:00
xmlSchemaSkipIgnored ( xmlSchemaValidCtxtPtr ctxt ATTRIBUTE_UNUSED ,
2003-10-10 04:49:42 +04:00
xmlSchemaTypePtr type , xmlNodePtr node )
{
2002-04-16 19:50:10 +04:00
int mixed = 0 ;
2003-10-10 04:49:42 +04:00
2002-04-16 19:50:10 +04:00
/*
* TODO complete and handle entities
*/
mixed = ( ( type - > contentType = = XML_SCHEMA_CONTENT_MIXED ) | |
2003-10-10 04:49:42 +04:00
( type - > contentType = = XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS ) ) ;
2002-04-16 19:50:10 +04:00
while ( ( node ! = NULL ) & &
2003-10-10 04:49:42 +04:00
( ( node - > type = = XML_COMMENT_NODE ) | |
( ( mixed = = 1 ) & & ( node - > type = = XML_TEXT_NODE ) ) | |
( ( ( type - > contentType = = XML_SCHEMA_CONTENT_ELEMENTS ) & &
( node - > type = = XML_TEXT_NODE ) & & ( IS_BLANK_NODE ( node ) ) ) ) ) ) {
node = node - > next ;
}
return ( node ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaValidateCallback :
* @ ctxt : a schema validation context
* @ name : the name of the element detected ( might be NULL )
* @ type : the type
*
* A transition has been made in the automata associated to an element
* content model
*/
static void
xmlSchemaValidateCallback ( xmlSchemaValidCtxtPtr ctxt ,
2003-10-10 04:49:42 +04:00
const xmlChar * name ATTRIBUTE_UNUSED ,
xmlSchemaTypePtr type , xmlNodePtr node )
{
2002-04-16 19:50:10 +04:00
xmlSchemaTypePtr oldtype = ctxt - > type ;
xmlNodePtr oldnode = ctxt - > node ;
2003-10-10 04:49:42 +04:00
2002-04-16 19:50:10 +04:00
# ifdef DEBUG_CONTENT
2002-04-17 13:06:27 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" xmlSchemaValidateCallback: %s, %s, %s \n " ,
2003-10-10 04:49:42 +04:00
name , type - > name , node - > name ) ;
2002-04-16 19:50:10 +04:00
# endif
ctxt - > type = type ;
ctxt - > node = node ;
xmlSchemaValidateContent ( ctxt , node ) ;
ctxt - > type = oldtype ;
ctxt - > node = oldnode ;
}
#if 0
2003-10-10 04:49:42 +04:00
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaValidateSimpleRestrictionType :
* @ ctxt : a schema validation context
* @ node : the top node .
*
* Validate the content of a restriction type .
*
* Returns 0 if the element is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
static int
xmlSchemaValidateSimpleRestrictionType ( xmlSchemaValidCtxtPtr ctxt ,
xmlNodePtr node )
{
xmlNodePtr child ;
xmlSchemaTypePtr type ;
int ret ;
child = ctxt - > node ;
type = ctxt - > type ;
if ( ( ctxt = = NULL ) | | ( type = = NULL ) ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_INTERNAL , " Internal error: xmlSchemaValidateSimpleRestrictionType %s \n " , node - > name , NULL ) ;
2002-04-16 19:50:10 +04:00
return ( - 1 ) ;
}
/*
* Only text and text based entities references shall be found there
*/
ret = xmlSchemaValidateCheckNodeList ( child ) ;
if ( ret < 0 ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_INTERNAL , " Internal error: xmlSchemaValidateSimpleType %s content \n " , node - > name , NULL ) ;
2002-04-16 19:50:10 +04:00
return ( - 1 ) ;
} else if ( ret = = 0 ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_NOTSIMPLE , " Element %s content is not a simple type \n " , node - > name , NULL ) ;
2002-04-16 19:50:10 +04:00
return ( - 1 ) ;
}
ctxt - > type = type - > subtypes ;
xmlSchemaValidateContent ( ctxt , node ) ;
ctxt - > type = type ;
return ( ret ) ;
}
# endif
/**
* xmlSchemaValidateSimpleType :
* @ ctxt : a schema validation context
* @ node : the top node .
*
* Validate the content of an simple type .
*
* Returns 0 if the element is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
static int
2003-10-10 04:49:42 +04:00
xmlSchemaValidateSimpleType ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr node )
{
2002-04-16 19:50:10 +04:00
xmlNodePtr child ;
xmlSchemaTypePtr type ;
xmlAttrPtr attr ;
int ret ;
child = ctxt - > node ;
type = ctxt - > type ;
if ( ( ctxt = = NULL ) | | ( type = = NULL ) ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_INTERNAL , " Internal error: xmlSchemaValidateSimpleType %s \n " , node - > name , NULL ) ;
return ( - 1 ) ;
2002-04-16 19:50:10 +04:00
}
/*
* Only text and text based entities references shall be found there
*/
ret = xmlSchemaValidateCheckNodeList ( child ) ;
if ( ret < 0 ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_INTERNAL , " Internal error: xmlSchemaValidateSimpleType %s content \n " , node - > name , NULL ) ;
return ( - 1 ) ;
2002-04-16 19:50:10 +04:00
} else if ( ret = = 0 ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_NOTSIMPLE , " Element %s content is not a simple type \n " , node - > name , NULL ) ;
return ( - 1 ) ;
2002-04-16 19:50:10 +04:00
}
/*
* Validation Rule : Element Locally Valid ( Type ) : 3.1 .1
*/
attr = node - > properties ;
while ( attr ! = NULL ) {
2003-10-10 04:49:42 +04:00
if ( ( attr - > ns = = NULL ) | |
( ! xmlStrEqual ( attr - > ns - > href , xmlSchemaInstanceNs ) ) | |
( ( ! xmlStrEqual ( attr - > name , BAD_CAST " type " ) ) & &
( ! xmlStrEqual ( attr - > name , BAD_CAST " nil " ) ) & &
( ! xmlStrEqual ( attr - > name , BAD_CAST " schemasLocation " ) ) & &
( ! xmlStrEqual
( attr - > name , BAD_CAST " noNamespaceSchemaLocation " ) ) ) ) {
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_INVALIDATTR , " Element %s: attribute %s should not be present \n " , node - > name , attr - > name ) ;
return ( ctxt - > err ) ;
}
2002-04-16 19:50:10 +04:00
}
ctxt - > type = type - > subtypes ;
ret = xmlSchemaValidateSimpleContent ( ctxt , node ) ;
ctxt - > type = type ;
2003-10-10 04:49:42 +04:00
return ( ret ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaValidateElementType :
* @ ctxt : a schema validation context
* @ node : the top node .
*
* Validate the content of an element type .
* Validation Rule : Element Locally Valid ( Complex Type )
*
* Returns 0 if the element is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
static int
2003-10-10 04:49:42 +04:00
xmlSchemaValidateElementType ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr node )
{
2002-04-16 19:50:10 +04:00
xmlNodePtr child ;
xmlSchemaTypePtr type ;
2003-10-10 04:49:42 +04:00
xmlRegExecCtxtPtr oldregexp ; /* cont model of the parent */
2002-04-16 19:50:10 +04:00
xmlSchemaElementPtr decl ;
int ret , attrBase ;
oldregexp = ctxt - > regexp ;
child = ctxt - > node ;
type = ctxt - > type ;
if ( ( ctxt = = NULL ) | | ( type = = NULL ) ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_INTERNAL , " Internal error: xmlSchemaValidateElementType \n " , node - > name , NULL ) ;
return ( - 1 ) ;
2002-04-16 19:50:10 +04:00
}
if ( child = = NULL ) {
2003-10-10 04:49:42 +04:00
if ( type - > minOccurs > 0 ) {
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_MISSING , " Element %s: missing child %s \n " , node - > name , type - > name ) ;
}
return ( ctxt - > err ) ;
2002-04-16 19:50:10 +04:00
}
/*
* Verify the element matches
*/
if ( ! xmlStrEqual ( child - > name , type - > name ) ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr3 ( ctxt , node , XML_SCHEMAS_ERR_WRONGELEM , " Element %s: missing child %s found %s \n " , node - > name , type - > name , child - > name ) ;
return ( ctxt - > err ) ;
2002-04-16 19:50:10 +04:00
}
/*
* Verify the attributes
*/
attrBase = ctxt - > attrBase ;
ctxt - > attrBase = ctxt - > attrNr ;
xmlSchemaRegisterAttributes ( ctxt , child - > properties ) ;
xmlSchemaValidateAttributes ( ctxt , child , type - > attributes ) ;
/*
* Verify the element content recursively
*/
decl = ( xmlSchemaElementPtr ) type ;
oldregexp = ctxt - > regexp ;
if ( decl - > contModel ! = NULL ) {
2003-10-10 04:49:42 +04:00
ctxt - > regexp = xmlRegNewExecCtxt ( decl - > contModel ,
( xmlRegExecCallbacks )
xmlSchemaValidateCallback , ctxt ) ;
2002-04-16 19:50:10 +04:00
# ifdef DEBUG_AUTOMATA
2003-10-10 04:49:42 +04:00
xmlGenericError ( xmlGenericErrorContext , " ====> %s \n " , node - > name ) ;
2002-04-16 19:50:10 +04:00
# endif
}
2003-10-10 04:49:42 +04:00
xmlSchemaValidateType ( ctxt , child , ( xmlSchemaElementPtr ) type ,
type - > subtypes ) ;
2002-04-16 19:50:10 +04:00
if ( decl - > contModel ! = NULL ) {
2003-10-10 04:49:42 +04:00
ret = xmlRegExecPushString ( ctxt - > regexp , NULL , NULL ) ;
2002-04-16 19:50:10 +04:00
# ifdef DEBUG_AUTOMATA
2003-10-10 04:49:42 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" ====> %s : %d \n " , node - > name , ret ) ;
2002-04-16 19:50:10 +04:00
# endif
2003-10-10 04:49:42 +04:00
if ( ret = = 0 ) {
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_ELEMCONT , " Element %s content check failed \n " , node - > name , NULL ) ;
} else if ( ret < 0 ) {
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_ELEMCONT , " Element %s content check failure \n " , node - > name , NULL ) ;
2002-04-16 19:50:10 +04:00
# ifdef DEBUG_CONTENT
2003-10-10 04:49:42 +04:00
} else {
xmlGenericError ( xmlGenericErrorContext ,
" Element %s content check succeeded \n " ,
node - > name ) ;
2002-04-16 19:50:10 +04:00
# endif
2003-10-10 04:49:42 +04:00
}
xmlRegFreeExecCtxt ( ctxt - > regexp ) ;
2002-04-16 19:50:10 +04:00
}
/*
* Verify that all attributes were Schemas - validated
*/
xmlSchemaCheckAttributes ( ctxt , node ) ;
ctxt - > attrNr = ctxt - > attrBase ;
ctxt - > attrBase = attrBase ;
ctxt - > regexp = oldregexp ;
ctxt - > node = child ;
ctxt - > type = type ;
2003-10-10 04:49:42 +04:00
return ( ctxt - > err ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaValidateBasicType :
* @ ctxt : a schema validation context
* @ node : the top node .
*
* Validate the content of an element expected to be a basic type type
*
* Returns 0 if the element is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
static int
2003-10-10 04:49:42 +04:00
xmlSchemaValidateBasicType ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr node )
{
2002-04-16 19:50:10 +04:00
int ret ;
xmlNodePtr child , cur ;
xmlSchemaTypePtr type ;
2003-10-10 04:49:42 +04:00
xmlChar * value ; /* lexical representation */
2002-04-16 19:50:10 +04:00
child = ctxt - > node ;
type = ctxt - > type ;
if ( ( ctxt = = NULL ) | | ( type = = NULL ) ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_INTERNAL , " Internal error: xmlSchemaValidateBasicType \n " , node - > name , NULL ) ;
return ( - 1 ) ;
2002-04-16 19:50:10 +04:00
}
/*
* First check the content model of the node .
*/
cur = child ;
while ( cur ! = NULL ) {
2003-10-10 04:49:42 +04:00
switch ( cur - > type ) {
case XML_TEXT_NODE :
case XML_CDATA_SECTION_NODE :
case XML_PI_NODE :
case XML_COMMENT_NODE :
case XML_XINCLUDE_START :
case XML_XINCLUDE_END :
break ;
case XML_ENTITY_REF_NODE :
case XML_ENTITY_NODE :
TODO break ;
case XML_ELEMENT_NODE :
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_INVALIDELEM , " Element %s: child %s should not be present \n " , node - > name , cur - > name ) ;
return ( ctxt - > err ) ;
2002-04-16 19:50:10 +04:00
case XML_ATTRIBUTE_NODE :
case XML_DOCUMENT_NODE :
case XML_DOCUMENT_TYPE_NODE :
case XML_DOCUMENT_FRAG_NODE :
case XML_NOTATION_NODE :
case XML_HTML_DOCUMENT_NODE :
case XML_DTD_NODE :
case XML_ELEMENT_DECL :
case XML_ATTRIBUTE_DECL :
case XML_ENTITY_DECL :
case XML_NAMESPACE_DECL :
# ifdef LIBXML_DOCB_ENABLED
case XML_DOCB_DOCUMENT_NODE :
# endif
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_INVALIDELEM , " Element %s: node type of node unexpected here \n " , node - > name , NULL ) ;
return ( ctxt - > err ) ;
}
cur = cur - > next ;
2002-04-16 19:50:10 +04:00
}
if ( child = = NULL )
2003-10-10 04:49:42 +04:00
value = NULL ;
2002-04-16 19:50:10 +04:00
else
2003-10-10 04:49:42 +04:00
value = xmlNodeGetContent ( child - > parent ) ;
2002-04-16 19:50:10 +04:00
if ( ctxt - > value ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaFreeValue ( ctxt - > value ) ;
ctxt - > value = NULL ;
2002-04-16 19:50:10 +04:00
}
ret = xmlSchemaValidatePredefinedType ( type , value , & ( ctxt - > value ) ) ;
if ( value ! = NULL )
2003-10-10 04:49:42 +04:00
xmlFree ( value ) ;
2002-04-16 19:50:10 +04:00
if ( ret ! = 0 ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_VALUE , " Element %s: failed to validate basic type %s \n " , node - > name , type - > name ) ;
}
return ( ret ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaValidateComplexType :
* @ ctxt : a schema validation context
* @ node : the top node .
*
* Validate the content of an element expected to be a complex type type
* xmlschema - 1. html # cvc - complex - type
* Validation Rule : Element Locally Valid ( Complex Type )
*
* Returns 0 if the element is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
static int
2003-10-10 04:49:42 +04:00
xmlSchemaValidateComplexType ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr node )
{
2002-04-16 19:50:10 +04:00
xmlNodePtr child ;
2002-04-17 13:06:27 +04:00
xmlSchemaTypePtr type , subtype ;
2002-04-16 19:50:10 +04:00
int ret ;
child = ctxt - > node ;
type = ctxt - > type ;
2003-05-12 00:16:09 +04:00
ctxt - > cur = node ;
2002-04-16 19:50:10 +04:00
switch ( type - > contentType ) {
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_CONTENT_EMPTY :
2003-11-22 23:37:51 +03:00
if ( type - > baseType ! = NULL ) {
} else if ( child ! = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_NOTEMPTY , " Element %s is supposed to be empty \n " , node - > name , NULL ) ;
}
if ( type - > attributes ! = NULL ) {
xmlSchemaValidateAttributes ( ctxt , node , type - > attributes ) ;
}
subtype = type - > subtypes ;
while ( subtype ! = NULL ) {
ctxt - > type = subtype ;
xmlSchemaValidateComplexType ( ctxt , node ) ;
subtype = subtype - > next ;
}
break ;
case XML_SCHEMA_CONTENT_ELEMENTS :
case XML_SCHEMA_CONTENT_MIXED :
case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS :
/*
* Skip ignorable nodes in that context
*/
child = xmlSchemaSkipIgnored ( ctxt , type , child ) ;
while ( child ! = NULL ) {
if ( child - > type = = XML_ELEMENT_NODE ) {
ret = xmlRegExecPushString ( ctxt - > regexp ,
child - > name , child ) ;
2002-04-16 19:50:10 +04:00
# ifdef DEBUG_AUTOMATA
2003-10-10 04:49:42 +04:00
if ( ret < 0 )
xmlGenericError ( xmlGenericErrorContext ,
" --> %s Error \n " , child - > name ) ;
else
xmlGenericError ( xmlGenericErrorContext ,
" --> %s \n " , child - > name ) ;
2002-04-16 19:50:10 +04:00
# endif
2003-10-10 04:49:42 +04:00
}
child = child - > next ;
/*
* Skip ignorable nodes in that context
*/
child = xmlSchemaSkipIgnored ( ctxt , type , child ) ;
}
2003-11-24 16:04:35 +03:00
if ( type - > attributes ! = NULL ) {
xmlSchemaValidateAttributes ( ctxt , node , type - > attributes ) ;
}
2003-10-10 04:49:42 +04:00
break ;
case XML_SCHEMA_CONTENT_BASIC : {
if ( type - > subtypes ! = NULL ) {
ctxt - > type = type - > subtypes ;
xmlSchemaValidateComplexType ( ctxt , node ) ;
}
if ( type - > baseType ! = NULL ) {
ctxt - > type = type - > baseType ;
xmlSchemaValidateBasicType ( ctxt , node ) ;
}
if ( type - > attributes ! = NULL ) {
xmlSchemaValidateAttributes ( ctxt , node ,
type - > attributes ) ;
}
ctxt - > type = type ;
break ;
}
2003-11-22 23:37:51 +03:00
case XML_SCHEMA_CONTENT_SIMPLE : {
if ( type - > subtypes ! = NULL ) {
ctxt - > type = type - > subtypes ;
xmlSchemaValidateComplexType ( ctxt , node ) ;
}
if ( type - > baseType ! = NULL ) {
ctxt - > type = type - > baseType ;
xmlSchemaValidateComplexType ( ctxt , node ) ;
}
if ( type - > attributes ! = NULL ) {
xmlSchemaValidateAttributes ( ctxt , node ,
type - > attributes ) ;
}
ctxt - > type = type ;
break ;
}
2003-10-10 04:49:42 +04:00
default :
TODO xmlGenericError ( xmlGenericErrorContext ,
" unimplemented content type %d \n " ,
type - > contentType ) ;
2002-04-16 19:50:10 +04:00
}
2003-10-10 04:49:42 +04:00
return ( ctxt - > err ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaValidateContent :
* @ ctxt : a schema validation context
* @ elem : an element
* @ type : the type declaration
*
* Validate the content of an element against the type .
*
* Returns 0 if the element is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
static int
2003-10-10 04:49:42 +04:00
xmlSchemaValidateContent ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr node )
{
2002-04-16 19:50:10 +04:00
xmlNodePtr child ;
xmlSchemaTypePtr type ;
child = ctxt - > node ;
type = ctxt - > type ;
2003-05-12 00:16:09 +04:00
ctxt - > cur = node ;
2002-04-16 19:50:10 +04:00
2002-04-22 20:01:24 +04:00
xmlSchemaValidateAttributes ( ctxt , node , type - > attributes ) ;
2003-05-12 00:16:09 +04:00
ctxt - > cur = node ;
2002-04-22 20:01:24 +04:00
2002-04-16 19:50:10 +04:00
switch ( type - > type ) {
2003-10-10 04:49:42 +04:00
case XML_SCHEMA_TYPE_ANY :
/* Any type will do it, fine */
TODO /* handle recursivity */
break ;
case XML_SCHEMA_TYPE_COMPLEX :
xmlSchemaValidateComplexType ( ctxt , node ) ;
break ;
case XML_SCHEMA_TYPE_ELEMENT : {
xmlSchemaElementPtr decl = ( xmlSchemaElementPtr ) type ;
/*
* Handle element reference here
*/
if ( decl - > ref ! = NULL ) {
if ( decl - > refDecl = = NULL ) {
xmlSchemaVErr ( ctxt , node , XML_SCHEMAS_ERR_INTERNAL , " Internal error: element reference %s not resolved \n " , decl - > ref , NULL ) ;
return ( - 1 ) ;
}
ctxt - > type = ( xmlSchemaTypePtr ) decl - > refDecl ;
decl = decl - > refDecl ;
}
xmlSchemaValidateElementType ( ctxt , node ) ;
ctxt - > type = type ;
break ;
}
case XML_SCHEMA_TYPE_BASIC :
xmlSchemaValidateBasicType ( ctxt , node ) ;
break ;
case XML_SCHEMA_TYPE_FACET :
TODO break ;
case XML_SCHEMA_TYPE_SIMPLE :
xmlSchemaValidateSimpleType ( ctxt , node ) ;
break ;
case XML_SCHEMA_TYPE_SEQUENCE :
TODO break ;
case XML_SCHEMA_TYPE_CHOICE :
TODO break ;
case XML_SCHEMA_TYPE_ALL :
TODO break ;
case XML_SCHEMA_TYPE_SIMPLE_CONTENT :
TODO break ;
case XML_SCHEMA_TYPE_COMPLEX_CONTENT :
TODO break ;
case XML_SCHEMA_TYPE_UR :
TODO break ;
case XML_SCHEMA_TYPE_RESTRICTION :
/*xmlSchemaValidateRestrictionType(ctxt, node); */
TODO break ;
case XML_SCHEMA_TYPE_EXTENSION :
TODO break ;
case XML_SCHEMA_TYPE_ATTRIBUTE :
TODO break ;
case XML_SCHEMA_TYPE_GROUP :
TODO break ;
case XML_SCHEMA_TYPE_NOTATION :
TODO break ;
case XML_SCHEMA_TYPE_LIST :
TODO break ;
case XML_SCHEMA_TYPE_UNION :
TODO break ;
case XML_SCHEMA_FACET_MININCLUSIVE :
TODO break ;
case XML_SCHEMA_FACET_MINEXCLUSIVE :
TODO break ;
case XML_SCHEMA_FACET_MAXINCLUSIVE :
TODO break ;
case XML_SCHEMA_FACET_MAXEXCLUSIVE :
TODO break ;
case XML_SCHEMA_FACET_TOTALDIGITS :
TODO break ;
case XML_SCHEMA_FACET_FRACTIONDIGITS :
TODO break ;
case XML_SCHEMA_FACET_PATTERN :
TODO break ;
case XML_SCHEMA_FACET_ENUMERATION :
TODO break ;
case XML_SCHEMA_FACET_WHITESPACE :
TODO break ;
case XML_SCHEMA_FACET_LENGTH :
TODO break ;
case XML_SCHEMA_FACET_MAXLENGTH :
TODO break ;
case XML_SCHEMA_FACET_MINLENGTH :
TODO break ;
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP :
TODO break ;
2002-04-16 19:50:10 +04:00
}
xmlSchemaValidateAttributes ( ctxt , node , type - > attributes ) ;
if ( ctxt - > node = = NULL )
2003-10-10 04:49:42 +04:00
return ( ctxt - > err ) ;
2002-04-16 19:50:10 +04:00
ctxt - > node = ctxt - > node - > next ;
ctxt - > type = type - > next ;
2003-10-10 04:49:42 +04:00
return ( ctxt - > err ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaValidateType :
* @ ctxt : a schema validation context
* @ elem : an element
* @ type : the list of type declarations
*
* Validate the content of an element against the types .
*
* Returns 0 if the element is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
static int
xmlSchemaValidateType ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr elem ,
2003-10-10 04:49:42 +04:00
xmlSchemaElementPtr elemDecl , xmlSchemaTypePtr type )
{
2002-04-16 19:50:10 +04:00
xmlChar * nil ;
2003-07-08 16:16:59 +04:00
if ( ( elem = = NULL ) | | ( type = = NULL ) | | ( elemDecl = = NULL ) )
2003-10-10 04:49:42 +04:00
return ( 0 ) ;
2003-07-08 16:16:59 +04:00
2002-04-16 19:50:10 +04:00
/*
* 3.3 .4 : 2
*/
if ( elemDecl - > flags & XML_SCHEMAS_ELEM_ABSTRACT ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , elem , XML_SCHEMAS_ERR_ISABSTRACT , " Element %s is abstract \n " , elem - > name , NULL ) ;
return ( ctxt - > err ) ;
2002-04-16 19:50:10 +04:00
}
/*
* 3.3 .4 : 3
*/
nil = xmlGetNsProp ( elem , BAD_CAST " nil " , xmlSchemaInstanceNs ) ;
if ( elemDecl - > flags & XML_SCHEMAS_ELEM_NILLABLE ) {
2003-10-10 04:49:42 +04:00
/* 3.3.4: 3.2 */
if ( xmlStrEqual ( nil , BAD_CAST " true " ) ) {
if ( elem - > children ! = NULL ) {
xmlSchemaVErr ( ctxt , elem , XML_SCHEMAS_ERR_NOTEMPTY , " Element %s is not empty \n " , elem - > name , NULL ) ;
return ( ctxt - > err ) ;
}
if ( ( elemDecl - > flags & XML_SCHEMAS_ELEM_FIXED ) & &
( elemDecl - > value ! = NULL ) ) {
xmlSchemaVErr ( ctxt , elem , XML_SCHEMAS_ERR_HAVEDEFAULT , " Empty element %s cannot get a fixed value \n " , elem - > name , NULL ) ;
return ( ctxt - > err ) ;
}
}
2002-04-16 19:50:10 +04:00
} else {
2003-10-10 04:49:42 +04:00
/* 3.3.4: 3.1 */
if ( nil ! = NULL ) {
xmlSchemaVErr ( ctxt , elem , XML_SCHEMAS_ERR_NOTNILLABLE , " Element %s with xs:nil but not nillable \n " , elem - > name , NULL ) ;
xmlFree ( nil ) ;
return ( ctxt - > err ) ;
}
2002-04-16 19:50:10 +04:00
}
2003-10-10 04:49:42 +04:00
/* TODO 3.3.4: 4 if the element carries xs:type */
2002-04-16 19:50:10 +04:00
ctxt - > type = elemDecl - > subtypes ;
ctxt - > node = elem - > children ;
xmlSchemaValidateContent ( ctxt , elem ) ;
xmlSchemaValidateAttributes ( ctxt , elem , elemDecl - > attributes ) ;
2003-10-10 04:49:42 +04:00
return ( ctxt - > err ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaValidateAttributes :
* @ ctxt : a schema validation context
* @ elem : an element
* @ attributes : the list of attribute declarations
*
* Validate the attributes of an element .
*
* Returns 0 if the element is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
static int
xmlSchemaValidateAttributes ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr elem ,
2003-10-10 04:49:42 +04:00
xmlSchemaAttributePtr attributes )
{
2004-04-17 18:58:15 +04:00
int i , ret ;
2002-04-16 19:50:10 +04:00
xmlAttrPtr attr ;
xmlChar * value ;
2002-04-23 21:51:29 +04:00
xmlSchemaAttributeGroupPtr group = NULL ;
2004-04-16 20:46:51 +04:00
int found ;
2002-04-16 19:50:10 +04:00
if ( attributes = = NULL )
2003-10-10 04:49:42 +04:00
return ( 0 ) ;
2002-04-16 19:50:10 +04:00
while ( attributes ! = NULL ) {
2004-04-16 20:46:51 +04:00
found = 0 ;
2003-10-10 04:49:42 +04:00
/*
* Handle attribute groups
*/
if ( attributes - > type = = XML_SCHEMA_TYPE_ATTRIBUTEGROUP ) {
group = ( xmlSchemaAttributeGroupPtr ) attributes ;
xmlSchemaValidateAttributes ( ctxt , elem , group - > attributes ) ;
attributes = group - > next ;
continue ;
}
for ( i = ctxt - > attrBase ; i < ctxt - > attrNr ; i + + ) {
attr = ctxt - > attr [ i ] . attr ;
if ( attr = = NULL )
continue ;
if ( attributes - > ref ! = NULL ) {
if ( ! xmlStrEqual ( attr - > name , attributes - > ref ) )
continue ;
if ( attr - > ns ! = NULL ) {
if ( ( attributes - > refNs = = NULL ) | |
( ! xmlStrEqual ( attr - > ns - > href , attributes - > refNs ) ) )
continue ;
} else if ( attributes - > refNs ! = NULL ) {
continue ;
}
} else {
if ( ! xmlStrEqual ( attr - > name , attributes - > name ) )
continue ;
/*
2003-11-22 23:37:51 +03:00
* handle the namespaces checks here
2003-10-10 04:49:42 +04:00
*/
2003-11-22 23:37:51 +03:00
if ( attr - > ns = = NULL ) {
/*
* accept an unqualified attribute only if the declaration
* is unqualified or if the schemas allowed it .
*/
if ( ( attributes - > targetNamespace ! = NULL ) & &
( ( attributes - > flags & XML_SCHEMAS_ATTR_NSDEFAULT ) = = 0 ) )
continue ;
} else {
if ( attributes - > targetNamespace = = NULL )
continue ;
if ( ! xmlStrEqual ( attributes - > targetNamespace ,
attr - > ns - > href ) )
continue ;
}
2003-10-10 04:49:42 +04:00
}
2004-04-16 20:46:51 +04:00
found = 1 ;
2003-10-10 04:49:42 +04:00
ctxt - > cur = ( xmlNodePtr ) attributes ;
2004-04-16 20:46:51 +04:00
2003-10-10 04:49:42 +04:00
if ( attributes - > subtypes = = NULL ) {
xmlSchemaVErr ( ctxt , ( xmlNodePtr ) attr , XML_SCHEMAS_ERR_INTERNAL , " Internal error: attribute %s type not resolved \n " , attr - > name , NULL ) ;
continue ;
}
2004-04-16 20:46:51 +04:00
if ( attributes - > occurs = = XML_SCHEMAS_ATTR_USE_PROHIBITED ) {
xmlSchemaVErr ( ctxt , elem , XML_SCHEMAS_ERR_INVALIDATTR , " attribute %s on %s is prohibited \n " , attributes - > name , elem - > name ) ;
/* Setting the state to XML_SCHEMAS_ATTR_CHECKED seems not very logical but it
surpresses the " attribute is unknown " error report . Please change this if you know better */
ctxt - > attr [ i ] . state = XML_SCHEMAS_ATTR_CHECKED ;
break ;
}
2003-10-10 04:49:42 +04:00
value = xmlNodeListGetString ( elem - > doc , attr - > children , 1 ) ;
ret = xmlSchemaValidateSimpleValue ( ctxt , attributes - > subtypes ,
value ) ;
if ( ret ! = 0 ) {
xmlSchemaVErr ( ctxt , ( xmlNodePtr ) attr , XML_SCHEMAS_ERR_ATTRINVALID , " attribute %s on %s does not match type \n " , attr - > name , elem - > name ) ;
} else {
ctxt - > attr [ i ] . state = XML_SCHEMAS_ATTR_CHECKED ;
}
if ( value ! = NULL ) {
xmlFree ( value ) ;
}
}
2004-04-16 20:46:51 +04:00
if ( ( ! found ) & & ( attributes - > occurs = = XML_SCHEMAS_ATTR_USE_REQUIRED ) ) {
xmlSchemaVErr ( ctxt , elem , XML_SCHEMAS_ERR_MISSING , " required attribute %s on %s is missing \n " , attributes - > name , elem - > name ) ;
}
2003-10-10 04:49:42 +04:00
attributes = attributes - > next ;
}
return ( ctxt - > err ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaValidateElement :
* @ ctxt : a schema validation context
* @ elem : an element
*
* Validate an element in a tree
*
* Returns 0 if the element is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
static int
2003-10-10 04:49:42 +04:00
xmlSchemaValidateElement ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr elem )
{
2002-04-16 19:50:10 +04:00
xmlSchemaElementPtr elemDecl ;
int ret , attrBase ;
2003-11-22 23:37:51 +03:00
if ( elem - > ns ! = NULL ) {
2003-10-10 04:49:42 +04:00
elemDecl = xmlHashLookup3 ( ctxt - > schema - > elemDecl ,
elem - > name , elem - > ns - > href , NULL ) ;
2003-11-22 23:37:51 +03:00
} else {
elemDecl = xmlHashLookup3 ( ctxt - > schema - > elemDecl ,
elem - > name , NULL , NULL ) ;
}
/*
* special case whe elementFormDefault is unqualified for top - level elem .
*/
if ( ( elemDecl = = NULL ) & & ( elem - > ns ! = NULL ) & &
( elem - > parent ! = NULL ) & & ( elem - > parent - > type ! = XML_ELEMENT_NODE ) & &
( xmlStrEqual ( ctxt - > schema - > targetNamespace , elem - > ns - > href ) ) & &
( ( ctxt - > schema - > flags & XML_SCHEMAS_QUALIF_ELEM ) = = 0 ) ) {
2003-10-10 04:49:42 +04:00
elemDecl = xmlHashLookup3 ( ctxt - > schema - > elemDecl ,
elem - > name , NULL , NULL ) ;
2003-11-22 23:37:51 +03:00
}
2002-04-16 19:50:10 +04:00
/*
* 3.3 .4 : 1
*/
if ( elemDecl = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , elem , XML_SCHEMAS_ERR_UNDECLAREDELEM , " Element %s not declared \n " , elem - > name , NULL ) ;
return ( ctxt - > err ) ;
2002-04-16 19:50:10 +04:00
}
if ( elemDecl - > subtypes = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , elem , XML_SCHEMAS_ERR_NOTYPE , " Element %s has no type \n " , elem - > name , NULL ) ;
return ( ctxt - > err ) ;
2002-04-16 19:50:10 +04:00
}
/*
* Verify the attributes
*/
attrBase = ctxt - > attrBase ;
ctxt - > attrBase = ctxt - > attrNr ;
xmlSchemaRegisterAttributes ( ctxt , elem - > properties ) ;
xmlSchemaValidateAttributes ( ctxt , elem , elemDecl - > attributes ) ;
/*
* Verify the element content recursively
*/
if ( elemDecl - > contModel ! = NULL ) {
2003-10-10 04:49:42 +04:00
ctxt - > regexp = xmlRegNewExecCtxt ( elemDecl - > contModel ,
( xmlRegExecCallbacks )
xmlSchemaValidateCallback , ctxt ) ;
2002-04-16 19:50:10 +04:00
# ifdef DEBUG_AUTOMATA
2003-10-10 04:49:42 +04:00
xmlGenericError ( xmlGenericErrorContext , " ====> %s \n " , elem - > name ) ;
2002-04-16 19:50:10 +04:00
# endif
}
xmlSchemaValidateType ( ctxt , elem , elemDecl , elemDecl - > subtypes ) ;
2002-04-18 18:41:51 +04:00
if ( elemDecl - > contModel ! = NULL ) {
2003-10-10 04:49:42 +04:00
ret = xmlRegExecPushString ( ctxt - > regexp , NULL , NULL ) ;
2002-04-16 19:50:10 +04:00
# ifdef DEBUG_AUTOMATA
2003-10-10 04:49:42 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" ====> %s : %d \n " , elem - > name , ret ) ;
2002-04-16 19:50:10 +04:00
# endif
2003-10-10 04:49:42 +04:00
if ( ret = = 0 ) {
xmlSchemaVErr ( ctxt , elem , XML_SCHEMAS_ERR_ELEMCONT , " Element %s content check failed \n " , elem - > name , NULL ) ;
} else if ( ret < 0 ) {
xmlSchemaVErr ( ctxt , elem , XML_SCHEMAS_ERR_ELEMCONT , " Element %s content check failed \n " , elem - > name , NULL ) ;
2002-04-16 19:50:10 +04:00
# ifdef DEBUG_CONTENT
2003-10-10 04:49:42 +04:00
} else {
xmlGenericError ( xmlGenericErrorContext ,
" Element %s content check succeeded \n " ,
elem - > name ) ;
2002-04-16 19:50:10 +04:00
# endif
2003-10-10 04:49:42 +04:00
}
xmlRegFreeExecCtxt ( ctxt - > regexp ) ;
2002-04-16 19:50:10 +04:00
}
/*
* Verify that all attributes were Schemas - validated
*/
xmlSchemaCheckAttributes ( ctxt , elem ) ;
ctxt - > attrNr = ctxt - > attrBase ;
ctxt - > attrBase = attrBase ;
2003-10-10 04:49:42 +04:00
return ( ctxt - > err ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaValidateDocument :
* @ ctxt : a schema validation context
* @ doc : a parsed document tree
*
* Validate a document tree in memory .
*
* Returns 0 if the document is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
static int
2003-10-10 04:49:42 +04:00
xmlSchemaValidateDocument ( xmlSchemaValidCtxtPtr ctxt , xmlDocPtr doc )
{
2002-04-16 19:50:10 +04:00
xmlNodePtr root ;
xmlSchemaElementPtr elemDecl ;
root = xmlDocGetRootElement ( doc ) ;
if ( root = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , ( xmlNodePtr ) doc , XML_SCHEMAS_ERR_NOROOT , " document has no root \n " , NULL , NULL ) ;
return ( ctxt - > err ) ;
2002-04-16 19:50:10 +04:00
}
if ( root - > ns ! = NULL )
2003-10-10 04:49:42 +04:00
elemDecl = xmlHashLookup3 ( ctxt - > schema - > elemDecl ,
root - > name , root - > ns - > href , NULL ) ;
2002-04-16 19:50:10 +04:00
else
2003-10-10 04:49:42 +04:00
elemDecl = xmlHashLookup3 ( ctxt - > schema - > elemDecl ,
root - > name , NULL , NULL ) ;
2003-11-22 23:37:51 +03:00
/*
* special case whe elementFormDefault is unqualified for top - level elem .
*/
if ( ( elemDecl = = NULL ) & & ( root - > ns ! = NULL ) & &
( xmlStrEqual ( ctxt - > schema - > targetNamespace , root - > ns - > href ) ) & &
( ( ctxt - > schema - > flags & XML_SCHEMAS_QUALIF_ELEM ) = = 0 ) ) {
elemDecl = xmlHashLookup3 ( ctxt - > schema - > elemDecl ,
root - > name , NULL , NULL ) ;
}
2002-04-16 19:50:10 +04:00
if ( elemDecl = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , root , XML_SCHEMAS_ERR_UNDECLAREDELEM , " Element %s not declared \n " , root - > name , NULL ) ;
2002-04-18 18:41:51 +04:00
} else if ( ( elemDecl - > flags & XML_SCHEMAS_ELEM_TOPLEVEL ) = = 0 ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErr ( ctxt , root , XML_SCHEMAS_ERR_NOTTOPLEVEL , " Root element %s not toplevel \n " , root - > name , NULL ) ;
2002-04-16 19:50:10 +04:00
}
/*
* Okay , start the recursive validation
*/
xmlSchemaValidateElement ( ctxt , root ) ;
2003-10-10 04:49:42 +04:00
return ( ctxt - > err ) ;
2002-04-16 19:50:10 +04:00
}
/************************************************************************
* *
* SAX Validation code *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/************************************************************************
* *
* Validation interfaces *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlSchemaNewValidCtxt :
* @ schema : a precompiled XML Schemas
*
* Create an XML Schemas validation context based on the given schema
*
* Returns the validation context or NULL in case of error
*/
xmlSchemaValidCtxtPtr
2003-10-10 04:49:42 +04:00
xmlSchemaNewValidCtxt ( xmlSchemaPtr schema )
{
2002-04-16 19:50:10 +04:00
xmlSchemaValidCtxtPtr ret ;
ret = ( xmlSchemaValidCtxtPtr ) xmlMalloc ( sizeof ( xmlSchemaValidCtxt ) ) ;
if ( ret = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErrMemory ( NULL , " allocating validation context " , NULL ) ;
2002-04-16 19:50:10 +04:00
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaValidCtxt ) ) ;
ret - > schema = schema ;
ret - > attrNr = 0 ;
ret - > attrMax = 10 ;
ret - > attr = ( xmlSchemaAttrStatePtr ) xmlMalloc ( ret - > attrMax *
2003-10-10 04:49:42 +04:00
sizeof
( xmlSchemaAttrState ) ) ;
2002-04-16 19:50:10 +04:00
if ( ret - > attr = = NULL ) {
2003-10-10 04:49:42 +04:00
xmlSchemaVErrMemory ( NULL , " allocating validation context " , NULL ) ;
free ( ret ) ;
return ( NULL ) ;
2002-04-16 19:50:10 +04:00
}
memset ( ret - > attr , 0 , ret - > attrMax * sizeof ( xmlSchemaAttrState ) ) ;
return ( ret ) ;
}
/**
* xmlSchemaFreeValidCtxt :
* @ ctxt : the schema validation context
*
* Free the resources associated to the schema validation context
*/
void
2003-10-10 04:49:42 +04:00
xmlSchemaFreeValidCtxt ( xmlSchemaValidCtxtPtr ctxt )
{
2002-04-16 19:50:10 +04:00
if ( ctxt = = NULL )
2003-10-10 04:49:42 +04:00
return ;
2002-04-16 19:50:10 +04:00
if ( ctxt - > attr ! = NULL )
2003-10-10 04:49:42 +04:00
xmlFree ( ctxt - > attr ) ;
2002-04-23 11:12:20 +04:00
if ( ctxt - > value ! = NULL )
2003-10-10 04:49:42 +04:00
xmlSchemaFreeValue ( ctxt - > value ) ;
2002-04-16 19:50:10 +04:00
xmlFree ( ctxt ) ;
}
/**
* xmlSchemaSetValidErrors :
* @ ctxt : a schema validation context
* @ err : the error function
* @ warn : the warning function
2002-12-11 17:23:49 +03:00
* @ ctx : the functions context
2002-04-16 19:50:10 +04:00
*
* Set the error and warning callback informations
*/
void
xmlSchemaSetValidErrors ( xmlSchemaValidCtxtPtr ctxt ,
2003-10-10 04:49:42 +04:00
xmlSchemaValidityErrorFunc err ,
xmlSchemaValidityWarningFunc warn , void * ctx )
{
2002-04-16 19:50:10 +04:00
if ( ctxt = = NULL )
2003-10-10 04:49:42 +04:00
return ;
2002-04-16 19:50:10 +04:00
ctxt - > error = err ;
ctxt - > warning = warn ;
ctxt - > userData = ctx ;
}
/**
* xmlSchemaValidateDoc :
* @ ctxt : a schema validation context
* @ doc : a parsed document tree
*
* Validate a document tree in memory .
*
* Returns 0 if the document is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
int
2003-10-10 04:49:42 +04:00
xmlSchemaValidateDoc ( xmlSchemaValidCtxtPtr ctxt , xmlDocPtr doc )
{
2002-04-16 19:50:10 +04:00
int ret ;
if ( ( ctxt = = NULL ) | | ( doc = = NULL ) )
2003-10-10 04:49:42 +04:00
return ( - 1 ) ;
2002-04-16 19:50:10 +04:00
ctxt - > doc = doc ;
ret = xmlSchemaValidateDocument ( ctxt , doc ) ;
2003-10-10 04:49:42 +04:00
return ( ret ) ;
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaValidateStream :
* @ ctxt : a schema validation context
* @ input : the input to use for reading the data
* @ enc : an optional encoding information
* @ sax : a SAX handler for the resulting events
* @ user_data : the context to provide to the SAX handler .
*
* Validate a document tree in memory .
*
* Returns 0 if the document is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
2003-10-10 04:49:42 +04:00
int
2002-04-16 19:50:10 +04:00
xmlSchemaValidateStream ( xmlSchemaValidCtxtPtr ctxt ,
2003-10-10 04:49:42 +04:00
xmlParserInputBufferPtr input , xmlCharEncoding enc ,
xmlSAXHandlerPtr sax , void * user_data )
{
2002-04-16 19:50:10 +04:00
if ( ( ctxt = = NULL ) | | ( input = = NULL ) )
2003-10-10 04:49:42 +04:00
return ( - 1 ) ;
2002-04-16 19:50:10 +04:00
ctxt - > input = input ;
ctxt - > enc = enc ;
ctxt - > sax = sax ;
ctxt - > user_data = user_data ;
2003-10-10 04:49:42 +04:00
TODO return ( 0 ) ;
2002-04-16 19:50:10 +04:00
}
# endif /* LIBXML_SCHEMAS_ENABLED */