2002-04-16 15:50:10 +00: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 >
*/
# 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 06:40:27 +00:00
# include <libxml/uri.h>
2002-04-16 15:50:10 +00:00
# include <libxml/xmlschemas.h>
# include <libxml/schemasInternals.h>
# include <libxml/xmlschemastypes.h>
# include <libxml/xmlautomata.h>
# include <libxml/xmlregexp.h>
2002-04-17 09:06:27 +00:00
# define DEBUG 1 /* very verbose output */
# define DEBUG_CONTENT 1
# define DEBUG_TYPE 1
2002-04-16 15:50:10 +00:00
/* #define DEBUG_AUTOMATA 1 */
# define UNBOUNDED (1 << 30)
# define TODO \
xmlGenericError ( xmlGenericErrorContext , \
" Unimplemented block at %s:%d \n " , \
__FILE__ , __LINE__ ) ;
2002-05-22 06:40:27 +00:00
# define XML_SCHEMAS_DEFAULT_NAMESPACE (const xmlChar *)"the default namespace"
2002-04-16 15:50:10 +00: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
struct _xmlSchemaParserCtxt {
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 16:01:24 +00:00
xmlSchemaValidError err ;
2002-04-16 15:50:10 +00:00
xmlSchemaPtr schema ; /* The schema in use */
xmlChar * container ; /* the current element, group, ... */
int counter ;
xmlChar * URL ;
xmlDocPtr doc ;
/*
* Used to build complex element content models
*/
xmlAutomataPtr am ;
xmlAutomataStatePtr start ;
xmlAutomataStatePtr end ;
xmlAutomataStatePtr state ;
} ;
# define XML_SCHEMAS_ATTR_UNKNOWN 1
# define XML_SCHEMAS_ATTR_CHECKED 2
typedef struct _xmlSchemaAttrState xmlSchemaAttrState ;
typedef xmlSchemaAttrState * xmlSchemaAttrStatePtr ;
struct _xmlSchemaAttrState {
xmlAttrPtr attr ;
int state ;
} ;
/**
* xmlSchemaValidCtxt :
*
* A Schemas validation context
*/
struct _xmlSchemaValidCtxt {
void * userData ; /* user specific data block */
xmlSchemaValidityErrorFunc error ; /* the callback in case of errors */
xmlSchemaValidityWarningFunc warning ; /* the callback in case of warning */
xmlSchemaPtr schema ; /* The schema in use */
xmlDocPtr doc ;
xmlParserInputBufferPtr input ;
xmlCharEncoding enc ;
xmlSAXHandlerPtr sax ;
void * user_data ;
xmlDocPtr myDoc ;
int err ;
xmlNodePtr node ;
xmlSchemaTypePtr type ;
xmlRegExecCtxtPtr regexp ;
xmlSchemaValPtr value ;
int attrNr ;
int attrBase ;
int attrMax ;
xmlSchemaAttrStatePtr attr ;
} ;
/************************************************************************
* *
* Some predeclarations *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int xmlSchemaValidateSimpleValue ( xmlSchemaValidCtxtPtr ctxt ,
xmlSchemaTypePtr type ,
xmlChar * value ) ;
/************************************************************************
* *
* Allocation functions *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlSchemaNewSchema :
* @ ctxt : a schema validation context ( optional )
*
* 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 ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Out of memory \n " ) ;
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchema ) ) ;
return ( ret ) ;
}
/**
* xmlSchemaNewFacet :
* @ ctxt : a schema validation context ( optional )
*
* Allocate a new Facet structure .
*
* Returns the newly allocated structure or NULL in case or error
*/
static xmlSchemaFacetPtr
xmlSchemaNewFacet ( xmlSchemaParserCtxtPtr ctxt )
{
xmlSchemaFacetPtr ret ;
ret = ( xmlSchemaFacetPtr ) xmlMalloc ( sizeof ( xmlSchemaFacet ) ) ;
if ( ret = = NULL ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Out of memory \n " ) ;
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaFacet ) ) ;
return ( ret ) ;
}
/**
* xmlSchemaNewAnnot :
* @ ctxt : a schema validation context ( optional )
* @ 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 ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Out of memory \n " ) ;
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaAnnot ) ) ;
ret - > content = node ;
return ( ret ) ;
}
2002-07-01 21:52:03 +00:00
/**
* xmlSchemaFreeAnnot :
* @ annot : a schema type structure
*
* Deallocate a annotation structure
*/
static void
xmlSchemaFreeAnnot ( xmlSchemaAnnotPtr annot )
{
if ( annot = = NULL )
return ;
xmlFree ( annot ) ;
}
2002-04-16 15:50:10 +00:00
/**
* xmlSchemaFreeNotation :
* @ schema : a schema notation structure
*
* Deallocate a Schema Notation structure .
*/
static void
xmlSchemaFreeNotation ( xmlSchemaNotationPtr nota )
{
if ( nota = = NULL )
return ;
if ( nota - > name ! = NULL )
xmlFree ( ( xmlChar * ) nota - > name ) ;
xmlFree ( nota ) ;
}
/**
* xmlSchemaFreeAttribute :
* @ schema : a schema attribute structure
*
* Deallocate a Schema Attribute structure .
*/
static void
xmlSchemaFreeAttribute ( xmlSchemaAttributePtr attr )
{
if ( attr = = NULL )
return ;
if ( attr - > name ! = NULL )
xmlFree ( ( xmlChar * ) attr - > name ) ;
if ( attr - > ref ! = NULL )
xmlFree ( ( xmlChar * ) attr - > ref ) ;
if ( attr - > refNs ! = NULL )
xmlFree ( ( xmlChar * ) attr - > refNs ) ;
if ( attr - > typeName ! = NULL )
xmlFree ( ( xmlChar * ) attr - > typeName ) ;
if ( attr - > typeNs ! = NULL )
xmlFree ( ( xmlChar * ) attr - > typeNs ) ;
xmlFree ( attr ) ;
}
/**
* xmlSchemaFreeAttributeGroup :
* @ schema : a schema attribute group structure
*
* Deallocate a Schema Attribute Group structure .
*/
static void
xmlSchemaFreeAttributeGroup ( xmlSchemaAttributeGroupPtr attr )
{
if ( attr = = NULL )
return ;
if ( attr - > name ! = NULL )
xmlFree ( ( xmlChar * ) attr - > name ) ;
xmlFree ( attr ) ;
}
/**
* xmlSchemaFreeElement :
* @ schema : a schema element structure
*
* Deallocate a Schema Element structure .
*/
static void
xmlSchemaFreeElement ( xmlSchemaElementPtr elem )
{
if ( elem = = NULL )
return ;
if ( elem - > name ! = NULL )
xmlFree ( ( xmlChar * ) elem - > name ) ;
if ( elem - > namedType ! = NULL )
xmlFree ( ( xmlChar * ) elem - > namedType ) ;
if ( elem - > namedTypeNs ! = NULL )
xmlFree ( ( xmlChar * ) elem - > namedTypeNs ) ;
if ( elem - > ref ! = NULL )
xmlFree ( ( xmlChar * ) elem - > ref ) ;
if ( elem - > refNs ! = NULL )
xmlFree ( ( xmlChar * ) elem - > refNs ) ;
if ( elem - > contModel ! = NULL )
xmlRegFreeRegexp ( elem - > contModel ) ;
xmlFree ( elem ) ;
}
/**
* xmlSchemaFreeFacet :
* @ facet : a schema facet structure
*
* Deallocate a Schema Facet structure .
*/
static void
xmlSchemaFreeFacet ( xmlSchemaFacetPtr facet )
{
if ( facet = = NULL )
return ;
if ( facet - > value ! = NULL )
xmlFree ( ( xmlChar * ) facet - > value ) ;
if ( facet - > id ! = NULL )
xmlFree ( ( xmlChar * ) facet - > id ) ;
if ( facet - > val ! = NULL )
xmlSchemaFreeValue ( facet - > val ) ;
if ( facet - > regexp ! = NULL )
xmlRegFreeRegexp ( facet - > regexp ) ;
2002-07-01 21:52:03 +00:00
if ( facet - > annot ! = NULL )
xmlSchemaFreeAnnot ( facet - > annot ) ;
2002-04-16 15:50:10 +00:00
xmlFree ( facet ) ;
}
/**
* xmlSchemaFreeType :
* @ type : a schema type structure
*
* Deallocate a Schema Type structure .
*/
void
xmlSchemaFreeType ( xmlSchemaTypePtr type )
{
if ( type = = NULL )
return ;
if ( type - > name ! = NULL )
xmlFree ( ( xmlChar * ) type - > name ) ;
if ( type - > base ! = NULL )
xmlFree ( ( xmlChar * ) type - > base ) ;
if ( type - > baseNs ! = NULL )
xmlFree ( ( xmlChar * ) type - > baseNs ) ;
if ( type - > annot ! = NULL )
xmlFree ( ( xmlChar * ) type - > annot ) ;
if ( type - > facets ! = NULL ) {
xmlSchemaFacetPtr facet , next ;
facet = type - > facets ;
while ( facet ! = NULL ) {
next = facet - > next ;
xmlSchemaFreeFacet ( facet ) ;
facet = next ;
}
}
xmlFree ( type ) ;
}
/**
* xmlSchemaFree :
* @ schema : a schema structure
*
* Deallocate a Schema structure .
*/
void
xmlSchemaFree ( xmlSchemaPtr schema )
{
if ( schema = = NULL )
return ;
if ( schema - > name ! = NULL )
xmlFree ( ( xmlChar * ) schema - > name ) ;
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 ,
( xmlHashDeallocator ) xmlSchemaFreeType ) ;
if ( schema - > annot ! = NULL )
xmlSchemaFreeAnnot ( schema - > annot ) ;
if ( schema - > doc ! = NULL )
xmlFreeDoc ( schema - > doc ) ;
xmlFree ( schema ) ;
}
/************************************************************************
* *
* Error functions *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlSchemaErrorContext :
* @ ctxt : the parsing context
* @ schema : the schema being built
* @ node : the node being processed
* @ child : the child being processed
*
* Dump a SchemaType structure
*/
static void
xmlSchemaErrorContext ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
xmlNodePtr node , xmlNodePtr child )
{
int line = 0 ;
const xmlChar * file = NULL ;
const xmlChar * name = NULL ;
const char * type = " error " ;
if ( ( ctxt = = NULL ) | | ( ctxt - > error = = NULL ) )
return ;
if ( child ! = NULL )
node = child ;
if ( node ! = NULL ) {
if ( ( node - > type = = XML_DOCUMENT_NODE ) | |
( node - > type = = XML_HTML_DOCUMENT_NODE ) ) {
xmlDocPtr doc = ( xmlDocPtr ) node ;
file = doc - > URL ;
} else {
/*
* Try to find contextual informations to report
*/
if ( node - > type = = XML_ELEMENT_NODE ) {
line = ( int ) node - > content ;
} else if ( ( node - > prev ! = NULL ) & &
( node - > prev - > type = = XML_ELEMENT_NODE ) ) {
line = ( int ) node - > prev - > content ;
} else if ( ( node - > parent ! = NULL ) & &
( node - > parent - > type = = XML_ELEMENT_NODE ) ) {
line = ( int ) node - > parent - > content ;
}
if ( ( node - > doc ! = NULL ) & & ( node - > doc - > URL ! = NULL ) )
file = node - > doc - > URL ;
if ( node - > name ! = NULL )
name = node - > name ;
}
}
if ( ctxt ! = NULL )
type = " compilation error " ;
else if ( schema ! = NULL )
type = " runtime error " ;
if ( ( file ! = NULL ) & & ( line ! = 0 ) & & ( name ! = NULL ) )
ctxt - > error ( ctxt - > userData , " %s: file %s line %d element %s \n " ,
type , file , line , name ) ;
else if ( ( file ! = NULL ) & & ( name ! = NULL ) )
ctxt - > error ( ctxt - > userData , " %s: file %s element %s \n " ,
type , file , name ) ;
else if ( ( file ! = NULL ) & & ( line ! = 0 ) )
ctxt - > error ( ctxt - > userData , " %s: file %s line %d \n " , type , file , line ) ;
else if ( file ! = NULL )
ctxt - > error ( ctxt - > userData , " %s: file %s \n " , type , file ) ;
else if ( name ! = NULL )
ctxt - > error ( ctxt - > userData , " %s: element %s \n " , type , name ) ;
else
ctxt - > error ( ctxt - > userData , " %s \n " , type ) ;
}
/************************************************************************
* *
* Debug functions *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlSchemaElementDump :
* @ elem : an element
* @ output : the file output
*
* Dump the element
*/
static void
xmlSchemaElementDump ( xmlSchemaElementPtr elem , FILE * output ,
ATTRIBUTE_UNUSED const xmlChar * name ,
ATTRIBUTE_UNUSED const xmlChar * context ,
ATTRIBUTE_UNUSED const xmlChar * namespace )
{
if ( elem = = NULL )
return ;
fprintf ( output , " Element " ) ;
if ( elem - > flags & XML_SCHEMAS_ELEM_TOPLEVEL )
fprintf ( output , " toplevel " ) ;
fprintf ( output , " : %s " , elem - > name ) ;
if ( namespace ! = NULL )
fprintf ( output , " namespace '%s' " , namespace ) ;
if ( elem - > flags & XML_SCHEMAS_ELEM_NILLABLE )
fprintf ( output , " nillable " ) ;
if ( elem - > flags & XML_SCHEMAS_ELEM_GLOBAL )
fprintf ( output , " global " ) ;
if ( elem - > flags & XML_SCHEMAS_ELEM_DEFAULT )
fprintf ( output , " default " ) ;
if ( elem - > flags & XML_SCHEMAS_ELEM_FIXED )
fprintf ( output , " fixed " ) ;
if ( elem - > flags & XML_SCHEMAS_ELEM_ABSTRACT )
fprintf ( output , " abstract " ) ;
if ( elem - > flags & XML_SCHEMAS_ELEM_REF )
fprintf ( output , " ref '%s' " , elem - > ref ) ;
if ( elem - > id ! = NULL )
fprintf ( output , " id '%s' " , elem - > id ) ;
fprintf ( output , " \n " ) ;
if ( ( elem - > minOccurs ! = 1 ) | | ( elem - > maxOccurs ! = 1 ) ) {
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 " ) ;
}
if ( elem - > namedType ! = NULL ) {
fprintf ( output , " type: %s " , elem - > namedType ) ;
if ( elem - > namedTypeNs ! = NULL )
fprintf ( output , " ns %s \n " , elem - > namedTypeNs ) ;
else
fprintf ( output , " \n " ) ;
}
if ( elem - > substGroup ! = NULL ) {
fprintf ( output , " substitutionGroup: %s " , elem - > substGroup ) ;
if ( elem - > substGroupNs ! = NULL )
fprintf ( output , " ns %s \n " , elem - > substGroupNs ) ;
else
fprintf ( output , " \n " ) ;
}
if ( elem - > value ! = NULL )
fprintf ( output , " default: %s " , elem - > value ) ;
}
/**
* 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 ) {
fprintf ( output , " base %s, " , type - > base ) ;
}
switch ( type - > contentType ) {
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 ;
2002-04-23 07:12:20 +00:00
case XML_SCHEMA_CONTENT_ANY :
fprintf ( output , " any " ) ;
break ;
2002-04-16 15:50:10 +00:00
}
fprintf ( output , " \n " ) ;
if ( ( type - > minOccurs ! = 1 ) | | ( type - > maxOccurs ! = 1 ) ) {
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 " ) ;
}
if ( type - > annot ! = NULL )
xmlSchemaAnnotDump ( output , type - > annot ) ;
if ( type - > subtypes ! = NULL ) {
xmlSchemaTypePtr sub = type - > subtypes ;
fprintf ( output , " subtypes: " ) ;
while ( sub ! = NULL ) {
fprintf ( output , " %s " , sub - > name ) ;
sub = sub - > next ;
}
fprintf ( output , " \n " ) ;
}
}
/**
* 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 )
fprintf ( output , " %s " , schema - > targetNamespace ) ;
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 ,
( xmlHashScannerFull ) xmlSchemaElementDump , output ) ;
}
/************************************************************************
* *
* Parsing functions *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlSchemaGetType :
* @ schema : the schemas context
* @ name : the type name
* @ ns : the type namespace
*
* Lookup a type in the schemas or the predefined types
*
* Returns 1 if the string is NULL or made of blanks chars , 0 otherwise
*/
static xmlSchemaTypePtr
xmlSchemaGetType ( xmlSchemaPtr schema , const xmlChar * name ,
const xmlChar * namespace ) {
xmlSchemaTypePtr ret ;
if ( name = = NULL )
return ( NULL ) ;
if ( schema ! = NULL ) {
ret = xmlHashLookup2 ( schema - > typeDecl , name , namespace ) ;
if ( ret ! = NULL )
return ( ret ) ;
}
ret = xmlSchemaGetPredefinedType ( name , namespace ) ;
# 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 ) ;
}
/************************************************************************
* *
* 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
xmlSchemaIsBlank ( xmlChar * str ) {
if ( str = = NULL )
return ( 1 ) ;
while ( * str ! = 0 ) {
if ( ! ( IS_BLANK ( * str ) ) ) return ( 0 ) ;
str + + ;
}
return ( 1 ) ;
}
/**
* 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 ,
const xmlChar * name )
{
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 ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Out of memory \n " ) ;
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaNotation ) ) ;
ret - > name = xmlStrdup ( name ) ;
val = xmlHashAddEntry2 ( schema - > notaDecl , name , schema - > targetNamespace ,
ret ) ;
if ( val ! = 0 ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Could not add notation %s \n " ,
name ) ;
xmlFree ( ( char * ) ret - > name ) ;
xmlFree ( ret ) ;
return ( NULL ) ;
}
return ( ret ) ;
}
/**
* xmlSchemaAddAttribute :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ name : the item name
* @ container : the container ' s 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 xmlSchemaAttributePtr
xmlSchemaAddAttribute ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
const xmlChar * name )
{
xmlSchemaAttributePtr ret = NULL ;
int val ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( name = = NULL ) )
return ( NULL ) ;
if ( schema - > attrDecl = = NULL )
schema - > attrDecl = xmlHashCreate ( 10 ) ;
if ( schema - > attrDecl = = NULL )
return ( NULL ) ;
ret = ( xmlSchemaAttributePtr ) xmlMalloc ( sizeof ( xmlSchemaAttribute ) ) ;
if ( ret = = NULL ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Out of memory \n " ) ;
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaAttribute ) ) ;
ret - > name = xmlStrdup ( name ) ;
val = xmlHashAddEntry3 ( schema - > attrDecl , name ,
schema - > targetNamespace , ctxt - > container , ret ) ;
if ( val ! = 0 ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Could not add attribute %s \n " ,
name ) ;
xmlFree ( ( char * ) ret - > name ) ;
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
xmlSchemaAddAttributeGroup ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
const xmlChar * name )
{
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 ) ;
ret = ( xmlSchemaAttributeGroupPtr ) xmlMalloc ( sizeof ( xmlSchemaAttributeGroup ) ) ;
if ( ret = = NULL ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Out of memory \n " ) ;
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaAttributeGroup ) ) ;
ret - > name = xmlStrdup ( name ) ;
val = xmlHashAddEntry3 ( schema - > attrgrpDecl , name ,
schema - > targetNamespace , ctxt - > container , ret ) ;
if ( val ! = 0 ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Could not add attribute group %s \n " ,
name ) ;
xmlFree ( ( char * ) ret - > name ) ;
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 ) ;
if ( schema - > elemDecl = = NULL )
schema - > elemDecl = xmlHashCreate ( 10 ) ;
if ( schema - > elemDecl = = NULL )
return ( NULL ) ;
ret = ( xmlSchemaElementPtr ) xmlMalloc ( sizeof ( xmlSchemaElement ) ) ;
if ( ret = = NULL ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Out of memory \n " ) ;
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaElement ) ) ;
ret - > name = xmlStrdup ( name ) ;
val = xmlHashAddEntry3 ( schema - > elemDecl , name ,
namespace , ctxt - > container , ret ) ;
if ( val ! = 0 ) {
char buf [ 100 ] ;
snprintf ( buf , 99 , " privatieelem%d " , ctxt - > counter + + + 1 ) ;
val = xmlHashAddEntry3 ( schema - > elemDecl , name , ( xmlChar * ) buf ,
namespace , ret ) ;
if ( val ! = 0 ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Could not add element %s \n " ,
name ) ;
xmlFree ( ( char * ) ret - > name ) ;
xmlFree ( ret ) ;
return ( NULL ) ;
}
}
return ( ret ) ;
}
/**
* xmlSchemaAddType :
* @ ctxt : a schema validation context
* @ schema : the schema being built
* @ name : the item name
*
* 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 ,
const xmlChar * name )
{
xmlSchemaTypePtr ret = NULL ;
int val ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( name = = NULL ) )
return ( NULL ) ;
if ( schema - > typeDecl = = NULL )
schema - > typeDecl = xmlHashCreate ( 10 ) ;
if ( schema - > typeDecl = = NULL )
return ( NULL ) ;
ret = ( xmlSchemaTypePtr ) xmlMalloc ( sizeof ( xmlSchemaType ) ) ;
if ( ret = = NULL ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Out of memory \n " ) ;
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaType ) ) ;
ret - > name = xmlStrdup ( name ) ;
val = xmlHashAddEntry2 ( schema - > typeDecl , name , schema - > targetNamespace ,
ret ) ;
if ( val ! = 0 ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Could not add type %s \n " , name ) ;
xmlFree ( ( char * ) ret - > name ) ;
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
*/
static xmlChar *
xmlGetQNameProp ( xmlSchemaParserCtxtPtr ctxt , xmlNodePtr node ,
const char * name ,
xmlChar * * namespace ) {
xmlChar * val , * ret , * prefix ;
xmlNsPtr ns ;
if ( namespace ! = NULL )
* namespace = NULL ;
val = xmlGetProp ( node , ( const xmlChar * ) name ) ;
if ( val = = NULL )
return ( NULL ) ;
ret = xmlSplitQName2 ( val , & prefix ) ;
if ( ret = = NULL )
return ( val ) ;
xmlFree ( val ) ;
ns = xmlSearchNs ( node - > doc , node , prefix ) ;
if ( ns = = NULL ) {
xmlSchemaErrorContext ( ctxt , NULL , node , NULL ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Attribute %s: the QName prefix %s is undefined \n " ,
name , prefix ) ;
} else {
* namespace = xmlStrdup ( ns - > href ) ;
}
xmlFree ( prefix ) ;
return ( ret ) ;
}
/**
* 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
xmlGetMaxOccurs ( xmlSchemaParserCtxtPtr ctxt , xmlNodePtr node ) {
xmlChar * val , * cur ;
int ret = 0 ;
val = xmlGetProp ( node , ( const xmlChar * ) " maxOccurs " ) ;
if ( val = = NULL )
return ( 1 ) ;
if ( xmlStrEqual ( val , ( const xmlChar * ) " unbounded " ) ) {
xmlFree ( val ) ;
return ( UNBOUNDED ) ; /* encoding it with -1 might be another option */
}
cur = val ;
while ( IS_BLANK ( * cur ) ) cur + + ;
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
ret = ret * 10 + ( * cur - ' 0 ' ) ;
cur + + ;
}
while ( IS_BLANK ( * cur ) ) cur + + ;
if ( * cur ! = 0 ) {
xmlSchemaErrorContext ( ctxt , NULL , node , NULL ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " invalid value for minOccurs: %s \n " ,
val ) ;
xmlFree ( val ) ;
return ( 1 ) ;
}
xmlFree ( val ) ;
return ( ret ) ;
}
/**
* 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
xmlGetMinOccurs ( xmlSchemaParserCtxtPtr ctxt , xmlNodePtr node ) {
xmlChar * val , * cur ;
int ret = 0 ;
val = xmlGetProp ( node , ( const xmlChar * ) " minOccurs " ) ;
if ( val = = NULL )
return ( 1 ) ;
cur = val ;
while ( IS_BLANK ( * cur ) ) cur + + ;
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
ret = ret * 10 + ( * cur - ' 0 ' ) ;
cur + + ;
}
while ( IS_BLANK ( * cur ) ) cur + + ;
if ( * cur ! = 0 ) {
xmlSchemaErrorContext ( ctxt , NULL , node , NULL ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " invalid value for minOccurs: %s \n " ,
val ) ;
xmlFree ( val ) ;
return ( 1 ) ;
}
xmlFree ( val ) ;
return ( ret ) ;
}
/**
* 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 ,
const char * name , int def ) {
xmlChar * val ;
val = xmlGetProp ( node , ( const xmlChar * ) name ) ;
if ( val = = NULL )
return ( def ) ;
if ( xmlStrEqual ( val , BAD_CAST " true " ) )
def = 1 ;
else if ( xmlStrEqual ( val , BAD_CAST " false " ) )
def = 0 ;
else {
xmlSchemaErrorContext ( ctxt , NULL , node , NULL ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Attribute %s: the value %s is not boolean \n " ,
name , val ) ;
}
xmlFree ( val ) ;
return ( def ) ;
}
/************************************************************************
* *
* Shema extraction from an Infoset *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static xmlSchemaTypePtr xmlSchemaParseSimpleType ( xmlSchemaParserCtxtPtr
ctxt , xmlSchemaPtr schema ,
xmlNodePtr node ) ;
static xmlSchemaTypePtr xmlSchemaParseComplexType ( xmlSchemaParserCtxtPtr ctxt ,
xmlSchemaPtr schema ,
xmlNodePtr node ) ;
static xmlSchemaTypePtr xmlSchemaParseRestriction ( xmlSchemaParserCtxtPtr ctxt ,
xmlSchemaPtr schema ,
xmlNodePtr node ,
int simple ) ;
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
xmlSchemaParseAnyAttribute ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
xmlNodePtr node ) ;
/**
* 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 " ) ) | |
( 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 ;
}
if ( IS_SCHEMA ( child , " anyAttribute " ) ) {
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 ) ;
}
/**
* 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 ,
xmlNodePtr node )
{
xmlSchemaFacetPtr facet ;
xmlNodePtr child = NULL ;
xmlChar * value ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
facet = xmlSchemaNewFacet ( ctxt ) ;
if ( facet = = NULL )
return ( NULL ) ;
facet - > node = node ;
value = xmlGetProp ( node , ( const xmlChar * ) " value " ) ;
if ( value = = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Facet %s has no value \n " , node - > name ) ;
xmlSchemaFreeFacet ( facet ) ;
return ( NULL ) ;
}
if ( IS_SCHEMA ( node , " minInclusive " ) ) {
facet - > type = XML_SCHEMA_FACET_MININCLUSIVE ;
} else if ( IS_SCHEMA ( node , " minExclusive " ) ) {
facet - > type = XML_SCHEMA_FACET_MINEXCLUSIVE ;
} else if ( IS_SCHEMA ( node , " maxInclusive " ) ) {
facet - > type = XML_SCHEMA_FACET_MAXINCLUSIVE ;
} else if ( IS_SCHEMA ( node , " maxExclusive " ) ) {
facet - > type = XML_SCHEMA_FACET_MAXEXCLUSIVE ;
} else if ( IS_SCHEMA ( node , " totalDigits " ) ) {
facet - > type = XML_SCHEMA_FACET_TOTALDIGITS ;
} else if ( IS_SCHEMA ( node , " fractionDigits " ) ) {
facet - > type = XML_SCHEMA_FACET_FRACTIONDIGITS ;
} else if ( IS_SCHEMA ( node , " pattern " ) ) {
facet - > type = XML_SCHEMA_FACET_PATTERN ;
} else if ( IS_SCHEMA ( node , " enumeration " ) ) {
facet - > type = XML_SCHEMA_FACET_ENUMERATION ;
} else if ( IS_SCHEMA ( node , " whiteSpace " ) ) {
facet - > type = XML_SCHEMA_FACET_WHITESPACE ;
} else if ( IS_SCHEMA ( node , " length " ) ) {
facet - > type = XML_SCHEMA_FACET_LENGTH ;
} else if ( IS_SCHEMA ( node , " maxLength " ) ) {
facet - > type = XML_SCHEMA_FACET_MAXLENGTH ;
} else if ( IS_SCHEMA ( node , " minLength " ) ) {
facet - > type = XML_SCHEMA_FACET_MINLENGTH ;
} else {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Unknown facet type %s \n " , node - > name ) ;
xmlSchemaFreeFacet ( facet ) ;
return ( NULL ) ;
}
facet - > id = xmlGetProp ( node , ( const xmlChar * ) " id " ) ;
facet - > value = value ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
facet - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Facet %s has unexpected child content \n " ,
node - > name ) ;
}
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 ) ;
snprintf ( ( char * ) name , 30 , " any %d " , ctxt - > counter + + + 1 ) ;
type = xmlSchemaAddType ( ctxt , schema , name ) ;
if ( type = = NULL )
return ( NULL ) ;
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 " ) ) {
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Sequence %s has unexpected content \n " ,
type - > name ) ;
}
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 ,
xmlNodePtr node )
{
xmlChar * name ;
xmlSchemaNotationPtr ret ;
xmlNodePtr child = NULL ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
name = xmlGetProp ( node , ( const xmlChar * ) " name " ) ;
if ( name = = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Notation has no name \n " ) ;
return ( NULL ) ;
}
ret = xmlSchemaAddNotation ( ctxt , schema , name ) ;
if ( ret = = NULL ) {
xmlFree ( name ) ;
return ( NULL ) ;
}
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
ret - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" notation %s has unexpected content \n " ,
name ) ;
}
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
xmlSchemaParseAnyAttribute ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
xmlNodePtr node )
{
xmlChar * processContents ;
xmlSchemaAttributePtr ret ;
xmlNodePtr child = NULL ;
char name [ 100 ] ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
snprintf ( name , 99 , " anyattr %d " , ctxt - > counter + + + 1 ) ;
ret = xmlSchemaAddAttribute ( ctxt , schema , ( xmlChar * ) name ) ;
if ( ret = = NULL ) {
return ( NULL ) ;
}
ret - > id = xmlGetProp ( node , ( const xmlChar * ) " id " ) ;
processContents = xmlGetProp ( node , ( const xmlChar * ) " processContents " ) ;
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 ;
} else {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" anyAttribute has unexpected content for processContents: %s \n " ,
processContents ) ;
ret - > occurs = XML_SCHEMAS_ANYATTR_STRICT ;
}
if ( processContents ! = NULL )
xmlFree ( processContents ) ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
ret - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" anyAttribute %s has unexpected content \n " ,
name ) ;
}
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 )
{
xmlChar * name , * refNs = NULL , * ref = NULL ;
xmlSchemaAttributePtr ret ;
xmlNodePtr child = NULL ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
name = xmlGetProp ( node , ( const xmlChar * ) " name " ) ;
if ( name = = NULL ) {
char buf [ 100 ] ;
ref = xmlGetQNameProp ( ctxt , node , " ref " , & refNs ) ;
if ( ref = = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Attribute has no name nor ref \n " ) ;
return ( NULL ) ;
}
snprintf ( buf , 99 , " anonattr%d " , ctxt - > counter + + + 1 ) ;
name = xmlStrdup ( ( xmlChar * ) buf ) ;
}
ret = xmlSchemaAddAttribute ( ctxt , schema , name ) ;
if ( ret = = NULL ) {
xmlFree ( name ) ;
if ( ref ! = NULL )
xmlFree ( ref ) ;
return ( NULL ) ;
}
xmlFree ( name ) ;
ret - > ref = ref ;
ret - > refNs = refNs ;
ret - > typeName = xmlGetQNameProp ( ctxt , node , " type " , & ( ret - > typeNs ) ) ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
ret - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
if ( IS_SCHEMA ( child , " simpleType " ) ) {
2002-04-23 07:12:20 +00:00
ret - > subtypes = xmlSchemaParseSimpleType ( ctxt , schema , child ) ;
2002-04-16 15:50:10 +00:00
child = child - > next ;
}
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" attribute %s has unexpected content \n " ,
name ) ;
}
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
xmlSchemaParseAttributeGroup ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
xmlNodePtr node )
{
xmlChar * name , * refNs = NULL , * ref = NULL ;
xmlSchemaAttributeGroupPtr ret ;
xmlSchemaAttributePtr last = NULL , attr ;
xmlNodePtr child = NULL ;
xmlChar * oldcontainer ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
oldcontainer = ctxt - > container ;
name = xmlGetProp ( node , ( const xmlChar * ) " name " ) ;
if ( name = = NULL ) {
char buf [ 100 ] ;
ref = xmlGetQNameProp ( ctxt , node , " ref " , & refNs ) ;
if ( ref = = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" AttributeGroup has no name nor ref \n " ) ;
return ( NULL ) ;
}
snprintf ( buf , 99 , " anonattrgroup%d " , ctxt - > counter + + + 1 ) ;
name = xmlStrdup ( ( xmlChar * ) buf ) ;
}
ret = xmlSchemaAddAttributeGroup ( ctxt , schema , name ) ;
if ( ret = = NULL ) {
xmlFree ( name ) ;
if ( ref ! = NULL )
xmlFree ( ref ) ;
return ( NULL ) ;
}
ret - > ref = ref ;
ret - > refNs = refNs ;
2002-04-23 17:51:29 +00:00
ret - > type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP ;
2002-04-16 15:50:10 +00:00
child = node - > children ;
ctxt - > container = name ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
ret - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
while ( ( IS_SCHEMA ( child , " attribute " ) ) | |
( 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 ;
}
if ( IS_SCHEMA ( child , " anyAttribute " ) ) {
TODO
child = child - > next ;
}
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" attribute group %s has unexpected content \n " ,
name ) ;
}
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 )
{
xmlChar * name , * refNs = NULL , * ref = NULL , * namespace , * fixed ;
xmlSchemaElementPtr ret ;
xmlNodePtr child = NULL ;
xmlChar * oldcontainer ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
oldcontainer = ctxt - > container ;
name = xmlGetProp ( node , ( const xmlChar * ) " name " ) ;
if ( name = = NULL ) {
char buf [ 100 ] ;
ref = xmlGetQNameProp ( ctxt , node , " ref " , & refNs ) ;
if ( ref = = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Element has no name nor ref \n " ) ;
return ( NULL ) ;
}
snprintf ( buf , 99 , " anonelem%d " , ctxt - > counter + + + 1 ) ;
name = xmlStrdup ( ( xmlChar * ) buf ) ;
}
namespace = xmlGetProp ( node , ( const xmlChar * ) " targetNamespace " ) ;
if ( namespace = = NULL )
ret =
xmlSchemaAddElement ( ctxt , schema , name ,
schema - > targetNamespace ) ;
else
ret = xmlSchemaAddElement ( ctxt , schema , name , namespace ) ;
if ( namespace ! = NULL )
xmlFree ( namespace ) ;
if ( ret = = NULL ) {
xmlFree ( name ) ;
if ( ref ! = NULL )
xmlFree ( ref ) ;
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 ;
ret - > id = xmlGetProp ( node , BAD_CAST " id " ) ;
ret - > namedType = xmlGetQNameProp ( ctxt , node , " type " , & ( ret - > namedTypeNs ) ) ;
ret - > substGroup = xmlGetQNameProp ( ctxt , node , " substitutionGroup " ,
& ( ret - > substGroupNs ) ) ;
fixed = xmlGetProp ( node , BAD_CAST " fixed " ) ;
ret - > minOccurs = xmlGetMinOccurs ( ctxt , node ) ;
ret - > maxOccurs = xmlGetMaxOccurs ( ctxt , node ) ;
ret - > value = xmlGetProp ( node , BAD_CAST " default " ) ;
if ( ( ret - > value ! = NULL ) & & ( fixed ! = NULL ) ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
ctxt - > error ( ctxt - > userData ,
" Element %s has both default and fixed \n " ,
ret - > name ) ;
xmlFree ( fixed ) ;
} else if ( fixed ! = NULL ) {
ret - > flags | = XML_SCHEMAS_ELEM_FIXED ;
ret - > value = fixed ;
}
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
ret - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
if ( IS_SCHEMA ( child , " complexType " ) ) {
ret - > subtypes = xmlSchemaParseComplexType ( ctxt , schema , child ) ;
child = child - > next ;
} else if ( IS_SCHEMA ( child , " simpleType " ) ) {
ret - > subtypes = xmlSchemaParseSimpleType ( ctxt , schema , child ) ;
child = child - > next ;
}
while ( ( IS_SCHEMA ( child , " unique " ) ) | |
( IS_SCHEMA ( child , " key " ) ) | |
( IS_SCHEMA ( child , " keyref " ) ) ) {
TODO
child = child - > next ;
}
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" element %s has unexpected content \n " ,
name ) ;
}
ctxt - > container = oldcontainer ;
xmlFree ( name ) ;
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 ,
xmlNodePtr node )
{
xmlSchemaTypePtr type , subtype , last = NULL ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
snprintf ( ( char * ) name , 30 , " union %d " , ctxt - > counter + + + 1 ) ;
type = xmlSchemaAddType ( ctxt , schema , name ) ;
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_LIST ;
type - > id = xmlGetProp ( node , BAD_CAST " id " ) ;
type - > ref = xmlGetProp ( node , BAD_CAST " memberTypes " ) ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
while ( IS_SCHEMA ( child , " simpleType " ) ) {
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 ;
}
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Union %s has unexpected content \n " ,
type - > name ) ;
}
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 ,
xmlNodePtr node )
{
xmlSchemaTypePtr type , subtype ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
snprintf ( ( char * ) name , 30 , " list %d " , ctxt - > counter + + + 1 ) ;
type = xmlSchemaAddType ( ctxt , schema , name ) ;
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_LIST ;
type - > id = xmlGetProp ( node , BAD_CAST " id " ) ;
type - > ref = xmlGetQNameProp ( ctxt , node , " ref " , & ( type - > refNs ) ) ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
subtype = NULL ;
if ( IS_SCHEMA ( child , " simpleType " ) ) {
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseSimpleType ( ctxt , schema , child ) ;
child = child - > next ;
type - > subtypes = subtype ;
}
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" List %s has unexpected content \n " ,
type - > name ) ;
}
return ( type ) ;
}
/**
* 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 ;
xmlChar * name ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
name = xmlGetProp ( node , ( const xmlChar * ) " name " ) ;
if ( name = = NULL ) {
char buf [ 100 ] ;
snprintf ( buf , 99 , " simpletype%d " , ctxt - > counter + + + 1 ) ;
name = xmlStrdup ( ( xmlChar * ) buf ) ;
}
if ( name = = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " simpleType has no name \n " ) ;
return ( NULL ) ;
}
type = xmlSchemaAddType ( ctxt , schema , name ) ;
xmlFree ( name ) ;
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_SIMPLE ;
type - > id = xmlGetProp ( node , BAD_CAST " id " ) ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
subtype = NULL ;
if ( IS_SCHEMA ( child , " restriction " ) ) {
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseRestriction ( ctxt , schema , child , 1 ) ;
child = child - > next ;
} else if ( IS_SCHEMA ( child , " list " ) ) {
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseList ( ctxt , schema , child ) ;
child = child - > next ;
} else if ( IS_SCHEMA ( child , " union " ) ) {
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseUnion ( ctxt , schema , child ) ;
child = child - > next ;
}
type - > subtypes = subtype ;
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" SimpleType %s has unexpected content \n " ,
type - > name ) ;
}
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 ,
xmlNodePtr node )
{
xmlSchemaTypePtr type , subtype ;
xmlNodePtr child = NULL ;
xmlChar * name , * ref = NULL , * refNs = NULL ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
name = xmlGetProp ( node , ( const xmlChar * ) " name " ) ;
if ( name = = NULL ) {
char buf [ 100 ] ;
ref = xmlGetQNameProp ( ctxt , node , " ref " , & refNs ) ;
if ( ref = = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " Group has no name nor ref \n " ) ;
return ( NULL ) ;
}
snprintf ( buf , 99 , " anongroup%d " , ctxt - > counter + + + 1 ) ;
name = xmlStrdup ( ( xmlChar * ) buf ) ;
}
type = xmlSchemaAddType ( ctxt , schema , name ) ;
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_GROUP ;
type - > id = xmlGetProp ( node , BAD_CAST " id " ) ;
type - > ref = ref ;
type - > refNs = refNs ;
type - > minOccurs = xmlGetMinOccurs ( ctxt , node ) ;
type - > maxOccurs = xmlGetMaxOccurs ( ctxt , node ) ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
subtype = NULL ;
if ( IS_SCHEMA ( child , " all " ) ) {
subtype = ( xmlSchemaTypePtr )
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 = ( xmlSchemaTypePtr )
xmlSchemaParseSequence ( ctxt , schema , child ) ;
child = child - > next ;
}
if ( subtype ! = NULL )
type - > subtypes = subtype ;
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Group %s has unexpected content \n " ,
type - > name ) ;
}
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 ,
xmlNodePtr node )
{
xmlSchemaTypePtr type , subtype , last = NULL ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
snprintf ( ( char * ) name , 30 , " all%d " , ctxt - > counter + + + 1 ) ;
type = xmlSchemaAddType ( ctxt , schema , name ) ;
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
2002-04-20 06:41:40 +00:00
type - > type = XML_SCHEMA_TYPE_ALL ;
2002-04-16 15:50:10 +00:00
type - > id = xmlGetProp ( node , BAD_CAST " id " ) ;
type - > minOccurs = xmlGetMinOccurs ( ctxt , node ) ;
type - > maxOccurs = xmlGetMaxOccurs ( ctxt , node ) ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
while ( IS_SCHEMA ( child , " element " ) ) {
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseElement ( ctxt , schema , child , 0 ) ;
if ( subtype ! = NULL ) {
if ( last = = NULL ) {
type - > subtypes = subtype ;
last = subtype ;
} else {
last - > next = subtype ;
last = subtype ;
}
last - > next = NULL ;
}
child = child - > next ;
}
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" All %s has unexpected content \n " ,
type - > name ) ;
}
return ( type ) ;
}
2002-05-22 06:40:27 +00: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 ,
xmlNodePtr node )
{
xmlNodePtr child = NULL ;
xmlChar * namespace ;
xmlChar * schemaLocation ;
xmlChar * previous ;
xmlURIPtr check ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( - 1 ) ;
namespace = xmlGetProp ( node , BAD_CAST " namespace " ) ;
if ( namespace ! = NULL ) {
check = xmlParseURI ( ( const char * ) namespace ) ;
if ( check = = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Import namespace attribute is not an URI: %s \n " ,
namespace ) ;
xmlFree ( namespace ) ;
return ( - 1 ) ;
} else {
xmlFreeURI ( check ) ;
}
}
schemaLocation = xmlGetProp ( node , BAD_CAST " schemaLocation " ) ;
if ( schemaLocation ! = NULL ) {
check = xmlParseURI ( ( const char * ) schemaLocation ) ;
if ( check = = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Import schemaLocation attribute is not an URI: %s \n " ,
schemaLocation ) ;
if ( namespace ! = NULL )
xmlFree ( namespace ) ;
xmlFree ( schemaLocation ) ;
return ( - 1 ) ;
} else {
xmlFreeURI ( check ) ;
}
}
if ( schema - > schemasImports = = NULL ) {
schema - > schemasImports = xmlHashCreate ( 10 ) ;
if ( schema - > schemasImports = = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Internal: failed to build import table \n " ) ;
if ( namespace ! = NULL )
xmlFree ( namespace ) ;
if ( schemaLocation ! = NULL )
xmlFree ( schemaLocation ) ;
return ( - 1 ) ;
}
}
if ( namespace = = NULL ) {
previous = xmlHashLookup ( schema - > schemasImports ,
XML_SCHEMAS_DEFAULT_NAMESPACE ) ;
if ( schemaLocation ! = NULL ) {
if ( previous ! = NULL ) {
if ( ! xmlStrEqual ( schemaLocation , previous ) ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Redefining import for default namespace with a different URI: %s \n " ,
schemaLocation ) ;
}
} else {
xmlHashAddEntry ( schema - > schemasImports ,
XML_SCHEMAS_DEFAULT_NAMESPACE , schemaLocation ) ;
}
}
} else {
previous = xmlHashLookup ( schema - > schemasImports , namespace ) ;
if ( schemaLocation ! = NULL ) {
if ( previous ! = NULL ) {
if ( ! xmlStrEqual ( schemaLocation , previous ) ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Redefining import for namespace %s with a different URI: %s \n " ,
namespace , schemaLocation ) ;
}
} else {
xmlHashAddEntry ( schema - > schemasImports ,
namespace , schemaLocation ) ;
}
}
}
child = node - > children ;
while ( IS_SCHEMA ( child , " annotation " ) ) {
2002-05-22 09:57:32 +00:00
/*
* the annotations here are simply discarded . . .
*/
2002-05-22 06:40:27 +00:00
child = child - > next ;
}
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Import has unexpected content \n " ) ;
return ( - 1 ) ;
}
return ( 1 ) ;
}
2002-04-16 15:50:10 +00: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 ,
xmlNodePtr node )
{
xmlSchemaTypePtr type , subtype , last = NULL ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
snprintf ( ( char * ) name , 30 , " choice %d " , ctxt - > counter + + + 1 ) ;
type = xmlSchemaAddType ( ctxt , schema , name ) ;
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_CHOICE ;
type - > id = xmlGetProp ( node , BAD_CAST " id " ) ;
type - > minOccurs = xmlGetMinOccurs ( ctxt , node ) ;
type - > maxOccurs = xmlGetMaxOccurs ( ctxt , node ) ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
while ( ( IS_SCHEMA ( child , " element " ) ) | |
( 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 ;
}
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Choice %s has unexpected content \n " ,
type - > name ) ;
}
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 ,
xmlNodePtr node )
{
xmlSchemaTypePtr type , subtype , last = NULL ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
snprintf ( ( char * ) name , 30 , " sequence %d " , ctxt - > counter + + + 1 ) ;
type = xmlSchemaAddType ( ctxt , schema , name ) ;
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_SEQUENCE ;
type - > id = xmlGetProp ( node , BAD_CAST " id " ) ;
type - > minOccurs = xmlGetMinOccurs ( ctxt , node ) ;
type - > maxOccurs = xmlGetMaxOccurs ( ctxt , node ) ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
while ( ( IS_SCHEMA ( child , " element " ) ) | |
( 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 ;
}
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Sequence %s has unexpected content \n " ,
type - > name ) ;
}
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 ] ;
xmlChar * oldcontainer ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
oldcontainer = ctxt - > container ;
snprintf ( ( char * ) name , 30 , " restriction %d " , ctxt - > counter + + + 1 ) ;
type = xmlSchemaAddType ( ctxt , schema , name ) ;
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_RESTRICTION ;
type - > id = xmlGetProp ( node , BAD_CAST " id " ) ;
type - > base = xmlGetQNameProp ( ctxt , node , " base " , & ( type - > baseNs ) ) ;
if ( ( ! simple ) & & ( type - > base = = NULL ) ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Restriction %s has no base \n " ,
type - > name ) ;
}
ctxt - > container = name ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
subtype = NULL ;
if ( IS_SCHEMA ( child , " all " ) ) {
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseAll ( ctxt , schema , child ) ;
child = child - > next ;
type - > subtypes = subtype ;
} else if ( IS_SCHEMA ( child , " choice " ) ) {
subtype = xmlSchemaParseChoice ( ctxt , schema , child ) ;
child = child - > next ;
type - > subtypes = subtype ;
} else if ( IS_SCHEMA ( child , " sequence " ) ) {
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseSequence ( ctxt , schema , child ) ;
child = child - > next ;
type - > subtypes = subtype ;
} else if ( IS_SCHEMA ( child , " group " ) ) {
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseGroup ( ctxt , schema , child ) ;
child = child - > next ;
type - > subtypes = subtype ;
} else {
if ( IS_SCHEMA ( child , " simpleType " ) ) {
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseSimpleType ( ctxt , schema , child ) ;
child = child - > next ;
type - > baseType = subtype ;
}
/*
* Facets
*/
while ( ( IS_SCHEMA ( child , " minInclusive " ) ) | |
( 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 ;
}
}
child = xmlSchemaParseAttrDecls ( ctxt , schema , child , type ) ;
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Restriction %s has unexpected content \n " ,
type - > name ) ;
}
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 ,
xmlNodePtr node )
{
xmlSchemaTypePtr type , subtype ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
xmlChar * oldcontainer ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
oldcontainer = ctxt - > container ;
snprintf ( ( char * ) name , 30 , " extension %d " , ctxt - > counter + + + 1 ) ;
type = xmlSchemaAddType ( ctxt , schema , name ) ;
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_EXTENSION ;
type - > id = xmlGetProp ( node , BAD_CAST " id " ) ;
ctxt - > container = name ;
type - > base = xmlGetQNameProp ( ctxt , node , " base " , & ( type - > baseNs ) ) ;
if ( type - > base = = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Extension %s has no base \n " ,
type - > name ) ;
}
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
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 ) ;
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Extension %s has unexpected content \n " ,
type - > name ) ;
}
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
xmlSchemaParseSimpleContent ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
xmlNodePtr node )
{
xmlSchemaTypePtr type , subtype ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
snprintf ( ( char * ) name , 30 , " complexContent %d " , ctxt - > counter + + + 1 ) ;
type = xmlSchemaAddType ( ctxt , schema , name ) ;
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_SIMPLE_CONTENT ;
type - > id = xmlGetProp ( node , BAD_CAST " id " ) ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
subtype = NULL ;
if ( IS_SCHEMA ( child , " restriction " ) ) {
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseRestriction ( ctxt , schema , child , 0 ) ;
child = child - > next ;
} else if ( IS_SCHEMA ( child , " extension " ) ) {
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseExtension ( ctxt , schema , child ) ;
child = child - > next ;
}
type - > subtypes = subtype ;
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" SimpleContent %s has unexpected content \n " ,
type - > name ) ;
}
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
xmlSchemaParseComplexContent ( xmlSchemaParserCtxtPtr ctxt , xmlSchemaPtr schema ,
xmlNodePtr node )
{
xmlSchemaTypePtr type , subtype ;
xmlNodePtr child = NULL ;
xmlChar name [ 30 ] ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
snprintf ( ( char * ) name , 30 , " complexContent %d " , ctxt - > counter + + + 1 ) ;
type = xmlSchemaAddType ( ctxt , schema , name ) ;
if ( type = = NULL )
return ( NULL ) ;
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_COMPLEX_CONTENT ;
type - > id = xmlGetProp ( node , BAD_CAST " id " ) ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
subtype = NULL ;
if ( IS_SCHEMA ( child , " restriction " ) ) {
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseRestriction ( ctxt , schema , child , 0 ) ;
child = child - > next ;
} else if ( IS_SCHEMA ( child , " extension " ) ) {
subtype = ( xmlSchemaTypePtr )
xmlSchemaParseExtension ( ctxt , schema , child ) ;
child = child - > next ;
}
type - > subtypes = subtype ;
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" ComplexContent %s has unexpected content \n " ,
type - > name ) ;
}
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 ;
xmlChar * name ;
xmlChar * oldcontainer ;
if ( ( ctxt = = NULL ) | | ( schema = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
oldcontainer = ctxt - > container ;
name = xmlGetProp ( node , ( const xmlChar * ) " name " ) ;
if ( name = = NULL ) {
char buf [ 100 ] ;
snprintf ( buf , 99 , " anontype%d " , ctxt - > counter + + + 1 ) ;
name = xmlStrdup ( ( xmlChar * ) buf ) ;
}
if ( name = = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData , " complexType has no name \n " ) ;
return ( NULL ) ;
}
type = xmlSchemaAddType ( ctxt , schema , name ) ;
if ( type = = NULL ) {
xmlFree ( name ) ;
return ( NULL ) ;
}
type - > node = node ;
type - > type = XML_SCHEMA_TYPE_COMPLEX ;
type - > id = xmlGetProp ( node , BAD_CAST " id " ) ;
ctxt - > container = name ;
child = node - > children ;
if ( IS_SCHEMA ( child , " annotation " ) ) {
type - > annot = xmlSchemaParseAnnotation ( ctxt , schema , child ) ;
child = child - > next ;
}
if ( IS_SCHEMA ( child , " simpleContent " ) ) {
2002-04-18 14:41:51 +00:00
type - > subtypes = xmlSchemaParseSimpleContent ( ctxt , schema , child ) ;
2002-04-16 15:50:10 +00:00
child = child - > next ;
} else if ( IS_SCHEMA ( child , " complexContent " ) ) {
type - > subtypes = xmlSchemaParseComplexContent ( ctxt , schema , child ) ;
child = child - > next ;
} else {
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 ) ;
}
if ( child ! = NULL ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" ComplexType %s has unexpected content \n " ,
type - > name ) ;
}
ctxt - > container = oldcontainer ;
xmlFree ( name ) ;
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 ;
xmlSchemaAnnotPtr annot ;
xmlNodePtr child = NULL ;
xmlChar * val ;
if ( ( ctxt = = NULL ) | | ( node = = NULL ) )
return ( NULL ) ;
if ( IS_SCHEMA ( node , " schema " ) ) {
schema = xmlSchemaNewSchema ( ctxt ) ;
if ( schema = = NULL )
return ( NULL ) ;
schema - > targetNamespace = xmlGetProp ( node , BAD_CAST " targetNamespace " ) ;
schema - > id = xmlGetProp ( node , BAD_CAST " id " ) ;
schema - > version = xmlGetProp ( node , BAD_CAST " version " ) ;
val = xmlGetProp ( node , BAD_CAST " elementFormDefault " ) ;
if ( val ! = NULL ) {
if ( xmlStrEqual ( val , BAD_CAST " qualified " ) )
schema - > flags | = XML_SCHEMAS_QUALIF_ELEM ;
else if ( ! xmlStrEqual ( val , BAD_CAST " unqualified " ) ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) ) {
ctxt - > error ( ctxt - > userData ,
" Invalid value %s for elementFormDefault \n " ,
val ) ;
}
}
xmlFree ( val ) ;
}
val = xmlGetProp ( node , BAD_CAST " attributeFormDefault " ) ;
if ( val ! = NULL ) {
if ( xmlStrEqual ( val , BAD_CAST " qualified " ) )
schema - > flags | = XML_SCHEMAS_QUALIF_ATTR ;
else if ( ! xmlStrEqual ( val , BAD_CAST " unqualified " ) ) {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) ) {
ctxt - > error ( ctxt - > userData ,
" Invalid value %s for elementFormDefault \n " ,
val ) ;
}
}
xmlFree ( val ) ;
}
child = node - > children ;
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 , " include " ) ) {
TODO
} else if ( IS_SCHEMA ( child , " import " ) ) {
2002-05-22 06:40:27 +00:00
xmlSchemaParseImport ( ctxt , schema , child ) ;
2002-04-16 15:50:10 +00: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 {
xmlSchemaErrorContext ( ctxt , schema , node , child ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Schemas: unexpected element %s here \n " ,
child - > name ) ;
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 ;
}
}
}
# 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
xmlSchemaNewParserCtxt ( const char * URL ) {
xmlSchemaParserCtxtPtr ret ;
if ( URL = = NULL )
return ( NULL ) ;
ret = ( xmlSchemaParserCtxtPtr ) xmlMalloc ( sizeof ( xmlSchemaParserCtxt ) ) ;
if ( ret = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" Failed to allocate new schama parser context for %s \n " , URL ) ;
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaParserCtxt ) ) ;
ret - > URL = xmlStrdup ( ( const xmlChar * ) URL ) ;
return ( ret ) ;
}
/**
* xmlSchemaFreeParserCtxt :
* @ ctxt : the schema parser context
*
* Free the resources associated to the schema parser context
*/
void
xmlSchemaFreeParserCtxt ( xmlSchemaParserCtxtPtr ctxt ) {
if ( ctxt = = NULL )
return ;
if ( ctxt - > URL ! = NULL )
xmlFree ( ctxt - > URL ) ;
xmlFree ( ctxt ) ;
}
/************************************************************************
* *
* Building the content models *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* 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 ,
xmlSchemaParserCtxtPtr ctxt ,
const xmlChar * name ) {
if ( type = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" Found unexpected type = NULL in %s content model \n " ,
name ) ;
return ;
}
switch ( type - > type ) {
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 - > 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 ) {
if ( elem - > refDecl ! = NULL ) {
TODO
xmlSchemaBuildAContentModel (
( xmlSchemaTypePtr ) elem - > refDecl ,
ctxt , elem - > refDecl - > name ) ;
} else {
ctxt - > state = xmlAutomataNewCountTrans ( ctxt - > am ,
ctxt - > state , NULL , elem - > name ,
elem - > minOccurs , elem - > maxOccurs , type ) ;
}
} 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 ;
/*
* Simply iterate over the subtypes
*/
subtypes = type - > subtypes ;
while ( subtypes ! = NULL ) {
xmlSchemaBuildAContentModel ( subtypes , ctxt , name ) ;
subtypes = subtypes - > next ;
}
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
*/
2002-04-17 16:28:10 +00:00
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 ;
/*
* use a counter to keep track of the number of transtions
* which went through the choice .
*/
if ( type - > minOccurs < 1 ) {
counter = xmlAutomataNewCounter ( ctxt - > am , 0 ,
type - > maxOccurs - 1 ) ;
} else {
counter = xmlAutomataNewCounter ( ctxt - > am ,
type - > minOccurs - 1 , type - > maxOccurs - 1 ) ;
}
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 ) ;
2002-04-16 15:50:10 +00:00
}
ctxt - > state = end ;
break ;
}
case XML_SCHEMA_TYPE_ALL : {
2002-04-20 06:41:40 +00:00
xmlAutomataStatePtr start ;
xmlSchemaTypePtr subtypes ;
xmlSchemaElementPtr elem = ( xmlSchemaElementPtr ) type ;
2002-04-20 17:38:48 +00:00
int lax ;
2002-04-20 06:41:40 +00:00
subtypes = type - > subtypes ;
if ( subtypes = = NULL )
break ;
start = ctxt - > state ;
while ( subtypes ! = NULL ) {
ctxt - > state = start ;
elem = ( xmlSchemaElementPtr ) subtypes ;
/* TODO : handle the namespace too */
xmlAutomataNewOnceTrans ( ctxt - > am , ctxt - > state , ctxt - > state ,
elem - > name , elem - > minOccurs , elem - > maxOccurs ,
subtypes ) ;
subtypes = subtypes - > next ;
}
2002-04-20 17:38:48 +00:00
lax = type - > minOccurs = = 0 ;
ctxt - > state = xmlAutomataNewAllTrans ( ctxt - > am , ctxt - > state , NULL ,
lax ) ;
2002-04-16 15:50:10 +00:00
break ;
}
case XML_SCHEMA_TYPE_RESTRICTION :
2002-04-19 07:01:55 +00:00
if ( type - > subtypes ! = NULL )
2002-04-18 11:54:04 +00:00
xmlSchemaBuildAContentModel ( type - > subtypes , ctxt , name ) ;
break ;
2002-04-16 15:50:10 +00:00
case XML_SCHEMA_TYPE_EXTENSION :
2002-04-18 11:54:04 +00:00
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 ;
2002-04-16 15:50:10 +00:00
case XML_SCHEMA_TYPE_GROUP :
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 ;
}
}
/**
* xmlSchemaBuildContentModel :
* @ typeDecl : the schema type definition
* @ ctxt : the schema parser context
*
* Fixes the content model of the element .
*/
static void
xmlSchemaBuildContentModel ( xmlSchemaElementPtr elem ,
xmlSchemaParserCtxtPtr ctxt ,
const xmlChar * name ) {
xmlAutomataStatePtr start ;
if ( elem - > contModel ! = NULL )
return ;
2002-04-23 07:12:20 +00:00
if ( elem - > subtypes = = NULL ) {
elem - > contentType = XML_SCHEMA_CONTENT_ANY ;
2002-04-16 15:50:10 +00:00
return ;
2002-04-23 07:12:20 +00:00
}
2002-04-16 15:50:10 +00:00
if ( elem - > subtypes - > type ! = XML_SCHEMA_TYPE_COMPLEX )
return ;
2002-04-18 14:41:51 +00:00
if ( elem - > subtypes - > contentType = = XML_SCHEMA_CONTENT_BASIC )
return ;
# ifdef DEBUG_CONTENT
xmlGenericError ( xmlGenericErrorContext ,
" Building content model for %s \n " , name ) ;
# endif
2002-04-16 15:50:10 +00:00
ctxt - > am = xmlNewAutomata ( ) ;
if ( ctxt - > am = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" Cannot create automata for elem %s \n " , name ) ;
return ;
}
start = ctxt - > state = xmlAutomataGetInitState ( ctxt - > am ) ;
xmlSchemaBuildAContentModel ( elem - > subtypes , ctxt , name ) ;
xmlAutomataSetFinalState ( ctxt - > am , ctxt - > state ) ;
2002-04-22 16:01:24 +00:00
if ( ! xmlAutomataIsDeterminist ( ctxt - > am ) ) {
xmlGenericError ( xmlGenericErrorContext ,
" Content model of %s is not determinist: \n " , name ) ;
elem - > contModel = xmlAutomataCompile ( ctxt - > am ) ;
ctxt - > err = XML_SCHEMAS_ERR_NOTDETERMINIST ;
} else {
elem - > contModel = xmlAutomataCompile ( ctxt - > am ) ;
2002-04-16 15:50:10 +00:00
# ifdef DEBUG_CONTENT
2002-04-22 16:01:24 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" Content model of %s: \n " , name ) ;
xmlRegexpPrint ( stderr , elem - > contModel ) ;
2002-04-16 15:50:10 +00:00
# endif
2002-04-22 16:01:24 +00:00
}
2002-04-16 15:50:10 +00:00
ctxt - > state = NULL ;
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 ,
xmlSchemaParserCtxtPtr ctxt ,
const xmlChar * name ,
ATTRIBUTE_UNUSED const xmlChar * context ,
ATTRIBUTE_UNUSED const xmlChar * namespace )
{
if ( ( ctxt = = NULL ) | | ( elem = = NULL ) )
return ;
if ( elem - > ref ! = NULL ) {
xmlSchemaElementPtr elemDecl ;
if ( elem - > subtypes ! = NULL ) {
xmlSchemaErrorContext ( ctxt , NULL , elem - > node , NULL ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Schemas: element %s have both ref and subtype \n " ,
name ) ;
return ;
}
elemDecl = xmlHashLookup2 ( ctxt - > schema - > elemDecl ,
elem - > ref , elem - > refNs ) ;
if ( elemDecl = = NULL ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Schemas: element %s ref to %s not found \n " ,
name , elem - > ref ) ;
return ;
}
elem - > refDecl = elemDecl ;
} else if ( elem - > namedType ! = NULL ) {
xmlSchemaTypePtr typeDecl ;
if ( elem - > subtypes ! = NULL ) {
xmlSchemaErrorContext ( ctxt , NULL , elem - > node , NULL ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Schemas: element %s have both type and subtype \n " ,
name ) ;
return ;
}
typeDecl = xmlSchemaGetType ( ctxt - > schema , elem - > namedType ,
elem - > namedTypeNs ) ;
if ( typeDecl = = NULL ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Schemas: element %s type %s not found \n " ,
name , elem - > namedType ) ;
return ;
}
elem - > subtypes = typeDecl ;
}
}
/**
* xmlSchemaTypeFixup :
* @ typeDecl : the schema type definition
* @ ctxt : the schema parser context
*
* Fixes the content model of the type .
*/
static void
xmlSchemaTypeFixup ( xmlSchemaTypePtr typeDecl ,
xmlSchemaParserCtxtPtr ctxt ,
const xmlChar * name )
{
if ( name = = NULL )
name = typeDecl - > name ;
if ( typeDecl - > contentType = = XML_SCHEMA_CONTENT_UNKNOWN ) {
switch ( typeDecl - > type ) {
case XML_SCHEMA_TYPE_SIMPLE_CONTENT : {
xmlSchemaTypeFixup ( typeDecl - > subtypes , ctxt , 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 ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Schemas: type %s base type %s not found \n " ,
name , typeDecl - > base ) ;
}
typeDecl - > baseType = baseType ;
}
if ( typeDecl - > subtypes = = NULL )
/* 1.1.1 */
typeDecl - > contentType = 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 */
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 ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Schemas: type %s base type %s not found \n " ,
name , typeDecl - > base ) ;
}
typeDecl - > baseType = baseType ;
}
if ( typeDecl - > subtypes ! = NULL )
xmlSchemaTypeFixup ( typeDecl - > subtypes , ctxt , NULL ) ;
2002-04-17 09:06:27 +00:00
explicitContentType = XML_SCHEMA_CONTENT_ELEMENTS ;
2002-04-16 15:50:10 +00:00
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 ) {
xmlSchemaErrorContext ( ctxt , NULL , typeDecl - > node , NULL ) ;
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Schemas: base type %s of type %s not found \n " ,
typeDecl - > base , name ) ;
return ;
}
xmlSchemaTypeFixup ( base , ctxt , NULL ) ;
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 ;
} else {
if ( typeDecl - > flags & XML_SCHEMAS_TYPE_MIXED )
typeDecl - > contentType = XML_SCHEMA_CONTENT_MIXED ;
else {
xmlSchemaTypeFixup ( typeDecl - > subtypes , ctxt , NULL ) ;
typeDecl - > contentType = typeDecl - > subtypes - > contentType ;
}
}
break ;
}
case XML_SCHEMA_TYPE_COMPLEX_CONTENT : {
if ( typeDecl - > subtypes = = NULL ) {
typeDecl - > contentType = XML_SCHEMA_CONTENT_EMPTY ;
} else {
if ( typeDecl - > flags & XML_SCHEMAS_TYPE_MIXED )
typeDecl - > contentType = XML_SCHEMA_CONTENT_MIXED ;
else {
xmlSchemaTypeFixup ( typeDecl - > subtypes , ctxt , NULL ) ;
typeDecl - > contentType = typeDecl - > subtypes - > contentType ;
}
}
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_NOTATION :
case XML_SCHEMA_TYPE_LIST :
case XML_SCHEMA_TYPE_UNION :
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 ;
break ;
}
}
2002-04-17 09:06:27 +00:00
# ifdef DEBUG_TYPE
2002-04-18 14:41:51 +00:00
if ( typeDecl - > node ! = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" Type of %s : %s:%d : " , name , typeDecl - > node - > doc - > URL ,
xmlGetLineNo ( typeDecl - > node ) ) ;
} else {
xmlGenericError ( xmlGenericErrorContext ,
" Type of %s : " , name ) ;
}
2002-04-17 09:06:27 +00:00
switch ( typeDecl - > contentType ) {
case XML_SCHEMA_CONTENT_SIMPLE :
xmlGenericError ( xmlGenericErrorContext ,
" simple \n " ) ; break ;
case XML_SCHEMA_CONTENT_ELEMENTS :
xmlGenericError ( xmlGenericErrorContext ,
" elements \n " ) ; break ;
case XML_SCHEMA_CONTENT_UNKNOWN :
xmlGenericError ( xmlGenericErrorContext ,
" unknown !!! \n " ) ; break ;
case XML_SCHEMA_CONTENT_EMPTY :
xmlGenericError ( xmlGenericErrorContext ,
" empty \n " ) ; break ;
case XML_SCHEMA_CONTENT_MIXED :
xmlGenericError ( xmlGenericErrorContext ,
" mixed \n " ) ; break ;
case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS :
xmlGenericError ( xmlGenericErrorContext ,
" mixed or elems \n " ) ; break ;
case XML_SCHEMA_CONTENT_BASIC :
xmlGenericError ( xmlGenericErrorContext ,
" basic \n " ) ; break ;
default :
xmlGenericError ( xmlGenericErrorContext ,
" not registered !!! \n " ) ; break ;
}
# endif
2002-04-16 15:50:10 +00: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 ,
xmlSchemaParserCtxtPtr ctxt ,
const xmlChar * name )
{
static xmlSchemaTypePtr nonNegativeIntegerType = NULL ;
if ( name = = NULL )
name = typeDecl - > name ;
if ( nonNegativeIntegerType = = NULL ) {
nonNegativeIntegerType = xmlSchemaGetPredefinedType (
BAD_CAST " nonNegativeInteger " , xmlSchemaNs ) ;
}
if ( typeDecl - > type = = XML_SCHEMA_TYPE_RESTRICTION ) {
if ( typeDecl - > facets ! = NULL ) {
xmlSchemaFacetPtr facet = typeDecl - > facets ;
while ( facet ! = NULL ) {
switch ( facet - > type ) {
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 */
xmlSchemaErrorContext ( ctxt , NULL ,
facet - > node , NULL ) ;
ctxt - > error ( ctxt - > userData ,
" Schemas: type %s facet value %s invalid \n " ,
name , facet - > value ) ;
}
xmlSchemaFreeValidCtxt ( vctxt ) ;
break ;
}
case XML_SCHEMA_FACET_ENUMERATION : {
/*
* Okay we need to validate the value
* at that point .
*/
xmlSchemaValidCtxtPtr vctxt ;
int ret ;
vctxt = xmlSchemaNewValidCtxt ( NULL ) ;
if ( vctxt = = NULL )
break ;
ret = xmlSchemaValidateSimpleValue ( vctxt , typeDecl ,
facet - > value ) ;
if ( ret ! = 0 ) {
xmlSchemaErrorContext ( ctxt , NULL ,
facet - > node , NULL ) ;
ctxt - > error ( ctxt - > userData ,
" Schemas: type %s enumeration value %s invalid \n " ,
name , facet - > value ) ;
}
xmlSchemaFreeValidCtxt ( vctxt ) ;
break ;
}
case XML_SCHEMA_FACET_PATTERN :
facet - > regexp = xmlRegexpCompile ( facet - > value ) ;
if ( facet - > regexp = = NULL ) {
/* error code */
ctxt - > error ( ctxt - > userData ,
" Schemas: type %s facet regexp %s invalid \n " ,
name , facet - > value ) ;
}
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 ret ;
ret = xmlSchemaValidatePredefinedType (
nonNegativeIntegerType , facet - > value ,
& facet - > val ) ;
if ( ret ! = 0 ) {
/* error code */
xmlSchemaErrorContext ( ctxt , NULL ,
facet - > node , NULL ) ;
ctxt - > error ( ctxt - > userData ,
" Schemas: type %s facet value %s invalid \n " ,
name , facet - > value ) ;
}
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 {
xmlSchemaErrorContext ( ctxt , NULL ,
facet - > node , NULL ) ;
ctxt - > error ( ctxt - > userData ,
" Schemas: type %s whiteSpace value %s invalid \n " ,
name , facet - > value ) ;
}
}
default :
break ;
}
facet = facet - > next ;
}
}
}
}
2002-04-23 17:51:29 +00: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 ,
xmlSchemaParserCtxtPtr ctxt ,
const xmlChar * name )
{
if ( name = = NULL )
name = attrgrpDecl - > name ;
if ( attrgrpDecl - > attributes ! = NULL )
return ;
if ( attrgrpDecl - > ref ! = NULL ) {
xmlSchemaAttributeGroupPtr ref ;
ref = xmlHashLookup2 ( ctxt - > schema - > attrgrpDecl , attrgrpDecl - > ref ,
attrgrpDecl - > refNs ) ;
if ( ref = = NULL ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Schemas: attribute group %s reference %s not found \n " ,
name , attrgrpDecl - > ref ) ;
return ;
}
xmlSchemaAttrGrpFixup ( ref , ctxt , NULL ) ;
attrgrpDecl - > attributes = ref - > attributes ;
} else {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Schemas: attribute %s has no attributes nor reference \n " ,
name ) ;
}
}
2002-04-16 15:50:10 +00: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 ,
xmlSchemaParserCtxtPtr ctxt ,
const xmlChar * name )
{
if ( name = = NULL )
name = attrDecl - > name ;
if ( attrDecl - > subtypes ! = NULL )
return ;
if ( attrDecl - > typeName ! = NULL ) {
xmlSchemaTypePtr type ;
type = xmlSchemaGetType ( ctxt - > schema , attrDecl - > typeName ,
attrDecl - > typeNs ) ;
if ( type = = NULL ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Schemas: attribute %s type %s not found \n " ,
name , attrDecl - > typeName ) ;
}
attrDecl - > subtypes = type ;
} else if ( attrDecl - > ref ! = NULL ) {
xmlSchemaAttributePtr ref ;
ref = xmlHashLookup2 ( ctxt - > schema - > attrDecl , attrDecl - > ref ,
attrDecl - > refNs ) ;
if ( ref = = NULL ) {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Schemas: attribute %s reference %s not found \n " ,
name , attrDecl - > ref ) ;
return ;
}
xmlSchemaAttrFixup ( ref , ctxt , NULL ) ;
attrDecl - > subtypes = ref - > subtypes ;
} else {
if ( ( ctxt ! = NULL ) & & ( ctxt - > error ! = NULL ) )
ctxt - > error ( ctxt - > userData ,
" Schemas: attribute %s has no type nor reference \n " ,
name ) ;
}
}
/**
* xmlSchemaParse :
* @ ctxt : a schema validation context
* @ URL : the location of the schema
*
* Load , XML parse a schema definition resource and build an internal
* 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 ;
xmlNodePtr root , cur , delete ;
xmlSchemaInitTypes ( ) ;
if ( ( ctxt = = NULL ) | | ( ctxt - > URL = = NULL ) )
return ( NULL ) ;
ctxt - > counter = 0 ;
ctxt - > container = NULL ;
/*
* First step is to parse the input document into an DOM / Infoset
*/
doc = xmlParseFile ( ( const char * ) ctxt - > URL ) ;
if ( doc = = NULL ) {
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" xmlSchemaParse: could not load %s \n " , ctxt - > URL ) ;
return ( NULL ) ;
}
/*
* Then extract the root and Schema parse it
*/
root = xmlDocGetRootElement ( doc ) ;
if ( root = = NULL ) {
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData , " xmlSchemaParse: %s is empty \n " ,
ctxt - > URL ) ;
return ( NULL ) ;
}
/*
* 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 ;
}
/*
* Then do the parsing for good
*/
ret = xmlSchemaParseSchema ( ctxt , root ) ;
2002-04-19 07:01:55 +00:00
if ( ret = = NULL )
return ( NULL ) ;
2002-04-16 15:50:10 +00:00
ret - > doc = doc ;
/*
* Then fix all the references .
*/
ctxt - > schema = ret ;
xmlHashScanFull ( ret - > elemDecl ,
( xmlHashScannerFull ) xmlSchemaRefFixupCallback , ctxt ) ;
/*
* Then fixup all types properties
*/
xmlHashScan ( ret - > typeDecl , ( xmlHashScanner ) xmlSchemaTypeFixup , ctxt ) ;
/*
* Then build the content model for all elements
*/
xmlHashScan ( ret - > elemDecl ,
( xmlHashScanner ) xmlSchemaBuildContentModel , ctxt ) ;
/*
* Then check the defaults part of the type like facets values
*/
xmlHashScan ( ret - > typeDecl , ( xmlHashScanner ) xmlSchemaCheckDefaults , ctxt ) ;
/*
* Then fixup all attributes declarations
*/
xmlHashScan ( ret - > attrDecl , ( xmlHashScanner ) xmlSchemaAttrFixup , ctxt ) ;
2002-04-23 17:51:29 +00:00
/*
* Then fixup all attributes group declarations
*/
xmlHashScan ( ret - > attrgrpDecl , ( xmlHashScanner ) xmlSchemaAttrGrpFixup , ctxt ) ;
2002-04-16 15:50:10 +00:00
return ( ret ) ;
}
/**
* xmlSchemaParse :
* @ ctxt : a schema validation context
* @ URL : the location of the schema
*
* Load , XML parse a schema definition resource and build an internal
* 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
*/
void
xmlSchemaSetParserErrors ( xmlSchemaParserCtxtPtr ctxt ,
xmlSchemaValidityErrorFunc err ,
xmlSchemaValidityWarningFunc warn , void * ctx ) {
if ( ctxt = = NULL )
return ;
ctxt - > error = err ;
ctxt - > warning = warn ;
ctxt - > userData = ctx ;
}
/************************************************************************
* *
* Simple type validation *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* 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
xmlSchemaValidateSimpleValue ( xmlSchemaValidCtxtPtr ctxt ,
xmlSchemaTypePtr type ,
xmlChar * value ) {
int ret = 0 ;
/*
* 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 ) {
if ( ctxt - > value ! = NULL ) {
xmlSchemaFreeValue ( ctxt - > value ) ;
ctxt - > value = NULL ;
}
ret = xmlSchemaValidatePredefinedType ( type , value , & ( ctxt - > value ) ) ;
} else if ( type - > type = = XML_SCHEMA_TYPE_RESTRICTION ) {
xmlSchemaTypePtr base ;
xmlSchemaFacetPtr facet ;
int tmp ;
base = type - > baseType ;
if ( base ! = NULL ) {
ret = xmlSchemaValidateSimpleValue ( ctxt , base , value ) ;
} else if ( type - > subtypes ! = NULL ) {
}
/*
* Do not validate facets when working on building the Schemas
*/
if ( ctxt - > schema ! = NULL ) {
if ( ret = = 0 ) {
facet = type - > facets ;
2002-04-23 07:12:20 +00:00
if ( ( type - > type = = XML_SCHEMA_TYPE_RESTRICTION ) & &
( facet ! = NULL ) & &
( facet - > type = = XML_SCHEMA_FACET_ENUMERATION ) ) {
while ( facet ! = NULL ) {
ret = 1 ;
tmp = xmlSchemaValidateFacet ( base , facet , value ,
ctxt - > value ) ;
if ( tmp = = 0 ) {
ret = 0 ;
break ;
}
facet = facet - > next ;
}
} else {
while ( facet ! = NULL ) {
tmp = xmlSchemaValidateFacet ( base , facet , value ,
ctxt - > value ) ;
if ( tmp ! = 0 )
ret = tmp ;
facet = facet - > next ;
}
2002-04-16 15:50:10 +00:00
}
}
}
} else if ( type - > type = = XML_SCHEMA_TYPE_SIMPLE ) {
xmlSchemaTypePtr base ;
base = type - > subtypes ;
if ( base ! = NULL ) {
ret = xmlSchemaValidateSimpleValue ( ctxt , base , value ) ;
} else {
TODO
}
} else if ( type - > type = = XML_SCHEMA_TYPE_LIST ) {
xmlSchemaTypePtr base ;
xmlChar * cur , * end , tmp ;
int ret2 ;
base = type - > subtypes ;
if ( base = = NULL ) {
ctxt - > err = XML_SCHEMAS_ERR_INTERNAL ;
if ( ctxt - > error ! = NULL ) {
xmlSchemaErrorContext ( NULL , ctxt - > schema , type - > node , NULL ) ;
ctxt - > error ( ctxt - > userData ,
" Internal: List type %s has no base type \n " ,
type - > name ) ;
}
return ( - 1 ) ;
}
cur = value ;
do {
while ( IS_BLANK ( * cur ) ) cur + + ;
end = cur ;
while ( ( * end ! = 0 ) & & ( ! ( IS_BLANK ( * end ) ) ) ) end + + ;
if ( end = = cur )
break ;
tmp = * end ;
* end = 0 ;
ret2 = xmlSchemaValidateSimpleValue ( ctxt , base , cur ) ;
if ( ret2 ! = 0 )
ret = 1 ;
* end = tmp ;
cur = end ;
} while ( * cur ! = 0 ) ;
} else {
TODO
}
return ( ret ) ;
}
/************************************************************************
* *
* DOM Validation code *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int xmlSchemaValidateContent ( xmlSchemaValidCtxtPtr ctxt ,
xmlNodePtr node ) ;
static int xmlSchemaValidateAttributes ( xmlSchemaValidCtxtPtr ctxt ,
xmlNodePtr elem , xmlSchemaAttributePtr attributes ) ;
static int xmlSchemaValidateType ( xmlSchemaValidCtxtPtr ctxt ,
xmlNodePtr elem , xmlSchemaElementPtr elemDecl , xmlSchemaTypePtr type ) ;
/**
* 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
xmlSchemaRegisterAttributes ( xmlSchemaValidCtxtPtr ctxt ,
xmlAttrPtr attrs ) {
while ( attrs ! = NULL ) {
2002-04-20 17:38:48 +00:00
if ( ( attrs - > ns ! = NULL ) & &
( xmlStrEqual ( attrs - > ns - > href , xmlSchemaInstanceNs ) ) ) {
attrs = attrs - > next ;
continue ;
}
2002-04-16 15:50:10 +00:00
if ( ctxt - > attrNr > = ctxt - > attrMax ) {
xmlSchemaAttrStatePtr tmp ;
ctxt - > attrMax * = 2 ;
tmp = ( xmlSchemaAttrStatePtr )
xmlRealloc ( ctxt - > attr , ctxt - > attrMax *
sizeof ( xmlSchemaAttrState ) ) ;
if ( tmp = = 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 ) ;
}
/**
* 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
xmlSchemaCheckAttributes ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr node ) {
int ret = 0 ;
int i ;
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 ;
ctxt - > err = XML_SCHEMAS_ERR_ATTRUNKNOWN ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Attribute %s on %s is unknown \n " ,
ctxt - > attr [ i ] . attr - > name ,
node - > name ) ;
}
}
return ( ret ) ;
}
/**
* 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 ,
ATTRIBUTE_UNUSED xmlNodePtr node ) {
xmlNodePtr child ;
xmlSchemaTypePtr type , base ;
xmlChar * value ;
int ret = 0 , tmp ;
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 ) {
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 ;
while ( facet ! = NULL ) {
tmp = xmlSchemaValidateFacet ( base , facet , value ,
ctxt - > value ) ;
if ( tmp ! = 0 )
ret = tmp ;
facet = facet - > next ;
}
}
break ;
}
default :
TODO
}
if ( value ! = NULL )
xmlFree ( value ) ;
return ( ret ) ;
}
/**
* 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
xmlSchemaValidateCheckNodeList ( xmlNodePtr nodelist ) {
while ( nodelist ! = NULL ) {
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 ) ;
}
/**
* 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
xmlSchemaSkipIgnored ( ATTRIBUTE_UNUSED xmlSchemaValidCtxtPtr ctxt ,
xmlSchemaTypePtr type ,
xmlNodePtr node ) {
int mixed = 0 ;
/*
* TODO complete and handle entities
*/
mixed = ( ( type - > contentType = = XML_SCHEMA_CONTENT_MIXED ) | |
( type - > contentType = = XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS ) ) ;
while ( ( node ! = NULL ) & &
( ( 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 ) ;
}
/**
* 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 ,
ATTRIBUTE_UNUSED const xmlChar * name ,
xmlSchemaTypePtr type ,
xmlNodePtr node ) {
xmlSchemaTypePtr oldtype = ctxt - > type ;
xmlNodePtr oldnode = ctxt - > node ;
# ifdef DEBUG_CONTENT
2002-04-17 09:06:27 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" xmlSchemaValidateCallback: %s, %s, %s \n " ,
name , type - > name , node - > name ) ;
2002-04-16 15:50:10 +00:00
# endif
ctxt - > type = type ;
ctxt - > node = node ;
xmlSchemaValidateContent ( ctxt , node ) ;
ctxt - > type = oldtype ;
ctxt - > node = oldnode ;
}
#if 0
/**
* 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 ) ) {
ctxt - > err = XML_SCHEMAS_ERR_INTERNAL ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Internal error: xmlSchemaValidateSimpleRestrictionType %s \n " ,
node - > name ) ;
return ( - 1 ) ;
}
/*
* Only text and text based entities references shall be found there
*/
ret = xmlSchemaValidateCheckNodeList ( child ) ;
if ( ret < 0 ) {
ctxt - > err = XML_SCHEMAS_ERR_INTERNAL ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Internal error: xmlSchemaValidateSimpleType %s content \n " ,
node - > name ) ;
return ( - 1 ) ;
} else if ( ret = = 0 ) {
ctxt - > err = XML_SCHEMAS_ERR_NOTSIMPLE ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Element %s content is not a simple type \n " ,
node - > name ) ;
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
xmlSchemaValidateSimpleType ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr node ) {
xmlNodePtr child ;
xmlSchemaTypePtr type ;
xmlAttrPtr attr ;
int ret ;
child = ctxt - > node ;
type = ctxt - > type ;
if ( ( ctxt = = NULL ) | | ( type = = NULL ) ) {
ctxt - > err = XML_SCHEMAS_ERR_INTERNAL ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Internal error: xmlSchemaValidateSimpleType %s \n " ,
node - > name ) ;
return ( - 1 ) ;
}
/*
* Only text and text based entities references shall be found there
*/
ret = xmlSchemaValidateCheckNodeList ( child ) ;
if ( ret < 0 ) {
ctxt - > err = XML_SCHEMAS_ERR_INTERNAL ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Internal error: xmlSchemaValidateSimpleType %s content \n " ,
node - > name ) ;
return ( - 1 ) ;
} else if ( ret = = 0 ) {
ctxt - > err = XML_SCHEMAS_ERR_NOTSIMPLE ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Element %s content is not a simple type \n " ,
node - > name ) ;
return ( - 1 ) ;
}
/*
* Validation Rule : Element Locally Valid ( Type ) : 3.1 .1
*/
attr = node - > properties ;
while ( attr ! = NULL ) {
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 " ) ) ) ) {
ctxt - > err = XML_SCHEMAS_ERR_INVALIDATTR ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Element %s: attribute %s should not be present \n " ,
child - > name , attr - > name ) ;
return ( ctxt - > err ) ;
}
}
ctxt - > type = type - > subtypes ;
ret = xmlSchemaValidateSimpleContent ( ctxt , node ) ;
ctxt - > type = type ;
return ( ret ) ;
}
/**
* 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
xmlSchemaValidateElementType ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr node ) {
xmlNodePtr child ;
xmlSchemaTypePtr type ;
xmlRegExecCtxtPtr oldregexp ; /* cont model of the parent */
xmlSchemaElementPtr decl ;
int ret , attrBase ;
oldregexp = ctxt - > regexp ;
child = ctxt - > node ;
type = ctxt - > type ;
if ( ( ctxt = = NULL ) | | ( type = = NULL ) ) {
ctxt - > err = XML_SCHEMAS_ERR_INTERNAL ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Internal error: xmlSchemaValidateElementType \n " ,
node - > name ) ;
return ( - 1 ) ;
}
if ( child = = NULL ) {
if ( type - > minOccurs > 0 ) {
ctxt - > err = XML_SCHEMAS_ERR_MISSING ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Element %s: missing child %s \n " ,
node - > name , type - > name ) ;
}
return ( ctxt - > err ) ;
}
/*
* Verify the element matches
*/
if ( ! xmlStrEqual ( child - > name , type - > name ) ) {
ctxt - > err = XML_SCHEMAS_ERR_WRONGELEM ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Element %s: missing child %s found %s \n " ,
node - > name , type - > name , child - > name ) ;
return ( ctxt - > err ) ;
}
/*
* 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 ) {
ctxt - > regexp = xmlRegNewExecCtxt ( decl - > contModel ,
( xmlRegExecCallbacks ) xmlSchemaValidateCallback ,
ctxt ) ;
# ifdef DEBUG_AUTOMATA
xmlGenericError ( xmlGenericErrorContext ,
" ====> %s \n " , node - > name ) ;
# endif
}
xmlSchemaValidateType ( ctxt , child , ( xmlSchemaElementPtr ) type ,
type - > subtypes ) ;
if ( decl - > contModel ! = NULL ) {
ret = xmlRegExecPushString ( ctxt - > regexp , NULL , NULL ) ;
# ifdef DEBUG_AUTOMATA
xmlGenericError ( xmlGenericErrorContext ,
" ====> %s : %d \n " , node - > name , ret ) ;
# endif
if ( ret = = 0 ) {
2002-04-17 09:06:27 +00:00
ctxt - > err = XML_SCHEMAS_ERR_ELEMCONT ;
2002-04-16 15:50:10 +00:00
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData , " Element %s content check failed \n " ,
node - > name ) ;
} else if ( ret < 0 ) {
2002-04-17 09:06:27 +00:00
ctxt - > err = XML_SCHEMAS_ERR_ELEMCONT ;
2002-04-16 15:50:10 +00:00
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData , " Element %s content check failure \n " ,
node - > name ) ;
# ifdef DEBUG_CONTENT
} else {
xmlGenericError ( xmlGenericErrorContext ,
" Element %s content check succeeded \n " , node - > name ) ;
# endif
}
xmlRegFreeExecCtxt ( ctxt - > regexp ) ;
}
/*
* 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 ;
return ( ctxt - > err ) ;
}
/**
* 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
xmlSchemaValidateBasicType ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr node ) {
int ret ;
xmlNodePtr child , cur ;
xmlSchemaTypePtr type ;
xmlChar * value ; /* lexical representation */
child = ctxt - > node ;
type = ctxt - > type ;
if ( ( ctxt = = NULL ) | | ( type = = NULL ) ) {
ctxt - > err = XML_SCHEMAS_ERR_INTERNAL ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Internal error: xmlSchemaValidateBasicType \n " ,
node - > name ) ;
return ( - 1 ) ;
}
/*
* First check the content model of the node .
*/
cur = child ;
while ( cur ! = NULL ) {
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 :
ctxt - > err = XML_SCHEMAS_ERR_INVALIDELEM ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Element %s: child %s should not be present \n " ,
node - > name , cur - > name ) ;
return ( ctxt - > err ) ;
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
ctxt - > err = XML_SCHEMAS_ERR_INVALIDELEM ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Element %s: node type %d unexpected here \n " ,
node - > name , cur - > type ) ;
return ( ctxt - > err ) ;
}
cur = cur - > next ;
}
if ( child = = NULL )
value = NULL ;
else
value = xmlNodeGetContent ( child - > parent ) ;
if ( ctxt - > value ! = NULL ) {
xmlSchemaFreeValue ( ctxt - > value ) ;
ctxt - > value = NULL ;
}
ret = xmlSchemaValidatePredefinedType ( type , value , & ( ctxt - > value ) ) ;
if ( value ! = NULL )
xmlFree ( value ) ;
if ( ret ! = 0 ) {
ctxt - > error ( ctxt - > userData ,
" Element %s: failed to validate basic type %s \n " ,
node - > name , type - > name ) ;
}
return ( ret ) ;
}
/**
* 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
xmlSchemaValidateComplexType ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr node ) {
xmlNodePtr child ;
2002-04-17 09:06:27 +00:00
xmlSchemaTypePtr type , subtype ;
2002-04-16 15:50:10 +00:00
int ret ;
child = ctxt - > node ;
type = ctxt - > type ;
switch ( type - > contentType ) {
case XML_SCHEMA_CONTENT_EMPTY :
if ( child ! = NULL ) {
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Element %s is supposed to be empty \n " ,
node - > name ) ;
}
2002-04-22 16:01:24 +00:00
if ( type - > attributes ! = NULL ) {
xmlSchemaValidateAttributes ( ctxt , node , type - > attributes ) ;
}
subtype = type - > subtypes ;
while ( subtype ! = NULL ) {
ctxt - > type = subtype ;
xmlSchemaValidateComplexType ( ctxt , node ) ;
subtype = subtype - > next ;
}
2002-04-16 15:50:10 +00:00
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 ) ;
# ifdef DEBUG_AUTOMATA
if ( ret < 0 )
xmlGenericError ( xmlGenericErrorContext ,
" --> %s Error \n " , child - > name ) ;
else
xmlGenericError ( xmlGenericErrorContext ,
" --> %s \n " , child - > name ) ;
# endif
}
child = child - > next ;
/*
* Skip ignorable nodes in that context
*/
child = xmlSchemaSkipIgnored ( ctxt , type , child ) ;
}
break ;
2002-04-18 14:41:51 +00:00
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 ;
}
2002-04-16 15:50:10 +00:00
default :
TODO
xmlGenericError ( xmlGenericErrorContext ,
" unimplemented content type %d \n " ,
type - > contentType ) ;
}
return ( ctxt - > err ) ;
}
/**
* 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
xmlSchemaValidateContent ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr node ) {
xmlNodePtr child ;
xmlSchemaTypePtr type ;
child = ctxt - > node ;
type = ctxt - > type ;
2002-04-22 16:01:24 +00:00
xmlSchemaValidateAttributes ( ctxt , node , type - > attributes ) ;
2002-04-16 15:50:10 +00:00
switch ( type - > type ) {
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 ) {
ctxt - > err = XML_SCHEMAS_ERR_INTERNAL ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Internal error: element reference %s not resolved \n " ,
decl - > ref ) ;
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 ;
}
xmlSchemaValidateAttributes ( ctxt , node , type - > attributes ) ;
if ( ctxt - > node = = NULL )
return ( ctxt - > err ) ;
ctxt - > node = ctxt - > node - > next ;
ctxt - > type = type - > next ;
return ( ctxt - > err ) ;
}
/**
* 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 ,
xmlSchemaElementPtr elemDecl ,
xmlSchemaTypePtr type ) {
xmlChar * nil ;
if ( ( elem - > content = = NULL ) | | ( type = = NULL ) | | ( elemDecl = = NULL ) )
return ( 0 ) ;
/*
* 3.3 .4 : 2
*/
if ( elemDecl - > flags & XML_SCHEMAS_ELEM_ABSTRACT ) {
ctxt - > err = XML_SCHEMAS_ERR_ISABSTRACT ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData , " Element %s is abstract \n " , elem - > name ) ;
return ( ctxt - > err ) ;
}
/*
* 3.3 .4 : 3
*/
nil = xmlGetNsProp ( elem , BAD_CAST " nil " , xmlSchemaInstanceNs ) ;
if ( elemDecl - > flags & XML_SCHEMAS_ELEM_NILLABLE ) {
/* 3.3.4: 3.2 */
if ( xmlStrEqual ( nil , BAD_CAST " true " ) ) {
if ( elem - > children ! = NULL ) {
ctxt - > err = XML_SCHEMAS_ERR_NOTEMPTY ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData , " Element %s is not empty \n " ,
elem - > name ) ;
return ( ctxt - > err ) ;
}
if ( ( elemDecl - > flags & XML_SCHEMAS_ELEM_FIXED ) & &
( elemDecl - > value ! = NULL ) ) {
ctxt - > err = XML_SCHEMAS_ERR_HAVEDEFAULT ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Empty element %s cannot get a fixed value \n " ,
elem - > name ) ;
return ( ctxt - > err ) ;
}
}
} else {
/* 3.3.4: 3.1 */
if ( nil ! = NULL ) {
ctxt - > err = XML_SCHEMAS_ERR_NOTNILLABLE ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Element %s with xs:nil but not nillable \n " ,
elem - > name ) ;
xmlFree ( nil ) ;
return ( ctxt - > err ) ;
}
}
/* TODO 3.3.4: 4 if the element carries xs:type*/
ctxt - > type = elemDecl - > subtypes ;
ctxt - > node = elem - > children ;
xmlSchemaValidateContent ( ctxt , elem ) ;
xmlSchemaValidateAttributes ( ctxt , elem , elemDecl - > attributes ) ;
return ( ctxt - > err ) ;
}
/**
* 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 ,
xmlSchemaAttributePtr attributes ) {
int i , ret ;
xmlAttrPtr attr ;
xmlChar * value ;
2002-04-23 17:51:29 +00:00
xmlSchemaAttributeGroupPtr group = NULL ;
2002-04-16 15:50:10 +00:00
if ( attributes = = NULL )
return ( 0 ) ;
while ( attributes ! = NULL ) {
2002-04-23 17:51:29 +00:00
/*
* Handle attribute groups
*/
if ( attributes - > type = = XML_SCHEMA_TYPE_ATTRIBUTEGROUP ) {
group = ( xmlSchemaAttributeGroupPtr ) attributes ;
xmlSchemaValidateAttributes ( ctxt , elem , group - > attributes ) ;
attributes = group - > next ;
continue ;
}
2002-04-16 15:50:10 +00:00
for ( i = ctxt - > attrBase ; i < ctxt - > attrNr ; i + + ) {
attr = ctxt - > attr [ i ] . attr ;
if ( attr = = NULL )
continue ;
if ( ! xmlStrEqual ( attr - > name , attributes - > name ) )
continue ;
/*
* TODO : handle the mess about namespaces here .
*/
if ( ( attr - > ns ! = NULL ) /* || (attributes->ns != NULL) */ ) {
TODO
}
if ( attributes - > subtypes = = NULL ) {
ctxt - > err = XML_SCHEMAS_ERR_INTERNAL ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" Internal error: attribute %s type not resolved \n " ,
attr - > name ) ;
continue ;
}
value = xmlNodeListGetString ( elem - > doc , attr - > children , 1 ) ;
ret = xmlSchemaValidateSimpleValue ( ctxt , attributes - > subtypes ,
2002-04-23 17:51:29 +00:00
value ) ;
2002-04-16 15:50:10 +00:00
if ( ret ! = 0 ) {
ctxt - > err = XML_SCHEMAS_ERR_ATTRINVALID ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData ,
" 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 ) ;
}
}
attributes = attributes - > next ;
}
return ( ctxt - > err ) ;
}
/**
* 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
xmlSchemaValidateElement ( xmlSchemaValidCtxtPtr ctxt , xmlNodePtr elem ) {
xmlSchemaElementPtr elemDecl ;
int ret , attrBase ;
if ( elem - > ns ! = NULL )
elemDecl = xmlHashLookup3 ( ctxt - > schema - > elemDecl ,
elem - > name , elem - > ns - > href , NULL ) ;
else
elemDecl = xmlHashLookup3 ( ctxt - > schema - > elemDecl ,
elem - > name , NULL , NULL ) ;
/*
* 3.3 .4 : 1
*/
if ( elemDecl = = NULL ) {
ctxt - > err = XML_SCHEMAS_ERR_UNDECLAREDELEM ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData , " Element %s not declared \n " ,
elem - > name ) ;
return ( ctxt - > err ) ;
}
if ( elemDecl - > subtypes = = NULL ) {
ctxt - > err = XML_SCHEMAS_ERR_NOTYPE ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData , " Element %s has no type \n " ,
elem - > name ) ;
return ( ctxt - > err ) ;
}
/*
* 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 ) {
ctxt - > regexp = xmlRegNewExecCtxt ( elemDecl - > contModel ,
( xmlRegExecCallbacks ) xmlSchemaValidateCallback ,
ctxt ) ;
# ifdef DEBUG_AUTOMATA
xmlGenericError ( xmlGenericErrorContext ,
" ====> %s \n " , elem - > name ) ;
# endif
}
xmlSchemaValidateType ( ctxt , elem , elemDecl , elemDecl - > subtypes ) ;
2002-04-18 14:41:51 +00:00
if ( elemDecl - > contModel ! = NULL ) {
ret = xmlRegExecPushString ( ctxt - > regexp , NULL , NULL ) ;
2002-04-16 15:50:10 +00:00
# ifdef DEBUG_AUTOMATA
2002-04-18 14:41:51 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" ====> %s : %d \n " , elem - > name , ret ) ;
2002-04-16 15:50:10 +00:00
# endif
2002-04-18 14:41:51 +00:00
if ( ret = = 0 ) {
ctxt - > err = XML_SCHEMAS_ERR_ELEMCONT ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData , " Element %s content check failed \n " ,
elem - > name ) ;
} else if ( ret < 0 ) {
ctxt - > err = XML_SCHEMAS_ERR_ELEMCONT ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData , " Element %s content check failed \n " ,
elem - > name ) ;
2002-04-16 15:50:10 +00:00
# ifdef DEBUG_CONTENT
2002-04-18 14:41:51 +00:00
} else {
xmlGenericError ( xmlGenericErrorContext ,
" Element %s content check succeeded \n " , elem - > name ) ;
2002-04-16 15:50:10 +00:00
# endif
2002-04-18 14:41:51 +00:00
}
2002-04-16 15:50:10 +00:00
xmlRegFreeExecCtxt ( ctxt - > regexp ) ;
}
/*
* Verify that all attributes were Schemas - validated
*/
xmlSchemaCheckAttributes ( ctxt , elem ) ;
ctxt - > attrNr = ctxt - > attrBase ;
ctxt - > attrBase = attrBase ;
return ( ctxt - > err ) ;
}
/**
* 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
xmlSchemaValidateDocument ( xmlSchemaValidCtxtPtr ctxt , xmlDocPtr doc ) {
xmlNodePtr root ;
xmlSchemaElementPtr elemDecl ;
root = xmlDocGetRootElement ( doc ) ;
if ( root = = NULL ) {
ctxt - > err = XML_SCHEMAS_ERR_NOROOT ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData , " document has no root \n " ) ;
return ( ctxt - > err ) ;
}
if ( root - > ns ! = NULL )
elemDecl = xmlHashLookup3 ( ctxt - > schema - > elemDecl ,
root - > name , root - > ns - > href , NULL ) ;
else
elemDecl = xmlHashLookup3 ( ctxt - > schema - > elemDecl ,
root - > name , NULL , NULL ) ;
if ( elemDecl = = NULL ) {
ctxt - > err = XML_SCHEMAS_ERR_UNDECLAREDELEM ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData , " Element %s not declared \n " ,
root - > name ) ;
2002-04-18 14:41:51 +00:00
} else if ( ( elemDecl - > flags & XML_SCHEMAS_ELEM_TOPLEVEL ) = = 0 ) {
2002-04-16 15:50:10 +00:00
ctxt - > err = XML_SCHEMAS_ERR_NOTTOPLEVEL ;
if ( ctxt - > error ! = NULL )
ctxt - > error ( ctxt - > userData , " Root element %s not toplevel \n " ,
root - > name ) ;
}
/*
* Okay , start the recursive validation
*/
xmlSchemaValidateElement ( ctxt , root ) ;
return ( ctxt - > err ) ;
}
/************************************************************************
* *
* 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
xmlSchemaNewValidCtxt ( xmlSchemaPtr schema ) {
xmlSchemaValidCtxtPtr ret ;
ret = ( xmlSchemaValidCtxtPtr ) xmlMalloc ( sizeof ( xmlSchemaValidCtxt ) ) ;
if ( ret = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" Failed to allocate new schama validation context \n " ) ;
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaValidCtxt ) ) ;
ret - > schema = schema ;
ret - > attrNr = 0 ;
ret - > attrMax = 10 ;
ret - > attr = ( xmlSchemaAttrStatePtr ) xmlMalloc ( ret - > attrMax *
sizeof ( xmlSchemaAttrState ) ) ;
if ( ret - > attr = = NULL ) {
free ( ret ) ;
return ( NULL ) ;
}
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
xmlSchemaFreeValidCtxt ( xmlSchemaValidCtxtPtr ctxt ) {
if ( ctxt = = NULL )
return ;
if ( ctxt - > attr ! = NULL )
xmlFree ( ctxt - > attr ) ;
2002-04-23 07:12:20 +00:00
if ( ctxt - > value ! = NULL )
xmlSchemaFreeValue ( ctxt - > value ) ;
2002-04-16 15:50:10 +00:00
xmlFree ( ctxt ) ;
}
/**
* xmlSchemaSetValidErrors :
* @ ctxt : a schema validation context
* @ err : the error function
* @ warn : the warning function
* @ ctxt : the functions context
*
* Set the error and warning callback informations
*/
void
xmlSchemaSetValidErrors ( xmlSchemaValidCtxtPtr ctxt ,
xmlSchemaValidityErrorFunc err ,
xmlSchemaValidityWarningFunc warn , void * ctx ) {
if ( ctxt = = NULL )
return ;
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
xmlSchemaValidateDoc ( xmlSchemaValidCtxtPtr ctxt , xmlDocPtr doc ) {
int ret ;
if ( ( ctxt = = NULL ) | | ( doc = = NULL ) )
return ( - 1 ) ;
ctxt - > doc = doc ;
ret = xmlSchemaValidateDocument ( ctxt , doc ) ;
return ( ret ) ;
}
/**
* 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 .
*/
int
xmlSchemaValidateStream ( xmlSchemaValidCtxtPtr ctxt ,
xmlParserInputBufferPtr input , xmlCharEncoding enc ,
xmlSAXHandlerPtr sax , void * user_data ) {
if ( ( ctxt = = NULL ) | | ( input = = NULL ) )
return ( - 1 ) ;
ctxt - > input = input ;
ctxt - > enc = enc ;
ctxt - > sax = sax ;
ctxt - > user_data = user_data ;
TODO
return ( 0 ) ;
}
# endif /* LIBXML_SCHEMAS_ENABLED */