| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1 | /* | 
|  | 2 | * schemas.c : implementation of the XML Schema handling and | 
|  | 3 | *             schema validity checking | 
|  | 4 | * | 
|  | 5 | * See Copyright for the status of this software. | 
|  | 6 | * | 
|  | 7 | * Daniel Veillard <veillard@redhat.com> | 
|  | 8 | */ | 
|  | 9 |  | 
| Daniel Veillard | b0f397e | 2003-12-23 23:30:53 +0000 | [diff] [blame] | 10 | /* | 
|  | 11 | * TODO: | 
|  | 12 | *   - when types are redefined in includes, check that all | 
|  | 13 | *     types in the redef list are equal | 
|  | 14 | *     -> need a type equality operation. | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 15 | *   - if we don't intend to use the schema for schemas, we | 
|  | 16 | *     need to validate all schema attributes (ref, type, name) | 
|  | 17 | *     against their types. | 
| Daniel Veillard | b0f397e | 2003-12-23 23:30:53 +0000 | [diff] [blame] | 18 | */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 19 | #define IN_LIBXML | 
|  | 20 | #include "libxml.h" | 
|  | 21 |  | 
|  | 22 | #ifdef LIBXML_SCHEMAS_ENABLED | 
|  | 23 |  | 
|  | 24 | #include <string.h> | 
|  | 25 | #include <libxml/xmlmemory.h> | 
|  | 26 | #include <libxml/parser.h> | 
|  | 27 | #include <libxml/parserInternals.h> | 
|  | 28 | #include <libxml/hash.h> | 
| Daniel Veillard | 5a87241 | 2002-05-22 06:40:27 +0000 | [diff] [blame] | 29 | #include <libxml/uri.h> | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 30 |  | 
|  | 31 | #include <libxml/xmlschemas.h> | 
|  | 32 | #include <libxml/schemasInternals.h> | 
|  | 33 | #include <libxml/xmlschemastypes.h> | 
|  | 34 | #include <libxml/xmlautomata.h> | 
|  | 35 | #include <libxml/xmlregexp.h> | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 36 | #include <libxml/dict.h> | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 37 |  | 
| Daniel Veillard | a84c0b3 | 2003-06-02 16:58:46 +0000 | [diff] [blame] | 38 | /* #define DEBUG 1 */ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 39 |  | 
| Daniel Veillard | 82bbbd4 | 2003-05-11 20:16:09 +0000 | [diff] [blame] | 40 | /* #define DEBUG_CONTENT 1 */ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 41 |  | 
| Daniel Veillard | 82bbbd4 | 2003-05-11 20:16:09 +0000 | [diff] [blame] | 42 | /* #define DEBUG_TYPE 1 */ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 43 |  | 
| Daniel Veillard | 118aed7 | 2002-09-24 14:13:13 +0000 | [diff] [blame] | 44 | /* #define DEBUG_CONTENT_REGEXP 1 */ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 45 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 46 | /* #define DEBUG_AUTOMATA 1 */ | 
|  | 47 |  | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 48 | /* #define DEBUG_ATTR_VALIDATION 1 */ | 
|  | 49 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 50 | /* #define DEBUG_UNION_VALIDATION 1 */ | 
|  | 51 |  | 
|  | 52 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 53 | #define UNBOUNDED (1 << 30) | 
|  | 54 | #define TODO 								\ | 
|  | 55 | xmlGenericError(xmlGenericErrorContext,				\ | 
|  | 56 | "Unimplemented block at %s:%d\n",				\ | 
|  | 57 | __FILE__, __LINE__); | 
|  | 58 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 59 | #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##" | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 60 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 61 | /* | 
|  | 62 | * The XML Schemas namespaces | 
|  | 63 | */ | 
|  | 64 | static const xmlChar *xmlSchemaNs = (const xmlChar *) | 
|  | 65 | "http://www.w3.org/2001/XMLSchema"; | 
|  | 66 |  | 
|  | 67 | static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *) | 
|  | 68 | "http://www.w3.org/2001/XMLSchema-instance"; | 
|  | 69 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 70 | static const xmlChar *xmlSchemaElemDesElemDecl = (const xmlChar *) | 
|  | 71 | "Element decl."; | 
|  | 72 | static const xmlChar *xmlSchemaElemDesElemRef = (const xmlChar *) | 
|  | 73 | "Element ref."; | 
|  | 74 | static const xmlChar *xmlSchemaElemDesAttrDecl = (const xmlChar *) | 
|  | 75 | "Attribute decl."; | 
|  | 76 | static const xmlChar *xmlSchemaElemDesAttrRef = (const xmlChar *) | 
|  | 77 | "Attribute ref."; | 
|  | 78 | static const xmlChar *xmlSchemaElemDesST = (const xmlChar *) | 
|  | 79 | "ST"; | 
|  | 80 | static const xmlChar *xmlSchemaElemDesCT = (const xmlChar *) | 
|  | 81 | "CT"; | 
|  | 82 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 83 | #define IS_SCHEMA(node, type)						\ | 
|  | 84 | ((node != NULL) && (node->ns != NULL) &&				\ | 
|  | 85 | (xmlStrEqual(node->name, (const xmlChar *) type)) &&		\ | 
|  | 86 | (xmlStrEqual(node->ns->href, xmlSchemaNs))) | 
|  | 87 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 88 | #define FREE_AND_NULL(str)						\ | 
|  | 89 | if (str != NULL) {							\ | 
|  | 90 | xmlFree(str);							\ | 
|  | 91 | str = NULL;							\ | 
|  | 92 | } | 
|  | 93 |  | 
|  | 94 | #define XML_SCHEMAS_VAL_WTSP_PRESERVE 0 | 
|  | 95 | #define XML_SCHEMAS_VAL_WTSP_REPLACE  1 | 
|  | 96 | #define XML_SCHEMAS_VAL_WTSP_COLLAPSE 2 | 
|  | 97 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 98 | #define XML_SCHEMAS_PARSE_ERROR		1 | 
|  | 99 |  | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 100 | #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT | 
|  | 101 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 102 | struct _xmlSchemaParserCtxt { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 103 | void *userData;             /* user specific data block */ | 
|  | 104 | xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */ | 
|  | 105 | xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */ | 
| Daniel Veillard | e19fc23 | 2002-04-22 16:01:24 +0000 | [diff] [blame] | 106 | xmlSchemaValidError err; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 107 | int nberrors; | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 108 | xmlStructuredErrorFunc serror; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 109 |  | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 110 | xmlSchemaPtr topschema;	/* The main schema */ | 
|  | 111 | xmlHashTablePtr namespaces;	/* Hash table of namespaces to schemas */ | 
|  | 112 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 113 | xmlSchemaPtr schema;        /* The schema in use */ | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 114 | const xmlChar *container;   /* the current element, group, ... */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 115 | int counter; | 
|  | 116 |  | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 117 | const xmlChar *URL; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 118 | xmlDocPtr doc; | 
| Daniel Veillard | dda22c1 | 2004-01-24 08:31:30 +0000 | [diff] [blame] | 119 | int preserve;		/* Whether the doc should be freed  */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 120 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 121 | const char *buffer; | 
|  | 122 | int size; | 
| Daniel Veillard | 6045c90 | 2002-10-09 21:13:59 +0000 | [diff] [blame] | 123 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 124 | /* | 
|  | 125 | * Used to build complex element content models | 
|  | 126 | */ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 127 | xmlAutomataPtr am; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 128 | xmlAutomataStatePtr start; | 
|  | 129 | xmlAutomataStatePtr end; | 
|  | 130 | xmlAutomataStatePtr state; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 131 |  | 
|  | 132 | xmlDictPtr dict;		/* dictionnary for interned string names */ | 
| Daniel Veillard | b0f397e | 2003-12-23 23:30:53 +0000 | [diff] [blame] | 133 | int        includes;	/* the inclusion level, 0 for root or imports */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 134 | xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */ | 
|  | 135 | xmlSchemaTypePtr parentItem; /* The current parent schema item */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 136 | }; | 
|  | 137 |  | 
|  | 138 |  | 
|  | 139 | #define XML_SCHEMAS_ATTR_UNKNOWN 1 | 
|  | 140 | #define XML_SCHEMAS_ATTR_CHECKED 2 | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 141 | #define XML_SCHEMAS_ATTR_PROHIBITED 3 | 
|  | 142 | #define XML_SCHEMAS_ATTR_MISSING 4 | 
|  | 143 | #define XML_SCHEMAS_ATTR_INVALID_VALUE 5 | 
|  | 144 | #define XML_SCHEMAS_ATTR_TYPE_NOT_RESOLVED 6 | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 145 |  | 
|  | 146 | typedef struct _xmlSchemaAttrState xmlSchemaAttrState; | 
|  | 147 | typedef xmlSchemaAttrState *xmlSchemaAttrStatePtr; | 
|  | 148 | struct _xmlSchemaAttrState { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 149 | xmlSchemaAttrStatePtr next; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 150 | xmlAttrPtr attr; | 
|  | 151 | int state; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 152 | xmlSchemaAttributePtr decl; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 153 | }; | 
|  | 154 |  | 
|  | 155 | /** | 
|  | 156 | * xmlSchemaValidCtxt: | 
|  | 157 | * | 
|  | 158 | * A Schemas validation context | 
|  | 159 | */ | 
|  | 160 |  | 
|  | 161 | struct _xmlSchemaValidCtxt { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 162 | void *userData;             /* user specific data block */ | 
|  | 163 | xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */ | 
|  | 164 | xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */ | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 165 | xmlStructuredErrorFunc serror; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 166 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 167 | xmlSchemaPtr schema;        /* The schema in use */ | 
|  | 168 | xmlDocPtr doc; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 169 | xmlParserInputBufferPtr input; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 170 | xmlCharEncoding enc; | 
|  | 171 | xmlSAXHandlerPtr sax; | 
|  | 172 | void *user_data; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 173 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 174 | xmlDocPtr myDoc; | 
|  | 175 | int err; | 
|  | 176 | int nberrors; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 177 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 178 | xmlNodePtr node; | 
|  | 179 | xmlNodePtr cur; | 
|  | 180 | xmlSchemaTypePtr type; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 181 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 182 | xmlRegExecCtxtPtr regexp; | 
|  | 183 | xmlSchemaValPtr value; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 184 |  | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 185 | xmlSchemaAttrStatePtr attrTop; | 
|  | 186 | /* xmlSchemaAttrStatePtr attrBase; */ | 
|  | 187 | /* int attrMax; */ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 188 | xmlSchemaAttrStatePtr attr; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 189 | xmlNodePtr scope; | 
|  | 190 | int valueWS; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 191 | }; | 
|  | 192 |  | 
| Daniel Veillard | 1d91386 | 2003-11-21 00:28:39 +0000 | [diff] [blame] | 193 | /* | 
|  | 194 | * These are the entries in the schemas importSchemas hash table | 
|  | 195 | */ | 
|  | 196 | typedef struct _xmlSchemaImport xmlSchemaImport; | 
|  | 197 | typedef xmlSchemaImport *xmlSchemaImportPtr; | 
|  | 198 | struct _xmlSchemaImport { | 
|  | 199 | const xmlChar *schemaLocation; | 
|  | 200 | xmlSchemaPtr schema; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 201 | xmlDocPtr doc; | 
| Daniel Veillard | 1d91386 | 2003-11-21 00:28:39 +0000 | [diff] [blame] | 202 | }; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 203 |  | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 204 | /* | 
|  | 205 | * These are the entries associated to includes in a schemas | 
|  | 206 | */ | 
|  | 207 | typedef struct _xmlSchemaInclude xmlSchemaInclude; | 
|  | 208 | typedef xmlSchemaInclude *xmlSchemaIncludePtr; | 
|  | 209 | struct _xmlSchemaInclude { | 
|  | 210 | xmlSchemaIncludePtr next; | 
|  | 211 |  | 
|  | 212 | const xmlChar *schemaLocation; | 
|  | 213 | xmlDocPtr doc; | 
|  | 214 | }; | 
|  | 215 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 216 | /************************************************************************ | 
|  | 217 | * 									* | 
|  | 218 | * 			Some predeclarations				* | 
|  | 219 | * 									* | 
|  | 220 | ************************************************************************/ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 221 |  | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 222 | static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, | 
|  | 223 | xmlSchemaPtr schema, | 
|  | 224 | xmlNodePtr node); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 225 | static void | 
|  | 226 | xmlSchemaTypeFixup(xmlSchemaTypePtr typeDecl, | 
|  | 227 | xmlSchemaParserCtxtPtr ctxt, const xmlChar * name); | 
|  | 228 | static const char * | 
|  | 229 | xmlSchemaFacetTypeToString(xmlSchemaTypeType type); | 
|  | 230 | static int | 
|  | 231 | xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt, | 
|  | 232 | const xmlChar *value, | 
|  | 233 | int fireErrors, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 234 | int applyFacets, | 
|  | 235 | int normalize); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 236 | static int | 
|  | 237 | xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
|  | 238 | xmlNodePtr node); | 
| William M. Brack | 87640d5 | 2004-04-17 14:58:15 +0000 | [diff] [blame] | 239 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 240 | /************************************************************************ | 
|  | 241 | *									* | 
|  | 242 | * 			Datatype error handlers				* | 
|  | 243 | *									* | 
|  | 244 | ************************************************************************/ | 
|  | 245 |  | 
|  | 246 | /** | 
|  | 247 | * xmlSchemaPErrMemory: | 
|  | 248 | * @node: a context node | 
|  | 249 | * @extra:  extra informations | 
|  | 250 | * | 
|  | 251 | * Handle an out of memory condition | 
|  | 252 | */ | 
|  | 253 | static void | 
|  | 254 | xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt, | 
|  | 255 | const char *extra, xmlNodePtr node) | 
|  | 256 | { | 
|  | 257 | if (ctxt != NULL) | 
|  | 258 | ctxt->nberrors++; | 
|  | 259 | __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL, | 
|  | 260 | extra); | 
|  | 261 | } | 
|  | 262 |  | 
|  | 263 | /** | 
|  | 264 | * xmlSchemaPErr: | 
|  | 265 | * @ctxt: the parsing context | 
|  | 266 | * @node: the context node | 
|  | 267 | * @error: the error code | 
|  | 268 | * @msg: the error message | 
|  | 269 | * @str1: extra data | 
|  | 270 | * @str2: extra data | 
|  | 271 | * | 
|  | 272 | * Handle a parser error | 
|  | 273 | */ | 
|  | 274 | static void | 
|  | 275 | xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, | 
|  | 276 | const char *msg, const xmlChar * str1, const xmlChar * str2) | 
|  | 277 | { | 
|  | 278 | xmlGenericErrorFunc channel = NULL; | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 279 | xmlStructuredErrorFunc schannel = NULL; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 280 | void *data = NULL; | 
|  | 281 |  | 
|  | 282 | if (ctxt != NULL) { | 
|  | 283 | ctxt->nberrors++; | 
|  | 284 | channel = ctxt->error; | 
|  | 285 | data = ctxt->userData; | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 286 | schannel = ctxt->serror; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 287 | } | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 288 | __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 289 | error, XML_ERR_ERROR, NULL, 0, | 
|  | 290 | (const char *) str1, (const char *) str2, NULL, 0, 0, | 
|  | 291 | msg, str1, str2); | 
|  | 292 | } | 
|  | 293 |  | 
|  | 294 | /** | 
|  | 295 | * xmlSchemaPErr2: | 
|  | 296 | * @ctxt: the parsing context | 
|  | 297 | * @node: the context node | 
|  | 298 | * @node: the current child | 
|  | 299 | * @error: the error code | 
|  | 300 | * @msg: the error message | 
|  | 301 | * @str1: extra data | 
|  | 302 | * @str2: extra data | 
|  | 303 | * | 
|  | 304 | * Handle a parser error | 
|  | 305 | */ | 
|  | 306 | static void | 
|  | 307 | xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, | 
|  | 308 | xmlNodePtr child, int error, | 
|  | 309 | const char *msg, const xmlChar * str1, const xmlChar * str2) | 
|  | 310 | { | 
|  | 311 | if (child != NULL) | 
|  | 312 | xmlSchemaPErr(ctxt, child, error, msg, str1, str2); | 
|  | 313 | else | 
|  | 314 | xmlSchemaPErr(ctxt, node, error, msg, str1, str2); | 
|  | 315 | } | 
|  | 316 |  | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 317 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 318 | /** | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 319 | * xmlSchemaPErrExt: | 
|  | 320 | * @ctxt: the parsing context | 
|  | 321 | * @node: the context node | 
|  | 322 | * @error: the error code | 
|  | 323 | * @strData1: extra data | 
|  | 324 | * @strData2: extra data | 
|  | 325 | * @strData3: extra data | 
|  | 326 | * @msg: the message | 
|  | 327 | * @str1:  extra parameter for the message display | 
|  | 328 | * @str2:  extra parameter for the message display | 
|  | 329 | * @str3:  extra parameter for the message display | 
|  | 330 | * @str4:  extra parameter for the message display | 
|  | 331 | * @str5:  extra parameter for the message display | 
|  | 332 | * | 
|  | 333 | * Handle a parser error | 
|  | 334 | */ | 
|  | 335 | static void | 
|  | 336 | xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, | 
|  | 337 | const xmlChar * strData1, const xmlChar * strData2, | 
|  | 338 | const xmlChar * strData3, const char *msg, const xmlChar * str1, | 
|  | 339 | const xmlChar * str2, const xmlChar * str3, const xmlChar * str4, | 
|  | 340 | const xmlChar * str5) | 
|  | 341 | { | 
|  | 342 |  | 
|  | 343 | xmlGenericErrorFunc channel = NULL; | 
|  | 344 | xmlStructuredErrorFunc schannel = NULL; | 
|  | 345 | void *data = NULL; | 
|  | 346 |  | 
|  | 347 | if (ctxt != NULL) { | 
|  | 348 | ctxt->nberrors++; | 
|  | 349 | channel = ctxt->error; | 
|  | 350 | data = ctxt->userData; | 
|  | 351 | schannel = ctxt->serror; | 
|  | 352 | } | 
|  | 353 | __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, | 
|  | 354 | error, XML_ERR_ERROR, NULL, 0, | 
|  | 355 | (const char *) strData1, (const char *) strData2, | 
| William M. Brack | 803812b | 2004-06-03 02:11:24 +0000 | [diff] [blame] | 356 | (const char *) strData3, 0, 0, msg, str1, str2, | 
|  | 357 | str3, str4, str5); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 358 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 359 |  | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 360 |  | 
|  | 361 | /** | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 362 | * xmlSchemaVTypeErrMemory: | 
|  | 363 | * @node: a context node | 
|  | 364 | * @extra:  extra informations | 
|  | 365 | * | 
|  | 366 | * Handle an out of memory condition | 
|  | 367 | */ | 
|  | 368 | static void | 
|  | 369 | xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt, | 
|  | 370 | const char *extra, xmlNodePtr node) | 
|  | 371 | { | 
|  | 372 | if (ctxt != NULL) { | 
|  | 373 | ctxt->nberrors++; | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 374 | ctxt->err = XML_SCHEMAV_INTERNAL; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 375 | } | 
|  | 376 | __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL, | 
|  | 377 | extra); | 
|  | 378 | } | 
|  | 379 |  | 
|  | 380 | /** | 
|  | 381 | * xmlSchemaVErr3: | 
|  | 382 | * @ctxt: the validation context | 
|  | 383 | * @node: the context node | 
|  | 384 | * @error: the error code | 
|  | 385 | * @msg: the error message | 
|  | 386 | * @str1: extra data | 
|  | 387 | * @str2: extra data | 
|  | 388 | * @str3: extra data | 
|  | 389 | * | 
|  | 390 | * Handle a validation error | 
|  | 391 | */ | 
|  | 392 | static void | 
|  | 393 | xmlSchemaVErr3(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node, int error, | 
|  | 394 | const char *msg, const xmlChar *str1, const xmlChar *str2, | 
|  | 395 | const xmlChar *str3) | 
|  | 396 | { | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 397 | xmlStructuredErrorFunc schannel = NULL; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 398 | xmlGenericErrorFunc channel = NULL; | 
|  | 399 | void *data = NULL; | 
|  | 400 |  | 
|  | 401 | if (ctxt != NULL) { | 
|  | 402 | ctxt->nberrors++; | 
|  | 403 | ctxt->err = error; | 
|  | 404 | channel = ctxt->error; | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 405 | schannel = ctxt->serror; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 406 | data = ctxt->userData; | 
|  | 407 | } | 
|  | 408 | /* reajust to global error numbers */ | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 409 | /* Removed, since the old schema error codes have been | 
|  | 410 | * substituted for the global error codes. | 
|  | 411 | * | 
|  | 412 | * error += XML_SCHEMAV_NOROOT - XML_SCHEMAS_ERR_NOROOT; | 
|  | 413 | */ | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 414 | __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASV, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 415 | error, XML_ERR_ERROR, NULL, 0, | 
|  | 416 | (const char *) str1, (const char *) str2, | 
|  | 417 | (const char *) str3, 0, 0, | 
|  | 418 | msg, str1, str2, str3); | 
|  | 419 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 420 |  | 
|  | 421 | /** | 
|  | 422 | * xmlSchemaVErrExt: | 
|  | 423 | * @ctxt: the validation context | 
|  | 424 | * @node: the context node | 
|  | 425 | * @error: the error code | 
|  | 426 | * @msg: the message | 
|  | 427 | * @str1:  extra parameter for the message display | 
|  | 428 | * @str2:  extra parameter for the message display | 
|  | 429 | * @str3:  extra parameter for the message display | 
|  | 430 | * @str4:  extra parameter for the message display | 
|  | 431 | * @str5:  extra parameter for the message display | 
|  | 432 | * | 
|  | 433 | * Handle a validation error | 
|  | 434 | */ | 
|  | 435 | static void | 
|  | 436 | xmlSchemaVErrExt(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node, int error, | 
|  | 437 | const char *msg, const xmlChar * str1, | 
|  | 438 | const xmlChar * str2, const xmlChar * str3, | 
|  | 439 | const xmlChar * str4, const xmlChar * str5) | 
|  | 440 | { | 
|  | 441 | xmlStructuredErrorFunc schannel = NULL; | 
|  | 442 | xmlGenericErrorFunc channel = NULL; | 
|  | 443 | void *data = NULL; | 
|  | 444 |  | 
|  | 445 | if (ctxt != NULL) { | 
|  | 446 | ctxt->nberrors++; | 
|  | 447 | ctxt->err = error; | 
|  | 448 | channel = ctxt->error; | 
|  | 449 | schannel = ctxt->serror; | 
|  | 450 | data = ctxt->userData; | 
|  | 451 | } | 
|  | 452 | /* reajust to global error numbers */ | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 453 | /* Removed, since the old schema error codes have been | 
|  | 454 | * substituted for the global error codes. | 
|  | 455 | * | 
|  | 456 | * error += XML_SCHEMAV_NOROOT - XML_SCHEMAS_ERR_NOROOT; | 
|  | 457 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 458 | __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, | 
|  | 459 | error, XML_ERR_ERROR, NULL, 0, NULL, NULL, NULL, 0, 0, | 
|  | 460 | msg, str1, str2, str3, str4, str5); | 
|  | 461 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 462 | /** | 
|  | 463 | * xmlSchemaVErr: | 
|  | 464 | * @ctxt: the validation context | 
|  | 465 | * @node: the context node | 
|  | 466 | * @error: the error code | 
|  | 467 | * @msg: the error message | 
|  | 468 | * @str1: extra data | 
|  | 469 | * @str2: extra data | 
|  | 470 | * | 
|  | 471 | * Handle a validation error | 
|  | 472 | */ | 
|  | 473 | static void | 
|  | 474 | xmlSchemaVErr(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node, int error, | 
|  | 475 | const char *msg, const xmlChar * str1, const xmlChar * str2) | 
|  | 476 | { | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 477 | xmlStructuredErrorFunc schannel = NULL; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 478 | xmlGenericErrorFunc channel = NULL; | 
|  | 479 | void *data = NULL; | 
|  | 480 |  | 
|  | 481 | if (ctxt != NULL) { | 
|  | 482 | ctxt->nberrors++; | 
|  | 483 | ctxt->err = error; | 
|  | 484 | channel = ctxt->error; | 
|  | 485 | data = ctxt->userData; | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 486 | schannel = ctxt->serror; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 487 | } | 
|  | 488 | /* reajust to global error numbers */ | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 489 | /* Removed, since the old schema error codes have been | 
|  | 490 | * substituted for the global error codes. | 
|  | 491 | * | 
|  | 492 | * error += XML_SCHEMAV_NOROOT - XML_SCHEMAS_ERR_NOROOT; | 
|  | 493 | */ | 
| Daniel Veillard | 659e71e | 2003-10-10 14:10:40 +0000 | [diff] [blame] | 494 | __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASV, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 495 | error, XML_ERR_ERROR, NULL, 0, | 
|  | 496 | (const char *) str1, (const char *) str2, NULL, 0, 0, | 
|  | 497 | msg, str1, str2); | 
|  | 498 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 499 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 500 | /** | 
|  | 501 | * xmlSchemaGetOnymousTypeName: | 
|  | 502 | * @attr:  the attribute declaration/use | 
|  | 503 | * | 
|  | 504 | * Returns the name of the attribute; if the attribute | 
|  | 505 | * is a reference, the name of the referenced global type will be returned. | 
|  | 506 | */ | 
|  | 507 | static const xmlChar * | 
|  | 508 | xmlSchemaGetAttrName(xmlSchemaAttributePtr attr) | 
|  | 509 | { | 
|  | 510 | if (attr->ref != NULL) | 
|  | 511 | return(attr->ref); | 
|  | 512 | else | 
|  | 513 | return(attr->name); | 
|  | 514 | } | 
|  | 515 |  | 
|  | 516 | /** | 
|  | 517 | * xmlSchemaGetOnymousTargetNsURI: | 
|  | 518 | * @type:  the type (element or attribute) | 
|  | 519 | * | 
|  | 520 | * Returns the target namespace URI of the type; if the type is a reference, | 
|  | 521 | * the target namespace of the referenced type will be returned. | 
|  | 522 | */ | 
|  | 523 | static const xmlChar * | 
|  | 524 | xmlSchemaGetAttrTargetNsURI(xmlSchemaAttributePtr attr) | 
|  | 525 | { | 
|  | 526 | if (attr->ref != NULL) | 
|  | 527 | return (attr->refNs); | 
|  | 528 | else | 
|  | 529 | return(attr->targetNamespace); | 
|  | 530 | } | 
|  | 531 |  | 
|  | 532 | /** | 
|  | 533 | * xmlSchemaFormatNsUriLocal: | 
|  | 534 | * @buf: the string buffer | 
|  | 535 | * @uri:  the namespace URI | 
|  | 536 | * @local: the local name | 
|  | 537 | * | 
|  | 538 | * Returns a representation of the given URI used | 
|  | 539 | * for error reports. | 
|  | 540 | * | 
|  | 541 | * Returns an empty string, if @ns is NULL, a formatted | 
|  | 542 | * string otherwise. | 
|  | 543 | */ | 
|  | 544 | static const xmlChar* | 
|  | 545 | xmlSchemaFormatNsUriLocal(xmlChar **buf, | 
|  | 546 | const xmlChar *uri, const xmlChar *local) | 
|  | 547 | { | 
|  | 548 | if (*buf != NULL) | 
|  | 549 | xmlFree(*buf); | 
|  | 550 | if (uri == NULL) { | 
|  | 551 | *buf = xmlStrdup(BAD_CAST "{'"); | 
|  | 552 | *buf = xmlStrcat(*buf, local); | 
|  | 553 | } else { | 
|  | 554 | *buf = xmlStrdup(BAD_CAST "{'"); | 
|  | 555 | *buf = xmlStrcat(*buf, uri); | 
|  | 556 | *buf = xmlStrcat(*buf, BAD_CAST "', '"); | 
|  | 557 | *buf = xmlStrcat(*buf, local); | 
|  | 558 | } | 
|  | 559 | *buf = xmlStrcat(*buf, BAD_CAST "'}"); | 
|  | 560 | return ((const xmlChar *) *buf); | 
|  | 561 | } | 
|  | 562 |  | 
|  | 563 | /** | 
|  | 564 | * xmlSchemaFormatNsPrefixLocal: | 
|  | 565 | * @buf: the string buffer | 
|  | 566 | * @ns:  the namespace | 
|  | 567 | * @local: the local name | 
|  | 568 | * | 
|  | 569 | * Returns a representation of the given URI used | 
|  | 570 | * for error reports. | 
|  | 571 | * | 
|  | 572 | * Returns an empty string, if @ns is NULL, a formatted | 
|  | 573 | * string otherwise. | 
|  | 574 | */ | 
|  | 575 | static const xmlChar* | 
|  | 576 | xmlSchemaFormatNsPrefixLocal(xmlChar **buf, | 
|  | 577 | xmlNsPtr ns, const xmlChar *local) | 
|  | 578 | { | 
|  | 579 | if (*buf != NULL) { | 
|  | 580 | xmlFree(*buf); | 
|  | 581 | *buf = NULL; | 
|  | 582 | } | 
|  | 583 | if ((ns == NULL) || (ns->prefix == NULL)) | 
|  | 584 | return(local); | 
|  | 585 | else { | 
|  | 586 | *buf = xmlStrdup(ns->prefix); | 
|  | 587 | *buf = xmlStrcat(*buf, BAD_CAST ":"); | 
|  | 588 | *buf = xmlStrcat(*buf, local); | 
|  | 589 | } | 
|  | 590 | return ((const xmlChar *) *buf); | 
|  | 591 | } | 
|  | 592 |  | 
|  | 593 | /** | 
|  | 594 | * xmlSchemaFormatItemForReport: | 
|  | 595 | * @buf: the string buffer | 
|  | 596 | * @itemDes: the designation of the item | 
|  | 597 | * @itemName: the name of the item | 
|  | 598 | * @item: the item as an object | 
|  | 599 | * @itemNode: the node of the item | 
|  | 600 | * @local: the local name | 
|  | 601 | * @parsing: if the function is used during the parse | 
|  | 602 | * | 
|  | 603 | * Returns a representation of the given item used | 
|  | 604 | * for error reports. | 
|  | 605 | * | 
|  | 606 | * The following order is used to build the resulting | 
|  | 607 | * designation if the arguments are not NULL: | 
|  | 608 | * 1a. If itemDes not NULL -> itemDes | 
|  | 609 | * 1b. If (itemDes not NULL) and (itemName not NULL) | 
|  | 610 | *     -> itemDes + itemName | 
|  | 611 | * 2. If the preceding was NULL and (item not NULL) -> item | 
|  | 612 | * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode | 
|  | 613 | * | 
|  | 614 | * If the itemNode is an attribute node, the name of the attribute | 
|  | 615 | * will be appended to the result. | 
|  | 616 | * | 
|  | 617 | * Returns the formatted string and sets @buf to the resulting value. | 
|  | 618 | */ | 
|  | 619 | static xmlChar* | 
|  | 620 | xmlSchemaFormatItemForReport(xmlChar **buf, | 
|  | 621 | const xmlChar *itemDes, | 
|  | 622 | xmlSchemaTypePtr item, | 
|  | 623 | xmlNodePtr itemNode, | 
|  | 624 | int parsing) | 
|  | 625 | { | 
|  | 626 | xmlChar *str = NULL; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 627 | int named = 1; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 628 |  | 
|  | 629 | if (*buf != NULL) { | 
|  | 630 | xmlFree(*buf); | 
|  | 631 | *buf = NULL; | 
|  | 632 | } | 
|  | 633 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 634 | if (itemDes != NULL) { | 
|  | 635 | *buf = xmlStrdup(itemDes); | 
|  | 636 | } else if (item != NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 637 | if (item->type == XML_SCHEMA_TYPE_BASIC) { | 
|  | 638 | if (item->builtInType == XML_SCHEMAS_ANYTYPE) | 
|  | 639 | *buf = xmlStrdup(BAD_CAST "'anyType'"); | 
|  | 640 | else if (item->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) | 
|  | 641 | *buf = xmlStrdup(BAD_CAST "'anySimpleType'"); | 
|  | 642 | else { | 
|  | 643 | /* *buf = xmlStrdup(BAD_CAST "bi "); */ | 
|  | 644 | /* *buf = xmlStrcat(*buf, xmlSchemaElemDesST); */ | 
|  | 645 | *buf = xmlStrdup(BAD_CAST "'"); | 
|  | 646 | *buf = xmlStrcat(*buf, item->name); | 
|  | 647 | *buf = xmlStrcat(*buf, BAD_CAST "'"); | 
|  | 648 | } | 
|  | 649 | } else if (item->type == XML_SCHEMA_TYPE_SIMPLE) { | 
|  | 650 | if (item->flags & XML_SCHEMAS_TYPE_GLOBAL) { | 
|  | 651 | *buf = xmlStrdup(xmlSchemaElemDesST); | 
|  | 652 | *buf = xmlStrcat(*buf, BAD_CAST " '"); | 
|  | 653 | *buf = xmlStrcat(*buf, item->name); | 
|  | 654 | *buf = xmlStrcat(*buf, BAD_CAST "'"); | 
|  | 655 | } else { | 
|  | 656 | *buf = xmlStrdup(xmlSchemaElemDesST); | 
|  | 657 | *buf = xmlStrcat(*buf, BAD_CAST " local"); | 
|  | 658 | } | 
|  | 659 | } else if (item->type == XML_SCHEMA_TYPE_COMPLEX) { | 
|  | 660 | if (item->flags & XML_SCHEMAS_TYPE_GLOBAL) { | 
|  | 661 | *buf = xmlStrdup(xmlSchemaElemDesCT); | 
|  | 662 | *buf = xmlStrcat(*buf, BAD_CAST " '"); | 
|  | 663 | *buf = xmlStrcat(*buf, item->name); | 
|  | 664 | *buf = xmlStrcat(*buf, BAD_CAST "'"); | 
|  | 665 | } else { | 
|  | 666 | *buf = xmlStrdup(xmlSchemaElemDesCT); | 
|  | 667 | *buf = xmlStrcat(*buf, BAD_CAST " local"); | 
|  | 668 | } | 
|  | 669 | } else if (item->type == XML_SCHEMA_TYPE_ATTRIBUTE) { | 
|  | 670 | xmlSchemaAttributePtr attr; | 
|  | 671 |  | 
|  | 672 | attr = (xmlSchemaAttributePtr) item; | 
|  | 673 | if ((attr->flags & XML_SCHEMAS_TYPE_GLOBAL) || | 
|  | 674 | (attr->ref == NULL)) { | 
|  | 675 | *buf = xmlStrdup(xmlSchemaElemDesAttrDecl); | 
|  | 676 | *buf = xmlStrcat(*buf, BAD_CAST " '"); | 
|  | 677 | *buf = xmlStrcat(*buf, attr->name); | 
|  | 678 | *buf = xmlStrcat(*buf, BAD_CAST "'"); | 
|  | 679 | } else { | 
|  | 680 | *buf = xmlStrdup(xmlSchemaElemDesAttrRef); | 
|  | 681 | *buf = xmlStrcat(*buf, BAD_CAST " '"); | 
|  | 682 | *buf = xmlStrcat(*buf, attr->refPrefix); | 
|  | 683 | *buf = xmlStrcat(*buf, BAD_CAST ":"); | 
|  | 684 | *buf = xmlStrcat(*buf, attr->ref); | 
|  | 685 | *buf = xmlStrcat(*buf, BAD_CAST "'"); | 
|  | 686 | } | 
|  | 687 | } else if (item->type == XML_SCHEMA_TYPE_ELEMENT) { | 
|  | 688 | xmlSchemaElementPtr elem; | 
|  | 689 |  | 
|  | 690 | elem = (xmlSchemaElementPtr) item; | 
|  | 691 | if ((elem->flags & XML_SCHEMAS_TYPE_GLOBAL) || | 
|  | 692 | (elem->ref == NULL)) { | 
|  | 693 | *buf = xmlStrdup(xmlSchemaElemDesElemDecl); | 
|  | 694 | *buf = xmlStrcat(*buf, BAD_CAST " '"); | 
|  | 695 | *buf = xmlStrcat(*buf, elem->name); | 
|  | 696 | *buf = xmlStrcat(*buf, BAD_CAST "'"); | 
|  | 697 | } else { | 
|  | 698 | *buf = xmlStrdup(xmlSchemaElemDesElemRef); | 
|  | 699 | *buf = xmlStrcat(*buf, BAD_CAST " '"); | 
|  | 700 | *buf = xmlStrcat(*buf, elem->refPrefix); | 
|  | 701 | *buf = xmlStrcat(*buf, BAD_CAST ":"); | 
|  | 702 | *buf = xmlStrcat(*buf, elem->ref); | 
|  | 703 | *buf = xmlStrcat(*buf, BAD_CAST "'"); | 
|  | 704 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 705 | } else | 
|  | 706 | named = 0; | 
|  | 707 | } else | 
|  | 708 | named = 0; | 
|  | 709 |  | 
|  | 710 | if ((named == 0) && (itemNode != NULL)) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 711 | xmlNodePtr elem; | 
|  | 712 |  | 
|  | 713 | if (itemNode->type == XML_ATTRIBUTE_NODE) | 
|  | 714 | elem = itemNode->parent; | 
|  | 715 | else | 
|  | 716 | elem = itemNode; | 
|  | 717 | *buf = xmlStrdup(BAD_CAST "Element '"); | 
|  | 718 | if (parsing) | 
|  | 719 | *buf = xmlStrcat(*buf, elem->name); | 
|  | 720 | else | 
|  | 721 | *buf = xmlStrcat(*buf, | 
|  | 722 | xmlSchemaFormatNsPrefixLocal(&str, elem->ns, elem->name)); | 
|  | 723 | *buf = xmlStrcat(*buf, BAD_CAST "'"); | 
|  | 724 | } | 
|  | 725 | if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) { | 
|  | 726 | *buf = xmlStrcat(*buf, BAD_CAST ", attribute '"); | 
|  | 727 | *buf = xmlStrcat(*buf, xmlSchemaFormatNsPrefixLocal(&str, | 
|  | 728 | itemNode->ns, itemNode->name)); | 
|  | 729 | *buf = xmlStrcat(*buf, BAD_CAST "'"); | 
|  | 730 | } | 
|  | 731 | FREE_AND_NULL(str); | 
|  | 732 |  | 
|  | 733 | return (*buf); | 
|  | 734 | } | 
|  | 735 |  | 
|  | 736 | /** | 
|  | 737 | * xmlSchemaPFormatItemDes: | 
|  | 738 | * @buf: the string buffer | 
|  | 739 | * @item: the item as a schema object | 
|  | 740 | * @itemNode: the item as a node | 
|  | 741 | * | 
|  | 742 | * If the pointer to @buf is not NULL and @but holds no value, | 
|  | 743 | * the value is set to a item designation using | 
|  | 744 | * xmlSchemaFormatItemForReport. This one avoids adding | 
|  | 745 | * an attribute designation postfix. | 
|  | 746 | * | 
|  | 747 | * Returns a string of all enumeration elements. | 
|  | 748 | */ | 
|  | 749 | static void | 
|  | 750 | xmlSchemaPRequestItemDes(xmlChar **buf, | 
|  | 751 | xmlSchemaTypePtr item, | 
|  | 752 | xmlNodePtr itemNode) | 
|  | 753 | { | 
|  | 754 | if ((buf == 0) || (*buf != NULL)) | 
|  | 755 | return; | 
|  | 756 | if (itemNode->type == XML_ATTRIBUTE_NODE) | 
|  | 757 | itemNode = itemNode->parent; | 
|  | 758 | xmlSchemaFormatItemForReport(buf, NULL, item, itemNode, 1); | 
|  | 759 | } | 
|  | 760 |  | 
|  | 761 | /** | 
|  | 762 | * xmlSchemaFormatFacetEnumSet: | 
|  | 763 | * @buf: the string buffer | 
|  | 764 | * @type: the type holding the enumeration facets | 
|  | 765 | * | 
|  | 766 | * Builds a string consisting of all enumeration elements. | 
|  | 767 | * | 
|  | 768 | * Returns a string of all enumeration elements. | 
|  | 769 | */ | 
|  | 770 | static const xmlChar * | 
|  | 771 | xmlSchemaFormatFacetEnumSet(xmlChar **buf, xmlSchemaTypePtr type) | 
|  | 772 | { | 
|  | 773 | xmlSchemaFacetLinkPtr link; | 
|  | 774 |  | 
|  | 775 | if (*buf != NULL) | 
|  | 776 | xmlFree(*buf); | 
|  | 777 | *buf = NULL; | 
|  | 778 | for (link = type->facetSet; link != NULL; link = link->next) { | 
|  | 779 | if (link->facet->type == XML_SCHEMA_FACET_ENUMERATION) { | 
|  | 780 | if (*buf == NULL) { | 
|  | 781 | *buf = xmlStrdup(BAD_CAST "'"); | 
|  | 782 | *buf = xmlStrcat(*buf, link->facet->value); | 
|  | 783 | *buf = xmlStrcat(*buf, BAD_CAST "'"); | 
|  | 784 | } else { | 
|  | 785 | *buf = xmlStrcat(*buf, BAD_CAST ", '"); | 
|  | 786 | *buf = xmlStrcat(*buf, link->facet->value); | 
|  | 787 | *buf = xmlStrcat(*buf, BAD_CAST "'"); | 
|  | 788 | } | 
|  | 789 | } | 
|  | 790 | } | 
|  | 791 | return ((const xmlChar *) *buf); | 
|  | 792 | } | 
|  | 793 |  | 
|  | 794 | /** | 
|  | 795 | * xmlSchemaVFacetErr: | 
|  | 796 | * @ctxt:  the schema validation context | 
|  | 797 | * @error: the error code | 
|  | 798 | * @node: the node to be validated | 
|  | 799 | * @value: the value of the node | 
|  | 800 | * @type: the type holding the facet | 
|  | 801 | * @facet: the facet | 
|  | 802 | * @message: the error message of NULL | 
|  | 803 | * @str1: extra data | 
|  | 804 | * @str2: extra data | 
|  | 805 | * @str3: extra data | 
|  | 806 | * | 
|  | 807 | * Reports a facet validation error. | 
|  | 808 | * TODO: Should this report the value of an element as well? | 
|  | 809 | */ | 
|  | 810 | static void | 
|  | 811 | xmlSchemaVFacetErr(xmlSchemaValidCtxtPtr ctxt, | 
|  | 812 | xmlParserErrors error, | 
|  | 813 | xmlNodePtr node, | 
|  | 814 | const xmlChar *value, | 
|  | 815 | unsigned long length, | 
|  | 816 | xmlSchemaTypePtr type, | 
|  | 817 | xmlSchemaFacetPtr facet, | 
|  | 818 | const char *message, | 
|  | 819 | const xmlChar *str1, | 
|  | 820 | const xmlChar *str2, | 
|  | 821 | const xmlChar *str3) | 
|  | 822 | { | 
|  | 823 | xmlChar *str = NULL, *msg = NULL; | 
|  | 824 | xmlSchemaTypeType facetType; | 
|  | 825 |  | 
|  | 826 | xmlSchemaFormatItemForReport(&msg, NULL, NULL, node, 0); | 
|  | 827 | msg = xmlStrcat(msg, BAD_CAST " ["); | 
|  | 828 | msg = xmlStrcat(msg, xmlSchemaFormatItemForReport(&str, NULL, type, NULL, 0)); | 
|  | 829 | msg = xmlStrcat(msg, BAD_CAST ", facet '"); | 
|  | 830 | if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) { | 
|  | 831 | facetType = XML_SCHEMA_FACET_ENUMERATION; | 
|  | 832 | /* | 
|  | 833 | * If enumerations are validated, one must not expect the | 
|  | 834 | * facet to be given. | 
|  | 835 | */ | 
|  | 836 | } else | 
|  | 837 | facetType = facet->type; | 
|  | 838 | msg = xmlStrcat(msg, BAD_CAST xmlSchemaFacetTypeToString(facetType)); | 
|  | 839 | msg = xmlStrcat(msg, BAD_CAST "']: "); | 
|  | 840 | if (message == NULL) { | 
|  | 841 | /* | 
|  | 842 | * Use a default message. | 
|  | 843 | */ | 
|  | 844 | if ((facetType == XML_SCHEMA_FACET_LENGTH) || | 
|  | 845 | (facetType == XML_SCHEMA_FACET_MINLENGTH) || | 
|  | 846 | (facetType == XML_SCHEMA_FACET_MAXLENGTH)) { | 
|  | 847 |  | 
|  | 848 | char len[25], actLen[25]; | 
|  | 849 |  | 
|  | 850 | /* FIXME, TODO: What is the max expected string length of the | 
|  | 851 | * this value? | 
|  | 852 | */ | 
|  | 853 | if (node->type == XML_ATTRIBUTE_NODE) | 
|  | 854 | msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; "); | 
|  | 855 | else | 
|  | 856 | msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; "); | 
|  | 857 |  | 
|  | 858 | snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet)); | 
|  | 859 | snprintf(actLen, 24, "%lu", length); | 
|  | 860 |  | 
|  | 861 | if (facetType == XML_SCHEMA_FACET_LENGTH) | 
|  | 862 | msg = xmlStrcat(msg, | 
|  | 863 | BAD_CAST "this differs from the allowed length of '%s'.\n"); | 
|  | 864 | else if (facetType == XML_SCHEMA_FACET_MAXLENGTH) | 
|  | 865 | msg = xmlStrcat(msg, | 
|  | 866 | BAD_CAST "this exceeds the allowed maximum length of '%s'.\n"); | 
|  | 867 | else if (facetType == XML_SCHEMA_FACET_MINLENGTH) | 
|  | 868 | msg = xmlStrcat(msg, | 
|  | 869 | BAD_CAST "this underruns the allowed minimum length of '%s'.\n"); | 
|  | 870 |  | 
|  | 871 | if (node->type == XML_ATTRIBUTE_NODE) | 
|  | 872 | xmlSchemaVErrExt(ctxt, node, error, | 
|  | 873 | (const char *) msg, | 
|  | 874 | value, (const xmlChar *) actLen, (const xmlChar *) len, | 
|  | 875 | NULL, NULL); | 
|  | 876 | else | 
|  | 877 | xmlSchemaVErr(ctxt, node, error, | 
|  | 878 | (const char *) msg, | 
|  | 879 | (const xmlChar *) actLen, (const xmlChar *) len); | 
|  | 880 |  | 
|  | 881 | } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) { | 
|  | 882 | msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element " | 
|  | 883 | "of the set {%s}.\n"); | 
|  | 884 | xmlSchemaVErr(ctxt, node, error, (const char *) msg, value, | 
|  | 885 | xmlSchemaFormatFacetEnumSet(&str, type)); | 
|  | 886 | } else if (facetType == XML_SCHEMA_FACET_PATTERN) { | 
|  | 887 | msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted " | 
|  | 888 | "by the pattern '%s'.\n"); | 
|  | 889 | xmlSchemaVErr(ctxt, node, error, (const char *) msg, value, | 
|  | 890 | facet->value); | 
|  | 891 | } else if (node->type == XML_ATTRIBUTE_NODE) { | 
|  | 892 | msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n"); | 
|  | 893 | xmlSchemaVErr(ctxt, node, error, (const char *) msg, value, NULL); | 
|  | 894 | } else { | 
|  | 895 | msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n"); | 
|  | 896 | xmlSchemaVErr(ctxt, node, error, (const char *) msg, NULL, NULL); | 
|  | 897 | } | 
|  | 898 | } else { | 
|  | 899 | msg = xmlStrcat(msg, (const xmlChar *) message); | 
|  | 900 | msg = xmlStrcat(msg, BAD_CAST ".\n"); | 
|  | 901 | xmlSchemaVErr3(ctxt, node, error, (const char *) msg, str1, str2, str3); | 
|  | 902 | } | 
|  | 903 | FREE_AND_NULL(str) | 
|  | 904 | xmlFree(msg); | 
|  | 905 | } | 
|  | 906 |  | 
|  | 907 | /** | 
|  | 908 | * xmlSchemaVSimpleTypeErr: | 
|  | 909 | * @ctxt:  the schema validation context | 
|  | 910 | * @error: the error code | 
|  | 911 | * @type: the type used for validation | 
|  | 912 | * @node: the node containing the validated value | 
|  | 913 | * @value: the validated value | 
|  | 914 | * | 
|  | 915 | * Reports a simple type validation error. | 
|  | 916 | * TODO: Should this report the value of an element as well? | 
|  | 917 | */ | 
|  | 918 | static void | 
|  | 919 | xmlSchemaVSimpleTypeErr(xmlSchemaValidCtxtPtr ctxt, | 
|  | 920 | xmlParserErrors error, | 
|  | 921 | xmlNodePtr node, | 
|  | 922 | const xmlChar *value, | 
|  | 923 | xmlSchemaTypePtr type) | 
|  | 924 | { | 
|  | 925 | xmlChar *str = NULL, *msg = NULL; | 
|  | 926 |  | 
|  | 927 | xmlSchemaFormatItemForReport(&msg, NULL,  NULL, node, 0); | 
|  | 928 | msg = xmlStrcat(msg, BAD_CAST " ["); | 
|  | 929 | msg = xmlStrcat(msg, xmlSchemaFormatItemForReport(&str, NULL, type, NULL, 0)); | 
|  | 930 | if (node->type == XML_ATTRIBUTE_NODE) { | 
|  | 931 | msg = xmlStrcat(msg, BAD_CAST "]: The value '%s' is not valid.\n"); | 
|  | 932 | xmlSchemaVErr(ctxt, node, error, (const char *) msg, value, NULL); | 
|  | 933 | } else { | 
|  | 934 | msg = xmlStrcat(msg, BAD_CAST "]: The character content is not valid.\n"); | 
|  | 935 | xmlSchemaVErr(ctxt, node, error, (const char *) msg, NULL, NULL); | 
|  | 936 | } | 
|  | 937 | FREE_AND_NULL(str) | 
|  | 938 | xmlFree(msg); | 
|  | 939 | } | 
|  | 940 |  | 
|  | 941 | /** | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 942 | * xmlSchemaVComplexTypeErr: | 
|  | 943 | * @ctxt:  the schema validation context | 
|  | 944 | * @error: the error code | 
|  | 945 | * @node: the node containing the validated value | 
|  | 946 | * @type: the complex type used for validation | 
|  | 947 | * @message: the error message | 
|  | 948 | * | 
|  | 949 | * Reports a complex type validation error. | 
|  | 950 | */ | 
|  | 951 | static void | 
|  | 952 | xmlSchemaVComplexTypeErr(xmlSchemaValidCtxtPtr ctxt, | 
|  | 953 | xmlParserErrors error, | 
|  | 954 | xmlNodePtr node, | 
|  | 955 | xmlSchemaTypePtr type, | 
|  | 956 | const char *message) | 
|  | 957 | { | 
|  | 958 | xmlChar *str = NULL, *msg = NULL; | 
|  | 959 |  | 
|  | 960 | xmlSchemaFormatItemForReport(&msg, NULL,  NULL, node, 0); | 
|  | 961 | msg = xmlStrcat(msg, BAD_CAST " ["); | 
|  | 962 | msg = xmlStrcat(msg, xmlSchemaFormatItemForReport(&str, NULL, type, NULL, 0)); | 
|  | 963 | msg = xmlStrcat(msg, BAD_CAST "]: %s.\n"); | 
|  | 964 | xmlSchemaVErr(ctxt, node, error, (const char *) msg, | 
|  | 965 | (const xmlChar *) message, NULL); | 
|  | 966 | FREE_AND_NULL(str) | 
|  | 967 | xmlFree(msg); | 
|  | 968 | } | 
|  | 969 |  | 
|  | 970 | /** | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 971 | * xmlSchemaPMissingAttrErr: | 
|  | 972 | * @ctxt: the schema validation context | 
|  | 973 | * @ownerDes: the designation of  the owner | 
|  | 974 | * @ownerName: the name of the owner | 
|  | 975 | * @ownerItem: the owner as a schema object | 
|  | 976 | * @ownerElem: the owner as an element node | 
|  | 977 | * @node: the parent element node of the missing attribute node | 
|  | 978 | * @type: the corresponding type of the attribute node | 
|  | 979 | * | 
|  | 980 | * Reports an illegal attribute. | 
|  | 981 | */ | 
|  | 982 | static void | 
|  | 983 | xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt, | 
|  | 984 | xmlParserErrors error, | 
|  | 985 | xmlChar **ownerDes, | 
|  | 986 | xmlSchemaTypePtr ownerItem, | 
|  | 987 | xmlNodePtr ownerElem, | 
|  | 988 | const char *name, | 
|  | 989 | const char *message) | 
|  | 990 | { | 
|  | 991 | xmlChar *des = NULL; | 
|  | 992 |  | 
|  | 993 | if (ownerDes == NULL) | 
|  | 994 | xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem, 1); | 
|  | 995 | else if (*ownerDes == NULL) { | 
|  | 996 | xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, ownerElem, 1); | 
|  | 997 | des = *ownerDes; | 
|  | 998 | } else | 
|  | 999 | des = *ownerDes; | 
|  | 1000 | if (message != NULL) | 
|  | 1001 | xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message); | 
|  | 1002 | else | 
|  | 1003 | xmlSchemaPErr(ctxt, ownerElem, error, | 
|  | 1004 | "%s: The attribute '%s' is required but missing.\n", | 
|  | 1005 | BAD_CAST des, BAD_CAST name); | 
|  | 1006 | if (ownerDes == NULL) | 
|  | 1007 | FREE_AND_NULL(des); | 
|  | 1008 | } | 
|  | 1009 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1010 | /** | 
|  | 1011 | * xmlSchemaCompTypeToString: | 
|  | 1012 | * @type: the type of the schema item | 
|  | 1013 | * | 
|  | 1014 | * Returns the component name of a schema item. | 
|  | 1015 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1016 | static const char * | 
|  | 1017 | xmlSchemaCompTypeToString(xmlSchemaTypeType type) | 
|  | 1018 | { | 
|  | 1019 | switch (type) { | 
|  | 1020 | case XML_SCHEMA_TYPE_SIMPLE: | 
|  | 1021 | return("simple type definition"); | 
|  | 1022 | case XML_SCHEMA_TYPE_COMPLEX: | 
|  | 1023 | return("complex type definition"); | 
|  | 1024 | case XML_SCHEMA_TYPE_ELEMENT: | 
|  | 1025 | return("element declaration"); | 
|  | 1026 | case XML_SCHEMA_TYPE_ATTRIBUTE: | 
|  | 1027 | return("attribute declaration"); | 
|  | 1028 | case XML_SCHEMA_TYPE_GROUP: | 
|  | 1029 | return("model group definition"); | 
|  | 1030 | case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: | 
|  | 1031 | return("attribute group definition"); | 
|  | 1032 | case XML_SCHEMA_TYPE_NOTATION: | 
|  | 1033 | return("notation declaration"); | 
|  | 1034 | default: | 
|  | 1035 | return("Not a schema component"); | 
|  | 1036 | } | 
|  | 1037 | } | 
|  | 1038 | /** | 
|  | 1039 | * xmlSchemaPResCompAttrErr: | 
|  | 1040 | * @ctxt: the schema validation context | 
|  | 1041 | * @error: the error code | 
|  | 1042 | * @ownerDes: the designation of  the owner | 
|  | 1043 | * @ownerItem: the owner as a schema object | 
|  | 1044 | * @ownerElem: the owner as an element node | 
|  | 1045 | * @name: the name of the attribute holding the QName | 
|  | 1046 | * @refName: the referenced local name | 
|  | 1047 | * @refURI: the referenced namespace URI | 
|  | 1048 | * @message: optional message | 
|  | 1049 | * | 
|  | 1050 | * Used to report QName attribute values that failed to resolve | 
|  | 1051 | * to schema components. | 
|  | 1052 | */ | 
|  | 1053 | static void | 
|  | 1054 | xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt, | 
|  | 1055 | xmlParserErrors error, | 
|  | 1056 | xmlChar **ownerDes, | 
|  | 1057 | xmlSchemaTypePtr ownerItem, | 
|  | 1058 | xmlNodePtr ownerElem, | 
|  | 1059 | const char *name, | 
|  | 1060 | const xmlChar *refName, | 
|  | 1061 | const xmlChar *refURI, | 
|  | 1062 | xmlSchemaTypeType refType, | 
|  | 1063 | const char *refTypeStr) | 
|  | 1064 | { | 
|  | 1065 | xmlChar *des = NULL, *strA = NULL; | 
|  | 1066 |  | 
|  | 1067 | if (ownerDes == NULL) | 
|  | 1068 | xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem, 1); | 
|  | 1069 | else if (*ownerDes == NULL) { | 
|  | 1070 | xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, ownerElem, 1); | 
|  | 1071 | des = *ownerDes; | 
|  | 1072 | } else | 
|  | 1073 | des = *ownerDes; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1074 | if (refTypeStr == NULL) | 
|  | 1075 | refTypeStr = xmlSchemaCompTypeToString(refType); | 
|  | 1076 | xmlSchemaPErrExt(ctxt, ownerElem, error, | 
|  | 1077 | NULL, NULL, NULL, | 
|  | 1078 | "%s, attribute '%s': The QName value %s does not resolve to a(n) " | 
|  | 1079 | "%s.\n", BAD_CAST des, BAD_CAST name, | 
|  | 1080 | xmlSchemaFormatNsUriLocal(&strA, refURI, refName), | 
|  | 1081 | BAD_CAST refTypeStr, NULL); | 
|  | 1082 | if (ownerDes == NULL) | 
|  | 1083 | FREE_AND_NULL(des) | 
|  | 1084 | FREE_AND_NULL(strA) | 
|  | 1085 | } | 
|  | 1086 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1087 | /** | 
|  | 1088 | * xmlSchemaPCustomAttrErr: | 
|  | 1089 | * @ctxt: the schema parser context | 
|  | 1090 | * @error: the error code | 
|  | 1091 | * @ownerDes: the designation of the owner | 
|  | 1092 | * @ownerItem: the owner as a schema object | 
|  | 1093 | * @attr: the illegal attribute node | 
|  | 1094 | * | 
|  | 1095 | * Reports an illegal attribute during the parse. | 
|  | 1096 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1097 | static void | 
|  | 1098 | xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1099 | xmlParserErrors error, | 
|  | 1100 | xmlChar **ownerDes, | 
|  | 1101 | xmlSchemaTypePtr ownerItem, | 
|  | 1102 | xmlAttrPtr attr, | 
|  | 1103 | const char *msg) | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1104 | { | 
|  | 1105 | xmlChar *des = NULL; | 
|  | 1106 |  | 
|  | 1107 | if (ownerDes == NULL) | 
|  | 1108 | xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent, 1); | 
|  | 1109 | else if (*ownerDes == NULL) { | 
|  | 1110 | xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent, 1); | 
|  | 1111 | des = *ownerDes; | 
|  | 1112 | } else | 
|  | 1113 | des = *ownerDes; | 
|  | 1114 | xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, | 
|  | 1115 | "%s, attribute '%s': %s.\n", | 
|  | 1116 | BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL); | 
|  | 1117 | if (ownerDes == NULL) | 
|  | 1118 | FREE_AND_NULL(des); | 
|  | 1119 | } | 
|  | 1120 |  | 
|  | 1121 | /** | 
|  | 1122 | * xmlSchemaPIllegalAttrErr: | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1123 | * @ctxt: the schema parser context | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1124 | * @error: the error code | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1125 | * @ownerDes: the designation of the attribute's owner | 
|  | 1126 | * @ownerItem: the attribute's owner item | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1127 | * @attr: the illegal attribute node | 
|  | 1128 | * | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1129 | * Reports an illegal attribute during the parse. | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1130 | */ | 
|  | 1131 | static void | 
|  | 1132 | xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt, | 
|  | 1133 | xmlParserErrors error, | 
|  | 1134 | xmlChar **ownerDes, | 
|  | 1135 | xmlSchemaTypePtr ownerItem, | 
|  | 1136 | xmlAttrPtr attr) | 
|  | 1137 | { | 
|  | 1138 | xmlChar *des = NULL, *strA = NULL; | 
|  | 1139 |  | 
|  | 1140 | if (ownerDes == NULL) | 
|  | 1141 | xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent, 1); | 
|  | 1142 | else if (*ownerDes == NULL) { | 
|  | 1143 | xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent, 1); | 
|  | 1144 | des = *ownerDes; | 
|  | 1145 | } else | 
|  | 1146 | des = *ownerDes; | 
|  | 1147 | xmlSchemaPErr(ctxt, (xmlNodePtr) attr, error, | 
|  | 1148 | "%s: The attribute '%s' is not allowed.\n", BAD_CAST des, | 
|  | 1149 | xmlSchemaFormatNsPrefixLocal(&strA, attr->ns, attr->name)); | 
|  | 1150 | if (ownerDes == NULL) | 
|  | 1151 | FREE_AND_NULL(des); | 
|  | 1152 | FREE_AND_NULL(strA); | 
|  | 1153 | } | 
|  | 1154 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1155 | /** | 
|  | 1156 | * xmlSchemaPAquireDes: | 
|  | 1157 | * @des: the first designation | 
|  | 1158 | * @itemDes: the second designation | 
|  | 1159 | * @item: the schema item | 
|  | 1160 | * @itemElem: the node of the schema item | 
|  | 1161 | * | 
|  | 1162 | * Creates a designation for an item. | 
|  | 1163 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1164 | static void | 
|  | 1165 | xmlSchemaPAquireDes(xmlChar **des, | 
|  | 1166 | xmlChar **itemDes, | 
|  | 1167 | xmlSchemaTypePtr item, | 
|  | 1168 | xmlNodePtr itemElem) | 
|  | 1169 | { | 
|  | 1170 | if (itemDes == NULL) | 
|  | 1171 | xmlSchemaFormatItemForReport(des, NULL, item, itemElem, 1); | 
|  | 1172 | else if (*itemDes == NULL) { | 
|  | 1173 | xmlSchemaFormatItemForReport(itemDes, NULL, item, itemElem, 1); | 
|  | 1174 | *des = *itemDes; | 
|  | 1175 | } else | 
|  | 1176 | *des = *itemDes; | 
|  | 1177 | } | 
|  | 1178 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1179 | /** | 
|  | 1180 | * xmlSchemaPCustomErr: | 
|  | 1181 | * @ctxt: the schema parser context | 
|  | 1182 | * @error: the error code | 
|  | 1183 | * @itemDes: the designation of the schema item | 
|  | 1184 | * @item: the schema item | 
|  | 1185 | * @itemElem: the node of the schema item | 
|  | 1186 | * @message: the error message | 
|  | 1187 | * @str1: an optional param for the error message | 
|  | 1188 | * @str2: an optional param for the error message | 
|  | 1189 | * @str3: an optional param for the error message | 
|  | 1190 | * | 
|  | 1191 | * Reports an error during parsing. | 
|  | 1192 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1193 | static void | 
|  | 1194 | xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt, | 
|  | 1195 | xmlParserErrors error, | 
|  | 1196 | xmlChar **itemDes, | 
|  | 1197 | xmlSchemaTypePtr item, | 
|  | 1198 | xmlNodePtr itemElem, | 
|  | 1199 | const char *message, | 
|  | 1200 | const xmlChar *str1, | 
|  | 1201 | const xmlChar *str2, | 
|  | 1202 | const xmlChar *str3) | 
|  | 1203 | { | 
|  | 1204 | xmlChar *des = NULL, *msg = NULL; | 
|  | 1205 |  | 
|  | 1206 | xmlSchemaPAquireDes(&des, itemDes, item, itemElem); | 
|  | 1207 | msg = xmlStrdup(BAD_CAST "%s: "); | 
|  | 1208 | msg = xmlStrcat(msg, (const xmlChar *) message); | 
|  | 1209 | msg = xmlStrcat(msg, BAD_CAST ".\n"); | 
|  | 1210 | if ((itemElem == NULL) && (item != NULL)) | 
|  | 1211 | itemElem = item->node; | 
|  | 1212 | xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL, | 
|  | 1213 | (const char *) msg, BAD_CAST des, str1, str2, str3, NULL); | 
|  | 1214 | if (itemDes == NULL) | 
|  | 1215 | FREE_AND_NULL(des); | 
|  | 1216 | FREE_AND_NULL(msg); | 
|  | 1217 | } | 
|  | 1218 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1219 | /** | 
|  | 1220 | * xmlSchemaPCustomErr: | 
|  | 1221 | * @ctxt: the schema parser context | 
|  | 1222 | * @error: the error code | 
|  | 1223 | * @itemDes: the designation of the schema item | 
|  | 1224 | * @item: the schema item | 
|  | 1225 | * @itemElem: the node of the schema item | 
|  | 1226 | * @message: the error message | 
|  | 1227 | * @str1: the optional param for the error message | 
|  | 1228 | * | 
|  | 1229 | * Reports an error during parsing. | 
|  | 1230 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1231 | static void | 
|  | 1232 | xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt, | 
|  | 1233 | xmlParserErrors error, | 
|  | 1234 | xmlChar **itemDes, | 
|  | 1235 | xmlSchemaTypePtr item, | 
|  | 1236 | xmlNodePtr itemElem, | 
|  | 1237 | const char *message, | 
|  | 1238 | const xmlChar *str1) | 
|  | 1239 | { | 
|  | 1240 | xmlSchemaPCustomErrExt(ctxt, error, itemDes, item, itemElem, message, | 
|  | 1241 | str1, NULL, NULL); | 
|  | 1242 | } | 
|  | 1243 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1244 | /** | 
|  | 1245 | * xmlSchemaPAttrUseErr: | 
|  | 1246 | * @ctxt: the schema parser context | 
|  | 1247 | * @error: the error code | 
|  | 1248 | * @itemDes: the designation of the schema type | 
|  | 1249 | * @item: the schema type | 
|  | 1250 | * @itemElem: the node of the schema type | 
|  | 1251 | * @attr: the invalid schema attribute | 
|  | 1252 | * @message: the error message | 
|  | 1253 | * @str1: the optional param for the error message | 
|  | 1254 | * | 
|  | 1255 | * Reports an attribute use error during parsing. | 
|  | 1256 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1257 | static void | 
|  | 1258 | xmlSchemaPAttrUseErr(xmlSchemaParserCtxtPtr ctxt, | 
|  | 1259 | xmlParserErrors error, | 
|  | 1260 | xmlChar **itemDes, | 
|  | 1261 | xmlSchemaTypePtr item, | 
|  | 1262 | xmlNodePtr itemElem, | 
|  | 1263 | const xmlSchemaAttributePtr attr, | 
|  | 1264 | const char *message, | 
|  | 1265 | const xmlChar *str1) | 
|  | 1266 | { | 
|  | 1267 | xmlChar *des = NULL, *strA = NULL, *msg = NULL; | 
|  | 1268 |  | 
|  | 1269 | xmlSchemaPAquireDes(&des, itemDes, item, itemElem); | 
|  | 1270 | xmlSchemaFormatNsUriLocal(&strA, xmlSchemaGetAttrTargetNsURI(attr), | 
|  | 1271 | xmlSchemaGetAttrName(attr)); | 
|  | 1272 | msg = xmlStrdup(BAD_CAST "%s, attr. use %s: "); | 
|  | 1273 | msg = xmlStrcat(msg, (const xmlChar *) message); | 
|  | 1274 | msg = xmlStrcat(msg, BAD_CAST ".\n"); | 
|  | 1275 | if ((itemElem == NULL) && (item != NULL)) | 
|  | 1276 | itemElem = item->node; | 
|  | 1277 | xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL, | 
|  | 1278 | (const char *) msg, BAD_CAST des, BAD_CAST strA, str1, NULL, NULL); | 
|  | 1279 | if (itemDes == NULL) | 
|  | 1280 | FREE_AND_NULL(des); | 
|  | 1281 | FREE_AND_NULL(strA); | 
|  | 1282 | xmlFree(msg); | 
|  | 1283 | } | 
|  | 1284 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1285 | /** | 
|  | 1286 | * xmlSchemaPIllegalFacetAtomicErr: | 
|  | 1287 | * @ctxt: the schema parser context | 
|  | 1288 | * @error: the error code | 
|  | 1289 | * @itemDes: the designation of the type | 
|  | 1290 | * @item: the schema type | 
|  | 1291 | * @baseItem: the base type of type | 
|  | 1292 | * @facet: the illegal facet | 
|  | 1293 | * | 
|  | 1294 | * Reports an illegal facet for atomic simple types. | 
|  | 1295 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1296 | static void | 
|  | 1297 | xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt, | 
|  | 1298 | xmlParserErrors error, | 
|  | 1299 | xmlChar **itemDes, | 
|  | 1300 | xmlSchemaTypePtr item, | 
|  | 1301 | xmlSchemaTypePtr baseItem, | 
|  | 1302 | xmlSchemaFacetPtr facet) | 
|  | 1303 | { | 
|  | 1304 | xmlChar *des = NULL, *strT = NULL; | 
|  | 1305 |  | 
|  | 1306 | xmlSchemaPAquireDes(&des, itemDes, item, item->node); | 
|  | 1307 | xmlSchemaPErrExt(ctxt, item->node, error, NULL, NULL, NULL, | 
|  | 1308 | "%s: The facet '%s' is not allowed on types derived from the " | 
|  | 1309 | "type %s.\n", | 
|  | 1310 | BAD_CAST des, BAD_CAST xmlSchemaFacetTypeToString(facet->type), | 
|  | 1311 | xmlSchemaFormatItemForReport(&strT, NULL, baseItem, NULL, 1), | 
|  | 1312 | NULL, NULL); | 
|  | 1313 | if (itemDes == NULL) | 
|  | 1314 | FREE_AND_NULL(des); | 
|  | 1315 | FREE_AND_NULL(strT); | 
|  | 1316 | } | 
|  | 1317 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1318 | /** | 
|  | 1319 | * xmlSchemaPIllegalFacetListUnionErr: | 
|  | 1320 | * @ctxt: the schema parser context | 
|  | 1321 | * @error: the error code | 
|  | 1322 | * @itemDes: the designation of the schema item involved | 
|  | 1323 | * @item: the schema item involved | 
|  | 1324 | * @facet: the illegal facet | 
|  | 1325 | * | 
|  | 1326 | * Reports an illegal facet for <list> and <union>. | 
|  | 1327 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1328 | static void | 
|  | 1329 | xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt, | 
|  | 1330 | xmlParserErrors error, | 
|  | 1331 | xmlChar **itemDes, | 
|  | 1332 | xmlSchemaTypePtr item, | 
|  | 1333 | xmlSchemaFacetPtr facet) | 
|  | 1334 | { | 
|  | 1335 | xmlChar *des = NULL, *strT = NULL; | 
|  | 1336 |  | 
|  | 1337 | xmlSchemaPAquireDes(&des, itemDes, item, item->node); | 
|  | 1338 | xmlSchemaPErr(ctxt, item->node, error, | 
|  | 1339 | "%s: The facet '%s' is not allowed.\n", | 
|  | 1340 | BAD_CAST des, BAD_CAST xmlSchemaFacetTypeToString(facet->type)); | 
|  | 1341 | if (itemDes == NULL) | 
|  | 1342 | FREE_AND_NULL(des); | 
|  | 1343 | FREE_AND_NULL(strT); | 
|  | 1344 | } | 
|  | 1345 |  | 
|  | 1346 | /** | 
|  | 1347 | * xmlSchemaPMutualExclAttrErr: | 
|  | 1348 | * @ctxt: the schema validation context | 
|  | 1349 | * @error: the error code | 
|  | 1350 | * @elemDes: the designation of the parent element node | 
|  | 1351 | * @attr: the bad attribute node | 
|  | 1352 | * @type: the corresponding type of the attribute node | 
|  | 1353 | * | 
|  | 1354 | * Reports an illegal attribute. | 
|  | 1355 | */ | 
|  | 1356 | static void | 
|  | 1357 | xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt, | 
|  | 1358 | xmlParserErrors error, | 
|  | 1359 | xmlChar **ownerDes, | 
|  | 1360 | xmlSchemaTypePtr ownerItem, | 
|  | 1361 | xmlAttrPtr attr, | 
|  | 1362 | const char *name1, | 
|  | 1363 | const char *name2) | 
|  | 1364 | { | 
|  | 1365 | xmlChar *des = NULL; | 
|  | 1366 |  | 
|  | 1367 | if (ownerDes == NULL) | 
|  | 1368 | xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent, 1); | 
|  | 1369 | else if (*ownerDes == NULL) { | 
|  | 1370 | xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent, 1); | 
|  | 1371 | des = *ownerDes; | 
|  | 1372 | } else | 
|  | 1373 | des = *ownerDes; | 
|  | 1374 | xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, | 
|  | 1375 | "%s: The attributes '%s' and '%s' are mutually exclusive.\n", | 
|  | 1376 | BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL); | 
|  | 1377 | if (ownerDes == NULL) | 
|  | 1378 | FREE_AND_NULL(des) | 
|  | 1379 | } | 
|  | 1380 |  | 
|  | 1381 | /** | 
|  | 1382 | * xmlSchemaPSimpleTypeErr: | 
|  | 1383 | * @ctxt:  the schema validation context | 
|  | 1384 | * @error: the error code | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1385 | * @type: the type specifier | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1386 | * @ownerDes: the designation of the owner | 
|  | 1387 | * @ownerItem: the schema object if existent | 
|  | 1388 | * @node: the validated node | 
|  | 1389 | * @value: the validated value | 
|  | 1390 | * | 
|  | 1391 | * Reports a simple type validation error. | 
|  | 1392 | * TODO: Should this report the value of an element as well? | 
|  | 1393 | */ | 
|  | 1394 | static void | 
|  | 1395 | xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt, | 
|  | 1396 | xmlParserErrors error, | 
|  | 1397 | xmlChar **ownerDes, | 
|  | 1398 | xmlSchemaTypePtr ownerItem, | 
|  | 1399 | xmlNodePtr node, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1400 | xmlSchemaTypePtr type, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1401 | const char *typeDes, | 
|  | 1402 | const xmlChar *value, | 
|  | 1403 | const char *message, | 
|  | 1404 | const xmlChar *str1, | 
|  | 1405 | const xmlChar *str2) | 
|  | 1406 | { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1407 | xmlChar *des = NULL, *strA = NULL, *strT = NULL; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1408 |  | 
|  | 1409 | if (ownerDes == NULL) | 
|  | 1410 | xmlSchemaPRequestItemDes(&des, ownerItem, node); | 
|  | 1411 | else if (*ownerDes == NULL) { | 
|  | 1412 | xmlSchemaPRequestItemDes(ownerDes, ownerItem, node); | 
|  | 1413 | des = *ownerDes; | 
|  | 1414 | } else | 
|  | 1415 | des = *ownerDes; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1416 | if (type != NULL) | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1417 | typeDes = (const char *) xmlSchemaFormatItemForReport(&strT, NULL, type, NULL, 1); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1418 | if (message == NULL) { | 
|  | 1419 | /* | 
|  | 1420 | * Use default messages. | 
|  | 1421 | */ | 
|  | 1422 | if (node->type == XML_ATTRIBUTE_NODE) { | 
|  | 1423 | xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL, | 
|  | 1424 | "%s, attribute '%s' [%s]: The value '%s' is not " | 
|  | 1425 | "valid.\n", | 
|  | 1426 | BAD_CAST des, xmlSchemaFormatNsPrefixLocal(&strA, node->ns, | 
|  | 1427 | node->name), BAD_CAST typeDes, value, NULL); | 
|  | 1428 | } else { | 
|  | 1429 | xmlSchemaPErr(ctxt, node, error, | 
|  | 1430 | "%s [%s]: The character content is not valid.\n", | 
|  | 1431 | BAD_CAST des, BAD_CAST typeDes); | 
|  | 1432 | } | 
|  | 1433 | } else { | 
|  | 1434 | xmlChar *msg; | 
|  | 1435 |  | 
|  | 1436 | msg = xmlStrdup(BAD_CAST "%s"); | 
|  | 1437 | if (node->type == XML_ATTRIBUTE_NODE) | 
|  | 1438 | msg = xmlStrcat(msg, BAD_CAST ", attribute '%s'"); | 
|  | 1439 | msg = xmlStrcat(msg, BAD_CAST " [%s]: "); | 
|  | 1440 | msg = xmlStrcat(msg, (const xmlChar *) message); | 
|  | 1441 | msg = xmlStrcat(msg, BAD_CAST ".\n"); | 
|  | 1442 | if (node->type == XML_ATTRIBUTE_NODE) { | 
|  | 1443 | xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL, | 
|  | 1444 | (const char *) msg, | 
|  | 1445 | BAD_CAST des, xmlSchemaFormatNsPrefixLocal(&strA, | 
|  | 1446 | node->ns, node->name), BAD_CAST typeDes, str1, str2); | 
|  | 1447 | } else { | 
|  | 1448 | xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL, | 
|  | 1449 | (const char *) msg, | 
|  | 1450 | BAD_CAST des, BAD_CAST typeDes, str1, str2, NULL); | 
|  | 1451 | } | 
|  | 1452 | xmlFree(msg); | 
|  | 1453 | } | 
|  | 1454 | /* Cleanup. */ | 
|  | 1455 | FREE_AND_NULL(strA) | 
|  | 1456 | FREE_AND_NULL(strT) | 
|  | 1457 | if (ownerDes == NULL) | 
|  | 1458 | FREE_AND_NULL(des) | 
|  | 1459 | } | 
|  | 1460 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1461 | /** | 
|  | 1462 | * xmlSchemaPContentErr: | 
|  | 1463 | * @ctxt: the schema parser context | 
|  | 1464 | * @error: the error code | 
|  | 1465 | * @onwerDes: the designation of the holder of the content | 
|  | 1466 | * @ownerItem: the owner item of the holder of the content | 
|  | 1467 | * @ownerElem: the node of the holder of the content | 
|  | 1468 | * @child: the invalid child node | 
|  | 1469 | * @message: the optional error message | 
|  | 1470 | * @content: the optional string describing the correct content | 
|  | 1471 | * | 
|  | 1472 | * Reports an error concerning the content of a schema element. | 
|  | 1473 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1474 | static void | 
|  | 1475 | xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt, | 
|  | 1476 | xmlParserErrors error, | 
|  | 1477 | xmlChar **ownerDes, | 
|  | 1478 | xmlSchemaTypePtr ownerItem, | 
|  | 1479 | xmlNodePtr ownerElem, | 
|  | 1480 | xmlNodePtr child, | 
|  | 1481 | const char *message, | 
|  | 1482 | const char *content) | 
|  | 1483 | { | 
|  | 1484 | xmlChar *des = NULL; | 
|  | 1485 |  | 
|  | 1486 | if (ownerDes == NULL) | 
|  | 1487 | xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem, 1); | 
|  | 1488 | else if (*ownerDes == NULL) { | 
|  | 1489 | xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, ownerElem, 1); | 
|  | 1490 | des = *ownerDes; | 
|  | 1491 | } else | 
|  | 1492 | des = *ownerDes; | 
|  | 1493 | if (message != NULL) | 
|  | 1494 | xmlSchemaPErr2(ctxt, ownerElem, child, error, | 
|  | 1495 | "%s: %s.\n", | 
|  | 1496 | BAD_CAST des, BAD_CAST message); | 
|  | 1497 | else { | 
|  | 1498 | if (content != NULL) { | 
|  | 1499 | xmlSchemaPErr2(ctxt, ownerElem, child, error, | 
|  | 1500 | "%s: The content is not valid. Expected is %s.\n", | 
|  | 1501 | BAD_CAST des, BAD_CAST content); | 
|  | 1502 | } else { | 
|  | 1503 | xmlSchemaPErr2(ctxt, ownerElem, child, error, | 
|  | 1504 | "%s: The content is not valid.\n", | 
|  | 1505 | BAD_CAST des, NULL); | 
|  | 1506 | } | 
|  | 1507 | } | 
|  | 1508 | if (ownerDes == NULL) | 
|  | 1509 | FREE_AND_NULL(des) | 
|  | 1510 | } | 
|  | 1511 |  | 
|  | 1512 | /** | 
|  | 1513 | * xmlSchemaVIllegalAttrErr: | 
|  | 1514 | * @ctxt: the schema validation context | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 1515 | * @error: the error code | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1516 | * @attr: the illegal attribute node | 
|  | 1517 | * | 
|  | 1518 | * Reports an illegal attribute. | 
|  | 1519 | */ | 
|  | 1520 | static void | 
|  | 1521 | xmlSchemaVIllegalAttrErr(xmlSchemaValidCtxtPtr ctxt, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 1522 | xmlParserErrors error, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1523 | xmlAttrPtr attr) | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1524 | { | 
|  | 1525 | xmlChar *strE = NULL, *strA = NULL; | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 1526 |  | 
|  | 1527 | xmlSchemaVErr(ctxt, (xmlNodePtr) attr, | 
|  | 1528 | error, | 
|  | 1529 | /* XML_SCHEMAS_ERR_ATTRUNKNOWN, */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1530 | "%s: The attribute '%s' is not allowed.\n", | 
|  | 1531 | xmlSchemaFormatItemForReport(&strE, NULL, NULL, attr->parent, 0), | 
|  | 1532 | xmlSchemaFormatNsPrefixLocal(&strA, attr->ns, attr->name)); | 
|  | 1533 | FREE_AND_NULL(strE) | 
|  | 1534 | FREE_AND_NULL(strA) | 
|  | 1535 | } | 
|  | 1536 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1537 | /** | 
|  | 1538 | * xmlSchemaVCustomErr: | 
|  | 1539 | * @ctxt: the schema validation context | 
|  | 1540 | * @error: the error code | 
|  | 1541 | * @node: the validated node | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 1542 | * @type: the schema type of the validated node | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1543 | * @message: the error message | 
|  | 1544 | * @str1: the optional param for the message | 
|  | 1545 | * | 
|  | 1546 | * Reports a validation error. | 
|  | 1547 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1548 | static void | 
|  | 1549 | xmlSchemaVCustomErr(xmlSchemaValidCtxtPtr ctxt, | 
|  | 1550 | xmlParserErrors error, | 
|  | 1551 | xmlNodePtr node, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 1552 | xmlSchemaTypePtr type, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1553 | const char *message, | 
|  | 1554 | const xmlChar *str1) | 
|  | 1555 | { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 1556 | xmlChar *msg = NULL, *str = NULL; | 
|  | 1557 |  | 
|  | 1558 | if (node == NULL) { | 
|  | 1559 | xmlSchemaVErr(ctxt, NULL, | 
|  | 1560 | XML_SCHEMAV_INTERNAL, | 
|  | 1561 | "Internal error: xmlSchemaVCustomErr, no node " | 
|  | 1562 | "given.\n", NULL, NULL); | 
|  | 1563 | return; | 
|  | 1564 | } | 
|  | 1565 | /* TODO: Are the HTML and DOCB doc nodes expected here? */ | 
|  | 1566 | if (node->type != XML_DOCUMENT_NODE) { | 
|  | 1567 | xmlSchemaFormatItemForReport(&msg, NULL, NULL, node, 0); | 
|  | 1568 | if (type != NULL) { | 
|  | 1569 | msg = xmlStrcat(msg, BAD_CAST " ["); | 
|  | 1570 | msg = xmlStrcat(msg, xmlSchemaFormatItemForReport(&str, NULL, type, NULL, 0)); | 
|  | 1571 | msg = xmlStrcat(msg, BAD_CAST "]"); | 
|  | 1572 | } | 
|  | 1573 | msg = xmlStrcat(msg, BAD_CAST ": "); | 
|  | 1574 | } else | 
|  | 1575 | msg = xmlStrdup((const xmlChar *) ""); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1576 | msg = xmlStrcat(msg, (const xmlChar *) message); | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 1577 | msg = xmlStrcat(msg, BAD_CAST ".\n"); | 
|  | 1578 | xmlSchemaVErr(ctxt, node, error, (const char *) msg, str1, NULL); | 
|  | 1579 | FREE_AND_NULL(msg) | 
|  | 1580 | FREE_AND_NULL(str) | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1581 | } | 
|  | 1582 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1583 | /** | 
|  | 1584 | * xmlSchemaWildcardPCToString: | 
|  | 1585 | * @pc: the type of processContents | 
|  | 1586 | * | 
|  | 1587 | * Returns a string representation of the type of | 
|  | 1588 | * processContents. | 
|  | 1589 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1590 | static const char * | 
|  | 1591 | xmlSchemaWildcardPCToString(int pc) | 
|  | 1592 | { | 
|  | 1593 | switch (pc) { | 
|  | 1594 | case XML_SCHEMAS_ANY_SKIP: | 
|  | 1595 | return ("skip"); | 
|  | 1596 | case XML_SCHEMAS_ANY_LAX: | 
|  | 1597 | return ("lax"); | 
|  | 1598 | case XML_SCHEMAS_ANY_STRICT: | 
|  | 1599 | return ("strict"); | 
|  | 1600 | default: | 
|  | 1601 | return ("invalid process contents"); | 
|  | 1602 | } | 
|  | 1603 | } | 
|  | 1604 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1605 | /** | 
|  | 1606 | * xmlSchemaVWildcardErr: | 
|  | 1607 | * @ctxt: the schema validation context | 
|  | 1608 | * @error: the error code | 
|  | 1609 | * @node: the validated node | 
|  | 1610 | * @wild: the wildcard used | 
|  | 1611 | * @message: the error message | 
|  | 1612 | * | 
|  | 1613 | * Reports an validation-by-wildcard error. | 
|  | 1614 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1615 | static void | 
|  | 1616 | xmlSchemaVWildcardErr(xmlSchemaValidCtxtPtr ctxt, | 
|  | 1617 | xmlParserErrors error, | 
|  | 1618 | xmlNodePtr node, | 
|  | 1619 | xmlSchemaWildcardPtr wild, | 
|  | 1620 | const char *message) | 
|  | 1621 | { | 
|  | 1622 | xmlChar *des = NULL, *msg = NULL; | 
|  | 1623 |  | 
|  | 1624 | xmlSchemaFormatItemForReport(&des, NULL, NULL, node, 0); | 
|  | 1625 | msg = xmlStrdup(BAD_CAST "%s, ["); | 
|  | 1626 | msg = xmlStrcat(msg, BAD_CAST xmlSchemaWildcardPCToString(wild->processContents)); | 
|  | 1627 | msg = xmlStrcat(msg, BAD_CAST " WC]: "); | 
|  | 1628 | msg = xmlStrcat(msg, (const xmlChar *) message); | 
|  | 1629 | msg = xmlStrcat(msg, BAD_CAST ".\n"); | 
|  | 1630 | xmlSchemaVErr(ctxt, node, error, (const char *) msg, BAD_CAST des, NULL); | 
|  | 1631 | FREE_AND_NULL(des); | 
|  | 1632 | FREE_AND_NULL(msg); | 
|  | 1633 | } | 
|  | 1634 |  | 
|  | 1635 | /** | 
|  | 1636 | * xmlSchemaVMissingAttrErr: | 
|  | 1637 | * @ctxt: the schema validation context | 
|  | 1638 | * @node: the parent element node of the missing attribute node | 
|  | 1639 | * @type: the corresponding type of the attribute node | 
|  | 1640 | * | 
|  | 1641 | * Reports an illegal attribute. | 
|  | 1642 | */ | 
|  | 1643 | static void | 
|  | 1644 | xmlSchemaVMissingAttrErr(xmlSchemaValidCtxtPtr ctxt, | 
|  | 1645 | xmlNodePtr elem, | 
|  | 1646 | xmlSchemaAttributePtr type) | 
|  | 1647 | { | 
|  | 1648 | const xmlChar *name, *uri; | 
|  | 1649 | xmlChar *strE = NULL, *strA = NULL; | 
|  | 1650 |  | 
|  | 1651 | if (type->ref != NULL) { | 
|  | 1652 | name = type->ref; | 
|  | 1653 | uri = type->refNs; | 
|  | 1654 | } else { | 
|  | 1655 | name = type->name; | 
|  | 1656 | uri = type->targetNamespace; | 
|  | 1657 | } | 
|  | 1658 | xmlSchemaVErr(ctxt, elem, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 1659 | XML_SCHEMAV_CVC_COMPLEX_TYPE_4, | 
|  | 1660 | /* XML_SCHEMAS_ERR_MISSING, */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1661 | "%s: The attribute %s is required but missing.\n", | 
|  | 1662 | xmlSchemaFormatItemForReport(&strE, NULL, NULL, elem, 0), | 
|  | 1663 | xmlSchemaFormatNsUriLocal(&strA, uri, name)); | 
|  | 1664 | FREE_AND_NULL(strE) | 
|  | 1665 | FREE_AND_NULL(strA) | 
|  | 1666 | } | 
|  | 1667 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1668 | /************************************************************************ | 
|  | 1669 | * 									* | 
|  | 1670 | * 			Allocation functions				* | 
|  | 1671 | * 									* | 
|  | 1672 | ************************************************************************/ | 
|  | 1673 |  | 
|  | 1674 | /** | 
|  | 1675 | * xmlSchemaNewSchema: | 
| William M. Brack | 0817191 | 2003-12-29 02:52:11 +0000 | [diff] [blame] | 1676 | * @ctxt:  a schema validation context | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1677 | * | 
|  | 1678 | * Allocate a new Schema structure. | 
|  | 1679 | * | 
|  | 1680 | * Returns the newly allocated structure or NULL in case or error | 
|  | 1681 | */ | 
|  | 1682 | static xmlSchemaPtr | 
|  | 1683 | xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt) | 
|  | 1684 | { | 
|  | 1685 | xmlSchemaPtr ret; | 
|  | 1686 |  | 
|  | 1687 | ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema)); | 
|  | 1688 | if (ret == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 1689 | xmlSchemaPErrMemory(ctxt, "allocating schema", NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1690 | return (NULL); | 
|  | 1691 | } | 
|  | 1692 | memset(ret, 0, sizeof(xmlSchema)); | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 1693 | ret->dict = ctxt->dict; | 
| Daniel Veillard | 500a1de | 2004-03-22 15:22:58 +0000 | [diff] [blame] | 1694 | xmlDictReference(ret->dict); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1695 |  | 
|  | 1696 | return (ret); | 
|  | 1697 | } | 
|  | 1698 |  | 
|  | 1699 | /** | 
|  | 1700 | * xmlSchemaNewFacet: | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1701 | * | 
|  | 1702 | * Allocate a new Facet structure. | 
|  | 1703 | * | 
|  | 1704 | * Returns the newly allocated structure or NULL in case or error | 
|  | 1705 | */ | 
| Daniel Veillard | 8bc6cf9 | 2003-02-27 17:42:22 +0000 | [diff] [blame] | 1706 | xmlSchemaFacetPtr | 
|  | 1707 | xmlSchemaNewFacet(void) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1708 | { | 
|  | 1709 | xmlSchemaFacetPtr ret; | 
|  | 1710 |  | 
|  | 1711 | ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet)); | 
|  | 1712 | if (ret == NULL) { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1713 | return (NULL); | 
|  | 1714 | } | 
|  | 1715 | memset(ret, 0, sizeof(xmlSchemaFacet)); | 
|  | 1716 |  | 
|  | 1717 | return (ret); | 
|  | 1718 | } | 
|  | 1719 |  | 
|  | 1720 | /** | 
|  | 1721 | * xmlSchemaNewAnnot: | 
| William M. Brack | 0817191 | 2003-12-29 02:52:11 +0000 | [diff] [blame] | 1722 | * @ctxt:  a schema validation context | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1723 | * @node:  a node | 
|  | 1724 | * | 
|  | 1725 | * Allocate a new annotation structure. | 
|  | 1726 | * | 
|  | 1727 | * Returns the newly allocated structure or NULL in case or error | 
|  | 1728 | */ | 
|  | 1729 | static xmlSchemaAnnotPtr | 
|  | 1730 | xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) | 
|  | 1731 | { | 
|  | 1732 | xmlSchemaAnnotPtr ret; | 
|  | 1733 |  | 
|  | 1734 | ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot)); | 
|  | 1735 | if (ret == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 1736 | xmlSchemaPErrMemory(ctxt, "allocating annotation", node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1737 | return (NULL); | 
|  | 1738 | } | 
|  | 1739 | memset(ret, 0, sizeof(xmlSchemaAnnot)); | 
|  | 1740 | ret->content = node; | 
|  | 1741 | return (ret); | 
|  | 1742 | } | 
|  | 1743 |  | 
|  | 1744 | /** | 
| Daniel Veillard | fdc9156 | 2002-07-01 21:52:03 +0000 | [diff] [blame] | 1745 | * xmlSchemaFreeAnnot: | 
|  | 1746 | * @annot:  a schema type structure | 
|  | 1747 | * | 
|  | 1748 | * Deallocate a annotation structure | 
|  | 1749 | */ | 
|  | 1750 | static void | 
|  | 1751 | xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot) | 
|  | 1752 | { | 
|  | 1753 | if (annot == NULL) | 
|  | 1754 | return; | 
|  | 1755 | xmlFree(annot); | 
|  | 1756 | } | 
|  | 1757 |  | 
|  | 1758 | /** | 
| Daniel Veillard | 1d91386 | 2003-11-21 00:28:39 +0000 | [diff] [blame] | 1759 | * xmlSchemaFreeImport: | 
|  | 1760 | * @import:  a schema import structure | 
|  | 1761 | * | 
|  | 1762 | * Deallocate an import structure | 
|  | 1763 | */ | 
|  | 1764 | static void | 
|  | 1765 | xmlSchemaFreeImport(xmlSchemaImportPtr import) | 
|  | 1766 | { | 
|  | 1767 | if (import == NULL) | 
|  | 1768 | return; | 
|  | 1769 |  | 
|  | 1770 | xmlSchemaFree(import->schema); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 1771 | xmlFreeDoc(import->doc); | 
| Daniel Veillard | 1d91386 | 2003-11-21 00:28:39 +0000 | [diff] [blame] | 1772 | xmlFree(import); | 
|  | 1773 | } | 
|  | 1774 |  | 
|  | 1775 | /** | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 1776 | * xmlSchemaFreeInclude: | 
|  | 1777 | * @include:  a schema include structure | 
|  | 1778 | * | 
|  | 1779 | * Deallocate an include structure | 
|  | 1780 | */ | 
|  | 1781 | static void | 
|  | 1782 | xmlSchemaFreeInclude(xmlSchemaIncludePtr include) | 
|  | 1783 | { | 
|  | 1784 | if (include == NULL) | 
|  | 1785 | return; | 
|  | 1786 |  | 
|  | 1787 | xmlFreeDoc(include->doc); | 
|  | 1788 | xmlFree(include); | 
|  | 1789 | } | 
|  | 1790 |  | 
|  | 1791 | /** | 
|  | 1792 | * xmlSchemaFreeIncludeList: | 
|  | 1793 | * @includes:  a schema include list | 
|  | 1794 | * | 
|  | 1795 | * Deallocate an include structure | 
|  | 1796 | */ | 
|  | 1797 | static void | 
|  | 1798 | xmlSchemaFreeIncludeList(xmlSchemaIncludePtr includes) | 
|  | 1799 | { | 
|  | 1800 | xmlSchemaIncludePtr next; | 
|  | 1801 |  | 
|  | 1802 | while (includes != NULL) { | 
|  | 1803 | next = includes->next; | 
|  | 1804 | xmlSchemaFreeInclude(includes); | 
|  | 1805 | includes = next; | 
|  | 1806 | } | 
|  | 1807 | } | 
|  | 1808 |  | 
|  | 1809 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1810 | * xmlSchemaFreeNotation: | 
|  | 1811 | * @schema:  a schema notation structure | 
|  | 1812 | * | 
|  | 1813 | * Deallocate a Schema Notation structure. | 
|  | 1814 | */ | 
|  | 1815 | static void | 
|  | 1816 | xmlSchemaFreeNotation(xmlSchemaNotationPtr nota) | 
|  | 1817 | { | 
|  | 1818 | if (nota == NULL) | 
|  | 1819 | return; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1820 | xmlFree(nota); | 
|  | 1821 | } | 
|  | 1822 |  | 
|  | 1823 | /** | 
|  | 1824 | * xmlSchemaFreeAttribute: | 
|  | 1825 | * @schema:  a schema attribute structure | 
|  | 1826 | * | 
|  | 1827 | * Deallocate a Schema Attribute structure. | 
|  | 1828 | */ | 
|  | 1829 | static void | 
|  | 1830 | xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr) | 
|  | 1831 | { | 
|  | 1832 | if (attr == NULL) | 
|  | 1833 | return; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1834 | if (attr->annot != NULL) | 
|  | 1835 | xmlSchemaFreeAnnot(attr->annot); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1836 | xmlFree(attr); | 
|  | 1837 | } | 
|  | 1838 |  | 
|  | 1839 | /** | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 1840 | * xmlSchemaFreeWildcardNsSet: | 
|  | 1841 | * set:  a schema wildcard namespace | 
|  | 1842 | * | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 1843 | * Deallocates a list of wildcard constraint structures. | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 1844 | */ | 
|  | 1845 | static void | 
|  | 1846 | xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set) | 
|  | 1847 | { | 
|  | 1848 | xmlSchemaWildcardNsPtr next; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 1849 |  | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 1850 | while (set != NULL) { | 
|  | 1851 | next = set->next; | 
|  | 1852 | xmlFree(set); | 
|  | 1853 | set = next; | 
|  | 1854 | } | 
|  | 1855 | } | 
|  | 1856 |  | 
|  | 1857 | /** | 
|  | 1858 | * xmlSchemaFreeWildcard: | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 1859 | * @wildcard:  a wildcard structure | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 1860 | * | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 1861 | * Deallocates a wildcard structure. | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 1862 | */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 1863 | void | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 1864 | xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard) | 
|  | 1865 | { | 
|  | 1866 | if (wildcard == NULL) | 
|  | 1867 | return; | 
|  | 1868 | if (wildcard->annot != NULL) | 
|  | 1869 | xmlSchemaFreeAnnot(wildcard->annot); | 
|  | 1870 | if (wildcard->nsSet != NULL) | 
|  | 1871 | xmlSchemaFreeWildcardNsSet(wildcard->nsSet); | 
|  | 1872 | if (wildcard->negNsSet != NULL) | 
|  | 1873 | xmlFree(wildcard->negNsSet); | 
|  | 1874 | xmlFree(wildcard); | 
|  | 1875 | } | 
|  | 1876 |  | 
|  | 1877 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1878 | * xmlSchemaFreeAttributeGroup: | 
|  | 1879 | * @schema:  a schema attribute group structure | 
|  | 1880 | * | 
|  | 1881 | * Deallocate a Schema Attribute Group structure. | 
|  | 1882 | */ | 
|  | 1883 | static void | 
|  | 1884 | xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attr) | 
|  | 1885 | { | 
|  | 1886 | if (attr == NULL) | 
|  | 1887 | return; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 1888 | if (attr->annot != NULL) | 
|  | 1889 | xmlSchemaFreeAnnot(attr->annot); | 
|  | 1890 | if ((attr->flags & XML_SCHEMAS_ATTRGROUP_GLOBAL) && | 
|  | 1891 | (attr->attributeWildcard != NULL)) | 
|  | 1892 | xmlSchemaFreeWildcard(attr->attributeWildcard); | 
|  | 1893 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1894 | xmlFree(attr); | 
|  | 1895 | } | 
|  | 1896 |  | 
|  | 1897 | /** | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 1898 | * xmlSchemaFreeAttributeUseList: | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 1899 | * @attrUse:  an attribute link | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 1900 | * | 
|  | 1901 | * Deallocate a list of schema attribute uses. | 
|  | 1902 | */ | 
|  | 1903 | static void | 
|  | 1904 | xmlSchemaFreeAttributeUseList(xmlSchemaAttributeLinkPtr attrUse) | 
|  | 1905 | { | 
|  | 1906 | xmlSchemaAttributeLinkPtr next; | 
|  | 1907 |  | 
|  | 1908 | while (attrUse != NULL) { | 
|  | 1909 | next = attrUse->next; | 
|  | 1910 | xmlFree(attrUse); | 
|  | 1911 | attrUse = next; | 
|  | 1912 | } | 
|  | 1913 | } | 
|  | 1914 |  | 
|  | 1915 | /** | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 1916 | * xmlSchemaFreeTypeLinkList: | 
|  | 1917 | * @alink: a type link | 
|  | 1918 | * | 
|  | 1919 | * Deallocate a list of types. | 
|  | 1920 | */ | 
|  | 1921 | static void | 
|  | 1922 | xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link) | 
|  | 1923 | { | 
|  | 1924 | xmlSchemaTypeLinkPtr next; | 
|  | 1925 |  | 
|  | 1926 | while (link != NULL) { | 
|  | 1927 | next = link->next; | 
|  | 1928 | xmlFree(link); | 
|  | 1929 | link = next; | 
|  | 1930 | } | 
|  | 1931 | } | 
|  | 1932 |  | 
|  | 1933 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1934 | * xmlSchemaFreeElement: | 
|  | 1935 | * @schema:  a schema element structure | 
|  | 1936 | * | 
|  | 1937 | * Deallocate a Schema Element structure. | 
|  | 1938 | */ | 
|  | 1939 | static void | 
|  | 1940 | xmlSchemaFreeElement(xmlSchemaElementPtr elem) | 
|  | 1941 | { | 
|  | 1942 | if (elem == NULL) | 
|  | 1943 | return; | 
| Daniel Veillard | 3237023 | 2002-10-16 14:08:14 +0000 | [diff] [blame] | 1944 | if (elem->annot != NULL) | 
|  | 1945 | xmlSchemaFreeAnnot(elem->annot); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1946 | if (elem->contModel != NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 1947 | xmlRegFreeRegexp(elem->contModel); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1948 | xmlFree(elem); | 
|  | 1949 | } | 
|  | 1950 |  | 
|  | 1951 | /** | 
|  | 1952 | * xmlSchemaFreeFacet: | 
|  | 1953 | * @facet:  a schema facet structure | 
|  | 1954 | * | 
|  | 1955 | * Deallocate a Schema Facet structure. | 
|  | 1956 | */ | 
| Daniel Veillard | 8bc6cf9 | 2003-02-27 17:42:22 +0000 | [diff] [blame] | 1957 | void | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1958 | xmlSchemaFreeFacet(xmlSchemaFacetPtr facet) | 
|  | 1959 | { | 
|  | 1960 | if (facet == NULL) | 
|  | 1961 | return; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1962 | if (facet->val != NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 1963 | xmlSchemaFreeValue(facet->val); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1964 | if (facet->regexp != NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 1965 | xmlRegFreeRegexp(facet->regexp); | 
| Daniel Veillard | fdc9156 | 2002-07-01 21:52:03 +0000 | [diff] [blame] | 1966 | if (facet->annot != NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 1967 | xmlSchemaFreeAnnot(facet->annot); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1968 | xmlFree(facet); | 
|  | 1969 | } | 
|  | 1970 |  | 
|  | 1971 | /** | 
|  | 1972 | * xmlSchemaFreeType: | 
|  | 1973 | * @type:  a schema type structure | 
|  | 1974 | * | 
|  | 1975 | * Deallocate a Schema Type structure. | 
|  | 1976 | */ | 
|  | 1977 | void | 
|  | 1978 | xmlSchemaFreeType(xmlSchemaTypePtr type) | 
|  | 1979 | { | 
|  | 1980 | if (type == NULL) | 
|  | 1981 | return; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1982 | if (type->annot != NULL) | 
| Daniel Veillard | 3237023 | 2002-10-16 14:08:14 +0000 | [diff] [blame] | 1983 | xmlSchemaFreeAnnot(type->annot); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1984 | if (type->facets != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 1985 | xmlSchemaFacetPtr facet, next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1986 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 1987 | facet = type->facets; | 
|  | 1988 | while (facet != NULL) { | 
|  | 1989 | next = facet->next; | 
|  | 1990 | xmlSchemaFreeFacet(facet); | 
|  | 1991 | facet = next; | 
|  | 1992 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 1993 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 1994 | if (type->type != XML_SCHEMA_TYPE_BASIC) { | 
|  | 1995 | if (type->attributeUses != NULL) | 
|  | 1996 | xmlSchemaFreeAttributeUseList(type->attributeUses); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 1997 | /* TODO: There must be a way more simple than this. */ | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 1998 | if ((type->attributeWildcard != NULL) && | 
|  | 1999 | ((type->type != XML_SCHEMA_TYPE_COMPLEX) || | 
|  | 2000 | ((type->type == XML_SCHEMA_TYPE_COMPLEX) && | 
|  | 2001 | (type->flags & XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD)))) { | 
|  | 2002 | xmlSchemaFreeWildcard(type->attributeWildcard); | 
|  | 2003 | } | 
|  | 2004 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 2005 | if (type->memberTypes != NULL) | 
|  | 2006 | xmlSchemaFreeTypeLinkList(type->memberTypes); | 
|  | 2007 | if (type->facetSet != NULL) { | 
|  | 2008 | xmlSchemaFacetLinkPtr next, link; | 
|  | 2009 |  | 
|  | 2010 | link = type->facetSet; | 
|  | 2011 | do { | 
|  | 2012 | next = link->next; | 
|  | 2013 | xmlFree(link); | 
|  | 2014 | link = next; | 
|  | 2015 | } while (link != NULL); | 
| Daniel Veillard | 4e5d665 | 2004-06-29 21:01:12 +0000 | [diff] [blame] | 2016 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2017 | xmlFree(type); | 
|  | 2018 | } | 
|  | 2019 |  | 
|  | 2020 | /** | 
| Daniel Veillard | b0f397e | 2003-12-23 23:30:53 +0000 | [diff] [blame] | 2021 | * xmlSchemaFreeTypeList: | 
|  | 2022 | * @type:  a schema type structure | 
|  | 2023 | * | 
|  | 2024 | * Deallocate a Schema Type structure. | 
|  | 2025 | */ | 
|  | 2026 | static void | 
|  | 2027 | xmlSchemaFreeTypeList(xmlSchemaTypePtr type) | 
|  | 2028 | { | 
|  | 2029 | xmlSchemaTypePtr next; | 
|  | 2030 |  | 
|  | 2031 | while (type != NULL) { | 
|  | 2032 | next = type->redef; | 
|  | 2033 | xmlSchemaFreeType(type); | 
|  | 2034 | type = next; | 
|  | 2035 | } | 
|  | 2036 | } | 
|  | 2037 |  | 
|  | 2038 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2039 | * xmlSchemaFree: | 
|  | 2040 | * @schema:  a schema structure | 
|  | 2041 | * | 
|  | 2042 | * Deallocate a Schema structure. | 
|  | 2043 | */ | 
|  | 2044 | void | 
|  | 2045 | xmlSchemaFree(xmlSchemaPtr schema) | 
|  | 2046 | { | 
|  | 2047 | if (schema == NULL) | 
|  | 2048 | return; | 
|  | 2049 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2050 | if (schema->notaDecl != NULL) | 
|  | 2051 | xmlHashFree(schema->notaDecl, | 
|  | 2052 | (xmlHashDeallocator) xmlSchemaFreeNotation); | 
|  | 2053 | if (schema->attrDecl != NULL) | 
|  | 2054 | xmlHashFree(schema->attrDecl, | 
|  | 2055 | (xmlHashDeallocator) xmlSchemaFreeAttribute); | 
|  | 2056 | if (schema->attrgrpDecl != NULL) | 
|  | 2057 | xmlHashFree(schema->attrgrpDecl, | 
|  | 2058 | (xmlHashDeallocator) xmlSchemaFreeAttributeGroup); | 
|  | 2059 | if (schema->elemDecl != NULL) | 
|  | 2060 | xmlHashFree(schema->elemDecl, | 
|  | 2061 | (xmlHashDeallocator) xmlSchemaFreeElement); | 
|  | 2062 | if (schema->typeDecl != NULL) | 
|  | 2063 | xmlHashFree(schema->typeDecl, | 
| Daniel Veillard | b0f397e | 2003-12-23 23:30:53 +0000 | [diff] [blame] | 2064 | (xmlHashDeallocator) xmlSchemaFreeTypeList); | 
| Daniel Veillard | a84c0b3 | 2003-06-02 16:58:46 +0000 | [diff] [blame] | 2065 | if (schema->groupDecl != NULL) | 
|  | 2066 | xmlHashFree(schema->groupDecl, | 
|  | 2067 | (xmlHashDeallocator) xmlSchemaFreeType); | 
| Daniel Veillard | 1d91386 | 2003-11-21 00:28:39 +0000 | [diff] [blame] | 2068 | if (schema->schemasImports != NULL) | 
|  | 2069 | xmlHashFree(schema->schemasImports, | 
|  | 2070 | (xmlHashDeallocator) xmlSchemaFreeImport); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 2071 | if (schema->includes != NULL) { | 
|  | 2072 | xmlSchemaFreeIncludeList((xmlSchemaIncludePtr) schema->includes); | 
|  | 2073 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2074 | if (schema->annot != NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2075 | xmlSchemaFreeAnnot(schema->annot); | 
| Daniel Veillard | dda22c1 | 2004-01-24 08:31:30 +0000 | [diff] [blame] | 2076 | if (schema->doc != NULL && !schema->preserve) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2077 | xmlFreeDoc(schema->doc); | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2078 | xmlDictFree(schema->dict); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2079 |  | 
|  | 2080 | xmlFree(schema); | 
|  | 2081 | } | 
|  | 2082 |  | 
|  | 2083 | /************************************************************************ | 
|  | 2084 | * 									* | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2085 | * 			Debug functions					* | 
|  | 2086 | * 									* | 
|  | 2087 | ************************************************************************/ | 
|  | 2088 |  | 
| Daniel Veillard | a9cce9c | 2003-09-29 13:20:24 +0000 | [diff] [blame] | 2089 | #ifdef LIBXML_OUTPUT_ENABLED | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2090 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2091 | /** | 
|  | 2092 | * xmlSchemaElementDump: | 
|  | 2093 | * @elem:  an element | 
|  | 2094 | * @output:  the file output | 
|  | 2095 | * | 
|  | 2096 | * Dump the element | 
|  | 2097 | */ | 
|  | 2098 | static void | 
|  | 2099 | xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2100 | const xmlChar * name ATTRIBUTE_UNUSED, | 
|  | 2101 | const xmlChar * context ATTRIBUTE_UNUSED, | 
|  | 2102 | const xmlChar * namespace ATTRIBUTE_UNUSED) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2103 | { | 
|  | 2104 | if (elem == NULL) | 
|  | 2105 | return; | 
|  | 2106 |  | 
|  | 2107 | fprintf(output, "Element "); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2108 | if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL) | 
|  | 2109 | fprintf(output, "global "); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2110 | fprintf(output, ": %s ", elem->name); | 
|  | 2111 | if (namespace != NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2112 | fprintf(output, "namespace '%s' ", namespace); | 
|  | 2113 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2114 | if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2115 | fprintf(output, "nillable "); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2116 | if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2117 | fprintf(output, "default "); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2118 | if (elem->flags & XML_SCHEMAS_ELEM_FIXED) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2119 | fprintf(output, "fixed "); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2120 | if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2121 | fprintf(output, "abstract "); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2122 | if (elem->flags & XML_SCHEMAS_ELEM_REF) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2123 | fprintf(output, "ref '%s' ", elem->ref); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2124 | if (elem->id != NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2125 | fprintf(output, "id '%s' ", elem->id); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2126 | fprintf(output, "\n"); | 
|  | 2127 | if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2128 | fprintf(output, "  "); | 
|  | 2129 | if (elem->minOccurs != 1) | 
|  | 2130 | fprintf(output, "min: %d ", elem->minOccurs); | 
|  | 2131 | if (elem->maxOccurs >= UNBOUNDED) | 
|  | 2132 | fprintf(output, "max: unbounded\n"); | 
|  | 2133 | else if (elem->maxOccurs != 1) | 
|  | 2134 | fprintf(output, "max: %d\n", elem->maxOccurs); | 
|  | 2135 | else | 
|  | 2136 | fprintf(output, "\n"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2137 | } | 
|  | 2138 | if (elem->namedType != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2139 | fprintf(output, "  type: %s", elem->namedType); | 
|  | 2140 | if (elem->namedTypeNs != NULL) | 
|  | 2141 | fprintf(output, " ns %s\n", elem->namedTypeNs); | 
|  | 2142 | else | 
|  | 2143 | fprintf(output, "\n"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2144 | } | 
|  | 2145 | if (elem->substGroup != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2146 | fprintf(output, "  substitutionGroup: %s", elem->substGroup); | 
|  | 2147 | if (elem->substGroupNs != NULL) | 
|  | 2148 | fprintf(output, " ns %s\n", elem->substGroupNs); | 
|  | 2149 | else | 
|  | 2150 | fprintf(output, "\n"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2151 | } | 
|  | 2152 | if (elem->value != NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2153 | fprintf(output, "  default: %s", elem->value); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2154 | } | 
|  | 2155 |  | 
|  | 2156 | /** | 
|  | 2157 | * xmlSchemaAnnotDump: | 
|  | 2158 | * @output:  the file output | 
|  | 2159 | * @annot:  a annotation | 
|  | 2160 | * | 
|  | 2161 | * Dump the annotation | 
|  | 2162 | */ | 
|  | 2163 | static void | 
|  | 2164 | xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot) | 
|  | 2165 | { | 
|  | 2166 | xmlChar *content; | 
|  | 2167 |  | 
|  | 2168 | if (annot == NULL) | 
|  | 2169 | return; | 
|  | 2170 |  | 
|  | 2171 | content = xmlNodeGetContent(annot->content); | 
|  | 2172 | if (content != NULL) { | 
|  | 2173 | fprintf(output, "  Annot: %s\n", content); | 
|  | 2174 | xmlFree(content); | 
|  | 2175 | } else | 
|  | 2176 | fprintf(output, "  Annot: empty\n"); | 
|  | 2177 | } | 
|  | 2178 |  | 
|  | 2179 | /** | 
|  | 2180 | * xmlSchemaTypeDump: | 
|  | 2181 | * @output:  the file output | 
|  | 2182 | * @type:  a type structure | 
|  | 2183 | * | 
|  | 2184 | * Dump a SchemaType structure | 
|  | 2185 | */ | 
|  | 2186 | static void | 
|  | 2187 | xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output) | 
|  | 2188 | { | 
|  | 2189 | if (type == NULL) { | 
|  | 2190 | fprintf(output, "Type: NULL\n"); | 
|  | 2191 | return; | 
|  | 2192 | } | 
|  | 2193 | fprintf(output, "Type: "); | 
|  | 2194 | if (type->name != NULL) | 
|  | 2195 | fprintf(output, "%s, ", type->name); | 
|  | 2196 | else | 
|  | 2197 | fprintf(output, "no name"); | 
|  | 2198 | switch (type->type) { | 
|  | 2199 | case XML_SCHEMA_TYPE_BASIC: | 
|  | 2200 | fprintf(output, "basic "); | 
|  | 2201 | break; | 
|  | 2202 | case XML_SCHEMA_TYPE_SIMPLE: | 
|  | 2203 | fprintf(output, "simple "); | 
|  | 2204 | break; | 
|  | 2205 | case XML_SCHEMA_TYPE_COMPLEX: | 
|  | 2206 | fprintf(output, "complex "); | 
|  | 2207 | break; | 
|  | 2208 | case XML_SCHEMA_TYPE_SEQUENCE: | 
|  | 2209 | fprintf(output, "sequence "); | 
|  | 2210 | break; | 
|  | 2211 | case XML_SCHEMA_TYPE_CHOICE: | 
|  | 2212 | fprintf(output, "choice "); | 
|  | 2213 | break; | 
|  | 2214 | case XML_SCHEMA_TYPE_ALL: | 
|  | 2215 | fprintf(output, "all "); | 
|  | 2216 | break; | 
|  | 2217 | case XML_SCHEMA_TYPE_UR: | 
|  | 2218 | fprintf(output, "ur "); | 
|  | 2219 | break; | 
|  | 2220 | case XML_SCHEMA_TYPE_RESTRICTION: | 
|  | 2221 | fprintf(output, "restriction "); | 
|  | 2222 | break; | 
|  | 2223 | case XML_SCHEMA_TYPE_EXTENSION: | 
|  | 2224 | fprintf(output, "extension "); | 
|  | 2225 | break; | 
|  | 2226 | default: | 
|  | 2227 | fprintf(output, "unknowntype%d ", type->type); | 
|  | 2228 | break; | 
|  | 2229 | } | 
|  | 2230 | if (type->base != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2231 | fprintf(output, "base %s, ", type->base); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2232 | } | 
|  | 2233 | switch (type->contentType) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2234 | case XML_SCHEMA_CONTENT_UNKNOWN: | 
|  | 2235 | fprintf(output, "unknown "); | 
|  | 2236 | break; | 
|  | 2237 | case XML_SCHEMA_CONTENT_EMPTY: | 
|  | 2238 | fprintf(output, "empty "); | 
|  | 2239 | break; | 
|  | 2240 | case XML_SCHEMA_CONTENT_ELEMENTS: | 
|  | 2241 | fprintf(output, "element "); | 
|  | 2242 | break; | 
|  | 2243 | case XML_SCHEMA_CONTENT_MIXED: | 
|  | 2244 | fprintf(output, "mixed "); | 
|  | 2245 | break; | 
|  | 2246 | case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 2247 | /* not used. */ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2248 | break; | 
|  | 2249 | case XML_SCHEMA_CONTENT_BASIC: | 
|  | 2250 | fprintf(output, "basic "); | 
|  | 2251 | break; | 
|  | 2252 | case XML_SCHEMA_CONTENT_SIMPLE: | 
|  | 2253 | fprintf(output, "simple "); | 
|  | 2254 | break; | 
|  | 2255 | case XML_SCHEMA_CONTENT_ANY: | 
|  | 2256 | fprintf(output, "any "); | 
|  | 2257 | break; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2258 | } | 
|  | 2259 | fprintf(output, "\n"); | 
|  | 2260 | if ((type->minOccurs != 1) || (type->maxOccurs != 1)) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2261 | fprintf(output, "  "); | 
|  | 2262 | if (type->minOccurs != 1) | 
|  | 2263 | fprintf(output, "min: %d ", type->minOccurs); | 
|  | 2264 | if (type->maxOccurs >= UNBOUNDED) | 
|  | 2265 | fprintf(output, "max: unbounded\n"); | 
|  | 2266 | else if (type->maxOccurs != 1) | 
|  | 2267 | fprintf(output, "max: %d\n", type->maxOccurs); | 
|  | 2268 | else | 
|  | 2269 | fprintf(output, "\n"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2270 | } | 
|  | 2271 | if (type->annot != NULL) | 
|  | 2272 | xmlSchemaAnnotDump(output, type->annot); | 
|  | 2273 | if (type->subtypes != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2274 | xmlSchemaTypePtr sub = type->subtypes; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2275 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2276 | fprintf(output, "  subtypes: "); | 
|  | 2277 | while (sub != NULL) { | 
|  | 2278 | fprintf(output, "%s ", sub->name); | 
|  | 2279 | sub = sub->next; | 
|  | 2280 | } | 
|  | 2281 | fprintf(output, "\n"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2282 | } | 
|  | 2283 |  | 
|  | 2284 | } | 
|  | 2285 |  | 
|  | 2286 | /** | 
|  | 2287 | * xmlSchemaDump: | 
|  | 2288 | * @output:  the file output | 
|  | 2289 | * @schema:  a schema structure | 
|  | 2290 | * | 
|  | 2291 | * Dump a Schema structure. | 
|  | 2292 | */ | 
|  | 2293 | void | 
|  | 2294 | xmlSchemaDump(FILE * output, xmlSchemaPtr schema) | 
|  | 2295 | { | 
|  | 2296 | if (schema == NULL) { | 
|  | 2297 | fprintf(output, "Schemas: NULL\n"); | 
|  | 2298 | return; | 
|  | 2299 | } | 
|  | 2300 | fprintf(output, "Schemas: "); | 
|  | 2301 | if (schema->name != NULL) | 
|  | 2302 | fprintf(output, "%s, ", schema->name); | 
|  | 2303 | else | 
|  | 2304 | fprintf(output, "no name, "); | 
|  | 2305 | if (schema->targetNamespace != NULL) | 
| Daniel Veillard | 580ced8 | 2003-03-21 21:22:48 +0000 | [diff] [blame] | 2306 | fprintf(output, "%s", (const char *) schema->targetNamespace); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2307 | else | 
|  | 2308 | fprintf(output, "no target namespace"); | 
|  | 2309 | fprintf(output, "\n"); | 
|  | 2310 | if (schema->annot != NULL) | 
|  | 2311 | xmlSchemaAnnotDump(output, schema->annot); | 
|  | 2312 |  | 
|  | 2313 | xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump, | 
|  | 2314 | output); | 
|  | 2315 | xmlHashScanFull(schema->elemDecl, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2316 | (xmlHashScannerFull) xmlSchemaElementDump, output); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2317 | } | 
| Daniel Veillard | a9cce9c | 2003-09-29 13:20:24 +0000 | [diff] [blame] | 2318 | #endif /* LIBXML_OUTPUT_ENABLED */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2319 |  | 
|  | 2320 | /************************************************************************ | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2321 | *									* | 
|  | 2322 | * 			Utilities					* | 
|  | 2323 | *									* | 
|  | 2324 | ************************************************************************/ | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2325 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 2326 | /** | 
|  | 2327 | * xmlSchemaGetPropNode: | 
|  | 2328 | * @node: the element node | 
|  | 2329 | * @name: the name of the attribute | 
|  | 2330 | * | 
|  | 2331 | * Seeks an attribute with a name of @name in | 
|  | 2332 | * no namespace. | 
|  | 2333 | * | 
|  | 2334 | * Returns the attribute or NULL if not present. | 
|  | 2335 | */ | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 2336 | static xmlAttrPtr | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 2337 | xmlSchemaGetPropNode(xmlNodePtr node, const char *name) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 2338 | { | 
|  | 2339 | xmlAttrPtr prop; | 
|  | 2340 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 2341 | if ((node == NULL) || (name == NULL)) | 
|  | 2342 | return(NULL); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 2343 | prop = node->properties; | 
|  | 2344 | while (prop != NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 2345 | if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name)) | 
|  | 2346 | return(prop); | 
|  | 2347 | prop = prop->next; | 
|  | 2348 | } | 
|  | 2349 | return (NULL); | 
|  | 2350 | } | 
|  | 2351 |  | 
|  | 2352 | /** | 
|  | 2353 | * xmlSchemaGetPropNodeNs: | 
|  | 2354 | * @node: the element node | 
|  | 2355 | * @uri: the uri | 
|  | 2356 | * @name: the name of the attribute | 
|  | 2357 | * | 
|  | 2358 | * Seeks an attribute with a local name of @name and | 
|  | 2359 | * a namespace URI of @uri. | 
|  | 2360 | * | 
|  | 2361 | * Returns the attribute or NULL if not present. | 
|  | 2362 | */ | 
|  | 2363 | static xmlAttrPtr | 
|  | 2364 | xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name) | 
|  | 2365 | { | 
|  | 2366 | xmlAttrPtr prop; | 
|  | 2367 |  | 
|  | 2368 | if ((node == NULL) || (name == NULL)) | 
|  | 2369 | return(NULL); | 
|  | 2370 | prop = node->properties; | 
|  | 2371 | while (prop != NULL) { | 
|  | 2372 | if ((prop->ns != NULL) && | 
|  | 2373 | xmlStrEqual(prop->name, BAD_CAST name) && | 
|  | 2374 | xmlStrEqual(prop->ns->href, BAD_CAST uri)) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 2375 | return(prop); | 
|  | 2376 | prop = prop->next; | 
|  | 2377 | } | 
|  | 2378 | return (NULL); | 
|  | 2379 | } | 
|  | 2380 |  | 
|  | 2381 | static const xmlChar * | 
|  | 2382 | xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) | 
|  | 2383 | { | 
|  | 2384 | xmlChar *val; | 
|  | 2385 | const xmlChar *ret; | 
|  | 2386 |  | 
|  | 2387 | val = xmlNodeGetContent(node); | 
|  | 2388 | if (val == NULL) | 
|  | 2389 | return(NULL); | 
|  | 2390 | ret = xmlDictLookup(ctxt->dict, val, -1); | 
|  | 2391 | xmlFree(val); | 
|  | 2392 | return(ret); | 
|  | 2393 | } | 
|  | 2394 |  | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2395 | /** | 
|  | 2396 | * xmlSchemaGetProp: | 
|  | 2397 | * @ctxt: the parser context | 
|  | 2398 | * @node: the node | 
|  | 2399 | * @name: the property name | 
|  | 2400 | * | 
|  | 2401 | * Read a attribute value and internalize the string | 
|  | 2402 | * | 
|  | 2403 | * Returns the string or NULL if not present. | 
|  | 2404 | */ | 
|  | 2405 | static const xmlChar * | 
|  | 2406 | xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, | 
|  | 2407 | const char *name) | 
|  | 2408 | { | 
|  | 2409 | xmlChar *val; | 
|  | 2410 | const xmlChar *ret; | 
|  | 2411 |  | 
|  | 2412 | val = xmlGetProp(node, BAD_CAST name); | 
|  | 2413 | if (val == NULL) | 
|  | 2414 | return(NULL); | 
|  | 2415 | ret = xmlDictLookup(ctxt->dict, val, -1); | 
|  | 2416 | xmlFree(val); | 
|  | 2417 | return(ret); | 
|  | 2418 | } | 
|  | 2419 |  | 
| William M. Brack | 29aa772 | 2004-05-12 00:27:56 +0000 | [diff] [blame] | 2420 | #if 0 | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2421 | /** | 
|  | 2422 | * xmlSchemaGetNamespace: | 
|  | 2423 | * @ctxt: the parser context | 
|  | 2424 | * @schema: the schemas containing the declaration | 
|  | 2425 | * @node: the node | 
|  | 2426 | * @qname: the QName to analyze | 
|  | 2427 | * | 
|  | 2428 | * Find the namespace name for the given declaration. | 
|  | 2429 | * | 
|  | 2430 | * Returns the local name for that declaration, as well as the namespace name | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 2431 | * NOTE: This function is no longer used (Buchcik, May '04) | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2432 | */ | 
|  | 2433 | static const xmlChar * | 
|  | 2434 | xmlSchemaGetNamespace(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
|  | 2435 | xmlNodePtr node, const xmlChar *qname, | 
|  | 2436 | const xmlChar **namespace) { | 
|  | 2437 | int len; | 
|  | 2438 | const xmlChar *name, *prefix, *def = NULL; | 
|  | 2439 | xmlNsPtr ns; | 
|  | 2440 |  | 
|  | 2441 | *namespace = NULL; | 
|  | 2442 |  | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 2443 | /* TODO: The following seems to be not correct here: | 
|  | 2444 | * 1. The name of a declaration is a NCName, not a QName. | 
|  | 2445 | * 2. The attribute "targetNamespace" is allowed for the | 
|  | 2446 | *    <schema> Element Information Item only. | 
|  | 2447 | * 3. One cannot evaluate the target namespace, by the type | 
|  | 2448 | *    of declaration, since it is dependant on the xxxFormDefault | 
|  | 2449 | *    of <schema> and the form attribute of an <element> or <attribute>. | 
|  | 2450 | */ | 
|  | 2451 |  | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2452 | if (xmlStrEqual(node->name, BAD_CAST "element") || | 
|  | 2453 | xmlStrEqual(node->name, BAD_CAST "attribute") || | 
|  | 2454 | xmlStrEqual(node->name, BAD_CAST "simpleType") || | 
|  | 2455 | xmlStrEqual(node->name, BAD_CAST "complexType")) { | 
|  | 2456 | def = xmlSchemaGetProp(ctxt, node, "targetNamespace"); | 
|  | 2457 | } | 
|  | 2458 |  | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 2459 |  | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2460 | qname = xmlDictLookup(ctxt->dict, qname, -1); /* intern the string */ | 
|  | 2461 | name = xmlSplitQName3(qname, &len); | 
|  | 2462 | if (name == NULL) { | 
|  | 2463 | if (def == NULL) { | 
|  | 2464 | if (xmlStrEqual(node->name, BAD_CAST "element")) { | 
|  | 2465 | if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) | 
|  | 2466 | *namespace = schema->targetNamespace; | 
|  | 2467 | } else if (xmlStrEqual(node->name, BAD_CAST "attribute")) { | 
|  | 2468 | if (schema->flags & XML_SCHEMAS_QUALIF_ATTR) | 
|  | 2469 | *namespace = schema->targetNamespace; | 
|  | 2470 | } else if ((xmlStrEqual(node->name, BAD_CAST "simpleType")) || | 
|  | 2471 | (xmlStrEqual(node->name, BAD_CAST "complexType"))) { | 
|  | 2472 | *namespace = schema->targetNamespace; | 
|  | 2473 | } | 
|  | 2474 | } else { | 
|  | 2475 | *namespace = def; | 
|  | 2476 | } | 
|  | 2477 | return(qname); | 
|  | 2478 | } | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 2479 |  | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2480 | name = xmlDictLookup(ctxt->dict, name, -1); | 
|  | 2481 | prefix = xmlDictLookup(ctxt->dict, qname, len); | 
|  | 2482 | if (def != NULL) { | 
|  | 2483 | xmlSchemaPErr(ctxt, node, XML_SCHEMAP_DEF_AND_PREFIX, | 
|  | 2484 | "%s: presence of both prefix %s and targetNamespace\n", | 
|  | 2485 | node->name, prefix); | 
|  | 2486 | } | 
|  | 2487 | ns = xmlSearchNs(node->doc, node, prefix); | 
|  | 2488 | if (ns == NULL) { | 
|  | 2489 | xmlSchemaPErr(ctxt, node, XML_SCHEMAP_PREFIX_UNDEFINED, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 2490 | "%s: The QName prefix %s is undefined\n", | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2491 | node->name, prefix); | 
|  | 2492 | return(name); | 
|  | 2493 | } | 
|  | 2494 | *namespace = xmlDictLookup(ctxt->dict, ns->href, -1); | 
|  | 2495 | return(name); | 
|  | 2496 | } | 
| William M. Brack | 29aa772 | 2004-05-12 00:27:56 +0000 | [diff] [blame] | 2497 | #endif | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2498 |  | 
|  | 2499 | /************************************************************************ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2500 | * 									* | 
|  | 2501 | * 			Parsing functions				* | 
|  | 2502 | * 									* | 
|  | 2503 | ************************************************************************/ | 
|  | 2504 |  | 
|  | 2505 | /** | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2506 | * xmlSchemaGetElem: | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 2507 | * @schema:  the schema context | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2508 | * @name:  the element name | 
|  | 2509 | * @ns:  the element namespace | 
|  | 2510 | * | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 2511 | * Lookup a global element declaration in the schema. | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2512 | * | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 2513 | * Returns the element declaration or NULL if not found. | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2514 | */ | 
|  | 2515 | static xmlSchemaElementPtr | 
|  | 2516 | xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 2517 | const xmlChar * namespace) | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2518 | { | 
|  | 2519 | xmlSchemaElementPtr ret; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2520 |  | 
|  | 2521 | if ((name == NULL) || (schema == NULL)) | 
|  | 2522 | return (NULL); | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 2523 |  | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2524 | ret = xmlHashLookup2(schema->elemDecl, name, namespace); | 
| Daniel Veillard | f2a1283 | 2003-11-24 13:04:35 +0000 | [diff] [blame] | 2525 | if ((ret != NULL) && | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 2526 | (ret->flags & XML_SCHEMAS_ELEM_GLOBAL)) { | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2527 | return (ret); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2528 | } else | 
|  | 2529 | ret = NULL; | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 2530 | /* | 
|  | 2531 | * This one was removed, since top level element declarations have | 
|  | 2532 | * the target namespace specified in targetNamespace of the <schema> | 
|  | 2533 | * information element, even if elementFormDefault is "unqualified". | 
|  | 2534 | */ | 
|  | 2535 |  | 
|  | 2536 | /* else if ((schema->flags & XML_SCHEMAS_QUALIF_ELEM) == 0) { | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2537 | if (xmlStrEqual(namespace, schema->targetNamespace)) | 
|  | 2538 | ret = xmlHashLookup2(schema->elemDecl, name, NULL); | 
|  | 2539 | else | 
|  | 2540 | ret = xmlHashLookup2(schema->elemDecl, name, namespace); | 
| Daniel Veillard | f2a1283 | 2003-11-24 13:04:35 +0000 | [diff] [blame] | 2541 | if ((ret != NULL) && | 
|  | 2542 | ((level == 0) || (ret->flags & XML_SCHEMAS_ELEM_TOPLEVEL))) { | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2543 | return (ret); | 
| Daniel Veillard | f2a1283 | 2003-11-24 13:04:35 +0000 | [diff] [blame] | 2544 | } | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 2545 | */ | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2546 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2547 | /* | 
|  | 2548 | * Removed since imported components will be hold by the main schema only. | 
|  | 2549 | * | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2550 | if (namespace == NULL) | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2551 | import = xmlHashLookup(schema->schemasImports, XML_SCHEMAS_NO_NAMESPACE); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2552 | else | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2553 | import = xmlHashLookup(schema->schemasImports, namespace); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2554 | if (import != NULL) { | 
| Daniel Veillard | f2a1283 | 2003-11-24 13:04:35 +0000 | [diff] [blame] | 2555 | ret = xmlSchemaGetElem(import->schema, name, namespace, level + 1); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2556 | if ((ret != NULL) && (ret->flags & XML_SCHEMAS_ELEM_GLOBAL)) { | 
|  | 2557 | return (ret); | 
|  | 2558 | } else | 
|  | 2559 | ret = NULL; | 
|  | 2560 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2561 | */ | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2562 | #ifdef DEBUG | 
|  | 2563 | if (ret == NULL) { | 
|  | 2564 | if (namespace == NULL) | 
|  | 2565 | fprintf(stderr, "Unable to lookup type %s", name); | 
|  | 2566 | else | 
|  | 2567 | fprintf(stderr, "Unable to lookup type %s:%s", name, | 
|  | 2568 | namespace); | 
|  | 2569 | } | 
|  | 2570 | #endif | 
|  | 2571 | return (ret); | 
|  | 2572 | } | 
|  | 2573 |  | 
|  | 2574 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2575 | * xmlSchemaGetType: | 
|  | 2576 | * @schema:  the schemas context | 
|  | 2577 | * @name:  the type name | 
|  | 2578 | * @ns:  the type namespace | 
|  | 2579 | * | 
|  | 2580 | * Lookup a type in the schemas or the predefined types | 
|  | 2581 | * | 
| Daniel Veillard | a84c0b3 | 2003-06-02 16:58:46 +0000 | [diff] [blame] | 2582 | * Returns the group definition or NULL if not found. | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2583 | */ | 
|  | 2584 | static xmlSchemaTypePtr | 
|  | 2585 | xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2586 | const xmlChar * namespace) | 
|  | 2587 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2588 | xmlSchemaTypePtr ret; | 
|  | 2589 |  | 
|  | 2590 | if (name == NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2591 | return (NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2592 | if (schema != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2593 | ret = xmlHashLookup2(schema->typeDecl, name, namespace); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2594 | if ((ret != NULL) && (ret->flags & XML_SCHEMAS_TYPE_GLOBAL)) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2595 | return (ret); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2596 | } | 
|  | 2597 | ret = xmlSchemaGetPredefinedType(name, namespace); | 
| Daniel Veillard | 1d91386 | 2003-11-21 00:28:39 +0000 | [diff] [blame] | 2598 | if (ret != NULL) | 
|  | 2599 | return (ret); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2600 | /* | 
|  | 2601 | * Removed, since the imported components will be grafted on the | 
|  | 2602 | * main schema only. | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2603 | if (namespace == NULL) | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2604 | import = xmlHashLookup(schema->schemasImports, XML_SCHEMAS_NO_NAMESPACE); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2605 | else | 
| Daniel Veillard | 1d91386 | 2003-11-21 00:28:39 +0000 | [diff] [blame] | 2606 | import = xmlHashLookup(schema->schemasImports, namespace); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2607 | if (import != NULL) { | 
| Daniel Veillard | 1d91386 | 2003-11-21 00:28:39 +0000 | [diff] [blame] | 2608 | ret = xmlSchemaGetType(import->schema, name, namespace); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2609 | if ((ret != NULL) && (ret->flags & XML_SCHEMAS_TYPE_GLOBAL)) { | 
|  | 2610 | return (ret); | 
|  | 2611 | } else | 
|  | 2612 | ret = NULL; | 
|  | 2613 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2614 | */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2615 | #ifdef DEBUG | 
|  | 2616 | if (ret == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2617 | if (namespace == NULL) | 
|  | 2618 | fprintf(stderr, "Unable to lookup type %s", name); | 
|  | 2619 | else | 
|  | 2620 | fprintf(stderr, "Unable to lookup type %s:%s", name, | 
|  | 2621 | namespace); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2622 | } | 
|  | 2623 | #endif | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2624 | return (ret); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2625 | } | 
|  | 2626 |  | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2627 | /** | 
|  | 2628 | * xmlSchemaGetAttribute: | 
|  | 2629 | * @schema:  the context of the schema | 
|  | 2630 | * @name:  the name of the attribute | 
|  | 2631 | * @ns:  the target namespace of the attribute | 
|  | 2632 | * | 
|  | 2633 | * Lookup a an attribute in the schema or imported schemas | 
|  | 2634 | * | 
|  | 2635 | * Returns the attribute declaration or NULL if not found. | 
|  | 2636 | */ | 
|  | 2637 | static xmlSchemaAttributePtr | 
|  | 2638 | xmlSchemaGetAttribute(xmlSchemaPtr schema, const xmlChar * name, | 
|  | 2639 | const xmlChar * namespace) | 
|  | 2640 | { | 
|  | 2641 | xmlSchemaAttributePtr ret; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2642 |  | 
|  | 2643 | if ((name == NULL) || (schema == NULL)) | 
|  | 2644 | return (NULL); | 
|  | 2645 |  | 
|  | 2646 |  | 
|  | 2647 | ret = xmlHashLookup2(schema->attrDecl, name, namespace); | 
|  | 2648 | if ((ret != NULL) && (ret->flags & XML_SCHEMAS_ATTR_GLOBAL)) | 
|  | 2649 | return (ret); | 
|  | 2650 | else | 
|  | 2651 | ret = NULL; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2652 | /* | 
|  | 2653 | * Removed, since imported components will be hold by the main schema only. | 
|  | 2654 | * | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2655 | if (namespace == NULL) | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2656 | import = xmlHashLookup(schema->schemasImports, XML_SCHEMAS_NO_NAMESPACE); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2657 | else | 
|  | 2658 | import = xmlHashLookup(schema->schemasImports, namespace); | 
|  | 2659 | if (import != NULL) { | 
|  | 2660 | ret = xmlSchemaGetAttribute(import->schema, name, namespace); | 
|  | 2661 | if ((ret != NULL) && (ret->flags & XML_SCHEMAS_ATTR_GLOBAL)) { | 
|  | 2662 | return (ret); | 
|  | 2663 | } else | 
|  | 2664 | ret = NULL; | 
|  | 2665 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2666 | */ | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2667 | #ifdef DEBUG | 
|  | 2668 | if (ret == NULL) { | 
|  | 2669 | if (namespace == NULL) | 
|  | 2670 | fprintf(stderr, "Unable to lookup attribute %s", name); | 
|  | 2671 | else | 
|  | 2672 | fprintf(stderr, "Unable to lookup attribute %s:%s", name, | 
|  | 2673 | namespace); | 
|  | 2674 | } | 
|  | 2675 | #endif | 
|  | 2676 | return (ret); | 
|  | 2677 | } | 
|  | 2678 |  | 
|  | 2679 | /** | 
|  | 2680 | * xmlSchemaGetAttributeGroup: | 
|  | 2681 | * @schema:  the context of the schema | 
|  | 2682 | * @name:  the name of the attribute group | 
|  | 2683 | * @ns:  the target namespace of the attribute group | 
|  | 2684 | * | 
|  | 2685 | * Lookup a an attribute group in the schema or imported schemas | 
|  | 2686 | * | 
|  | 2687 | * Returns the attribute group definition or NULL if not found. | 
|  | 2688 | */ | 
|  | 2689 | static xmlSchemaAttributeGroupPtr | 
|  | 2690 | xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name, | 
|  | 2691 | const xmlChar * namespace) | 
|  | 2692 | { | 
|  | 2693 | xmlSchemaAttributeGroupPtr ret; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2694 |  | 
|  | 2695 | if ((name == NULL) || (schema == NULL)) | 
|  | 2696 | return (NULL); | 
|  | 2697 |  | 
|  | 2698 |  | 
|  | 2699 | ret = xmlHashLookup2(schema->attrgrpDecl, name, namespace); | 
|  | 2700 | if ((ret != NULL) && (ret->flags & XML_SCHEMAS_ATTRGROUP_GLOBAL)) | 
|  | 2701 | return (ret); | 
|  | 2702 | else | 
|  | 2703 | ret = NULL; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2704 | /* | 
|  | 2705 | * Removed since imported components will be hold by the main schema only. | 
|  | 2706 | * | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2707 | if (namespace == NULL) | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2708 | import = xmlHashLookup(schema->schemasImports, XML_SCHEMAS_NO_NAMESPACE); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2709 | else | 
|  | 2710 | import = xmlHashLookup(schema->schemasImports, namespace); | 
|  | 2711 | if (import != NULL) { | 
|  | 2712 | ret = xmlSchemaGetAttributeGroup(import->schema, name, namespace); | 
|  | 2713 | if ((ret != NULL) && (ret->flags & XML_SCHEMAS_ATTRGROUP_GLOBAL)) | 
|  | 2714 | return (ret); | 
|  | 2715 | else | 
|  | 2716 | ret = NULL; | 
|  | 2717 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2718 | */ | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2719 | #ifdef DEBUG | 
|  | 2720 | if (ret == NULL) { | 
|  | 2721 | if (namespace == NULL) | 
|  | 2722 | fprintf(stderr, "Unable to lookup attribute group %s", name); | 
|  | 2723 | else | 
|  | 2724 | fprintf(stderr, "Unable to lookup attribute group %s:%s", name, | 
|  | 2725 | namespace); | 
|  | 2726 | } | 
|  | 2727 | #endif | 
|  | 2728 | return (ret); | 
|  | 2729 | } | 
|  | 2730 |  | 
|  | 2731 | /** | 
|  | 2732 | * xmlSchemaGetGroup: | 
|  | 2733 | * @schema:  the context of the schema | 
|  | 2734 | * @name:  the name of the group | 
|  | 2735 | * @ns:  the target namespace of the group | 
|  | 2736 | * | 
|  | 2737 | * Lookup a group in the schema or imported schemas | 
|  | 2738 | * | 
|  | 2739 | * Returns the group definition or NULL if not found. | 
|  | 2740 | */ | 
|  | 2741 | static xmlSchemaTypePtr | 
|  | 2742 | xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name, | 
|  | 2743 | const xmlChar * namespace) | 
|  | 2744 | { | 
|  | 2745 | xmlSchemaTypePtr ret; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2746 |  | 
|  | 2747 | if ((name == NULL) || (schema == NULL)) | 
|  | 2748 | return (NULL); | 
|  | 2749 |  | 
|  | 2750 |  | 
|  | 2751 | ret = xmlHashLookup2(schema->groupDecl, name, namespace); | 
|  | 2752 | if ((ret != NULL) && (ret->flags & XML_SCHEMAS_TYPE_GLOBAL)) | 
|  | 2753 | return (ret); | 
|  | 2754 | else | 
|  | 2755 | ret = NULL; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2756 | /* | 
|  | 2757 | * Removed since imported components will be hold by the main schema only. | 
|  | 2758 | * | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2759 | if (namespace == NULL) | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2760 | import = xmlHashLookup(schema->schemasImports, XML_SCHEMAS_NO_NAMESPACE); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2761 | else | 
|  | 2762 | import = xmlHashLookup(schema->schemasImports, namespace); | 
|  | 2763 | if (import != NULL) { | 
|  | 2764 | ret = xmlSchemaGetGroup(import->schema, name, namespace); | 
|  | 2765 | if ((ret != NULL) && (ret->flags & XML_SCHEMAS_TYPE_GLOBAL)) | 
|  | 2766 | return (ret); | 
|  | 2767 | else | 
|  | 2768 | ret = NULL; | 
|  | 2769 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2770 | */ | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 2771 | #ifdef DEBUG | 
|  | 2772 | if (ret == NULL) { | 
|  | 2773 | if (namespace == NULL) | 
|  | 2774 | fprintf(stderr, "Unable to lookup group %s", name); | 
|  | 2775 | else | 
|  | 2776 | fprintf(stderr, "Unable to lookup group %s:%s", name, | 
|  | 2777 | namespace); | 
|  | 2778 | } | 
|  | 2779 | #endif | 
|  | 2780 | return (ret); | 
|  | 2781 | } | 
|  | 2782 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2783 | /************************************************************************ | 
|  | 2784 | * 									* | 
|  | 2785 | * 			Parsing functions				* | 
|  | 2786 | * 									* | 
|  | 2787 | ************************************************************************/ | 
|  | 2788 |  | 
|  | 2789 | #define IS_BLANK_NODE(n)						\ | 
|  | 2790 | (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content))) | 
|  | 2791 |  | 
|  | 2792 | /** | 
|  | 2793 | * xmlSchemaIsBlank: | 
|  | 2794 | * @str:  a string | 
|  | 2795 | * | 
|  | 2796 | * Check if a string is ignorable | 
|  | 2797 | * | 
|  | 2798 | * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise | 
|  | 2799 | */ | 
|  | 2800 | static int | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2801 | xmlSchemaIsBlank(xmlChar * str) | 
|  | 2802 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2803 | if (str == NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2804 | return (1); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2805 | while (*str != 0) { | 
| William M. Brack | 76e95df | 2003-10-18 16:20:14 +0000 | [diff] [blame] | 2806 | if (!(IS_BLANK_CH(*str))) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2807 | return (0); | 
|  | 2808 | str++; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2809 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2810 | return (1); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2811 | } | 
|  | 2812 |  | 
|  | 2813 | /** | 
|  | 2814 | * xmlSchemaAddNotation: | 
|  | 2815 | * @ctxt:  a schema validation context | 
|  | 2816 | * @schema:  the schema being built | 
|  | 2817 | * @name:  the item name | 
|  | 2818 | * | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 2819 | * Add an XML schema annotation declaration | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2820 | * *WARNING* this interface is highly subject to change | 
|  | 2821 | * | 
|  | 2822 | * Returns the new struture or NULL in case of error | 
|  | 2823 | */ | 
|  | 2824 | static xmlSchemaNotationPtr | 
|  | 2825 | xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2826 | const xmlChar * name) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2827 | { | 
|  | 2828 | xmlSchemaNotationPtr ret = NULL; | 
|  | 2829 | int val; | 
|  | 2830 |  | 
|  | 2831 | if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) | 
|  | 2832 | return (NULL); | 
|  | 2833 |  | 
|  | 2834 | if (schema->notaDecl == NULL) | 
|  | 2835 | schema->notaDecl = xmlHashCreate(10); | 
|  | 2836 | if (schema->notaDecl == NULL) | 
|  | 2837 | return (NULL); | 
|  | 2838 |  | 
|  | 2839 | ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation)); | 
|  | 2840 | if (ret == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2841 | xmlSchemaPErrMemory(ctxt, "add annotation", NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2842 | return (NULL); | 
|  | 2843 | } | 
|  | 2844 | memset(ret, 0, sizeof(xmlSchemaNotation)); | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2845 | ret->name = xmlDictLookup(ctxt->dict, name, -1); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2846 | val = xmlHashAddEntry2(schema->notaDecl, name, schema->targetNamespace, | 
|  | 2847 | ret); | 
|  | 2848 | if (val != 0) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 2849 | /* | 
|  | 2850 | * TODO: This should never happen, since a unique name will be computed. | 
|  | 2851 | * If it fails, then an other internal error must have occured. | 
|  | 2852 | */ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2853 | xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc, | 
|  | 2854 | XML_SCHEMAP_REDEFINED_NOTATION, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 2855 | "Annotation declaration '%s' is already declared.\n", | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2856 | name, NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2857 | xmlFree(ret); | 
|  | 2858 | return (NULL); | 
|  | 2859 | } | 
|  | 2860 | return (ret); | 
|  | 2861 | } | 
|  | 2862 |  | 
|  | 2863 |  | 
|  | 2864 | /** | 
|  | 2865 | * xmlSchemaAddAttribute: | 
|  | 2866 | * @ctxt:  a schema validation context | 
|  | 2867 | * @schema:  the schema being built | 
|  | 2868 | * @name:  the item name | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2869 | * @namespace:  the namespace | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2870 | * | 
|  | 2871 | * Add an XML schema Attrribute declaration | 
|  | 2872 | * *WARNING* this interface is highly subject to change | 
|  | 2873 | * | 
|  | 2874 | * Returns the new struture or NULL in case of error | 
|  | 2875 | */ | 
|  | 2876 | static xmlSchemaAttributePtr | 
|  | 2877 | xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2878 | const xmlChar * name, const xmlChar * namespace, | 
|  | 2879 | xmlNodePtr node) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2880 | { | 
|  | 2881 | xmlSchemaAttributePtr ret = NULL; | 
|  | 2882 | int val; | 
|  | 2883 |  | 
|  | 2884 | if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) | 
|  | 2885 | return (NULL); | 
|  | 2886 |  | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2887 | #ifdef DEBUG | 
|  | 2888 | fprintf(stderr, "Adding attribute %s\n", name); | 
|  | 2889 | if (namespace != NULL) | 
|  | 2890 | fprintf(stderr, "  target namespace %s\n", namespace); | 
|  | 2891 | #endif | 
|  | 2892 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2893 | if (schema->attrDecl == NULL) | 
|  | 2894 | schema->attrDecl = xmlHashCreate(10); | 
|  | 2895 | if (schema->attrDecl == NULL) | 
|  | 2896 | return (NULL); | 
|  | 2897 |  | 
|  | 2898 | ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute)); | 
|  | 2899 | if (ret == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2900 | xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2901 | return (NULL); | 
|  | 2902 | } | 
|  | 2903 | memset(ret, 0, sizeof(xmlSchemaAttribute)); | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2904 | ret->name = xmlDictLookup(ctxt->dict, name, -1); | 
|  | 2905 | ret->targetNamespace = xmlDictLookup(ctxt->dict, namespace, -1); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2906 | val = xmlHashAddEntry3(schema->attrDecl, name, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2907 | schema->targetNamespace, ctxt->container, ret); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2908 | if (val != 0) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2909 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 2910 | XML_SCHEMAP_REDEFINED_ATTR, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2911 | NULL, NULL, node, | 
|  | 2912 | "A global attribute declaration with the name '%s' does already exist", name); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2913 | xmlFree(ret); | 
|  | 2914 | return (NULL); | 
|  | 2915 | } | 
|  | 2916 | return (ret); | 
|  | 2917 | } | 
|  | 2918 |  | 
|  | 2919 | /** | 
|  | 2920 | * xmlSchemaAddAttributeGroup: | 
|  | 2921 | * @ctxt:  a schema validation context | 
|  | 2922 | * @schema:  the schema being built | 
|  | 2923 | * @name:  the item name | 
|  | 2924 | * | 
|  | 2925 | * Add an XML schema Attrribute Group declaration | 
|  | 2926 | * | 
|  | 2927 | * Returns the new struture or NULL in case of error | 
|  | 2928 | */ | 
|  | 2929 | static xmlSchemaAttributeGroupPtr | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2930 | xmlSchemaAddAttributeGroup(xmlSchemaParserCtxtPtr ctxt, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2931 | xmlSchemaPtr schema, const xmlChar * name, | 
|  | 2932 | xmlNodePtr node) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2933 | { | 
|  | 2934 | xmlSchemaAttributeGroupPtr ret = NULL; | 
|  | 2935 | int val; | 
|  | 2936 |  | 
|  | 2937 | if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) | 
|  | 2938 | return (NULL); | 
|  | 2939 |  | 
|  | 2940 | if (schema->attrgrpDecl == NULL) | 
|  | 2941 | schema->attrgrpDecl = xmlHashCreate(10); | 
|  | 2942 | if (schema->attrgrpDecl == NULL) | 
|  | 2943 | return (NULL); | 
|  | 2944 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2945 | ret = | 
|  | 2946 | (xmlSchemaAttributeGroupPtr) | 
|  | 2947 | xmlMalloc(sizeof(xmlSchemaAttributeGroup)); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2948 | if (ret == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2949 | xmlSchemaPErrMemory(ctxt, "allocating attribute group", NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2950 | return (NULL); | 
|  | 2951 | } | 
|  | 2952 | memset(ret, 0, sizeof(xmlSchemaAttributeGroup)); | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2953 | ret->name = xmlDictLookup(ctxt->dict, name, -1); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2954 | val = xmlHashAddEntry3(schema->attrgrpDecl, name, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 2955 | schema->targetNamespace, ctxt->container, ret); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2956 | if (val != 0) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2957 | xmlSchemaPCustomErr(ctxt, | 
|  | 2958 | XML_SCHEMAP_REDEFINED_ATTRGROUP, | 
|  | 2959 | NULL, NULL, node, | 
|  | 2960 | "A global attribute group definition with the name '%s' does already exist", name); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2961 | xmlFree(ret); | 
|  | 2962 | return (NULL); | 
|  | 2963 | } | 
|  | 2964 | return (ret); | 
|  | 2965 | } | 
|  | 2966 |  | 
|  | 2967 | /** | 
|  | 2968 | * xmlSchemaAddElement: | 
|  | 2969 | * @ctxt:  a schema validation context | 
|  | 2970 | * @schema:  the schema being built | 
|  | 2971 | * @name:  the type name | 
|  | 2972 | * @namespace:  the type namespace | 
|  | 2973 | * | 
|  | 2974 | * Add an XML schema Element declaration | 
|  | 2975 | * *WARNING* this interface is highly subject to change | 
|  | 2976 | * | 
|  | 2977 | * Returns the new struture or NULL in case of error | 
|  | 2978 | */ | 
|  | 2979 | static xmlSchemaElementPtr | 
|  | 2980 | xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 2981 | const xmlChar * name, const xmlChar * namespace, | 
|  | 2982 | xmlNodePtr node, int topLevel) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2983 | { | 
|  | 2984 | xmlSchemaElementPtr ret = NULL; | 
|  | 2985 | int val; | 
|  | 2986 |  | 
|  | 2987 | if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) | 
|  | 2988 | return (NULL); | 
|  | 2989 |  | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 2990 | #ifdef DEBUG | 
|  | 2991 | fprintf(stderr, "Adding element %s\n", name); | 
|  | 2992 | if (namespace != NULL) | 
|  | 2993 | fprintf(stderr, "  target namespace %s\n", namespace); | 
|  | 2994 | #endif | 
|  | 2995 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 2996 | if (schema->elemDecl == NULL) | 
|  | 2997 | schema->elemDecl = xmlHashCreate(10); | 
|  | 2998 | if (schema->elemDecl == NULL) | 
|  | 2999 | return (NULL); | 
|  | 3000 |  | 
|  | 3001 | ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement)); | 
|  | 3002 | if (ret == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3003 | xmlSchemaPErrMemory(ctxt, "allocating element", NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3004 | return (NULL); | 
|  | 3005 | } | 
|  | 3006 | memset(ret, 0, sizeof(xmlSchemaElement)); | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3007 | ret->name = xmlDictLookup(ctxt->dict, name, -1); | 
|  | 3008 | ret->targetNamespace = xmlDictLookup(ctxt->dict, namespace, -1); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3009 | val = xmlHashAddEntry3(schema->elemDecl, name, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3010 | namespace, ctxt->container, ret); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3011 | if (val != 0) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 3012 | if (topLevel) { | 
|  | 3013 | xmlSchemaPCustomErr(ctxt, | 
|  | 3014 | XML_SCHEMAP_REDEFINED_ELEMENT, | 
|  | 3015 | NULL, NULL, node, | 
|  | 3016 | "A global element declaration with the name '%s' does " | 
|  | 3017 | "already exist", name); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3018 | xmlFree(ret); | 
|  | 3019 | return (NULL); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 3020 | } else { | 
|  | 3021 | char buf[30]; | 
|  | 3022 |  | 
|  | 3023 | snprintf(buf, 29, "#eCont %d", ctxt->counter++ + 1); | 
|  | 3024 | val = xmlHashAddEntry3(schema->elemDecl, name, (xmlChar *) buf, | 
|  | 3025 | namespace, ret); | 
|  | 3026 | if (val != 0) { | 
|  | 3027 | xmlSchemaPCustomErr(ctxt, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 3028 | XML_SCHEMAP_INTERNAL, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 3029 | NULL, NULL, node, | 
|  | 3030 | "Internal error: xmlSchemaAddElement, " | 
|  | 3031 | "a dublicate element declaration with the name '%s' " | 
|  | 3032 | "could not be added to the hash.", name); | 
|  | 3033 | xmlFree(ret); | 
|  | 3034 | return (NULL); | 
|  | 3035 | } | 
|  | 3036 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3037 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3038 | } | 
|  | 3039 | return (ret); | 
|  | 3040 | } | 
|  | 3041 |  | 
|  | 3042 | /** | 
|  | 3043 | * xmlSchemaAddType: | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 3044 | * @ctxt:  a schema parser context | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3045 | * @schema:  the schema being built | 
|  | 3046 | * @name:  the item name | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3047 | * @namespace:  the namespace | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3048 | * | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 3049 | * Add an XML schema item | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3050 | * *WARNING* this interface is highly subject to change | 
|  | 3051 | * | 
|  | 3052 | * Returns the new struture or NULL in case of error | 
|  | 3053 | */ | 
|  | 3054 | static xmlSchemaTypePtr | 
|  | 3055 | xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 3056 | const xmlChar * name, const xmlChar * namespace, | 
|  | 3057 | xmlNodePtr node) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3058 | { | 
|  | 3059 | xmlSchemaTypePtr ret = NULL; | 
|  | 3060 | int val; | 
|  | 3061 |  | 
|  | 3062 | if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) | 
|  | 3063 | return (NULL); | 
|  | 3064 |  | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3065 | #ifdef DEBUG | 
|  | 3066 | fprintf(stderr, "Adding type %s\n", name); | 
|  | 3067 | if (namespace != NULL) | 
|  | 3068 | fprintf(stderr, "  target namespace %s\n", namespace); | 
|  | 3069 | #endif | 
|  | 3070 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3071 | if (schema->typeDecl == NULL) | 
|  | 3072 | schema->typeDecl = xmlHashCreate(10); | 
|  | 3073 | if (schema->typeDecl == NULL) | 
|  | 3074 | return (NULL); | 
|  | 3075 |  | 
|  | 3076 | ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType)); | 
|  | 3077 | if (ret == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3078 | xmlSchemaPErrMemory(ctxt, "allocating type", NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3079 | return (NULL); | 
|  | 3080 | } | 
|  | 3081 | memset(ret, 0, sizeof(xmlSchemaType)); | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3082 | ret->name = xmlDictLookup(ctxt->dict, name, -1); | 
| Daniel Veillard | b0f397e | 2003-12-23 23:30:53 +0000 | [diff] [blame] | 3083 | ret->redef = NULL; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3084 | val = xmlHashAddEntry2(schema->typeDecl, name, namespace, ret); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 3085 | if (val != 0) { | 
|  | 3086 | if (ctxt->includes == 0) { | 
|  | 3087 | xmlSchemaPCustomErr(ctxt, | 
|  | 3088 | XML_SCHEMAP_REDEFINED_TYPE, | 
|  | 3089 | NULL, NULL, node, | 
|  | 3090 | "A global type definition with the name '%s' does already exist", name); | 
| Daniel Veillard | b0f397e | 2003-12-23 23:30:53 +0000 | [diff] [blame] | 3091 | xmlFree(ret); | 
|  | 3092 | return (NULL); | 
|  | 3093 | } else { | 
|  | 3094 | xmlSchemaTypePtr prev; | 
|  | 3095 |  | 
|  | 3096 | prev = xmlHashLookup2(schema->typeDecl, name, namespace); | 
|  | 3097 | if (prev == NULL) { | 
|  | 3098 | xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3099 | XML_ERR_INTERNAL_ERROR, | 
|  | 3100 | "Internal error: xmlSchemaAddType, on type " | 
|  | 3101 | "'%s'.\n", | 
|  | 3102 | name, NULL); | 
| Daniel Veillard | b0f397e | 2003-12-23 23:30:53 +0000 | [diff] [blame] | 3103 | xmlFree(ret); | 
|  | 3104 | return (NULL); | 
|  | 3105 | } | 
|  | 3106 | ret->redef = prev->redef; | 
|  | 3107 | prev->redef = ret; | 
|  | 3108 | } | 
| Daniel Veillard | a84c0b3 | 2003-06-02 16:58:46 +0000 | [diff] [blame] | 3109 | } | 
|  | 3110 | ret->minOccurs = 1; | 
|  | 3111 | ret->maxOccurs = 1; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 3112 | ret->attributeUses = NULL; | 
|  | 3113 | ret->attributeWildcard = NULL; | 
| Daniel Veillard | a84c0b3 | 2003-06-02 16:58:46 +0000 | [diff] [blame] | 3114 |  | 
|  | 3115 | return (ret); | 
|  | 3116 | } | 
|  | 3117 |  | 
|  | 3118 | /** | 
|  | 3119 | * xmlSchemaAddGroup: | 
|  | 3120 | * @ctxt:  a schema validation context | 
|  | 3121 | * @schema:  the schema being built | 
|  | 3122 | * @name:  the group name | 
|  | 3123 | * | 
|  | 3124 | * Add an XML schema Group definition | 
|  | 3125 | * | 
|  | 3126 | * Returns the new struture or NULL in case of error | 
|  | 3127 | */ | 
|  | 3128 | static xmlSchemaTypePtr | 
|  | 3129 | xmlSchemaAddGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 3130 | const xmlChar * name, xmlNodePtr node) | 
| Daniel Veillard | a84c0b3 | 2003-06-02 16:58:46 +0000 | [diff] [blame] | 3131 | { | 
|  | 3132 | xmlSchemaTypePtr ret = NULL; | 
|  | 3133 | int val; | 
|  | 3134 |  | 
|  | 3135 | if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) | 
|  | 3136 | return (NULL); | 
|  | 3137 |  | 
|  | 3138 | if (schema->groupDecl == NULL) | 
|  | 3139 | schema->groupDecl = xmlHashCreate(10); | 
|  | 3140 | if (schema->groupDecl == NULL) | 
|  | 3141 | return (NULL); | 
|  | 3142 |  | 
|  | 3143 | ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType)); | 
|  | 3144 | if (ret == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3145 | xmlSchemaPErrMemory(ctxt, "adding group", NULL); | 
| Daniel Veillard | a84c0b3 | 2003-06-02 16:58:46 +0000 | [diff] [blame] | 3146 | return (NULL); | 
|  | 3147 | } | 
|  | 3148 | memset(ret, 0, sizeof(xmlSchemaType)); | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3149 | ret->name = xmlDictLookup(ctxt->dict, name, -1); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3150 | val = | 
|  | 3151 | xmlHashAddEntry2(schema->groupDecl, name, schema->targetNamespace, | 
|  | 3152 | ret); | 
| Daniel Veillard | a84c0b3 | 2003-06-02 16:58:46 +0000 | [diff] [blame] | 3153 | if (val != 0) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 3154 | xmlSchemaPCustomErr(ctxt, | 
|  | 3155 | XML_SCHEMAP_REDEFINED_GROUP, | 
|  | 3156 | NULL, NULL, node, | 
|  | 3157 | "A global model group definition with the name '%s' does already exist", name); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3158 | xmlFree(ret); | 
|  | 3159 | return (NULL); | 
|  | 3160 | } | 
|  | 3161 | ret->minOccurs = 1; | 
|  | 3162 | ret->maxOccurs = 1; | 
|  | 3163 |  | 
|  | 3164 | return (ret); | 
|  | 3165 | } | 
|  | 3166 |  | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 3167 | /** | 
|  | 3168 | * xmlSchemaNewWildcardNs: | 
|  | 3169 | * @ctxt:  a schema validation context | 
|  | 3170 | * | 
|  | 3171 | * Creates a new wildcard namespace constraint. | 
|  | 3172 | * | 
|  | 3173 | * Returns the new struture or NULL in case of error | 
|  | 3174 | */ | 
|  | 3175 | static xmlSchemaWildcardNsPtr | 
|  | 3176 | xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt) | 
|  | 3177 | { | 
|  | 3178 | xmlSchemaWildcardNsPtr ret; | 
|  | 3179 |  | 
|  | 3180 | ret = (xmlSchemaWildcardNsPtr) | 
|  | 3181 | xmlMalloc(sizeof(xmlSchemaWildcardNs)); | 
|  | 3182 | if (ret == NULL) { | 
|  | 3183 | xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL); | 
|  | 3184 | return (NULL); | 
|  | 3185 | } | 
|  | 3186 | ret->value = NULL; | 
|  | 3187 | ret->next = NULL; | 
|  | 3188 | return (ret); | 
|  | 3189 | } | 
|  | 3190 |  | 
|  | 3191 | /** | 
|  | 3192 | * xmlSchemaAddWildcard: | 
|  | 3193 | * @ctxt:  a schema validation context | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3194 | * Adds a wildcard. It corresponds to a | 
|  | 3195 | * xsd:anyAttribute and is used as storage for namespace | 
|  | 3196 | * constraints on a xsd:any. | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 3197 | * | 
|  | 3198 | * Returns the new struture or NULL in case of error | 
|  | 3199 | */ | 
|  | 3200 | static xmlSchemaWildcardPtr | 
|  | 3201 | xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt) | 
|  | 3202 | { | 
|  | 3203 | xmlSchemaWildcardPtr ret = NULL; | 
|  | 3204 |  | 
|  | 3205 | if (ctxt == NULL) | 
|  | 3206 | return (NULL); | 
|  | 3207 |  | 
|  | 3208 | ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard)); | 
|  | 3209 | if (ret == NULL) { | 
|  | 3210 | xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL); | 
|  | 3211 | return (NULL); | 
|  | 3212 | } | 
|  | 3213 | memset(ret, 0, sizeof(xmlSchemaWildcard)); | 
|  | 3214 | ret->minOccurs = 1; | 
|  | 3215 | ret->maxOccurs = 1; | 
|  | 3216 |  | 
|  | 3217 | return (ret); | 
|  | 3218 | } | 
|  | 3219 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3220 | /************************************************************************ | 
|  | 3221 | * 									* | 
|  | 3222 | *		Utilities for parsing					* | 
|  | 3223 | * 									* | 
|  | 3224 | ************************************************************************/ | 
|  | 3225 |  | 
|  | 3226 | /** | 
|  | 3227 | * xmlGetQNameProp: | 
|  | 3228 | * @ctxt:  a schema validation context | 
|  | 3229 | * @node:  a subtree containing XML Schema informations | 
|  | 3230 | * @name:  the attribute name | 
|  | 3231 | * @namespace:  the result namespace if any | 
|  | 3232 | * | 
|  | 3233 | * Extract a QName Attribute value | 
|  | 3234 | * | 
|  | 3235 | * Returns the NCName or NULL if not found, and also update @namespace | 
|  | 3236 | *    with the namespace URI | 
|  | 3237 | */ | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3238 | static const xmlChar * | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3239 | xmlGetQNameProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3240 | const char *name, const xmlChar ** namespace) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3241 | { | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3242 | const xmlChar *val; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3243 | xmlNsPtr ns; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3244 | const xmlChar *ret, *prefix; | 
|  | 3245 | int len; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3246 |  | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3247 | *namespace = NULL; | 
|  | 3248 | val = xmlSchemaGetProp(ctxt, node, name); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3249 | if (val == NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3250 | return (NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3251 |  | 
| Daniel Veillard | ba0153a | 2004-04-01 10:42:31 +0000 | [diff] [blame] | 3252 | if (!strchr((char *) val, ':')) { | 
| Daniel Veillard | ebcdebd | 2004-03-05 00:15:50 +0000 | [diff] [blame] | 3253 | ns = xmlSearchNs(node->doc, node, 0); | 
|  | 3254 | if (ns) { | 
|  | 3255 | *namespace = xmlDictLookup(ctxt->dict, ns->href, -1); | 
|  | 3256 | return (val); | 
|  | 3257 | } | 
|  | 3258 | } | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3259 | ret = xmlSplitQName3(val, &len); | 
|  | 3260 | if (ret == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3261 | return (val); | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3262 | } | 
|  | 3263 | ret = xmlDictLookup(ctxt->dict, ret, -1); | 
|  | 3264 | prefix = xmlDictLookup(ctxt->dict, val, len); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3265 |  | 
|  | 3266 | ns = xmlSearchNs(node->doc, node, prefix); | 
|  | 3267 | if (ns == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3268 | xmlSchemaPErr(ctxt, node, XML_SCHEMAP_PREFIX_UNDEFINED, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3269 | "Attribute '%s': The prefix '%s' of the QName " | 
|  | 3270 | "'%s' has no corresponding namespace declaration is scope.\n", | 
|  | 3271 | (const xmlChar *) name, prefix); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3272 | } else { | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3273 | *namespace = xmlDictLookup(ctxt->dict, ns->href, -1); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3274 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3275 | return (ret); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3276 | } | 
|  | 3277 |  | 
|  | 3278 | /** | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3279 | * xmlSchemaPValAttrNodeQNameValue: | 
|  | 3280 | * @ctxt:  a schema parser context | 
|  | 3281 | * @schema: the schema context | 
|  | 3282 | * @ownerDes: the designation of the parent element | 
|  | 3283 | * @ownerItem: the parent as a schema object | 
|  | 3284 | * @value:  the QName value | 
|  | 3285 | * @local: the resulting local part if found, the attribute value otherwise | 
|  | 3286 | * @uri:  the resulting namespace URI if found | 
|  | 3287 | * | 
|  | 3288 | * Extracts the local name and the URI of a QName value and validates it. | 
|  | 3289 | * This one is intended to be used on attribute values that | 
|  | 3290 | * should resolve to schema components. | 
|  | 3291 | * | 
|  | 3292 | * Returns 0, in case the QName is valid, a positive error code | 
|  | 3293 | * if not valid and -1 if an internal error occurs. | 
|  | 3294 | */ | 
|  | 3295 | static int | 
|  | 3296 | xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt, | 
|  | 3297 | xmlSchemaPtr schema, | 
|  | 3298 | xmlChar **ownerDes, | 
|  | 3299 | xmlSchemaTypePtr ownerItem, | 
|  | 3300 | xmlAttrPtr attr, | 
|  | 3301 | const xmlChar *value, | 
|  | 3302 | const xmlChar **uri, | 
|  | 3303 | const xmlChar **prefix, | 
|  | 3304 | const xmlChar **local) | 
|  | 3305 | { | 
|  | 3306 | const xmlChar *pref; | 
|  | 3307 | xmlNsPtr ns; | 
|  | 3308 | int len, ret; | 
|  | 3309 |  | 
|  | 3310 | *uri = NULL; | 
|  | 3311 | *local = NULL; | 
|  | 3312 | if (prefix != 0) | 
|  | 3313 | *prefix = NULL; | 
|  | 3314 | ret = xmlValidateQName(value, 1); | 
|  | 3315 | if (ret > 0) { | 
|  | 3316 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 3317 | XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, | 
|  | 3318 | ownerDes, ownerItem, (xmlNodePtr) attr, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 3319 | xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), | 
|  | 3320 | "QName", value, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3321 | NULL, NULL, NULL); | 
|  | 3322 | *local = value; | 
|  | 3323 | return (ctxt->err); | 
|  | 3324 | } else if (ret < 0) | 
|  | 3325 | return (-1); | 
|  | 3326 |  | 
|  | 3327 | if (!strchr((char *) value, ':')) { | 
|  | 3328 | ns = xmlSearchNs(attr->doc, attr->parent, 0); | 
|  | 3329 | if (ns) | 
|  | 3330 | *uri = xmlDictLookup(ctxt->dict, ns->href, -1); | 
|  | 3331 | else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) { | 
|  | 3332 | /* | 
|  | 3333 | * This one takes care of included schemas with no | 
|  | 3334 | * target namespace. | 
|  | 3335 | */ | 
|  | 3336 | *uri = schema->targetNamespace; | 
|  | 3337 | } | 
|  | 3338 | *local = value; | 
|  | 3339 | return (0); | 
|  | 3340 | } | 
|  | 3341 | /* | 
|  | 3342 | * At this point xmlSplitQName3 has to return a local name. | 
|  | 3343 | */ | 
|  | 3344 | *local = xmlSplitQName3(value, &len); | 
|  | 3345 | *local = xmlDictLookup(ctxt->dict, *local, -1); | 
|  | 3346 | pref = xmlDictLookup(ctxt->dict, value, len); | 
|  | 3347 | if (prefix != 0) | 
|  | 3348 | *prefix = pref; | 
|  | 3349 | ns = xmlSearchNs(attr->doc, attr->parent, pref); | 
|  | 3350 | if (ns == NULL) { | 
|  | 3351 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 3352 | XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, | 
|  | 3353 | ownerDes, ownerItem, (xmlNodePtr) attr, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 3354 | xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), "QName", value, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3355 | "The prefix '%s' of the value '%s' is not declared.\n", | 
|  | 3356 | pref, value); | 
|  | 3357 | return (ctxt->err); | 
|  | 3358 | } else { | 
|  | 3359 | *uri = xmlDictLookup(ctxt->dict, ns->href, -1); | 
|  | 3360 | } | 
|  | 3361 | return (0); | 
|  | 3362 | } | 
|  | 3363 |  | 
|  | 3364 | /** | 
|  | 3365 | * xmlSchemaPValAttrNodeQName: | 
|  | 3366 | * @ctxt:  a schema parser context | 
|  | 3367 | * @schema: the schema context | 
|  | 3368 | * @ownerDes: the designation of the owner element | 
|  | 3369 | * @ownerItem: the owner as a schema object | 
|  | 3370 | * @attr:  the attribute node | 
|  | 3371 | * @local: the resulting local part if found, the attribute value otherwise | 
|  | 3372 | * @uri:  the resulting namespace URI if found | 
|  | 3373 | * | 
|  | 3374 | * Extracts and validates the QName of an attribute value. | 
|  | 3375 | * This one is intended to be used on attribute values that | 
|  | 3376 | * should resolve to schema components. | 
|  | 3377 | * | 
|  | 3378 | * Returns 0, in case the QName is valid, a positive error code | 
|  | 3379 | * if not valid and -1 if an internal error occurs. | 
|  | 3380 | */ | 
|  | 3381 | static int | 
|  | 3382 | xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt, | 
|  | 3383 | xmlSchemaPtr schema, | 
|  | 3384 | xmlChar **ownerDes, | 
|  | 3385 | xmlSchemaTypePtr ownerItem, | 
|  | 3386 | xmlAttrPtr attr, | 
|  | 3387 | const xmlChar **uri, | 
|  | 3388 | const xmlChar **prefix, | 
|  | 3389 | const xmlChar **local) | 
|  | 3390 | { | 
|  | 3391 | const xmlChar *value; | 
|  | 3392 |  | 
|  | 3393 | value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); | 
|  | 3394 | return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, | 
|  | 3395 | ownerDes, ownerItem, attr, value, uri, prefix, local)); | 
|  | 3396 | } | 
|  | 3397 |  | 
|  | 3398 | /** | 
|  | 3399 | * xmlSchemaPValAttrQName: | 
|  | 3400 | * @ctxt:  a schema parser context | 
|  | 3401 | * @schema: the schema context | 
|  | 3402 | * @ownerDes: the designation of the parent element | 
|  | 3403 | * @ownerItem: the owner as a schema object | 
|  | 3404 | * @ownerElem:  the parent node of the attribute | 
|  | 3405 | * @name:  the name of the attribute | 
|  | 3406 | * @local: the resulting local part if found, the attribute value otherwise | 
|  | 3407 | * @uri:  the resulting namespace URI if found | 
|  | 3408 | * | 
|  | 3409 | * Extracts and validates the QName of an attribute value. | 
|  | 3410 | * | 
|  | 3411 | * Returns 0, in case the QName is valid, a positive error code | 
|  | 3412 | * if not valid and -1 if an internal error occurs. | 
|  | 3413 | */ | 
|  | 3414 | static int | 
|  | 3415 | xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt, | 
|  | 3416 | xmlSchemaPtr schema, | 
|  | 3417 | xmlChar **ownerDes, | 
|  | 3418 | xmlSchemaTypePtr ownerItem, | 
|  | 3419 | xmlNodePtr ownerElem, | 
|  | 3420 | const char *name, | 
|  | 3421 | const xmlChar **uri, | 
|  | 3422 | const xmlChar **prefix, | 
|  | 3423 | const xmlChar **local) | 
|  | 3424 | { | 
|  | 3425 | xmlAttrPtr attr; | 
|  | 3426 |  | 
|  | 3427 | attr = xmlSchemaGetPropNode(ownerElem, name); | 
|  | 3428 | if (attr == NULL) { | 
|  | 3429 | *local = NULL; | 
|  | 3430 | *uri = NULL; | 
|  | 3431 | return (0); | 
|  | 3432 | } | 
|  | 3433 | return (xmlSchemaPValAttrNodeQName(ctxt, schema, | 
|  | 3434 | ownerDes, ownerItem, attr, uri, prefix, local)); | 
|  | 3435 | } | 
|  | 3436 |  | 
|  | 3437 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3438 | * xmlGetMaxOccurs: | 
|  | 3439 | * @ctxt:  a schema validation context | 
|  | 3440 | * @node:  a subtree containing XML Schema informations | 
|  | 3441 | * | 
|  | 3442 | * Get the maxOccurs property | 
|  | 3443 | * | 
|  | 3444 | * Returns the default if not found, or the value | 
|  | 3445 | */ | 
|  | 3446 | static int | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 3447 | xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, | 
|  | 3448 | int min, int max, int def, const char *expected) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3449 | { | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3450 | const xmlChar *val, *cur; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3451 | int ret = 0; | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 3452 | xmlAttrPtr attr; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3453 |  | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 3454 | attr = xmlSchemaGetPropNode(node, "maxOccurs"); | 
|  | 3455 | if (attr == NULL) | 
|  | 3456 | return (def); | 
|  | 3457 | val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3458 |  | 
|  | 3459 | if (xmlStrEqual(val, (const xmlChar *) "unbounded")) { | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 3460 | if (max != UNBOUNDED) { | 
|  | 3461 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 3462 | XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, | 
|  | 3463 | /* XML_SCHEMAP_INVALID_MINOCCURS, */ | 
|  | 3464 | NULL, NULL, (xmlNodePtr) attr, NULL, expected, | 
|  | 3465 | val, NULL, NULL, NULL); | 
|  | 3466 | return (def); | 
|  | 3467 | } else | 
|  | 3468 | return (UNBOUNDED);  /* encoding it with -1 might be another option */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3469 | } | 
|  | 3470 |  | 
|  | 3471 | cur = val; | 
| William M. Brack | 76e95df | 2003-10-18 16:20:14 +0000 | [diff] [blame] | 3472 | while (IS_BLANK_CH(*cur)) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3473 | cur++; | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 3474 | if (*cur == 0) { | 
|  | 3475 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 3476 | XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, | 
|  | 3477 | /* XML_SCHEMAP_INVALID_MINOCCURS, */ | 
|  | 3478 | NULL, NULL, (xmlNodePtr) attr, NULL, expected, | 
|  | 3479 | val, NULL, NULL, NULL); | 
|  | 3480 | return (def); | 
|  | 3481 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3482 | while ((*cur >= '0') && (*cur <= '9')) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3483 | ret = ret * 10 + (*cur - '0'); | 
|  | 3484 | cur++; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3485 | } | 
| William M. Brack | 76e95df | 2003-10-18 16:20:14 +0000 | [diff] [blame] | 3486 | while (IS_BLANK_CH(*cur)) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3487 | cur++; | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 3488 | /* | 
|  | 3489 | * TODO: Restrict the maximal value to Integer. | 
|  | 3490 | */ | 
|  | 3491 | if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { | 
|  | 3492 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 3493 | XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, | 
|  | 3494 | /* XML_SCHEMAP_INVALID_MINOCCURS, */ | 
|  | 3495 | NULL, NULL, (xmlNodePtr) attr, NULL, expected, | 
|  | 3496 | val, NULL, NULL, NULL); | 
|  | 3497 | return (def); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3498 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3499 | return (ret); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3500 | } | 
|  | 3501 |  | 
|  | 3502 | /** | 
|  | 3503 | * xmlGetMinOccurs: | 
|  | 3504 | * @ctxt:  a schema validation context | 
|  | 3505 | * @node:  a subtree containing XML Schema informations | 
|  | 3506 | * | 
|  | 3507 | * Get the minOccurs property | 
|  | 3508 | * | 
|  | 3509 | * Returns the default if not found, or the value | 
|  | 3510 | */ | 
|  | 3511 | static int | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 3512 | xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, | 
|  | 3513 | int min, int max, int def, const char *expected) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3514 | { | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3515 | const xmlChar *val, *cur; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3516 | int ret = 0; | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 3517 | xmlAttrPtr attr; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3518 |  | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 3519 | attr = xmlSchemaGetPropNode(node, "minOccurs"); | 
|  | 3520 | if (attr == NULL) | 
|  | 3521 | return (def); | 
|  | 3522 | val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3523 | cur = val; | 
| William M. Brack | 76e95df | 2003-10-18 16:20:14 +0000 | [diff] [blame] | 3524 | while (IS_BLANK_CH(*cur)) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3525 | cur++; | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 3526 | if (*cur == 0) { | 
|  | 3527 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 3528 | XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, | 
|  | 3529 | /* XML_SCHEMAP_INVALID_MINOCCURS, */ | 
|  | 3530 | NULL, NULL, (xmlNodePtr) attr, NULL, expected, | 
|  | 3531 | val, NULL, NULL, NULL); | 
|  | 3532 | return (def); | 
|  | 3533 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3534 | while ((*cur >= '0') && (*cur <= '9')) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3535 | ret = ret * 10 + (*cur - '0'); | 
|  | 3536 | cur++; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3537 | } | 
| William M. Brack | 76e95df | 2003-10-18 16:20:14 +0000 | [diff] [blame] | 3538 | while (IS_BLANK_CH(*cur)) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3539 | cur++; | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 3540 | /* | 
|  | 3541 | * TODO: Restrict the maximal value to Integer. | 
|  | 3542 | */ | 
|  | 3543 | if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { | 
|  | 3544 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 3545 | XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, | 
|  | 3546 | /* XML_SCHEMAP_INVALID_MINOCCURS, */ | 
|  | 3547 | NULL, NULL, (xmlNodePtr) attr, NULL, expected, | 
|  | 3548 | val, NULL, NULL, NULL); | 
|  | 3549 | return (def); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3550 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3551 | return (ret); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3552 | } | 
|  | 3553 |  | 
|  | 3554 | /** | 
|  | 3555 | * xmlGetBooleanProp: | 
|  | 3556 | * @ctxt:  a schema validation context | 
|  | 3557 | * @node:  a subtree containing XML Schema informations | 
|  | 3558 | * @name:  the attribute name | 
|  | 3559 | * @def:  the default value | 
|  | 3560 | * | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3561 | * Evaluate if a boolean property is set | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3562 | * | 
|  | 3563 | * Returns the default if not found, 0 if found to be false, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3564 | * 1 if found to be true | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3565 | */ | 
|  | 3566 | static int | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3567 | xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, | 
|  | 3568 | xmlChar **ownerDes, | 
|  | 3569 | xmlSchemaTypePtr ownerItem, | 
|  | 3570 | xmlNodePtr node, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3571 | const char *name, int def) | 
|  | 3572 | { | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3573 | const xmlChar *val; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3574 |  | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 3575 | val = xmlSchemaGetProp(ctxt, node, name); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3576 | if (val == NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3577 | return (def); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3578 | /* | 
|  | 3579 | * 3.2.2.1 Lexical representation | 
|  | 3580 | * An instance of a datatype that is defined as ·boolean· | 
|  | 3581 | * can have the following legal literals {true, false, 1, 0}. | 
|  | 3582 | */ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3583 | if (xmlStrEqual(val, BAD_CAST "true")) | 
|  | 3584 | def = 1; | 
|  | 3585 | else if (xmlStrEqual(val, BAD_CAST "false")) | 
|  | 3586 | def = 0; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3587 | else if (xmlStrEqual(val, BAD_CAST "1")) | 
|  | 3588 | def = 1; | 
|  | 3589 | else if (xmlStrEqual(val, BAD_CAST "0")) | 
|  | 3590 | def = 0; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3591 | else { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3592 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 3593 | XML_SCHEMAP_INVALID_BOOLEAN, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 3594 | ownerDes, ownerItem, node, | 
|  | 3595 | xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), | 
|  | 3596 | "(1 | 0 | true | false)", val, NULL, NULL, NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3597 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3598 | return (def); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3599 | } | 
|  | 3600 |  | 
|  | 3601 | /************************************************************************ | 
|  | 3602 | * 									* | 
|  | 3603 | *		Shema extraction from an Infoset			* | 
|  | 3604 | * 									* | 
|  | 3605 | ************************************************************************/ | 
|  | 3606 | static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr | 
|  | 3607 | ctxt, xmlSchemaPtr schema, | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 3608 | xmlNodePtr node, | 
|  | 3609 | int topLevel); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3610 | static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr | 
|  | 3611 | ctxt, | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3612 | xmlSchemaPtr schema, | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 3613 | xmlNodePtr node, | 
|  | 3614 | int topLevel); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3615 | static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr | 
|  | 3616 | ctxt, | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3617 | xmlSchemaPtr schema, | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 3618 | xmlNodePtr node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3619 | static xmlSchemaTypePtr xmlSchemaParseSequence(xmlSchemaParserCtxtPtr ctxt, | 
|  | 3620 | xmlSchemaPtr schema, | 
|  | 3621 | xmlNodePtr node); | 
|  | 3622 | static xmlSchemaTypePtr xmlSchemaParseAll(xmlSchemaParserCtxtPtr ctxt, | 
|  | 3623 | xmlSchemaPtr schema, | 
|  | 3624 | xmlNodePtr node); | 
|  | 3625 | static xmlSchemaAttributePtr xmlSchemaParseAttribute(xmlSchemaParserCtxtPtr | 
|  | 3626 | ctxt, | 
|  | 3627 | xmlSchemaPtr schema, | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 3628 | xmlNodePtr node, | 
|  | 3629 | int topLevel); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3630 | static xmlSchemaAttributeGroupPtr | 
|  | 3631 | xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt, | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 3632 | xmlSchemaPtr schema, xmlNodePtr node, | 
|  | 3633 | int topLevel); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3634 | static xmlSchemaTypePtr xmlSchemaParseChoice(xmlSchemaParserCtxtPtr ctxt, | 
|  | 3635 | xmlSchemaPtr schema, | 
|  | 3636 | xmlNodePtr node); | 
|  | 3637 | static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, | 
|  | 3638 | xmlSchemaPtr schema, | 
|  | 3639 | xmlNodePtr node); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 3640 | static xmlSchemaWildcardPtr | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3641 | xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, | 
|  | 3642 | xmlSchemaPtr schema, xmlNodePtr node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3643 |  | 
|  | 3644 | /** | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3645 | * xmlSchemaPValAttrNode: | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 3646 | * | 
|  | 3647 | * @ctxt:  a schema parser context | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3648 | * @ownerDes: the designation of the parent element | 
|  | 3649 | * @ownerItem: the schema object owner if existent | 
|  | 3650 | * @attr:  the schema attribute node being validated | 
|  | 3651 | * @value: the value | 
|  | 3652 | * @type: the built-in type to be validated against | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 3653 | * | 
|  | 3654 | * Validates a value against the given built-in type. | 
|  | 3655 | * This one is intended to be used internally for validation | 
|  | 3656 | * of schema attribute values during parsing of the schema. | 
|  | 3657 | * | 
|  | 3658 | * Returns 0 if the value is valid, a positive error code | 
|  | 3659 | * number otherwise and -1 in case of an internal or API error. | 
|  | 3660 | */ | 
|  | 3661 | static int | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3662 | xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr ctxt, | 
|  | 3663 | xmlChar **ownerDes, | 
|  | 3664 | xmlSchemaTypePtr ownerItem, | 
|  | 3665 | xmlAttrPtr attr, | 
|  | 3666 | const xmlChar *value, | 
|  | 3667 | xmlSchemaTypePtr type) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 3668 | { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 3669 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3670 | int ret = 0; | 
|  | 3671 |  | 
|  | 3672 | /* | 
|  | 3673 | * NOTE: Should we move this to xmlschematypes.c? Hmm, but this | 
|  | 3674 | * one is really meant to be used internally, so better not. | 
|  | 3675 | */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 3676 | if ((ctxt == NULL) || (type == NULL) || (attr == NULL)) | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3677 | return (-1); | 
|  | 3678 | if (type->type != XML_SCHEMA_TYPE_BASIC) { | 
|  | 3679 | xmlSchemaPErr(ctxt, (xmlNodePtr) attr, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 3680 | XML_SCHEMAP_INTERNAL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3681 | "Internal error: xmlSchemaPvalueAttrNode, the given " | 
|  | 3682 | "type '%s' is not a built-in type.\n", | 
|  | 3683 | type->name, NULL); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 3684 | return (-1); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3685 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 3686 | switch (type->builtInType) { | 
|  | 3687 | case XML_SCHEMAS_NCNAME: | 
|  | 3688 | ret = xmlValidateNCName(value, 1); | 
|  | 3689 | break; | 
|  | 3690 | case XML_SCHEMAS_QNAME: | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3691 | xmlSchemaPErr(ctxt, (xmlNodePtr) attr, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 3692 | XML_SCHEMAP_INTERNAL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3693 | "Internal error: xmlSchemaPvalueAttrNode, use " | 
|  | 3694 | "the function xmlSchemaExtractSchemaQNamePropvalueidated " | 
|  | 3695 | "for extracting QName valueues instead.\n", | 
|  | 3696 | NULL, NULL); | 
|  | 3697 | return (-1); | 
|  | 3698 | case XML_SCHEMAS_ANYURI: | 
|  | 3699 | if (value != NULL) { | 
|  | 3700 | xmlURIPtr uri = xmlParseURI((const char *) value); | 
|  | 3701 | if (uri == NULL) | 
|  | 3702 | ret = 1; | 
|  | 3703 | else | 
|  | 3704 | xmlFreeURI(uri); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 3705 | } | 
|  | 3706 | break; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3707 | case XML_SCHEMAS_TOKEN: { | 
|  | 3708 | const xmlChar *cur = value; | 
|  | 3709 |  | 
|  | 3710 | if (IS_BLANK_CH(*cur)) { | 
|  | 3711 | ret = 1; | 
|  | 3712 | } else while (*cur != 0) { | 
|  | 3713 | if ((*cur == 0xd) || (*cur == 0xa) || (*cur == 0x9)) { | 
|  | 3714 | ret = 1; | 
|  | 3715 | break; | 
|  | 3716 | } else if (*cur == ' ') { | 
|  | 3717 | cur++; | 
|  | 3718 | if ((*cur == 0) || (*cur == ' ')) { | 
|  | 3719 | ret = 1; | 
|  | 3720 | break; | 
|  | 3721 | } | 
|  | 3722 | } else { | 
|  | 3723 | cur++; | 
|  | 3724 | } | 
|  | 3725 | } | 
|  | 3726 | } | 
|  | 3727 | break; | 
|  | 3728 | case XML_SCHEMAS_LANGUAGE: | 
|  | 3729 | if (xmlCheckLanguageID(value) != 1) | 
|  | 3730 | ret = 1; | 
|  | 3731 | break; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 3732 | default: { | 
|  | 3733 | xmlSchemaPErr(ctxt, (xmlNodePtr) attr, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 3734 | XML_SCHEMAP_INTERNAL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3735 | "Internal error: xmlSchemaPvalueAttrNode, " | 
|  | 3736 | "valueidation using the type '%s' is not implemented " | 
|  | 3737 | "yet.\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 3738 | type->name, NULL); | 
|  | 3739 | return (-1); | 
|  | 3740 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3741 | } | 
|  | 3742 | /* | 
|  | 3743 | * TODO: Should we use the S4S error codes instead? | 
|  | 3744 | */ | 
|  | 3745 | if (ret > 0) { | 
|  | 3746 | if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) { | 
|  | 3747 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 3748 | XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2, | 
|  | 3749 | ownerDes, ownerItem, (xmlNodePtr) attr, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 3750 | type, NULL, value, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3751 | NULL, NULL, NULL); | 
|  | 3752 | return(XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2); | 
|  | 3753 | } else { | 
|  | 3754 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 3755 | XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, | 
|  | 3756 | ownerDes, ownerItem, (xmlNodePtr) attr, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 3757 | type, NULL, value, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3758 | NULL, NULL, NULL); | 
|  | 3759 | return(XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1); | 
|  | 3760 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 3761 | } | 
|  | 3762 | return (ret); | 
|  | 3763 | } | 
|  | 3764 |  | 
|  | 3765 | /** | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3766 | * xmlSchemaPValAttrNode: | 
|  | 3767 | * | 
|  | 3768 | * @ctxt:  a schema parser context | 
|  | 3769 | * @ownerDes: the designation of the parent element | 
|  | 3770 | * @ownerItem: the schema object owner if existent | 
|  | 3771 | * @attr:  the schema attribute node being validated | 
|  | 3772 | * @type: the built-in type to be validated against | 
|  | 3773 | * @value: the resulting value if any | 
|  | 3774 | * | 
|  | 3775 | * Extracts and validates a value against the given built-in type. | 
|  | 3776 | * This one is intended to be used internally for validation | 
|  | 3777 | * of schema attribute values during parsing of the schema. | 
|  | 3778 | * | 
|  | 3779 | * Returns 0 if the value is valid, a positive error code | 
|  | 3780 | * number otherwise and -1 in case of an internal or API error. | 
|  | 3781 | */ | 
|  | 3782 | static int | 
|  | 3783 | xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt, | 
|  | 3784 | xmlChar **ownerDes, | 
|  | 3785 | xmlSchemaTypePtr ownerItem, | 
|  | 3786 | xmlAttrPtr attr, | 
|  | 3787 | xmlSchemaTypePtr type, | 
|  | 3788 | const xmlChar **value) | 
|  | 3789 | { | 
|  | 3790 | const xmlChar *val; | 
|  | 3791 |  | 
|  | 3792 | if ((ctxt == NULL) || (type == NULL) || (attr == NULL)) | 
|  | 3793 | return (-1); | 
|  | 3794 |  | 
|  | 3795 | val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); | 
|  | 3796 | if (value != NULL) | 
|  | 3797 | *value = val; | 
|  | 3798 |  | 
|  | 3799 | return (xmlSchemaPValAttrNodeValue(ctxt, ownerDes, ownerItem, attr, | 
|  | 3800 | val, type)); | 
|  | 3801 | } | 
|  | 3802 |  | 
|  | 3803 | /** | 
|  | 3804 | * xmlSchemaPValAttr: | 
|  | 3805 | * | 
|  | 3806 | * @ctxt:  a schema parser context | 
|  | 3807 | * @node: the element node of the attribute | 
|  | 3808 | * @ownerDes: the designation of the parent element | 
|  | 3809 | * @ownerItem: the schema object owner if existent | 
|  | 3810 | * @ownerElem: the owner element node | 
|  | 3811 | * @name:  the name of the schema attribute node | 
|  | 3812 | * @type: the built-in type to be validated against | 
|  | 3813 | * @value: the resulting value if any | 
|  | 3814 | * | 
|  | 3815 | * Extracts and validates a value against the given built-in type. | 
|  | 3816 | * This one is intended to be used internally for validation | 
|  | 3817 | * of schema attribute values during parsing of the schema. | 
|  | 3818 | * | 
|  | 3819 | * Returns 0 if the value is valid, a positive error code | 
|  | 3820 | * number otherwise and -1 in case of an internal or API error. | 
|  | 3821 | */ | 
|  | 3822 | static int | 
|  | 3823 | xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt, | 
|  | 3824 | xmlChar **ownerDes, | 
|  | 3825 | xmlSchemaTypePtr ownerItem, | 
|  | 3826 | xmlNodePtr ownerElem, | 
|  | 3827 | const char *name, | 
|  | 3828 | xmlSchemaTypePtr type, | 
|  | 3829 | const xmlChar **value) | 
|  | 3830 | { | 
|  | 3831 | xmlAttrPtr attr; | 
|  | 3832 |  | 
|  | 3833 | if ((ctxt == NULL) || (type == NULL)) { | 
|  | 3834 | if (value != NULL) | 
|  | 3835 | *value = NULL; | 
|  | 3836 | return (-1); | 
|  | 3837 | } | 
|  | 3838 | if (type->type != XML_SCHEMA_TYPE_BASIC) { | 
|  | 3839 | if (value != NULL) | 
|  | 3840 | *value = NULL; | 
|  | 3841 | xmlSchemaPErr(ctxt, ownerElem, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 3842 | XML_SCHEMAP_INTERNAL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3843 | "Internal error: xmlSchemaPValAttr, the given " | 
|  | 3844 | "type '%s' is not a built-in type.\n", | 
|  | 3845 | type->name, NULL); | 
|  | 3846 | return (-1); | 
|  | 3847 | } | 
|  | 3848 | attr = xmlSchemaGetPropNode(ownerElem, name); | 
|  | 3849 | if (attr == NULL) { | 
|  | 3850 | if (value != NULL) | 
|  | 3851 | *value = NULL; | 
|  | 3852 | return (0); | 
|  | 3853 | } | 
|  | 3854 | return (xmlSchemaPValAttrNode(ctxt, ownerDes, ownerItem, attr, | 
|  | 3855 | type, value)); | 
|  | 3856 | } | 
|  | 3857 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3858 | * xmlSchemaParseAttrDecls: | 
|  | 3859 | * @ctxt:  a schema validation context | 
|  | 3860 | * @schema:  the schema being built | 
|  | 3861 | * @node:  a subtree containing XML Schema informations | 
|  | 3862 | * @type:  the hosting type | 
|  | 3863 | * | 
|  | 3864 | * parse a XML schema attrDecls declaration corresponding to | 
|  | 3865 | * <!ENTITY % attrDecls | 
|  | 3866 | *       '((%attribute;| %attributeGroup;)*,(%anyAttribute;)?)'> | 
|  | 3867 | */ | 
|  | 3868 | static xmlNodePtr | 
|  | 3869 | xmlSchemaParseAttrDecls(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
|  | 3870 | xmlNodePtr child, xmlSchemaTypePtr type) | 
|  | 3871 | { | 
|  | 3872 | xmlSchemaAttributePtr lastattr, attr; | 
|  | 3873 |  | 
|  | 3874 | lastattr = NULL; | 
|  | 3875 | while ((IS_SCHEMA(child, "attribute")) || | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3876 | (IS_SCHEMA(child, "attributeGroup"))) { | 
|  | 3877 | attr = NULL; | 
|  | 3878 | if (IS_SCHEMA(child, "attribute")) { | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 3879 | attr = xmlSchemaParseAttribute(ctxt, schema, child, 0); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3880 | } else if (IS_SCHEMA(child, "attributeGroup")) { | 
|  | 3881 | attr = (xmlSchemaAttributePtr) | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 3882 | xmlSchemaParseAttributeGroup(ctxt, schema, child, 0); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3883 | } | 
|  | 3884 | if (attr != NULL) { | 
|  | 3885 | if (lastattr == NULL) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 3886 | if (type->type == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) | 
|  | 3887 | ((xmlSchemaAttributeGroupPtr) type)->attributes = attr; | 
|  | 3888 | else | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3889 | type->attributes = attr; | 
|  | 3890 | lastattr = attr; | 
|  | 3891 | } else { | 
|  | 3892 | lastattr->next = attr; | 
|  | 3893 | lastattr = attr; | 
|  | 3894 | } | 
|  | 3895 | } | 
|  | 3896 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3897 | } | 
|  | 3898 | if (IS_SCHEMA(child, "anyAttribute")) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 3899 | xmlSchemaWildcardPtr wildcard; | 
|  | 3900 |  | 
|  | 3901 | wildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child); | 
|  | 3902 | if (wildcard != NULL) { | 
|  | 3903 | if (type->type == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) | 
|  | 3904 | ((xmlSchemaAttributeGroupPtr) type)->attributeWildcard = wildcard; | 
|  | 3905 | else | 
|  | 3906 | type->attributeWildcard = wildcard; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3907 | } | 
|  | 3908 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3909 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 3910 | return (child); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3911 | } | 
|  | 3912 |  | 
|  | 3913 | /** | 
|  | 3914 | * xmlSchemaParseAnnotation: | 
|  | 3915 | * @ctxt:  a schema validation context | 
|  | 3916 | * @schema:  the schema being built | 
|  | 3917 | * @node:  a subtree containing XML Schema informations | 
|  | 3918 | * | 
|  | 3919 | * parse a XML schema Attrribute declaration | 
|  | 3920 | * *WARNING* this interface is highly subject to change | 
|  | 3921 | * | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 3922 | * Returns -1 in case of error, 0 if the declaration is improper and | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3923 | *         1 in case of success. | 
|  | 3924 | */ | 
|  | 3925 | static xmlSchemaAnnotPtr | 
|  | 3926 | xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
|  | 3927 | xmlNodePtr node) | 
|  | 3928 | { | 
|  | 3929 | xmlSchemaAnnotPtr ret; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3930 | xmlNodePtr child = NULL; | 
|  | 3931 | xmlAttrPtr attr; | 
|  | 3932 | int barked = 0; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3933 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3934 | /* | 
|  | 3935 | * INFO: S4S completed. | 
|  | 3936 | */ | 
|  | 3937 | /* | 
|  | 3938 | * id = ID | 
|  | 3939 | * {any attributes with non-schema namespace . . .}> | 
|  | 3940 | * Content: (appinfo | documentation)* | 
|  | 3941 | */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3942 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 3943 | return (NULL); | 
|  | 3944 | ret = xmlSchemaNewAnnot(ctxt, node); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3945 | attr = node->properties; | 
|  | 3946 | while (attr != NULL) { | 
|  | 3947 | if (((attr->ns == NULL) && | 
|  | 3948 | (!xmlStrEqual(attr->name, BAD_CAST "id"))) || | 
|  | 3949 | ((attr->ns != NULL) && | 
|  | 3950 | xmlStrEqual(attr->ns->href, xmlSchemaNs))) { | 
|  | 3951 |  | 
|  | 3952 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 3953 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 3954 | NULL, NULL, attr); | 
|  | 3955 | } | 
|  | 3956 | attr = attr->next; | 
|  | 3957 | } | 
|  | 3958 | /* TODO: Check id. */ | 
|  | 3959 |  | 
|  | 3960 | /* | 
|  | 3961 | * And now for the children... | 
|  | 3962 | */ | 
|  | 3963 | child = node->children; | 
|  | 3964 | while (child != NULL) { | 
|  | 3965 | if (IS_SCHEMA(child, "appinfo")) { | 
|  | 3966 | /* TODO: make available the content of "appinfo". */ | 
|  | 3967 | /* | 
|  | 3968 | * source = anyURI | 
|  | 3969 | * {any attributes with non-schema namespace . . .}> | 
|  | 3970 | * Content: ({any})* | 
|  | 3971 | */ | 
|  | 3972 | attr = child->properties; | 
|  | 3973 | while (attr != NULL) { | 
|  | 3974 | if (((attr->ns == NULL) && | 
|  | 3975 | (!xmlStrEqual(attr->name, BAD_CAST "source"))) || | 
|  | 3976 | ((attr->ns != NULL) && | 
|  | 3977 | xmlStrEqual(attr->ns->href, xmlSchemaNs))) { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 3978 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 3979 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 3980 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 3981 | NULL, NULL, attr); | 
|  | 3982 | } | 
|  | 3983 | attr = attr->next; | 
|  | 3984 | } | 
|  | 3985 | xmlSchemaPValAttr(ctxt, NULL, NULL, child, "source", | 
|  | 3986 | xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); | 
|  | 3987 | child = child->next; | 
|  | 3988 | } else if (IS_SCHEMA(child, "documentation")) { | 
|  | 3989 | /* TODO: make available the content of "documentation". */ | 
|  | 3990 | /* | 
|  | 3991 | * source = anyURI | 
|  | 3992 | * {any attributes with non-schema namespace . . .}> | 
|  | 3993 | * Content: ({any})* | 
|  | 3994 | */ | 
|  | 3995 | attr = child->properties; | 
|  | 3996 | while (attr != NULL) { | 
|  | 3997 | if (attr->ns == NULL) { | 
|  | 3998 | if (!xmlStrEqual(attr->name, BAD_CAST "source")) { | 
|  | 3999 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 4000 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 4001 | NULL, NULL, attr); | 
|  | 4002 | } | 
|  | 4003 | } else { | 
|  | 4004 | if (xmlStrEqual(attr->ns->href, xmlSchemaNs) || | 
|  | 4005 | (xmlStrEqual(attr->name, BAD_CAST "lang") && | 
|  | 4006 | (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) { | 
|  | 4007 |  | 
|  | 4008 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 4009 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 4010 | NULL, NULL, attr); | 
|  | 4011 | } | 
|  | 4012 | } | 
|  | 4013 | attr = attr->next; | 
|  | 4014 | } | 
|  | 4015 | /* | 
|  | 4016 | * Attribute "xml:lang". | 
|  | 4017 | */ | 
|  | 4018 | attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang"); | 
|  | 4019 | if (attr != NULL) | 
|  | 4020 | xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr, | 
|  | 4021 | xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL); | 
|  | 4022 | child = child->next; | 
|  | 4023 | } else { | 
|  | 4024 | if (!barked) | 
|  | 4025 | xmlSchemaPContentErr(ctxt, | 
|  | 4026 | XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, | 
|  | 4027 | NULL, NULL, node, child, NULL, "(appinfo | documentation)*"); | 
|  | 4028 | barked = 1; | 
|  | 4029 | child = child->next; | 
|  | 4030 | } | 
|  | 4031 | } | 
|  | 4032 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4033 | return (ret); | 
|  | 4034 | } | 
|  | 4035 |  | 
|  | 4036 | /** | 
|  | 4037 | * xmlSchemaParseFacet: | 
|  | 4038 | * @ctxt:  a schema validation context | 
|  | 4039 | * @schema:  the schema being built | 
|  | 4040 | * @node:  a subtree containing XML Schema informations | 
|  | 4041 | * | 
|  | 4042 | * parse a XML schema Facet declaration | 
|  | 4043 | * *WARNING* this interface is highly subject to change | 
|  | 4044 | * | 
|  | 4045 | * Returns the new type structure or NULL in case of error | 
|  | 4046 | */ | 
|  | 4047 | static xmlSchemaFacetPtr | 
|  | 4048 | xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4049 | xmlNodePtr node) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4050 | { | 
|  | 4051 | xmlSchemaFacetPtr facet; | 
|  | 4052 | xmlNodePtr child = NULL; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 4053 | const xmlChar *value; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4054 |  | 
|  | 4055 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 4056 | return (NULL); | 
|  | 4057 |  | 
| Daniel Veillard | 8bc6cf9 | 2003-02-27 17:42:22 +0000 | [diff] [blame] | 4058 | facet = xmlSchemaNewFacet(); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4059 | if (facet == NULL) { | 
|  | 4060 | xmlSchemaPErrMemory(ctxt, "allocating facet", node); | 
|  | 4061 | return (NULL); | 
|  | 4062 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4063 | facet->node = node; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 4064 | value = xmlSchemaGetProp(ctxt, node, "value"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4065 | if (value == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4066 | xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE, | 
|  | 4067 | "Facet %s has no value\n", node->name, NULL); | 
|  | 4068 | xmlSchemaFreeFacet(facet); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4069 | return (NULL); | 
|  | 4070 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4071 | if (IS_SCHEMA(node, "minInclusive")) { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4072 | facet->type = XML_SCHEMA_FACET_MININCLUSIVE; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4073 | } else if (IS_SCHEMA(node, "minExclusive")) { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4074 | facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4075 | } else if (IS_SCHEMA(node, "maxInclusive")) { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4076 | facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4077 | } else if (IS_SCHEMA(node, "maxExclusive")) { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4078 | facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4079 | } else if (IS_SCHEMA(node, "totalDigits")) { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4080 | facet->type = XML_SCHEMA_FACET_TOTALDIGITS; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4081 | } else if (IS_SCHEMA(node, "fractionDigits")) { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4082 | facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4083 | } else if (IS_SCHEMA(node, "pattern")) { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4084 | facet->type = XML_SCHEMA_FACET_PATTERN; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4085 | } else if (IS_SCHEMA(node, "enumeration")) { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4086 | facet->type = XML_SCHEMA_FACET_ENUMERATION; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4087 | } else if (IS_SCHEMA(node, "whiteSpace")) { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4088 | facet->type = XML_SCHEMA_FACET_WHITESPACE; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4089 | } else if (IS_SCHEMA(node, "length")) { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4090 | facet->type = XML_SCHEMA_FACET_LENGTH; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4091 | } else if (IS_SCHEMA(node, "maxLength")) { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4092 | facet->type = XML_SCHEMA_FACET_MAXLENGTH; | 
|  | 4093 | } else if (IS_SCHEMA(node, "minLength")) { | 
|  | 4094 | facet->type = XML_SCHEMA_FACET_MINLENGTH; | 
|  | 4095 | } else { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4096 | xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE, | 
|  | 4097 | "Unknown facet type %s\n", node->name, NULL); | 
|  | 4098 | xmlSchemaFreeFacet(facet); | 
|  | 4099 | return (NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4100 | } | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 4101 | facet->id = xmlSchemaGetProp(ctxt, node, "id"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4102 | facet->value = value; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 4103 | if ((facet->type != XML_SCHEMA_FACET_PATTERN) && | 
|  | 4104 | (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { | 
|  | 4105 | const xmlChar *fixed; | 
|  | 4106 |  | 
|  | 4107 | fixed = xmlSchemaGetProp(ctxt, node, "fixed"); | 
|  | 4108 | if (fixed != NULL) { | 
|  | 4109 | if (xmlStrEqual(fixed, BAD_CAST "true")) | 
|  | 4110 | facet->fixed = 1; | 
|  | 4111 | } | 
|  | 4112 | } | 
|  | 4113 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4114 | child = node->children; | 
|  | 4115 |  | 
|  | 4116 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4117 | facet->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 4118 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4119 | } | 
|  | 4120 | if (child != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4121 | xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD, | 
|  | 4122 | "Facet %s has unexpected child content\n", | 
|  | 4123 | node->name, NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4124 | } | 
|  | 4125 | return (facet); | 
|  | 4126 | } | 
|  | 4127 |  | 
|  | 4128 | /** | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4129 | * xmlSchemaParseWildcardNs: | 
|  | 4130 | * @ctxt:  a schema parser context | 
|  | 4131 | * @wildc:  the wildcard, already created | 
|  | 4132 | * @node:  a subtree containing XML Schema informations | 
|  | 4133 | * | 
|  | 4134 | * Parses the attribute "processContents" and "namespace" | 
|  | 4135 | * of a xsd:anyAttribute and xsd:any. | 
|  | 4136 | * *WARNING* this interface is highly subject to change | 
|  | 4137 | * | 
|  | 4138 | * Returns 0 if everything goes fine, a positive error code | 
|  | 4139 | * if something is not valid and -1 if an internal error occurs. | 
|  | 4140 | */ | 
|  | 4141 | static int | 
|  | 4142 | xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt, | 
|  | 4143 | xmlSchemaPtr schema, | 
|  | 4144 | xmlSchemaWildcardPtr wildc, | 
|  | 4145 | xmlNodePtr node) | 
|  | 4146 | { | 
|  | 4147 | const xmlChar *pc, *ns, *dictnsItem; | 
|  | 4148 | int ret = 0; | 
|  | 4149 | xmlChar *nsItem; | 
|  | 4150 | xmlSchemaWildcardNsPtr tmp, lastNs = NULL; | 
|  | 4151 | xmlAttrPtr attr; | 
|  | 4152 |  | 
|  | 4153 | pc = xmlSchemaGetProp(ctxt, node, "processContents"); | 
|  | 4154 | if ((pc == NULL) | 
|  | 4155 | || (xmlStrEqual(pc, (const xmlChar *) "strict"))) { | 
|  | 4156 | wildc->processContents = XML_SCHEMAS_ANY_STRICT; | 
|  | 4157 | } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) { | 
|  | 4158 | wildc->processContents = XML_SCHEMAS_ANY_SKIP; | 
|  | 4159 | } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) { | 
|  | 4160 | wildc->processContents = XML_SCHEMAS_ANY_LAX; | 
|  | 4161 | } else { | 
|  | 4162 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 4163 | XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD, | 
|  | 4164 | NULL, NULL, node, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 4165 | NULL, "(strict | skip | lax)", pc, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4166 | NULL, NULL, NULL); | 
|  | 4167 | wildc->processContents = XML_SCHEMAS_ANY_STRICT; | 
|  | 4168 | ret = XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD; | 
|  | 4169 | } | 
|  | 4170 | /* | 
|  | 4171 | * Build the namespace constraints. | 
|  | 4172 | */ | 
|  | 4173 | attr = xmlSchemaGetPropNode(node, "namespace"); | 
|  | 4174 | ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); | 
|  | 4175 | if ((ns == NULL) || (xmlStrEqual(ns, BAD_CAST "##any"))) | 
|  | 4176 | wildc->any = 1; | 
|  | 4177 | else if (xmlStrEqual(ns, BAD_CAST "##other")) { | 
|  | 4178 | wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); | 
|  | 4179 | if (wildc->negNsSet == NULL) { | 
|  | 4180 | return (-1); | 
|  | 4181 | } | 
|  | 4182 | wildc->negNsSet->value = schema->targetNamespace; | 
|  | 4183 | } else { | 
|  | 4184 | const xmlChar *end, *cur; | 
|  | 4185 |  | 
|  | 4186 | cur = ns; | 
|  | 4187 | do { | 
|  | 4188 | while (IS_BLANK_CH(*cur)) | 
|  | 4189 | cur++; | 
|  | 4190 | end = cur; | 
|  | 4191 | while ((*end != 0) && (!(IS_BLANK_CH(*end)))) | 
|  | 4192 | end++; | 
|  | 4193 | if (end == cur) | 
|  | 4194 | break; | 
|  | 4195 | nsItem = xmlStrndup(cur, end - cur); | 
|  | 4196 | if ((xmlStrEqual(nsItem, BAD_CAST "##other")) || | 
|  | 4197 | (xmlStrEqual(nsItem, BAD_CAST "##any"))) { | 
|  | 4198 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 4199 | XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER, | 
|  | 4200 | NULL, NULL, (xmlNodePtr) attr, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 4201 | NULL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4202 | "((##any | ##other) | List of (anyURI | " | 
|  | 4203 | "(##targetNamespace | ##local)))", | 
|  | 4204 | nsItem, NULL, NULL, NULL); | 
|  | 4205 | ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER; | 
|  | 4206 | } else { | 
|  | 4207 | if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) { | 
|  | 4208 | dictnsItem = schema->targetNamespace; | 
|  | 4209 | } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) { | 
|  | 4210 | dictnsItem = NULL; | 
|  | 4211 | } else { | 
|  | 4212 | /* | 
|  | 4213 | * Validate the item (anyURI). | 
|  | 4214 | */ | 
|  | 4215 | xmlSchemaPValAttrNodeValue(ctxt, NULL, NULL, attr, | 
|  | 4216 | nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI)); | 
|  | 4217 | dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1); | 
|  | 4218 | } | 
|  | 4219 | /* | 
|  | 4220 | * Avoid dublicate namespaces. | 
|  | 4221 | */ | 
|  | 4222 | tmp = wildc->nsSet; | 
|  | 4223 | while (tmp != NULL) { | 
|  | 4224 | if (dictnsItem == tmp->value) | 
|  | 4225 | break; | 
|  | 4226 | tmp = tmp->next; | 
|  | 4227 | } | 
|  | 4228 | if (tmp == NULL) { | 
|  | 4229 | tmp = xmlSchemaNewWildcardNsConstraint(ctxt); | 
|  | 4230 | if (tmp == NULL) { | 
|  | 4231 | xmlFree(nsItem); | 
|  | 4232 | return (-1); | 
|  | 4233 | } | 
|  | 4234 | tmp->value = dictnsItem; | 
|  | 4235 | tmp->next = NULL; | 
|  | 4236 | if (wildc->nsSet == NULL) | 
|  | 4237 | wildc->nsSet = tmp; | 
|  | 4238 | else | 
|  | 4239 | lastNs->next = tmp; | 
|  | 4240 | lastNs = tmp; | 
|  | 4241 | } | 
|  | 4242 |  | 
|  | 4243 | } | 
|  | 4244 | xmlFree(nsItem); | 
|  | 4245 | cur = end; | 
|  | 4246 | } while (*cur != 0); | 
|  | 4247 | } | 
|  | 4248 | return (ret); | 
|  | 4249 | } | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 4250 |  | 
|  | 4251 | static int | 
|  | 4252 | xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt, | 
|  | 4253 | xmlSchemaTypePtr item, | 
|  | 4254 | xmlNodePtr node, | 
|  | 4255 | int minOccurs, | 
|  | 4256 | int maxOccurs) { | 
|  | 4257 |  | 
|  | 4258 | if (maxOccurs != UNBOUNDED) { | 
|  | 4259 | /* | 
|  | 4260 | * TODO: Maby we should better not create the particle, | 
|  | 4261 | * if min/max is invalid, since it could confuse the build of the | 
|  | 4262 | * content model. | 
|  | 4263 | */ | 
|  | 4264 | /* | 
|  | 4265 | * 3.9.6 Schema Component Constraint: Particle Correct | 
|  | 4266 | * | 
|  | 4267 | */ | 
|  | 4268 | if (maxOccurs < 1) { | 
|  | 4269 | /* | 
|  | 4270 | * 2.2 {max occurs} must be greater than or equal to 1. | 
|  | 4271 | */ | 
|  | 4272 | xmlSchemaPCustomAttrErr(ctxt, | 
|  | 4273 | XML_SCHEMAP_P_PROPS_CORRECT_2_2, | 
|  | 4274 | NULL, item, xmlSchemaGetPropNode(node, "maxOccurs"), | 
|  | 4275 | "The value must be greater than or equal to 1"); | 
|  | 4276 | return (XML_SCHEMAP_P_PROPS_CORRECT_2_2); | 
|  | 4277 | } else if (minOccurs > maxOccurs) { | 
|  | 4278 | /* | 
|  | 4279 | * 2.1 {min occurs} must not be greater than {max occurs}. | 
|  | 4280 | */ | 
|  | 4281 | xmlSchemaPCustomAttrErr(ctxt, | 
|  | 4282 | XML_SCHEMAP_P_PROPS_CORRECT_2_1, | 
|  | 4283 | NULL, item, xmlSchemaGetPropNode(node, "minOccurs"), | 
|  | 4284 | "The value must not be greater than the value of 'maxOccurs'"); | 
|  | 4285 | return (XML_SCHEMAP_P_PROPS_CORRECT_2_1); | 
|  | 4286 | } | 
|  | 4287 | } | 
|  | 4288 | return (0); | 
|  | 4289 | } | 
|  | 4290 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4291 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4292 | * xmlSchemaParseAny: | 
|  | 4293 | * @ctxt:  a schema validation context | 
|  | 4294 | * @schema:  the schema being built | 
|  | 4295 | * @node:  a subtree containing XML Schema informations | 
|  | 4296 | * | 
|  | 4297 | * parse a XML schema Any declaration | 
|  | 4298 | * *WARNING* this interface is highly subject to change | 
|  | 4299 | * | 
|  | 4300 | * Returns the new type structure or NULL in case of error | 
|  | 4301 | */ | 
|  | 4302 | static xmlSchemaTypePtr | 
|  | 4303 | xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
|  | 4304 | xmlNodePtr node) | 
|  | 4305 | { | 
|  | 4306 | xmlSchemaTypePtr type; | 
|  | 4307 | xmlNodePtr child = NULL; | 
|  | 4308 | xmlChar name[30]; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4309 | xmlSchemaWildcardPtr wildc; | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 4310 | int minOccurs, maxOccurs; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4311 |  | 
|  | 4312 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 4313 | return (NULL); | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 4314 | maxOccurs = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, | 
|  | 4315 | "(nonNegativeInteger | unbounded)"); | 
|  | 4316 | minOccurs = xmlGetMinOccurs(ctxt, node, 0, -1, 1, | 
|  | 4317 | "nonNegativeInteger"); | 
|  | 4318 | if ((minOccurs == 0) && (maxOccurs == 0)) | 
|  | 4319 | return (NULL); | 
|  | 4320 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4321 | snprintf((char *) name, 30, "any %d", ctxt->counter++ + 1); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 4322 | type = xmlSchemaAddType(ctxt, schema, name, NULL, node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4323 | if (type == NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4324 | return (NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4325 | type->node = node; | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 4326 | type->type = XML_SCHEMA_TYPE_ANY; | 
|  | 4327 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4328 | wildc = xmlSchemaAddWildcard(ctxt); | 
|  | 4329 | /* | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 4330 | * Check min/max sanity. | 
|  | 4331 | */ | 
|  | 4332 | type->maxOccurs = maxOccurs; | 
|  | 4333 | type->minOccurs = minOccurs; | 
|  | 4334 | xmlSchemaPCheckParticleCorrect_2(ctxt, type, | 
|  | 4335 | node, type->minOccurs, type->maxOccurs); | 
|  | 4336 | /* | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4337 | * This is not nice, since it is won't be used as a attribute wildcard, | 
|  | 4338 | * but better than adding a field to the structure. | 
|  | 4339 | */ | 
|  | 4340 | type->attributeWildcard = wildc; | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 4341 | xmlSchemaParseWildcardNs(ctxt, schema, wildc, node); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4342 | child = node->children; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4343 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4344 | type->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 4345 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4346 | } | 
|  | 4347 | if (child != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4348 | xmlSchemaPErr2(ctxt, node, child, | 
|  | 4349 | XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD, | 
|  | 4350 | "Sequence %s has unexpected content\n", type->name, | 
|  | 4351 | NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4352 | } | 
|  | 4353 |  | 
|  | 4354 | return (type); | 
|  | 4355 | } | 
|  | 4356 |  | 
|  | 4357 | /** | 
|  | 4358 | * xmlSchemaParseNotation: | 
|  | 4359 | * @ctxt:  a schema validation context | 
|  | 4360 | * @schema:  the schema being built | 
|  | 4361 | * @node:  a subtree containing XML Schema informations | 
|  | 4362 | * | 
|  | 4363 | * parse a XML schema Notation declaration | 
|  | 4364 | * | 
|  | 4365 | * Returns the new structure or NULL in case of error | 
|  | 4366 | */ | 
|  | 4367 | static xmlSchemaNotationPtr | 
|  | 4368 | xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4369 | xmlNodePtr node) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4370 | { | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 4371 | const xmlChar *name; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4372 | xmlSchemaNotationPtr ret; | 
|  | 4373 | xmlNodePtr child = NULL; | 
|  | 4374 |  | 
|  | 4375 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 4376 | return (NULL); | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 4377 | name = xmlSchemaGetProp(ctxt, node, "name"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4378 | if (name == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4379 | xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME, | 
|  | 4380 | "Notation has no name\n", NULL, NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4381 | return (NULL); | 
|  | 4382 | } | 
|  | 4383 | ret = xmlSchemaAddNotation(ctxt, schema, name); | 
|  | 4384 | if (ret == NULL) { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4385 | return (NULL); | 
|  | 4386 | } | 
|  | 4387 | child = node->children; | 
|  | 4388 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4389 | ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 4390 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4391 | } | 
|  | 4392 | if (child != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4393 | xmlSchemaPErr2(ctxt, node, child, | 
|  | 4394 | XML_SCHEMAP_UNKNOWN_NOTATION_CHILD, | 
|  | 4395 | "notation %s has unexpected content\n", name, NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4396 | } | 
|  | 4397 |  | 
|  | 4398 | return (ret); | 
|  | 4399 | } | 
|  | 4400 |  | 
|  | 4401 | /** | 
|  | 4402 | * xmlSchemaParseAnyAttribute: | 
|  | 4403 | * @ctxt:  a schema validation context | 
|  | 4404 | * @schema:  the schema being built | 
|  | 4405 | * @node:  a subtree containing XML Schema informations | 
|  | 4406 | * | 
|  | 4407 | * parse a XML schema AnyAttrribute declaration | 
|  | 4408 | * *WARNING* this interface is highly subject to change | 
|  | 4409 | * | 
|  | 4410 | * Returns an attribute def structure or NULL | 
|  | 4411 | */ | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 4412 | static xmlSchemaWildcardPtr | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4413 | xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, | 
|  | 4414 | xmlSchemaPtr schema, xmlNodePtr node) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4415 | { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 4416 | xmlSchemaWildcardPtr ret; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4417 | xmlNodePtr child = NULL; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4418 |  | 
|  | 4419 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 4420 | return (NULL); | 
|  | 4421 |  | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 4422 | ret = xmlSchemaAddWildcard(ctxt); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4423 | if (ret == NULL) { | 
|  | 4424 | return (NULL); | 
|  | 4425 | } | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 4426 | ret->type = XML_SCHEMA_TYPE_ANY_ATTRIBUTE; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 4427 | ret->id = xmlSchemaGetProp(ctxt, node, "id"); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4428 | if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0) { | 
|  | 4429 | xmlSchemaFreeWildcard(ret); | 
|  | 4430 | return (NULL); | 
|  | 4431 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4432 | child = node->children; | 
|  | 4433 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4434 | ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 4435 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4436 | } | 
|  | 4437 | if (child != NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4438 | /* TODO: Change the error code. */ | 
|  | 4439 | xmlSchemaPContentErr(ctxt, | 
|  | 4440 | XML_SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD, | 
|  | 4441 | NULL, NULL, node, child, | 
|  | 4442 | NULL, "(annotation?)"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4443 | } | 
|  | 4444 |  | 
|  | 4445 | return (ret); | 
|  | 4446 | } | 
|  | 4447 |  | 
|  | 4448 |  | 
|  | 4449 | /** | 
|  | 4450 | * xmlSchemaParseAttribute: | 
|  | 4451 | * @ctxt:  a schema validation context | 
|  | 4452 | * @schema:  the schema being built | 
|  | 4453 | * @node:  a subtree containing XML Schema informations | 
|  | 4454 | * | 
|  | 4455 | * parse a XML schema Attrribute declaration | 
|  | 4456 | * *WARNING* this interface is highly subject to change | 
|  | 4457 | * | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 4458 | * Returns the attribute declaration. | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4459 | */ | 
|  | 4460 | static xmlSchemaAttributePtr | 
|  | 4461 | xmlSchemaParseAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 4462 | xmlNodePtr node, int topLevel) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4463 | { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4464 | const xmlChar *name, *attrValue; | 
|  | 4465 | xmlChar *repName = NULL; /* The reported designation. */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4466 | xmlSchemaAttributePtr ret; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4467 | xmlNodePtr child = NULL; | 
|  | 4468 | xmlAttrPtr attr, nameAttr; | 
|  | 4469 | int isRef = 0; | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 4470 |  | 
|  | 4471 | /* | 
|  | 4472 | * Note that the w3c spec assumes the schema to be validated with schema | 
|  | 4473 | * for schemas beforehand. | 
|  | 4474 | * | 
|  | 4475 | * 3.2.3 Constraints on XML Representations of Attribute Declarations | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 4476 | */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4477 |  | 
|  | 4478 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 4479 | return (NULL); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4480 | attr = xmlSchemaGetPropNode(node, "ref"); | 
|  | 4481 | nameAttr = xmlSchemaGetPropNode(node, "name"); | 
|  | 4482 |  | 
|  | 4483 | if ((attr == NULL) && (nameAttr == NULL)) { | 
|  | 4484 | /* | 
|  | 4485 | * 3.2.3 : 3.1 | 
|  | 4486 | * One of ref or name must be present, but not both | 
|  | 4487 | */ | 
|  | 4488 | xmlSchemaPMissingAttrErr(ctxt, XML_SCHEMAP_SRC_ATTRIBUTE_3_1, | 
|  | 4489 | (xmlChar **) &xmlSchemaElemDesAttrDecl, NULL, node, NULL, | 
|  | 4490 | "One of the attributes 'ref' or 'name' must be present"); | 
|  | 4491 | return (NULL); | 
|  | 4492 | } | 
|  | 4493 | if ((topLevel) || (attr == NULL)) { | 
|  | 4494 | if (nameAttr == NULL) { | 
|  | 4495 | xmlSchemaPMissingAttrErr(ctxt, XML_SCHEMAP_S4S_ATTR_MISSING, | 
|  | 4496 | (xmlChar **) &xmlSchemaElemDesAttrDecl, NULL, node, | 
|  | 4497 | "name", NULL); | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 4498 | return (NULL); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4499 | } | 
|  | 4500 | } else | 
|  | 4501 | isRef = 1; | 
|  | 4502 |  | 
|  | 4503 | if (isRef) { | 
|  | 4504 | char buf[100]; | 
|  | 4505 | const xmlChar *refNs = NULL, *ref = NULL, *refPrefix = NULL; | 
|  | 4506 |  | 
|  | 4507 | /* | 
|  | 4508 | * Parse as attribute reference. | 
|  | 4509 | */ | 
|  | 4510 | if (xmlSchemaPValAttrNodeQName(ctxt, schema, | 
|  | 4511 | (xmlChar **) &xmlSchemaElemDesAttrRef, NULL, attr, &refNs, | 
|  | 4512 | &refPrefix, &ref) != 0) { | 
|  | 4513 | return (NULL); | 
|  | 4514 | } | 
|  | 4515 | snprintf(buf, 99, "#aRef %d", ctxt->counter++ + 1); | 
|  | 4516 | name = (const xmlChar *) buf; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 4517 | ret = xmlSchemaAddAttribute(ctxt, schema, name, NULL, node); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4518 | if (ret == NULL) { | 
|  | 4519 | if (repName != NULL) | 
|  | 4520 | xmlFree(repName); | 
|  | 4521 | return (NULL); | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 4522 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4523 | ret->type = XML_SCHEMA_TYPE_ATTRIBUTE; | 
|  | 4524 | ret->node = node; | 
|  | 4525 | ret->refNs = refNs; | 
|  | 4526 | ret->refPrefix = refPrefix; | 
|  | 4527 | ret->ref = ref; | 
|  | 4528 | /* | 
|  | 4529 | xmlSchemaFormatTypeRep(&repName, (xmlSchemaTypePtr) ret, NULL, NULL); | 
|  | 4530 | */ | 
|  | 4531 | if (nameAttr != NULL) | 
|  | 4532 | xmlSchemaPMutualExclAttrErr(ctxt, XML_SCHEMAP_SRC_ATTRIBUTE_3_1, | 
|  | 4533 | &repName, (xmlSchemaTypePtr) ret, nameAttr, | 
|  | 4534 | "ref", "name"); | 
|  | 4535 | /* | 
|  | 4536 | * Check for illegal attributes. | 
|  | 4537 | */ | 
|  | 4538 | attr = node->properties; | 
|  | 4539 | while (attr != NULL) { | 
|  | 4540 | if (attr->ns == NULL) { | 
|  | 4541 | if (xmlStrEqual(attr->name, BAD_CAST "type") || | 
|  | 4542 | xmlStrEqual(attr->name, BAD_CAST "form")) { | 
|  | 4543 | /* | 
|  | 4544 | * 3.2.3 : 3.2 | 
|  | 4545 | * If ref is present, then all of <simpleType>, | 
|  | 4546 | * form and type must be absent. | 
|  | 4547 | */ | 
|  | 4548 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 4549 | XML_SCHEMAP_SRC_ATTRIBUTE_3_2, &repName, | 
|  | 4550 | (xmlSchemaTypePtr) ret, attr); | 
|  | 4551 | } else if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && | 
|  | 4552 | (!xmlStrEqual(attr->name, BAD_CAST "use")) && | 
|  | 4553 | (!xmlStrEqual(attr->name, BAD_CAST "id")) && | 
|  | 4554 | (!xmlStrEqual(attr->name, BAD_CAST "name")) && | 
|  | 4555 | (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && | 
|  | 4556 | (!xmlStrEqual(attr->name, BAD_CAST "default"))) { | 
|  | 4557 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 4558 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 4559 | &repName, (xmlSchemaTypePtr) ret, attr); | 
|  | 4560 | } | 
|  | 4561 | } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { | 
|  | 4562 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 4563 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 4564 | &repName, (xmlSchemaTypePtr) ret, attr); | 
|  | 4565 | } | 
|  | 4566 | attr = attr->next; | 
|  | 4567 | } | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 4568 | } else { | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 4569 | const xmlChar *ns = NULL; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4570 |  | 
|  | 4571 | /* | 
|  | 4572 | * Parse as attribute declaration. | 
|  | 4573 | */ | 
|  | 4574 | if (xmlSchemaPValAttrNode(ctxt, | 
|  | 4575 | (xmlChar **) &xmlSchemaElemDesAttrDecl, NULL, nameAttr, | 
|  | 4576 | xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { | 
|  | 4577 | return (NULL); | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 4578 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4579 | /* | 
|  | 4580 | xmlSchemaFormatTypeRep(&repName, NULL, xmlSchemaElemDesAttrDecl, name); | 
|  | 4581 | */ | 
|  | 4582 | /* | 
|  | 4583 | * 3.2.6 Schema Component Constraint: xmlns Not Allowed | 
|  | 4584 | */ | 
|  | 4585 | if (xmlStrEqual(name, BAD_CAST "xmlns")) { | 
|  | 4586 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 4587 | XML_SCHEMAP_NO_XMLNS, | 
|  | 4588 | &repName, NULL, (xmlNodePtr) nameAttr, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 4589 | xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), "NCName", NULL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4590 | "The value must not match 'xmlns'", | 
|  | 4591 | NULL, NULL); | 
|  | 4592 | if (repName != NULL) | 
|  | 4593 | xmlFree(repName); | 
|  | 4594 | return (NULL); | 
|  | 4595 | } | 
|  | 4596 | /* | 
|  | 4597 | * Evaluate the target namespace | 
|  | 4598 | */ | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 4599 | if (topLevel) { | 
|  | 4600 | ns = schema->targetNamespace; | 
|  | 4601 | } else { | 
|  | 4602 | attr = xmlSchemaGetPropNode(node, "form"); | 
|  | 4603 | if (attr != NULL) { | 
|  | 4604 | attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); | 
|  | 4605 | if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { | 
|  | 4606 | ns = schema->targetNamespace; | 
|  | 4607 | } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) { | 
|  | 4608 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 4609 | XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, | 
|  | 4610 | &repName, NULL, (xmlNodePtr) attr, | 
|  | 4611 | NULL, "(qualified | unqualified)", | 
|  | 4612 | attrValue, NULL, NULL, NULL); | 
|  | 4613 | } | 
|  | 4614 | } else if (schema->flags & XML_SCHEMAS_QUALIF_ATTR) | 
|  | 4615 | ns = schema->targetNamespace; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4616 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 4617 | ret = xmlSchemaAddAttribute(ctxt, schema, name, ns, node); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4618 | if (ret == NULL) { | 
|  | 4619 | if (repName != NULL) | 
|  | 4620 | xmlFree(repName); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 4621 | return (NULL); | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 4622 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4623 | ret->type = XML_SCHEMA_TYPE_ATTRIBUTE; | 
|  | 4624 | ret->node = node; | 
|  | 4625 | if (topLevel) | 
|  | 4626 | ret->flags |= XML_SCHEMAS_ATTR_GLOBAL; | 
|  | 4627 | /* | 
|  | 4628 | * 3.2.6 Schema Component Constraint: xsi: Not Allowed | 
|  | 4629 | */ | 
|  | 4630 | if (xmlStrEqual(ret->targetNamespace, xmlSchemaInstanceNs)) { | 
|  | 4631 | xmlSchemaPCustomErr(ctxt, | 
|  | 4632 | XML_SCHEMAP_NO_XSI, | 
|  | 4633 | &repName, (xmlSchemaTypePtr) ret, node, | 
|  | 4634 | "The target namespace must not match '%s'", | 
|  | 4635 | xmlSchemaInstanceNs); | 
|  | 4636 | } | 
|  | 4637 | /* | 
|  | 4638 | * Check for illegal attributes. | 
|  | 4639 | */ | 
|  | 4640 | attr = node->properties; | 
|  | 4641 | while (attr != NULL) { | 
|  | 4642 | if (attr->ns == NULL) { | 
|  | 4643 | if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && | 
|  | 4644 | (!xmlStrEqual(attr->name, BAD_CAST "default")) && | 
|  | 4645 | (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && | 
|  | 4646 | (!xmlStrEqual(attr->name, BAD_CAST "name")) && | 
|  | 4647 | (!xmlStrEqual(attr->name, BAD_CAST "type"))) { | 
|  | 4648 | if ((topLevel) || | 
|  | 4649 | ((!xmlStrEqual(attr->name, BAD_CAST "form")) && | 
|  | 4650 | (!xmlStrEqual(attr->name, BAD_CAST "use")))) { | 
|  | 4651 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 4652 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 4653 | &repName, (xmlSchemaTypePtr) ret, attr); | 
|  | 4654 | } | 
|  | 4655 | } | 
|  | 4656 | } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { | 
|  | 4657 | xmlSchemaPIllegalAttrErr(ctxt, XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 4658 | &repName, (xmlSchemaTypePtr) ret, attr); | 
|  | 4659 | } | 
|  | 4660 | attr = attr->next; | 
|  | 4661 | } | 
|  | 4662 | xmlSchemaPValAttrQName(ctxt, schema, &repName, (xmlSchemaTypePtr) ret, | 
|  | 4663 | node, "type", &ret->typeNs, NULL, &ret->typeName); | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 4664 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4665 | /* TODO: Check ID. */ | 
|  | 4666 | ret->id = xmlSchemaGetProp(ctxt, node, "id"); | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 4667 | /* | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4668 | * Attribute "fixed". | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 4669 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4670 | ret->defValue = xmlSchemaGetProp(ctxt, node, "fixed"); | 
|  | 4671 | if (ret->defValue != NULL) | 
|  | 4672 | ret->flags |= XML_SCHEMAS_ATTR_FIXED; | 
|  | 4673 | /* | 
|  | 4674 | * Attribute "default". | 
|  | 4675 | */ | 
|  | 4676 | attr = xmlSchemaGetPropNode(node, "default"); | 
|  | 4677 | if (attr != NULL) { | 
|  | 4678 | /* | 
|  | 4679 | * 3.2.3 : 1 | 
|  | 4680 | * default and fixed must not both be present. | 
|  | 4681 | */ | 
|  | 4682 | if (ret->flags & XML_SCHEMAS_ATTR_FIXED) { | 
|  | 4683 | xmlSchemaPMutualExclAttrErr(ctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1, | 
|  | 4684 | &repName, (xmlSchemaTypePtr) ret, attr, "default", "fixed"); | 
|  | 4685 | } else | 
|  | 4686 | ret->defValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); | 
|  | 4687 | } | 
|  | 4688 | if (topLevel == 0) { | 
|  | 4689 | /* | 
|  | 4690 | * Attribute "use". | 
|  | 4691 | */ | 
|  | 4692 | attr = xmlSchemaGetPropNode(node, "use"); | 
|  | 4693 | if (attr != NULL) { | 
|  | 4694 | attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); | 
|  | 4695 | if (xmlStrEqual(attrValue, BAD_CAST "optional")) | 
|  | 4696 | ret->occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; | 
|  | 4697 | else if (xmlStrEqual(attrValue, BAD_CAST "prohibited")) | 
|  | 4698 | ret->occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED; | 
|  | 4699 | else if (xmlStrEqual(attrValue, BAD_CAST "required")) | 
|  | 4700 | ret->occurs = XML_SCHEMAS_ATTR_USE_REQUIRED; | 
|  | 4701 | else | 
|  | 4702 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 4703 | XML_SCHEMAP_INVALID_ATTR_USE, | 
|  | 4704 | &repName, (xmlSchemaTypePtr) ret, (xmlNodePtr) attr, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 4705 | NULL, "(optional | prohibited | required)", | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4706 | attrValue, NULL, NULL, NULL); | 
|  | 4707 | } else | 
|  | 4708 | ret->occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; | 
|  | 4709 | /* | 
|  | 4710 | * 3.2.3 : 2 | 
|  | 4711 | * If default and use are both present, use must have | 
|  | 4712 | * the actual value optional. | 
|  | 4713 | */ | 
|  | 4714 | if ((ret->occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL) && | 
|  | 4715 | (ret->defValue != NULL) && | 
|  | 4716 | ((ret->flags & XML_SCHEMAS_ATTR_FIXED) == 0)) { | 
|  | 4717 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 4718 | XML_SCHEMAP_SRC_ATTRIBUTE_2, | 
|  | 4719 | &repName, (xmlSchemaTypePtr) ret, (xmlNodePtr) attr, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 4720 | NULL, "(optional | prohibited | required)", NULL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4721 | "The value must be 'optional' if the attribute " | 
|  | 4722 | "'default' is present as well", NULL, NULL); | 
|  | 4723 | } | 
|  | 4724 | } | 
|  | 4725 | /* | 
|  | 4726 | * And now for the children... | 
|  | 4727 | */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4728 | child = node->children; | 
|  | 4729 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4730 | ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 4731 | child = child->next; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4732 | } | 
|  | 4733 | if (isRef) { | 
|  | 4734 | if (child != NULL) { | 
|  | 4735 | if (IS_SCHEMA(child, "simpleType")) | 
|  | 4736 | /* | 
|  | 4737 | * 3.2.3 : 3.2 | 
|  | 4738 | * If ref is present, then all of <simpleType>, | 
|  | 4739 | * form and type must be absent. | 
|  | 4740 | */ | 
|  | 4741 | xmlSchemaPContentErr(ctxt, XML_SCHEMAP_SRC_ATTRIBUTE_3_2, | 
|  | 4742 | &repName, (xmlSchemaTypePtr) ret, node, child, NULL, | 
|  | 4743 | "(annotation?)"); | 
|  | 4744 | else | 
|  | 4745 | xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, | 
|  | 4746 | &repName, (xmlSchemaTypePtr) ret, node, child, NULL, | 
|  | 4747 | "(annotation?)"); | 
|  | 4748 | } | 
|  | 4749 | } else { | 
|  | 4750 | if (IS_SCHEMA(child, "simpleType")) { | 
|  | 4751 | if (ret->typeName != NULL) { | 
|  | 4752 | /* | 
|  | 4753 | * 3.2.3 : 4 | 
|  | 4754 | * type and <simpleType> must not both be present. | 
|  | 4755 | */ | 
|  | 4756 | xmlSchemaPContentErr(ctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, | 
|  | 4757 | &repName,  (xmlSchemaTypePtr) ret, node, child, | 
|  | 4758 | "The attribute 'type' and the <simpleType> child " | 
|  | 4759 | "are mutually exclusive", NULL); | 
|  | 4760 | } else | 
|  | 4761 | ret->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0); | 
|  | 4762 | child = child->next; | 
|  | 4763 | } | 
|  | 4764 | if (child != NULL) | 
|  | 4765 | xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, | 
|  | 4766 | &repName, (xmlSchemaTypePtr) ret, node, child, NULL, | 
|  | 4767 | "(annotation?, simpleType?)"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4768 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4769 | /* | 
|  | 4770 | * Cleanup. | 
|  | 4771 | */ | 
|  | 4772 | if (repName != NULL) | 
|  | 4773 | xmlFree(repName); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4774 | return (ret); | 
|  | 4775 | } | 
|  | 4776 |  | 
|  | 4777 | /** | 
|  | 4778 | * xmlSchemaParseAttributeGroup: | 
|  | 4779 | * @ctxt:  a schema validation context | 
|  | 4780 | * @schema:  the schema being built | 
|  | 4781 | * @node:  a subtree containing XML Schema informations | 
|  | 4782 | * | 
|  | 4783 | * parse a XML schema Attribute Group declaration | 
|  | 4784 | * *WARNING* this interface is highly subject to change | 
|  | 4785 | * | 
|  | 4786 | * Returns the attribute group or NULL in case of error. | 
|  | 4787 | */ | 
|  | 4788 | static xmlSchemaAttributeGroupPtr | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4789 | xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt, | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 4790 | xmlSchemaPtr schema, xmlNodePtr node, | 
|  | 4791 | int topLevel) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4792 | { | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 4793 | const xmlChar *name, *refNs = NULL, *ref = NULL; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4794 | xmlSchemaAttributeGroupPtr ret; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4795 | xmlNodePtr child = NULL; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 4796 | const xmlChar *oldcontainer; | 
|  | 4797 | char buf[100]; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4798 |  | 
|  | 4799 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 4800 | return (NULL); | 
|  | 4801 | oldcontainer = ctxt->container; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 4802 | name = xmlSchemaGetProp(ctxt, node, "name"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4803 | if (name == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4804 | ref = xmlGetQNameProp(ctxt, node, "ref", &refNs); | 
|  | 4805 | if (ref == NULL) { | 
|  | 4806 | xmlSchemaPErr2(ctxt, node, child, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4807 | XML_SCHEMAP_ATTRGRP_NONAME_NOREF, | 
|  | 4808 | "Attribute group or particle: One of the attributes 'name' " | 
|  | 4809 | "or 'ref' must be present.\n", NULL, | 
|  | 4810 | NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4811 | return (NULL); | 
|  | 4812 | } | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 4813 | snprintf(buf, 99, "anonattrgroup %d", ctxt->counter++ + 1); | 
|  | 4814 | name = (const xmlChar *) buf; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4815 | if (name == NULL) { | 
|  | 4816 | xmlSchemaPErrMemory(ctxt, "creating attribute group", node); | 
|  | 4817 | return (NULL); | 
|  | 4818 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4819 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 4820 | ret = xmlSchemaAddAttributeGroup(ctxt, schema, name, node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4821 | if (ret == NULL) { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4822 | return (NULL); | 
|  | 4823 | } | 
|  | 4824 | ret->ref = ref; | 
|  | 4825 | ret->refNs = refNs; | 
| Daniel Veillard | 13e04c6 | 2002-04-23 17:51:29 +0000 | [diff] [blame] | 4826 | ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 4827 | if (topLevel) | 
|  | 4828 | ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL; | 
| Daniel Veillard | 75bb3bb | 2003-05-12 15:25:56 +0000 | [diff] [blame] | 4829 | ret->node = node; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4830 | child = node->children; | 
|  | 4831 | ctxt->container = name; | 
|  | 4832 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4833 | ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 4834 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4835 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4836 | child = xmlSchemaParseAttrDecls(ctxt, schema, child, (xmlSchemaTypePtr) ret); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4837 | if (child != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4838 | xmlSchemaPErr2(ctxt, node, child, | 
|  | 4839 | XML_SCHEMAP_UNKNOWN_ATTRGRP_CHILD, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4840 | "Attribute group '%s' has unexpected content.\n", name, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 4841 | NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4842 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4843 | ctxt->container = oldcontainer; | 
|  | 4844 | return (ret); | 
|  | 4845 | } | 
|  | 4846 |  | 
|  | 4847 | /** | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 4848 | * xmlSchemaPValAttrFormDefault: | 
|  | 4849 | * @value:  the value | 
|  | 4850 | * @flags: the flags to be modified | 
|  | 4851 | * @flagQualified: the specific flag for "qualified" | 
|  | 4852 | * | 
|  | 4853 | * Returns 0 if the value is valid, 1 otherwise. | 
|  | 4854 | */ | 
|  | 4855 | static int | 
|  | 4856 | xmlSchemaPValAttrFormDefault(const xmlChar *value, | 
|  | 4857 | int *flags, | 
|  | 4858 | int flagQualified) | 
|  | 4859 | { | 
|  | 4860 | if (xmlStrEqual(value, BAD_CAST "qualified")) { | 
|  | 4861 | if  ((*flags & flagQualified) == 0) | 
|  | 4862 | *flags |= flagQualified; | 
|  | 4863 | } else if (!xmlStrEqual(value, BAD_CAST "unqualified")) | 
|  | 4864 | return (1); | 
|  | 4865 |  | 
|  | 4866 | return (0); | 
|  | 4867 | } | 
|  | 4868 |  | 
|  | 4869 | /** | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4870 | * xmlSchemaPValAttrBlockFinal: | 
|  | 4871 | * @value:  the value | 
|  | 4872 | * @flags: the flags to be modified | 
|  | 4873 | * @flagAll: the specific flag for "#all" | 
|  | 4874 | * @flagExtension: the specific flag for "extension" | 
|  | 4875 | * @flagRestriction: the specific flag for "restriction" | 
|  | 4876 | * @flagSubstitution: the specific flag for "substitution" | 
|  | 4877 | * @flagList: the specific flag for "list" | 
|  | 4878 | * @flagUnion: the specific flag for "union" | 
|  | 4879 | * | 
|  | 4880 | * Validates the value of the attribute "final" and "block". The value | 
|  | 4881 | * is converted into the specified flag values and returned in @flags. | 
|  | 4882 | * | 
|  | 4883 | * Returns 0 if the value is valid, 1 otherwise. | 
|  | 4884 | */ | 
|  | 4885 |  | 
|  | 4886 | static int | 
|  | 4887 | xmlSchemaPValAttrBlockFinal(const xmlChar *value, | 
|  | 4888 | int *flags, | 
|  | 4889 | int flagAll, | 
|  | 4890 | int flagExtension, | 
|  | 4891 | int flagRestriction, | 
|  | 4892 | int flagSubstitution, | 
|  | 4893 | int flagList, | 
|  | 4894 | int flagUnion) | 
|  | 4895 | { | 
|  | 4896 | int ret = 0; | 
|  | 4897 |  | 
|  | 4898 | /* | 
|  | 4899 | * TODO: This does not check for dublicate entries. | 
|  | 4900 | */ | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 4901 | if (value == NULL) | 
|  | 4902 | return (1); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4903 | if (xmlStrEqual(value, BAD_CAST "#all")) { | 
|  | 4904 | if (flagAll != -1) | 
|  | 4905 | *flags |= flagAll; | 
|  | 4906 | else { | 
|  | 4907 | if (flagExtension != -1) | 
|  | 4908 | *flags |= flagExtension; | 
|  | 4909 | if (flagRestriction != -1) | 
|  | 4910 | *flags |= flagRestriction; | 
|  | 4911 | if (flagSubstitution != -1) | 
|  | 4912 | *flags |= flagSubstitution; | 
|  | 4913 | if (flagList != -1) | 
|  | 4914 | *flags |= flagList; | 
|  | 4915 | if (flagUnion != -1) | 
|  | 4916 | *flags |= flagUnion; | 
|  | 4917 | } | 
|  | 4918 | } else { | 
|  | 4919 | const xmlChar *end, *cur = value; | 
|  | 4920 | xmlChar *item; | 
|  | 4921 |  | 
|  | 4922 | do { | 
|  | 4923 | while (IS_BLANK_CH(*cur)) | 
|  | 4924 | cur++; | 
|  | 4925 | end = cur; | 
|  | 4926 | while ((*end != 0) && (!(IS_BLANK_CH(*end)))) | 
|  | 4927 | end++; | 
|  | 4928 | if (end == cur) | 
|  | 4929 | break; | 
|  | 4930 | item = xmlStrndup(cur, end - cur); | 
|  | 4931 | if (xmlStrEqual(item, BAD_CAST "extension")) { | 
|  | 4932 | if (flagExtension != -1) { | 
|  | 4933 | if ((*flags & flagExtension) == 0) | 
|  | 4934 | *flags |= flagExtension; | 
|  | 4935 | } else | 
|  | 4936 | ret = 1; | 
|  | 4937 | } else if (xmlStrEqual(item, BAD_CAST "restriction")) { | 
|  | 4938 | if (flagRestriction != -1) { | 
|  | 4939 | if ((*flags & flagRestriction) == 0) | 
|  | 4940 | *flags |= flagRestriction; | 
|  | 4941 | } else | 
|  | 4942 | ret = 1; | 
|  | 4943 | } else if (xmlStrEqual(item, BAD_CAST "substitution")) { | 
|  | 4944 | if (flagSubstitution != -1) { | 
|  | 4945 | if ((*flags & flagSubstitution) == 0) | 
|  | 4946 | *flags |= flagSubstitution; | 
|  | 4947 | } else | 
|  | 4948 | ret = 1; | 
|  | 4949 | } else if (xmlStrEqual(item, BAD_CAST "list")) { | 
|  | 4950 | if (flagList != -1) { | 
|  | 4951 | if ((*flags & flagList) == 0) | 
|  | 4952 | *flags |= flagList; | 
|  | 4953 | } else | 
|  | 4954 | ret = 1; | 
|  | 4955 | } else if (xmlStrEqual(item, BAD_CAST "union")) { | 
|  | 4956 | if (flagUnion != -1) { | 
|  | 4957 | if ((*flags & flagUnion) == 0) | 
|  | 4958 | *flags |= flagUnion; | 
|  | 4959 | } else | 
|  | 4960 | ret = 1; | 
|  | 4961 | } else | 
|  | 4962 | ret = 1; | 
|  | 4963 | if (item != NULL) | 
|  | 4964 | xmlFree(item); | 
|  | 4965 | cur = end; | 
|  | 4966 | } while ((ret == 0) && (*cur != 0)); | 
|  | 4967 | } | 
|  | 4968 |  | 
|  | 4969 | return (ret); | 
|  | 4970 | } | 
|  | 4971 |  | 
|  | 4972 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4973 | * xmlSchemaParseElement: | 
|  | 4974 | * @ctxt:  a schema validation context | 
|  | 4975 | * @schema:  the schema being built | 
|  | 4976 | * @node:  a subtree containing XML Schema informations | 
|  | 4977 | * | 
|  | 4978 | * parse a XML schema Element declaration | 
|  | 4979 | * *WARNING* this interface is highly subject to change | 
|  | 4980 | * | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 4981 | * Returns the parsed element declaration. | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4982 | */ | 
|  | 4983 | static xmlSchemaElementPtr | 
|  | 4984 | xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 4985 | xmlNodePtr node, int topLevel) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4986 | { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4987 | const xmlChar *name = NULL; | 
|  | 4988 | const xmlChar *attrValue; | 
|  | 4989 | xmlChar *repName = NULL; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 4990 | xmlSchemaElementPtr ret; | 
|  | 4991 | xmlNodePtr child = NULL; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4992 | const xmlChar *oldcontainer; | 
|  | 4993 | xmlAttrPtr attr, nameAttr; | 
|  | 4994 | int minOccurs, maxOccurs; | 
|  | 4995 | int isRef = 0; | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 4996 |  | 
|  | 4997 | /* 3.3.3 Constraints on XML Representations of Element Declarations */ | 
|  | 4998 | /* TODO: Complete implementation of 3.3.6 */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 4999 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5000 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 5001 | return (NULL); | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 5002 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5003 | oldcontainer = ctxt->container; | 
|  | 5004 |  | 
|  | 5005 | nameAttr = xmlSchemaGetPropNode(node, "name"); | 
|  | 5006 | attr = xmlSchemaGetPropNode(node, "ref"); | 
|  | 5007 | if ((topLevel) || (attr == NULL)) { | 
|  | 5008 | if (nameAttr == NULL) { | 
|  | 5009 | xmlSchemaPMissingAttrErr(ctxt, | 
|  | 5010 | XML_SCHEMAP_S4S_ATTR_MISSING, | 
|  | 5011 | (xmlChar **) &xmlSchemaElemDesElemDecl, NULL, node, | 
|  | 5012 | "name", NULL); | 
|  | 5013 | return (NULL); | 
|  | 5014 | } | 
|  | 5015 | name = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) nameAttr); | 
|  | 5016 | } else { | 
|  | 5017 | isRef = 1; | 
|  | 5018 |  | 
|  | 5019 | } | 
|  | 5020 | /* | 
|  | 5021 | * ... unless minOccurs=maxOccurs=0, in which case the item corresponds | 
|  | 5022 | * to no component at all | 
|  | 5023 | * TODO: It might be better to validate the element, even if it won't be | 
|  | 5024 | * used. | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 5025 | */ | 
|  | 5026 | minOccurs = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "nonNegativeInteger"); | 
|  | 5027 | maxOccurs = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(nonNegativeInteger | unbounded)"); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5028 | if ((minOccurs == 0) && (maxOccurs == 0)) | 
|  | 5029 | return (NULL); | 
|  | 5030 | /* | 
|  | 5031 | * If we get a "ref" attribute on a local <element> we will assume it's | 
|  | 5032 | * a reference - even if there's a "name" attribute; this seems to be more | 
|  | 5033 | * robust. | 
|  | 5034 | */ | 
|  | 5035 | if (isRef) { | 
|  | 5036 | char buf[100]; | 
|  | 5037 | const xmlChar *refNs = NULL, *ref = NULL, *refPrefix; | 
|  | 5038 |  | 
|  | 5039 | /* | 
|  | 5040 | * Parse as a particle. | 
|  | 5041 | */ | 
|  | 5042 | xmlSchemaPValAttrNodeQName(ctxt, schema, | 
|  | 5043 | (xmlChar **) &xmlSchemaElemDesAttrRef, | 
|  | 5044 | NULL, attr, &refNs, &refPrefix, &ref); | 
|  | 5045 |  | 
|  | 5046 | snprintf(buf, 99, "#eRef %d", ctxt->counter++ + 1); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5047 | name = (const xmlChar *) buf; | 
|  | 5048 | ret = xmlSchemaAddElement(ctxt, schema, name, NULL, node, 0); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5049 | if (ret == NULL) { | 
|  | 5050 | if (repName != NULL) | 
|  | 5051 | xmlFree(repName); | 
|  | 5052 | return (NULL); | 
|  | 5053 | } | 
|  | 5054 | ret->type = XML_SCHEMA_TYPE_ELEMENT; | 
|  | 5055 | ret->node = node; | 
|  | 5056 | ret->ref = ref; | 
|  | 5057 | ret->refNs = refNs; | 
|  | 5058 | ret->refPrefix = refPrefix; | 
|  | 5059 | ret->flags |= XML_SCHEMAS_ELEM_REF; | 
|  | 5060 | /* | 
|  | 5061 | * Check for illegal attributes. | 
|  | 5062 | */ | 
|  | 5063 | /* | 
|  | 5064 | * 3.3.3 : 2.1 | 
|  | 5065 | * One of ref or name must be present, but not both | 
|  | 5066 | */ | 
|  | 5067 | if (nameAttr != NULL) { | 
|  | 5068 | xmlSchemaPMutualExclAttrErr(ctxt, | 
|  | 5069 | XML_SCHEMAP_SRC_ELEMENT_2_1, | 
|  | 5070 | &repName, (xmlSchemaTypePtr) ret, nameAttr, | 
|  | 5071 | "ref", "name"); | 
|  | 5072 | } | 
|  | 5073 | /* 3.3.3 : 2.2 */ | 
|  | 5074 | attr = node->properties; | 
|  | 5075 | while (attr != NULL) { | 
|  | 5076 | if (attr->ns == NULL) { | 
|  | 5077 | if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && | 
|  | 5078 | (!xmlStrEqual(attr->name, BAD_CAST "id")) && | 
|  | 5079 | (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && | 
|  | 5080 | (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && | 
|  | 5081 | (!xmlStrEqual(attr->name, BAD_CAST "name"))) { | 
|  | 5082 | xmlSchemaPCustomAttrErr(ctxt, | 
|  | 5083 | XML_SCHEMAP_SRC_ELEMENT_2_2, | 
|  | 5084 | &repName, (xmlSchemaTypePtr) ret, attr, | 
|  | 5085 | "Only the attributes 'minOccurs', 'maxOccurs' and " | 
|  | 5086 | "'id' are allowed in addition to 'ref'"); | 
|  | 5087 | break; | 
|  | 5088 | } | 
|  | 5089 | } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { | 
|  | 5090 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 5091 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 5092 | &repName, (xmlSchemaTypePtr) ret, attr); | 
|  | 5093 | } | 
|  | 5094 | attr = attr->next; | 
|  | 5095 | } | 
|  | 5096 | } else { | 
|  | 5097 | const xmlChar *ns = NULL, *fixed; | 
|  | 5098 |  | 
|  | 5099 | /* | 
|  | 5100 | * Parse as an element declaration. | 
|  | 5101 | */ | 
|  | 5102 | if (xmlSchemaPValAttrNode(ctxt, | 
|  | 5103 | (xmlChar **) &xmlSchemaElemDesElemDecl, NULL, nameAttr, | 
|  | 5104 | xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) | 
|  | 5105 | return (NULL); | 
|  | 5106 | /* | 
|  | 5107 | * Evaluate the target namespace. | 
|  | 5108 | */ | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 5109 | if (topLevel) { | 
|  | 5110 | ns = schema->targetNamespace; | 
|  | 5111 | } else { | 
|  | 5112 | attr = xmlSchemaGetPropNode(node, "form"); | 
|  | 5113 | if (attr != NULL) { | 
|  | 5114 | attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); | 
|  | 5115 | if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5116 | ns = schema->targetNamespace; | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 5117 | } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) { | 
|  | 5118 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 5119 | XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, | 
|  | 5120 | &repName, NULL, (xmlNodePtr) attr, | 
|  | 5121 | NULL, "(qualified | unqualified)", | 
|  | 5122 | attrValue, NULL, NULL, NULL); | 
|  | 5123 | } | 
|  | 5124 | } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) | 
|  | 5125 | ns = schema->targetNamespace; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5126 | } | 
|  | 5127 | ret = xmlSchemaAddElement(ctxt, schema, name, ns, node, topLevel); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5128 | if (ret == NULL) { | 
|  | 5129 | if (repName != NULL) | 
|  | 5130 | xmlFree(repName); | 
|  | 5131 | return (NULL); | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5132 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5133 | ret->type = XML_SCHEMA_TYPE_ELEMENT; | 
|  | 5134 | ret->node = node; | 
|  | 5135 | /* | 
|  | 5136 | * Check for illegal attributes. | 
|  | 5137 | */ | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5138 | attr = node->properties; | 
|  | 5139 | while (attr != NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5140 | if (attr->ns == NULL) { | 
|  | 5141 | if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && | 
|  | 5142 | (!xmlStrEqual(attr->name, BAD_CAST "type")) && | 
|  | 5143 | (!xmlStrEqual(attr->name, BAD_CAST "id")) && | 
|  | 5144 | (!xmlStrEqual(attr->name, BAD_CAST "default")) && | 
|  | 5145 | (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && | 
|  | 5146 | (!xmlStrEqual(attr->name, BAD_CAST "block")) && | 
|  | 5147 | (!xmlStrEqual(attr->name, BAD_CAST "nillable"))) { | 
|  | 5148 | if (topLevel == 0) { | 
|  | 5149 | if (xmlStrEqual(attr->name, BAD_CAST "substitutionGroup")) { | 
|  | 5150 | /* | 
|  | 5151 | * 3.3.6 : 3 If there is a non-·absent· {substitution | 
|  | 5152 | * group affiliation}, then {scope} must be global. | 
|  | 5153 | * TODO: This one is redundant, since the S4S does | 
|  | 5154 | * prohibit this attribute on local declarations already; | 
|  | 5155 | * so why an explicit error code? Weird spec. | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5156 | * TODO: Move this to the proper constraint layer. | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5157 | */ | 
|  | 5158 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 5159 | XML_SCHEMAP_E_PROPS_CORRECT_3, | 
|  | 5160 | &repName, (xmlSchemaTypePtr) ret, attr); | 
|  | 5161 | } else if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && | 
|  | 5162 | (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && | 
|  | 5163 | (!xmlStrEqual(attr->name, BAD_CAST "form"))) { | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5164 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5165 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 5166 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 5167 | &repName, (xmlSchemaTypePtr) ret, attr); | 
|  | 5168 | } | 
|  | 5169 | } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) && | 
|  | 5170 | (!xmlStrEqual(attr->name, BAD_CAST "abstract")) && | 
|  | 5171 | (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) { | 
|  | 5172 |  | 
|  | 5173 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 5174 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 5175 | &repName, (xmlSchemaTypePtr) ret, attr); | 
|  | 5176 | } | 
|  | 5177 | } | 
|  | 5178 | } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { | 
|  | 5179 |  | 
|  | 5180 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 5181 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 5182 | &repName, (xmlSchemaTypePtr) ret, attr); | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5183 | } | 
|  | 5184 | attr = attr->next; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5185 | } | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5186 | /* | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5187 | * Extract/validate attributes. | 
|  | 5188 | */ | 
|  | 5189 | if (topLevel) { | 
|  | 5190 | /* | 
|  | 5191 | * Process top attributes of global element declarations here. | 
|  | 5192 | */ | 
|  | 5193 | ret->flags |= XML_SCHEMAS_ELEM_GLOBAL; | 
|  | 5194 | ret->flags |= XML_SCHEMAS_ELEM_TOPLEVEL; | 
|  | 5195 | xmlSchemaPValAttrQName(ctxt, schema, &repName, | 
|  | 5196 | (xmlSchemaTypePtr) ret, node, "substitutionGroup", | 
|  | 5197 | &(ret->substGroupNs), NULL, &(ret->substGroup)); | 
|  | 5198 | if (xmlGetBooleanProp(ctxt, &repName, (xmlSchemaTypePtr) ret, | 
|  | 5199 | node, "abstract", 0)) | 
|  | 5200 | ret->flags |= XML_SCHEMAS_ELEM_ABSTRACT; | 
|  | 5201 | /* | 
|  | 5202 | * Attribute "final". | 
|  | 5203 | */ | 
|  | 5204 | attr = xmlSchemaGetPropNode(node, "final"); | 
|  | 5205 | if (attr == NULL) { | 
|  | 5206 | ret->flags |= XML_SCHEMAS_ELEM_FINAL_ABSENT; | 
|  | 5207 | } else { | 
|  | 5208 | attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); | 
|  | 5209 | if (xmlSchemaPValAttrBlockFinal(attrValue, &(ret->flags), | 
|  | 5210 | -1, | 
|  | 5211 | XML_SCHEMAS_ELEM_FINAL_EXTENSION, | 
|  | 5212 | XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) { | 
|  | 5213 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 5214 | XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, | 
|  | 5215 | &repName, (xmlSchemaTypePtr) ret, (xmlNodePtr) attr, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5216 | NULL, "(#all | List of (extension | restriction))", | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5217 | attrValue, NULL, NULL, NULL); | 
|  | 5218 | } | 
|  | 5219 | } | 
|  | 5220 | } | 
|  | 5221 | /* | 
|  | 5222 | * Attribute "block". | 
|  | 5223 | */ | 
|  | 5224 | attr = xmlSchemaGetPropNode(node, "block"); | 
|  | 5225 | if (attr == NULL) { | 
|  | 5226 | ret->flags |= XML_SCHEMAS_ELEM_BLOCK_ABSENT; | 
|  | 5227 | } else { | 
|  | 5228 | attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); | 
|  | 5229 | if (xmlSchemaPValAttrBlockFinal(attrValue, &(ret->flags), | 
|  | 5230 | -1, | 
|  | 5231 | XML_SCHEMAS_ELEM_BLOCK_EXTENSION, | 
|  | 5232 | XML_SCHEMAS_ELEM_BLOCK_RESTRICTION, | 
|  | 5233 | XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) { | 
|  | 5234 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 5235 | XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, | 
|  | 5236 | &repName, (xmlSchemaTypePtr) ret, (xmlNodePtr) attr, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5237 | NULL, "(#all | List of (extension | " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5238 | "restriction | substitution))", attrValue, | 
|  | 5239 | NULL, NULL, NULL); | 
|  | 5240 | } | 
|  | 5241 | } | 
|  | 5242 | if (xmlGetBooleanProp(ctxt, &repName, (xmlSchemaTypePtr) ret, | 
|  | 5243 | node, "nillable", 0)) | 
|  | 5244 | ret->flags |= XML_SCHEMAS_ELEM_NILLABLE; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5245 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5246 | xmlSchemaPValAttrQName(ctxt, schema, | 
|  | 5247 | &repName, (xmlSchemaTypePtr) ret, node, | 
|  | 5248 | "type", &(ret->namedTypeNs), NULL, &(ret->namedType)); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5249 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5250 | ret->value = xmlSchemaGetProp(ctxt, node, "default"); | 
|  | 5251 | attr = xmlSchemaGetPropNode(node, "fixed"); | 
|  | 5252 | if (attr != NULL) { | 
|  | 5253 | fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); | 
|  | 5254 | if (ret->value != NULL) { | 
|  | 5255 | /* | 
|  | 5256 | * 3.3.3 : 1 | 
|  | 5257 | * default and fixed must not both be present. | 
|  | 5258 | */ | 
|  | 5259 | xmlSchemaPMutualExclAttrErr(ctxt, | 
|  | 5260 | XML_SCHEMAP_SRC_ELEMENT_1, | 
|  | 5261 | &repName, (xmlSchemaTypePtr) ret, attr, | 
|  | 5262 | "default", "fixed"); | 
|  | 5263 | } else { | 
|  | 5264 | ret->flags |= XML_SCHEMAS_ELEM_FIXED; | 
|  | 5265 | ret->value = fixed; | 
|  | 5266 | } | 
|  | 5267 | } | 
|  | 5268 | } | 
|  | 5269 | /* | 
|  | 5270 | * Extract/validate common attributes. | 
|  | 5271 | */ | 
|  | 5272 | /* TODO: Check ID: */ | 
|  | 5273 | ret->id = xmlSchemaGetProp(ctxt, node, "id"); | 
|  | 5274 | ret->minOccurs = minOccurs; | 
|  | 5275 | ret->maxOccurs = maxOccurs; | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 5276 | if (topLevel != 1) | 
|  | 5277 | xmlSchemaPCheckParticleCorrect_2(ctxt, (xmlSchemaTypePtr) ret, | 
|  | 5278 | node, minOccurs, maxOccurs); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5279 | /* | 
|  | 5280 | * And now for the children... | 
|  | 5281 | */ | 
|  | 5282 | ctxt->container = name; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5283 | child = node->children; | 
|  | 5284 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5285 | ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 5286 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5287 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5288 | if (isRef) { | 
|  | 5289 | if (child != NULL) { | 
|  | 5290 | xmlSchemaPContentErr(ctxt, | 
|  | 5291 | XML_SCHEMAP_SRC_ELEMENT_2_2, | 
|  | 5292 | &repName, (xmlSchemaTypePtr) ret, node, child, | 
|  | 5293 | NULL, "(annotation?)"); | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5294 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5295 | } else { | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5296 | if (IS_SCHEMA(child, "complexType")) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5297 | /* | 
|  | 5298 | * 3.3.3 : 3 | 
|  | 5299 | * "type" and either <simpleType> or <complexType> are mutually | 
|  | 5300 | * exclusive | 
|  | 5301 | */ | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5302 | if (ret->namedType != NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5303 | xmlSchemaPContentErr(ctxt, | 
|  | 5304 | XML_SCHEMAP_SRC_ELEMENT_3, | 
|  | 5305 | &repName, (xmlSchemaTypePtr) ret, node, child, | 
|  | 5306 | "The attribute 'type' and the <complexType> child are " | 
|  | 5307 | "mutually exclusive", NULL); | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5308 | } else | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 5309 | ret->subtypes = xmlSchemaParseComplexType(ctxt, schema, child, 0); | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5310 | child = child->next; | 
|  | 5311 | } else if (IS_SCHEMA(child, "simpleType")) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5312 | /* | 
|  | 5313 | * 3.3.3 : 3 | 
|  | 5314 | * "type" and either <simpleType> or <complexType> are | 
|  | 5315 | * mutually exclusive | 
|  | 5316 | */ | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5317 | if (ret->namedType != NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5318 | xmlSchemaPContentErr(ctxt, | 
|  | 5319 | XML_SCHEMAP_SRC_ELEMENT_3, | 
|  | 5320 | &repName, (xmlSchemaTypePtr) ret, node, child, | 
|  | 5321 | "The attribute 'type' and the <simpleType> child are " | 
|  | 5322 | "mutually exclusive", NULL); | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5323 | } else | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 5324 | ret->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0); | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5325 | child = child->next; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5326 | } | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5327 | while ((IS_SCHEMA(child, "unique")) || | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5328 | (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) { | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5329 | TODO child = child->next; | 
|  | 5330 | } | 
|  | 5331 | if (child != NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5332 | xmlSchemaPContentErr(ctxt, | 
|  | 5333 | XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, | 
|  | 5334 | &repName, (xmlSchemaTypePtr) ret, node, child, | 
|  | 5335 | NULL, "(annotation?, ((simpleType | complexType)?, " | 
|  | 5336 | "(unique | key | keyref)*))"); | 
|  | 5337 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5338 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5339 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5340 | ctxt->container = oldcontainer; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5341 | /* | 
|  | 5342 | * Cleanup. | 
|  | 5343 | */ | 
|  | 5344 | if (repName != NULL) | 
|  | 5345 | xmlFree(repName); | 
|  | 5346 | /* | 
|  | 5347 | * NOTE: Element Declaration Representation OK 4. will be checked at a | 
|  | 5348 | * different layer. | 
|  | 5349 | */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5350 | return (ret); | 
|  | 5351 | } | 
|  | 5352 |  | 
|  | 5353 | /** | 
|  | 5354 | * xmlSchemaParseUnion: | 
|  | 5355 | * @ctxt:  a schema validation context | 
|  | 5356 | * @schema:  the schema being built | 
|  | 5357 | * @node:  a subtree containing XML Schema informations | 
|  | 5358 | * | 
|  | 5359 | * parse a XML schema Union definition | 
|  | 5360 | * *WARNING* this interface is highly subject to change | 
|  | 5361 | * | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5362 | * Returns -1 in case of error, 0 if the declaration is improper and | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5363 | *         1 in case of success. | 
|  | 5364 | */ | 
|  | 5365 | static xmlSchemaTypePtr | 
|  | 5366 | xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5367 | xmlNodePtr node) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5368 | { | 
|  | 5369 | xmlSchemaTypePtr type, subtype, last = NULL; | 
|  | 5370 | xmlNodePtr child = NULL; | 
|  | 5371 | xmlChar name[30]; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5372 | xmlAttrPtr attr; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5373 |  | 
|  | 5374 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 5375 | return (NULL); | 
|  | 5376 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5377 | snprintf((char *) name, 30, "#union %d", ctxt->counter++ + 1); | 
|  | 5378 | type = xmlSchemaAddType(ctxt, schema, name, NULL, node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5379 | if (type == NULL) | 
|  | 5380 | return (NULL); | 
| Daniel Veillard | 4e5d665 | 2004-06-29 21:01:12 +0000 | [diff] [blame] | 5381 | type->type = XML_SCHEMA_TYPE_UNION; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5382 | type->node = node; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5383 | /* | 
|  | 5384 | * Check for illegal attributes. | 
|  | 5385 | */ | 
|  | 5386 | attr = node->properties; | 
|  | 5387 | while (attr != NULL) { | 
|  | 5388 | if (attr->ns == NULL) { | 
|  | 5389 | if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && | 
|  | 5390 | (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) { | 
|  | 5391 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 5392 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 5393 | NULL, type, attr); | 
|  | 5394 | } | 
|  | 5395 | } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { | 
|  | 5396 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 5397 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 5398 | NULL, type, attr); | 
|  | 5399 | } | 
|  | 5400 | attr = attr->next; | 
|  | 5401 | } | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 5402 | type->id = xmlSchemaGetProp(ctxt, node, "id"); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5403 | /* | 
|  | 5404 | * Attribute "memberTypes". This is a list of QNames. | 
|  | 5405 | * TODO: Validate the QNames. | 
|  | 5406 | */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 5407 | type->base = xmlSchemaGetProp(ctxt, node, "memberTypes"); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5408 | /* | 
|  | 5409 | * And now for the children... | 
|  | 5410 | */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5411 | child = node->children; | 
|  | 5412 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5413 | type->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 5414 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5415 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5416 | while (IS_SCHEMA(child, "simpleType")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5417 | subtype = (xmlSchemaTypePtr) | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 5418 | xmlSchemaParseSimpleType(ctxt, schema, child, 0); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5419 | if (subtype != NULL) { | 
|  | 5420 | if (last == NULL) { | 
|  | 5421 | type->subtypes = subtype; | 
|  | 5422 | last = subtype; | 
|  | 5423 | } else { | 
|  | 5424 | last->next = subtype; | 
|  | 5425 | last = subtype; | 
|  | 5426 | } | 
|  | 5427 | last->next = NULL; | 
|  | 5428 | } | 
|  | 5429 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5430 | } | 
|  | 5431 | if (child != NULL) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5432 | /* TODO: Think about the error code. */ | 
|  | 5433 | xmlSchemaPContentErr(ctxt, | 
|  | 5434 | XML_SCHEMAP_UNKNOWN_UNION_CHILD, | 
|  | 5435 | NULL, type, node, child, NULL, "(annotation?, simpleType*)"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5436 | } | 
|  | 5437 | return (type); | 
|  | 5438 | } | 
|  | 5439 |  | 
|  | 5440 | /** | 
|  | 5441 | * xmlSchemaParseList: | 
|  | 5442 | * @ctxt:  a schema validation context | 
|  | 5443 | * @schema:  the schema being built | 
|  | 5444 | * @node:  a subtree containing XML Schema informations | 
|  | 5445 | * | 
|  | 5446 | * parse a XML schema List definition | 
|  | 5447 | * *WARNING* this interface is highly subject to change | 
|  | 5448 | * | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5449 | * Returns -1 in case of error, 0 if the declaration is improper and | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5450 | *         1 in case of success. | 
|  | 5451 | */ | 
|  | 5452 | static xmlSchemaTypePtr | 
|  | 5453 | xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5454 | xmlNodePtr node) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5455 | { | 
|  | 5456 | xmlSchemaTypePtr type, subtype; | 
|  | 5457 | xmlNodePtr child = NULL; | 
|  | 5458 | xmlChar name[30]; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5459 | xmlAttrPtr attr; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5460 |  | 
|  | 5461 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 5462 | return (NULL); | 
|  | 5463 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5464 | snprintf((char *) name, 30, "#list %d", ctxt->counter++ + 1); | 
|  | 5465 | type = xmlSchemaAddType(ctxt, schema, name, NULL, node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5466 | if (type == NULL) | 
|  | 5467 | return (NULL); | 
|  | 5468 | type->node = node; | 
|  | 5469 | type->type = XML_SCHEMA_TYPE_LIST; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 5470 | type->id = xmlSchemaGetProp(ctxt, node, "id"); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5471 | /* | 
|  | 5472 | * Check for illegal attributes. | 
|  | 5473 | */ | 
|  | 5474 | attr = node->properties; | 
|  | 5475 | while (attr != NULL) { | 
|  | 5476 | if (attr->ns == NULL) { | 
|  | 5477 | if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && | 
|  | 5478 | (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) { | 
|  | 5479 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 5480 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 5481 | NULL, type, attr); | 
|  | 5482 | } | 
|  | 5483 | } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { | 
|  | 5484 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 5485 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 5486 | NULL, type, attr); | 
|  | 5487 | } | 
|  | 5488 | attr = attr->next; | 
|  | 5489 | } | 
|  | 5490 | /* | 
|  | 5491 | * Attribute "itemType". | 
|  | 5492 | */ | 
|  | 5493 | xmlSchemaPValAttrQName(ctxt, schema, NULL, NULL, | 
|  | 5494 | node, "itemType", &(type->baseNs), NULL, &(type->base)); | 
|  | 5495 | /* | 
|  | 5496 | * And now for the children... | 
|  | 5497 | */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5498 | child = node->children; | 
|  | 5499 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5500 | type->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 5501 | child = child->next; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5502 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5503 | subtype = NULL; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5504 | if (IS_SCHEMA(child, "simpleType")) { | 
|  | 5505 | if (type->base != NULL) { | 
|  | 5506 | xmlSchemaPCustomErr(ctxt, | 
|  | 5507 | XML_SCHEMAP_SRC_SIMPLE_TYPE_1, | 
|  | 5508 | NULL, type, node, | 
|  | 5509 | "The attribute 'itemType' and the <simpleType> child " | 
|  | 5510 | "are mutually exclusive", NULL); | 
|  | 5511 | } else { | 
|  | 5512 | subtype = (xmlSchemaTypePtr) | 
|  | 5513 | xmlSchemaParseSimpleType(ctxt, schema, child, 0); | 
|  | 5514 | type->subtypes = subtype; | 
|  | 5515 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 5516 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5517 | } | 
|  | 5518 | if (child != NULL) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5519 | /* TODO: Think about the error code. */ | 
|  | 5520 | xmlSchemaPContentErr(ctxt, | 
|  | 5521 | XML_SCHEMAP_UNKNOWN_LIST_CHILD, | 
|  | 5522 | NULL, type, node, child, NULL, "(annotation?, simpleType?)"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5523 | } | 
|  | 5524 | return (type); | 
|  | 5525 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5526 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5527 | /** | 
|  | 5528 | * xmlSchemaParseSimpleType: | 
|  | 5529 | * @ctxt:  a schema validation context | 
|  | 5530 | * @schema:  the schema being built | 
|  | 5531 | * @node:  a subtree containing XML Schema informations | 
|  | 5532 | * | 
|  | 5533 | * parse a XML schema Simple Type definition | 
|  | 5534 | * *WARNING* this interface is highly subject to change | 
|  | 5535 | * | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5536 | * Returns -1 in case of error, 0 if the declaration is improper and | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5537 | * 1 in case of success. | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5538 | */ | 
|  | 5539 | static xmlSchemaTypePtr | 
|  | 5540 | xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 5541 | xmlNodePtr node, int topLevel) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5542 | { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 5543 | xmlSchemaTypePtr type, subtype, ctxtType; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5544 | xmlNodePtr child = NULL; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5545 | const xmlChar *attrValue = NULL; | 
|  | 5546 | xmlChar *repName = NULL; | 
|  | 5547 | xmlAttrPtr attr; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5548 |  | 
|  | 5549 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 5550 | return (NULL); | 
|  | 5551 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5552 | attr = xmlSchemaGetPropNode(node, "name"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5553 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5554 | if (topLevel) { | 
|  | 5555 | if (attr == NULL) { | 
|  | 5556 | xmlSchemaPMissingAttrErr(ctxt, | 
|  | 5557 | XML_SCHEMAP_S4S_ATTR_MISSING, | 
|  | 5558 | (xmlChar **) &xmlSchemaElemDesAttrDecl, NULL, node, | 
|  | 5559 | "name", NULL); | 
|  | 5560 | return (NULL); | 
|  | 5561 | } else if (xmlSchemaPValAttrNode(ctxt, | 
|  | 5562 | (xmlChar **) &xmlSchemaElemDesAttrDecl, NULL, attr, | 
|  | 5563 | xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 5564 | return (NULL); | 
|  | 5565 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5566 | } | 
|  | 5567 |  | 
|  | 5568 | if (topLevel == 0) { | 
|  | 5569 | char buf[100]; | 
|  | 5570 |  | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 5571 | /* | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5572 | * Parse as local simple type definition. | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 5573 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5574 | snprintf(buf, 99, "#st %d", ctxt->counter++ + 1); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5575 | type = xmlSchemaAddType(ctxt, schema, (const xmlChar *)buf, NULL, node); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5576 | if (type == NULL) | 
|  | 5577 | return (NULL); | 
|  | 5578 | type->node = node; | 
|  | 5579 | type->type = XML_SCHEMA_TYPE_SIMPLE; | 
|  | 5580 | /* | 
|  | 5581 | * Check for illegal attributes. | 
|  | 5582 | */ | 
|  | 5583 | attr = node->properties; | 
|  | 5584 | while (attr != NULL) { | 
|  | 5585 | if (attr->ns == NULL) { | 
|  | 5586 | if (!xmlStrEqual(attr->name, BAD_CAST "id")) { | 
|  | 5587 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 5588 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 5589 | &repName, type, attr); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 5590 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5591 | } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { | 
|  | 5592 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 5593 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 5594 | &repName, type, attr); | 
|  | 5595 | } | 
|  | 5596 | attr = attr->next; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 5597 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5598 | } else { | 
|  | 5599 | /* | 
|  | 5600 | * Parse as global simple type definition. | 
|  | 5601 | */ | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5602 | type = xmlSchemaAddType(ctxt, schema, attrValue, schema->targetNamespace, node); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5603 | if (type == NULL) | 
|  | 5604 | return (NULL); | 
|  | 5605 | type->node = node; | 
|  | 5606 | type->type = XML_SCHEMA_TYPE_SIMPLE; | 
|  | 5607 | type->flags |= XML_SCHEMAS_TYPE_GLOBAL; | 
|  | 5608 | /* | 
|  | 5609 | * Check for illegal attributes. | 
|  | 5610 | */ | 
|  | 5611 | attr = node->properties; | 
|  | 5612 | while (attr != NULL) { | 
|  | 5613 | if (attr->ns == NULL) { | 
|  | 5614 | if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && | 
|  | 5615 | (!xmlStrEqual(attr->name, BAD_CAST "name")) && | 
|  | 5616 | (!xmlStrEqual(attr->name, BAD_CAST "final"))){ | 
|  | 5617 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 5618 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 5619 | &repName, type, attr); | 
|  | 5620 | } | 
|  | 5621 | } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { | 
|  | 5622 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 5623 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 5624 | &repName, type, attr); | 
|  | 5625 | } | 
|  | 5626 | attr = attr->next; | 
|  | 5627 | } | 
|  | 5628 | /* | 
|  | 5629 | * Attribute "final". | 
|  | 5630 | */ | 
|  | 5631 | attr = xmlSchemaGetPropNode(node, "final"); | 
|  | 5632 | if (attr == NULL) { | 
|  | 5633 | type->flags |= XML_SCHEMAS_TYPE_FINAL_DEFAULT; | 
|  | 5634 | } else { | 
|  | 5635 | attrValue = xmlSchemaGetProp(ctxt, node, "final"); | 
|  | 5636 | if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), | 
|  | 5637 | -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1, | 
|  | 5638 | XML_SCHEMAS_TYPE_FINAL_LIST, | 
|  | 5639 | XML_SCHEMAS_TYPE_FINAL_UNION) != 0) { | 
|  | 5640 |  | 
|  | 5641 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 5642 | XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, | 
|  | 5643 | &repName, type, (xmlNodePtr) attr, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5644 | NULL, "(#all | List of (list | union | restriction)", | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5645 | attrValue, NULL, NULL, NULL); | 
|  | 5646 | } | 
|  | 5647 | } | 
|  | 5648 | } | 
|  | 5649 | /* TODO: Check id. */ | 
|  | 5650 | type->id = xmlSchemaGetProp(ctxt, node, "id"); | 
|  | 5651 | /* | 
|  | 5652 | * And now for the children... | 
|  | 5653 | */ | 
|  | 5654 | ctxtType = ctxt->ctxtType; | 
|  | 5655 | ctxt->ctxtType = type; | 
|  | 5656 | ctxt->parentItem = type; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5657 | child = node->children; | 
|  | 5658 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5659 | type->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 5660 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5661 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5662 | subtype = NULL; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5663 | if (IS_SCHEMA(child, "restriction")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5664 | subtype = (xmlSchemaTypePtr) | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 5665 | xmlSchemaParseRestriction(ctxt, schema, child); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5666 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5667 | } else if (IS_SCHEMA(child, "list")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5668 | subtype = (xmlSchemaTypePtr) | 
|  | 5669 | xmlSchemaParseList(ctxt, schema, child); | 
|  | 5670 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5671 | } else if (IS_SCHEMA(child, "union")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5672 | subtype = (xmlSchemaTypePtr) | 
|  | 5673 | xmlSchemaParseUnion(ctxt, schema, child); | 
|  | 5674 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5675 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5676 | type->subtypes = subtype; | 
|  | 5677 | if ((child != NULL) || (subtype == NULL)) { | 
|  | 5678 | xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, | 
|  | 5679 | &repName, type, node, child, NULL, | 
|  | 5680 | "(annotation?, (restriction | list | union))"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5681 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 5682 | ctxt->ctxtType = ctxtType; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5683 | if (repName != NULL) | 
|  | 5684 | xmlFree(repName); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 5685 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5686 | return (type); | 
|  | 5687 | } | 
|  | 5688 |  | 
|  | 5689 |  | 
|  | 5690 | /** | 
|  | 5691 | * xmlSchemaParseGroup: | 
|  | 5692 | * @ctxt:  a schema validation context | 
|  | 5693 | * @schema:  the schema being built | 
|  | 5694 | * @node:  a subtree containing XML Schema informations | 
|  | 5695 | * | 
|  | 5696 | * parse a XML schema Group definition | 
|  | 5697 | * *WARNING* this interface is highly subject to change | 
|  | 5698 | * | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5699 | * Returns -1 in case of error, 0 if the declaration is improper and | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5700 | *         1 in case of success. | 
|  | 5701 | */ | 
|  | 5702 | static xmlSchemaTypePtr | 
|  | 5703 | xmlSchemaParseGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 5704 | xmlNodePtr node, int topLevel) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5705 | { | 
|  | 5706 | xmlSchemaTypePtr type, subtype; | 
|  | 5707 | xmlNodePtr child = NULL; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 5708 | const xmlChar *name; | 
|  | 5709 | const xmlChar *ref = NULL, *refNs = NULL; | 
|  | 5710 | char buf[100]; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5711 |  | 
|  | 5712 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 5713 | return (NULL); | 
|  | 5714 |  | 
|  | 5715 |  | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 5716 | name = xmlSchemaGetProp(ctxt, node, "name"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5717 | if (name == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5718 | ref = xmlGetQNameProp(ctxt, node, "ref", &refNs); | 
|  | 5719 | if (ref == NULL) { | 
|  | 5720 | xmlSchemaPErr2(ctxt, node, child, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5721 | XML_SCHEMAP_GROUP_NONAME_NOREF, | 
|  | 5722 | "Group definition or particle: One of the attributes \"name\" " | 
|  | 5723 | "or \"ref\" must be present.\n", NULL, NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5724 | return (NULL); | 
|  | 5725 | } | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 5726 | if (refNs == NULL) | 
|  | 5727 | refNs = schema->targetNamespace; | 
|  | 5728 | snprintf(buf, 99, "anongroup %d", ctxt->counter++ + 1); | 
|  | 5729 | name = (const xmlChar *) buf; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5730 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5731 | type = xmlSchemaAddGroup(ctxt, schema, name, node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5732 | if (type == NULL) | 
|  | 5733 | return (NULL); | 
|  | 5734 | type->node = node; | 
|  | 5735 | type->type = XML_SCHEMA_TYPE_GROUP; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 5736 | if (topLevel) | 
|  | 5737 | type->flags |= XML_SCHEMAS_TYPE_GLOBAL; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 5738 | type->id = xmlSchemaGetProp(ctxt, node, "id"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5739 | type->ref = ref; | 
|  | 5740 | type->refNs = refNs; | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 5741 |  | 
|  | 5742 | type->minOccurs = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "nonNegativeInteger"); | 
|  | 5743 | type->maxOccurs = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(nonNegativeInteger | unbounded)"); | 
|  | 5744 | xmlSchemaPCheckParticleCorrect_2(ctxt, type, | 
|  | 5745 | node, type->minOccurs, type->maxOccurs); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5746 |  | 
|  | 5747 | child = node->children; | 
|  | 5748 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5749 | type->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 5750 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5751 | } | 
|  | 5752 | subtype = NULL; | 
|  | 5753 | if (IS_SCHEMA(child, "all")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5754 | subtype = (xmlSchemaTypePtr) | 
|  | 5755 | xmlSchemaParseAll(ctxt, schema, child); | 
|  | 5756 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5757 | } else if (IS_SCHEMA(child, "choice")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5758 | subtype = xmlSchemaParseChoice(ctxt, schema, child); | 
|  | 5759 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5760 | } else if (IS_SCHEMA(child, "sequence")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5761 | subtype = (xmlSchemaTypePtr) | 
|  | 5762 | xmlSchemaParseSequence(ctxt, schema, child); | 
|  | 5763 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5764 | } | 
|  | 5765 | if (subtype != NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5766 | type->subtypes = subtype; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5767 | if (child != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5768 | xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_GROUP_CHILD, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5769 | "Group definition \"%s\" has unexpected content.\n", type->name, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5770 | NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5771 | } | 
|  | 5772 |  | 
|  | 5773 | return (type); | 
|  | 5774 | } | 
|  | 5775 |  | 
|  | 5776 | /** | 
|  | 5777 | * xmlSchemaParseAll: | 
|  | 5778 | * @ctxt:  a schema validation context | 
|  | 5779 | * @schema:  the schema being built | 
|  | 5780 | * @node:  a subtree containing XML Schema informations | 
|  | 5781 | * | 
|  | 5782 | * parse a XML schema All definition | 
|  | 5783 | * *WARNING* this interface is highly subject to change | 
|  | 5784 | * | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 5785 | * Returns -1 in case of error, 0 if the declaration is improper and | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5786 | *         1 in case of success. | 
|  | 5787 | */ | 
|  | 5788 | static xmlSchemaTypePtr | 
|  | 5789 | xmlSchemaParseAll(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5790 | xmlNodePtr node) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5791 | { | 
|  | 5792 | xmlSchemaTypePtr type, subtype, last = NULL; | 
|  | 5793 | xmlNodePtr child = NULL; | 
|  | 5794 | xmlChar name[30]; | 
|  | 5795 |  | 
|  | 5796 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 5797 | return (NULL); | 
|  | 5798 |  | 
|  | 5799 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5800 | snprintf((char *) name, 30, "all%d", ctxt->counter++ + 1); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5801 | type = xmlSchemaAddType(ctxt, schema, name, NULL, node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5802 | if (type == NULL) | 
|  | 5803 | return (NULL); | 
|  | 5804 | type->node = node; | 
| Daniel Veillard | 7646b18 | 2002-04-20 06:41:40 +0000 | [diff] [blame] | 5805 | type->type = XML_SCHEMA_TYPE_ALL; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 5806 | type->id = xmlSchemaGetProp(ctxt, node, "id"); | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 5807 |  | 
|  | 5808 | type->minOccurs = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)"); | 
|  | 5809 | type->maxOccurs = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5810 |  | 
|  | 5811 | child = node->children; | 
|  | 5812 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5813 | type->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 5814 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5815 | } | 
|  | 5816 | while (IS_SCHEMA(child, "element")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5817 | subtype = (xmlSchemaTypePtr) | 
|  | 5818 | xmlSchemaParseElement(ctxt, schema, child, 0); | 
|  | 5819 | if (subtype != NULL) { | 
| William M. Brack | b15351e | 2003-12-27 04:34:42 +0000 | [diff] [blame] | 5820 | if (subtype->minOccurs > 1) | 
|  | 5821 | xmlSchemaPErr(ctxt, child, XML_SCHEMAP_INVALID_MINOCCURS, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5822 | "invalid value for minOccurs (must be 0 or 1).\n", | 
| William M. Brack | b15351e | 2003-12-27 04:34:42 +0000 | [diff] [blame] | 5823 | NULL, NULL); | 
|  | 5824 | if (subtype->maxOccurs > 1) | 
|  | 5825 | xmlSchemaPErr(ctxt, child, XML_SCHEMAP_INVALID_MAXOCCURS, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5826 | "invalid value for maxOccurs (must be 0 or 1).\n", | 
| William M. Brack | b15351e | 2003-12-27 04:34:42 +0000 | [diff] [blame] | 5827 | NULL, NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5828 | if (last == NULL) { | 
|  | 5829 | type->subtypes = subtype; | 
|  | 5830 | last = subtype; | 
|  | 5831 | } else { | 
|  | 5832 | last->next = subtype; | 
|  | 5833 | last = subtype; | 
|  | 5834 | } | 
|  | 5835 | last->next = NULL; | 
|  | 5836 | } | 
|  | 5837 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5838 | } | 
|  | 5839 | if (child != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5840 | xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_ALL_CHILD, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 5841 | "<all> has unexpected content.\n", type->name, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 5842 | NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 5843 | } | 
|  | 5844 |  | 
|  | 5845 | return (type); | 
|  | 5846 | } | 
|  | 5847 |  | 
|  | 5848 | /** | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 5849 | * xmlSchemaCleanupDoc: | 
|  | 5850 | * @ctxt:  a schema validation context | 
|  | 5851 | * @node:  the root of the document. | 
|  | 5852 | * | 
|  | 5853 | * removes unwanted nodes in a schemas document tree | 
|  | 5854 | */ | 
|  | 5855 | static void | 
|  | 5856 | xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root) | 
|  | 5857 | { | 
|  | 5858 | xmlNodePtr delete, cur; | 
|  | 5859 |  | 
|  | 5860 | if ((ctxt == NULL) || (root == NULL)) return; | 
|  | 5861 |  | 
|  | 5862 | /* | 
|  | 5863 | * Remove all the blank text nodes | 
|  | 5864 | */ | 
|  | 5865 | delete = NULL; | 
|  | 5866 | cur = root; | 
|  | 5867 | while (cur != NULL) { | 
|  | 5868 | if (delete != NULL) { | 
|  | 5869 | xmlUnlinkNode(delete); | 
|  | 5870 | xmlFreeNode(delete); | 
|  | 5871 | delete = NULL; | 
|  | 5872 | } | 
|  | 5873 | if (cur->type == XML_TEXT_NODE) { | 
|  | 5874 | if (IS_BLANK_NODE(cur)) { | 
|  | 5875 | if (xmlNodeGetSpacePreserve(cur) != 1) { | 
|  | 5876 | delete = cur; | 
|  | 5877 | } | 
|  | 5878 | } | 
|  | 5879 | } else if ((cur->type != XML_ELEMENT_NODE) && | 
|  | 5880 | (cur->type != XML_CDATA_SECTION_NODE)) { | 
|  | 5881 | delete = cur; | 
|  | 5882 | goto skip_children; | 
|  | 5883 | } | 
|  | 5884 |  | 
|  | 5885 | /* | 
|  | 5886 | * Skip to next node | 
|  | 5887 | */ | 
|  | 5888 | if (cur->children != NULL) { | 
|  | 5889 | if ((cur->children->type != XML_ENTITY_DECL) && | 
|  | 5890 | (cur->children->type != XML_ENTITY_REF_NODE) && | 
|  | 5891 | (cur->children->type != XML_ENTITY_NODE)) { | 
|  | 5892 | cur = cur->children; | 
|  | 5893 | continue; | 
|  | 5894 | } | 
|  | 5895 | } | 
|  | 5896 | skip_children: | 
|  | 5897 | if (cur->next != NULL) { | 
|  | 5898 | cur = cur->next; | 
|  | 5899 | continue; | 
|  | 5900 | } | 
|  | 5901 |  | 
|  | 5902 | do { | 
|  | 5903 | cur = cur->parent; | 
|  | 5904 | if (cur == NULL) | 
|  | 5905 | break; | 
|  | 5906 | if (cur == root) { | 
|  | 5907 | cur = NULL; | 
|  | 5908 | break; | 
|  | 5909 | } | 
|  | 5910 | if (cur->next != NULL) { | 
|  | 5911 | cur = cur->next; | 
|  | 5912 | break; | 
|  | 5913 | } | 
|  | 5914 | } while (cur != NULL); | 
|  | 5915 | } | 
|  | 5916 | if (delete != NULL) { | 
|  | 5917 | xmlUnlinkNode(delete); | 
|  | 5918 | xmlFreeNode(delete); | 
|  | 5919 | delete = NULL; | 
|  | 5920 | } | 
|  | 5921 | } | 
|  | 5922 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5923 |  | 
|  | 5924 | /** | 
|  | 5925 | * xmlSchemaImportSchema | 
|  | 5926 | * | 
|  | 5927 | * @ctxt:  a schema validation context | 
|  | 5928 | * @schemaLocation:  an URI defining where to find the imported schema | 
|  | 5929 | * | 
|  | 5930 | * import a XML schema | 
|  | 5931 | * *WARNING* this interface is highly subject to change | 
|  | 5932 | * | 
|  | 5933 | * Returns -1 in case of error and 1 in case of success. | 
|  | 5934 | */ | 
|  | 5935 | #if 0 | 
|  | 5936 | static xmlSchemaImportPtr | 
|  | 5937 | xmlSchemaImportSchema(xmlSchemaParserCtxtPtr ctxt, | 
|  | 5938 | const xmlChar *schemaLocation) | 
|  | 5939 | { | 
|  | 5940 | xmlSchemaImportPtr import; | 
|  | 5941 | xmlSchemaParserCtxtPtr newctxt; | 
|  | 5942 |  | 
|  | 5943 | newctxt = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt)); | 
|  | 5944 | if (newctxt == NULL) { | 
|  | 5945 | xmlSchemaPErrMemory(ctxt, "allocating schema parser context", | 
|  | 5946 | NULL); | 
|  | 5947 | return (NULL); | 
|  | 5948 | } | 
|  | 5949 | memset(newctxt, 0, sizeof(xmlSchemaParserCtxt)); | 
|  | 5950 | /* Keep the same dictionnary for parsing, really */ | 
|  | 5951 | xmlDictReference(ctxt->dict); | 
|  | 5952 | newctxt->dict = ctxt->dict; | 
|  | 5953 | newctxt->includes = 0; | 
|  | 5954 | newctxt->URL = xmlDictLookup(newctxt->dict, schemaLocation, -1); | 
|  | 5955 |  | 
|  | 5956 | xmlSchemaSetParserErrors(newctxt, ctxt->error, ctxt->warning, | 
|  | 5957 | ctxt->userData); | 
|  | 5958 |  | 
|  | 5959 | import = (xmlSchemaImport*) xmlMalloc(sizeof(xmlSchemaImport)); | 
|  | 5960 | if (import == NULL) { | 
|  | 5961 | xmlSchemaPErrMemory(NULL, "allocating imported schema", | 
|  | 5962 | NULL); | 
|  | 5963 | xmlSchemaFreeParserCtxt(newctxt); | 
|  | 5964 | return (NULL); | 
|  | 5965 | } | 
|  | 5966 |  | 
|  | 5967 | memset(import, 0, sizeof(xmlSchemaImport)); | 
|  | 5968 | import->schemaLocation = xmlDictLookup(ctxt->dict, schemaLocation, -1); | 
|  | 5969 | import->schema = xmlSchemaParse(newctxt); | 
|  | 5970 |  | 
|  | 5971 | if (import->schema == NULL) { | 
|  | 5972 | /* FIXME use another error enum here ? */ | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 5973 | xmlSchemaPErr(ctxt, NULL, XML_SCHEMAP_INTERNAL, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 5974 | "Failed to import schema from location \"%s\".\n", | 
|  | 5975 | schemaLocation, NULL); | 
|  | 5976 |  | 
|  | 5977 | xmlSchemaFreeParserCtxt(newctxt); | 
|  | 5978 | /* The schemaLocation is held by the dictionary. | 
|  | 5979 | if (import->schemaLocation != NULL) | 
|  | 5980 | xmlFree((xmlChar *)import->schemaLocation); | 
|  | 5981 | */ | 
|  | 5982 | xmlFree(import); | 
|  | 5983 | return NULL; | 
|  | 5984 | } | 
|  | 5985 |  | 
|  | 5986 | xmlSchemaFreeParserCtxt(newctxt); | 
|  | 5987 | return import; | 
|  | 5988 | } | 
|  | 5989 | #endif | 
|  | 5990 |  | 
|  | 5991 | static void | 
|  | 5992 | xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema) | 
|  | 5993 | { | 
|  | 5994 | if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) | 
|  | 5995 | schema->flags ^= XML_SCHEMAS_QUALIF_ELEM; | 
|  | 5996 |  | 
|  | 5997 | if (schema->flags & XML_SCHEMAS_QUALIF_ATTR) | 
|  | 5998 | schema->flags ^= XML_SCHEMAS_QUALIF_ATTR; | 
|  | 5999 |  | 
|  | 6000 | if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) | 
|  | 6001 | schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION; | 
|  | 6002 | if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) | 
|  | 6003 | schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION; | 
|  | 6004 | if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) | 
|  | 6005 | schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST; | 
|  | 6006 | if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) | 
|  | 6007 | schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION; | 
|  | 6008 |  | 
|  | 6009 | if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) | 
|  | 6010 | schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION; | 
|  | 6011 | if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) | 
|  | 6012 | schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION; | 
|  | 6013 | if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) | 
|  | 6014 | schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION; | 
|  | 6015 | } | 
|  | 6016 |  | 
|  | 6017 | static void | 
|  | 6018 | xmlSchemaParseSchemaDefaults(xmlSchemaParserCtxtPtr ctxt, | 
|  | 6019 | xmlSchemaPtr schema, | 
|  | 6020 | xmlNodePtr node) | 
|  | 6021 | { | 
|  | 6022 | xmlAttrPtr attr; | 
|  | 6023 | const xmlChar *val; | 
|  | 6024 |  | 
|  | 6025 | attr = xmlSchemaGetPropNode(node, "elementFormDefault"); | 
|  | 6026 | if (attr != NULL) { | 
|  | 6027 | val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); | 
|  | 6028 | if (xmlSchemaPValAttrFormDefault(val, &schema->flags, | 
|  | 6029 | XML_SCHEMAS_QUALIF_ELEM) != 0) { | 
|  | 6030 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 6031 | XML_SCHEMAP_ELEMFORMDEFAULT_VALUE, | 
|  | 6032 | NULL, NULL, (xmlNodePtr) attr, NULL, | 
|  | 6033 | "(qualified | unqualified)", val, NULL, NULL, NULL); | 
|  | 6034 | } | 
|  | 6035 | } | 
|  | 6036 |  | 
|  | 6037 | attr = xmlSchemaGetPropNode(node, "attributeFormDefault"); | 
|  | 6038 | if (attr != NULL) { | 
|  | 6039 | val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); | 
|  | 6040 | if (xmlSchemaPValAttrFormDefault(val, &schema->flags, | 
|  | 6041 | XML_SCHEMAS_QUALIF_ATTR) != 0) { | 
|  | 6042 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 6043 | XML_SCHEMAP_ATTRFORMDEFAULT_VALUE, | 
|  | 6044 | NULL, NULL, (xmlNodePtr) attr, NULL, | 
|  | 6045 | "(qualified | unqualified)", val, NULL, NULL, NULL); | 
|  | 6046 | } | 
|  | 6047 | } | 
|  | 6048 |  | 
|  | 6049 | attr = xmlSchemaGetPropNode(node, "finalDefault"); | 
|  | 6050 | if (attr != NULL) { | 
|  | 6051 | val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); | 
|  | 6052 | if (xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, | 
|  | 6053 | XML_SCHEMAS_FINAL_DEFAULT_EXTENSION, | 
|  | 6054 | XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION, | 
|  | 6055 | -1, | 
|  | 6056 | XML_SCHEMAS_FINAL_DEFAULT_LIST, | 
|  | 6057 | XML_SCHEMAS_FINAL_DEFAULT_UNION) != 0) { | 
|  | 6058 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 6059 | XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, | 
|  | 6060 | NULL, NULL, (xmlNodePtr) attr, NULL, | 
|  | 6061 | "(#all | List of (extension | restriction | list | union))", | 
|  | 6062 | val, NULL, NULL, NULL); | 
|  | 6063 | } | 
|  | 6064 | } | 
|  | 6065 |  | 
|  | 6066 | attr = xmlSchemaGetPropNode(node, "blockDefault"); | 
|  | 6067 | if (attr != NULL) { | 
|  | 6068 | val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); | 
|  | 6069 | if (xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, | 
|  | 6070 | XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION, | 
|  | 6071 | XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION, | 
|  | 6072 | XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1) != 0) { | 
|  | 6073 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 6074 | XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, | 
|  | 6075 | NULL, NULL, (xmlNodePtr) attr, NULL, | 
|  | 6076 | "(#all | List of (extension | restriction | substitution))", | 
|  | 6077 | val, NULL, NULL, NULL); | 
|  | 6078 | } | 
|  | 6079 | } | 
|  | 6080 | } | 
|  | 6081 |  | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6082 | /** | 
|  | 6083 | * xmlSchemaParseSchemaTopLevel: | 
|  | 6084 | * @ctxt:  a schema validation context | 
|  | 6085 | * @schema:  the schemas | 
|  | 6086 | * @nodes:  the list of top level nodes | 
|  | 6087 | * | 
|  | 6088 | * Returns the internal XML Schema structure built from the resource or | 
|  | 6089 | *         NULL in case of error | 
|  | 6090 | */ | 
|  | 6091 | static void | 
|  | 6092 | xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt, | 
|  | 6093 | xmlSchemaPtr schema, xmlNodePtr nodes) | 
|  | 6094 | { | 
|  | 6095 | xmlNodePtr child; | 
|  | 6096 | xmlSchemaAnnotPtr annot; | 
|  | 6097 |  | 
|  | 6098 | if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL)) | 
|  | 6099 | return; | 
|  | 6100 |  | 
|  | 6101 | child = nodes; | 
|  | 6102 | while ((IS_SCHEMA(child, "include")) || | 
|  | 6103 | (IS_SCHEMA(child, "import")) || | 
|  | 6104 | (IS_SCHEMA(child, "redefine")) || | 
|  | 6105 | (IS_SCHEMA(child, "annotation"))) { | 
|  | 6106 | if (IS_SCHEMA(child, "annotation")) { | 
|  | 6107 | annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 6108 | if (schema->annot == NULL) | 
|  | 6109 | schema->annot = annot; | 
|  | 6110 | else | 
|  | 6111 | xmlSchemaFreeAnnot(annot); | 
|  | 6112 | } else if (IS_SCHEMA(child, "import")) { | 
|  | 6113 | xmlSchemaParseImport(ctxt, schema, child); | 
|  | 6114 | } else if (IS_SCHEMA(child, "include")) { | 
| Daniel Veillard | b0f397e | 2003-12-23 23:30:53 +0000 | [diff] [blame] | 6115 | ctxt->includes++; | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6116 | xmlSchemaParseInclude(ctxt, schema, child); | 
| Daniel Veillard | b0f397e | 2003-12-23 23:30:53 +0000 | [diff] [blame] | 6117 | ctxt->includes--; | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6118 | } else if (IS_SCHEMA(child, "redefine")) { | 
|  | 6119 | TODO | 
|  | 6120 | } | 
|  | 6121 | child = child->next; | 
|  | 6122 | } | 
|  | 6123 | while (child != NULL) { | 
|  | 6124 | if (IS_SCHEMA(child, "complexType")) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 6125 | xmlSchemaParseComplexType(ctxt, schema, child, 1); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6126 | child = child->next; | 
|  | 6127 | } else if (IS_SCHEMA(child, "simpleType")) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 6128 | xmlSchemaParseSimpleType(ctxt, schema, child, 1); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6129 | child = child->next; | 
|  | 6130 | } else if (IS_SCHEMA(child, "element")) { | 
|  | 6131 | xmlSchemaParseElement(ctxt, schema, child, 1); | 
|  | 6132 | child = child->next; | 
|  | 6133 | } else if (IS_SCHEMA(child, "attribute")) { | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 6134 | xmlSchemaParseAttribute(ctxt, schema, child, 1); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6135 | child = child->next; | 
|  | 6136 | } else if (IS_SCHEMA(child, "attributeGroup")) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 6137 | xmlSchemaParseAttributeGroup(ctxt, schema, child, 1); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6138 | child = child->next; | 
|  | 6139 | } else if (IS_SCHEMA(child, "group")) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 6140 | xmlSchemaParseGroup(ctxt, schema, child, 1); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6141 | child = child->next; | 
|  | 6142 | } else if (IS_SCHEMA(child, "notation")) { | 
|  | 6143 | xmlSchemaParseNotation(ctxt, schema, child); | 
|  | 6144 | child = child->next; | 
|  | 6145 | } else { | 
|  | 6146 | xmlSchemaPErr2(ctxt, NULL, child, | 
|  | 6147 | XML_SCHEMAP_UNKNOWN_SCHEMAS_CHILD, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 6148 | "Unexpected element \"%s\" as child of <schema>.\n", | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6149 | child->name, NULL); | 
|  | 6150 | child = child->next; | 
|  | 6151 | } | 
|  | 6152 | while (IS_SCHEMA(child, "annotation")) { | 
|  | 6153 | annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 6154 | if (schema->annot == NULL) | 
|  | 6155 | schema->annot = annot; | 
|  | 6156 | else | 
|  | 6157 | xmlSchemaFreeAnnot(annot); | 
|  | 6158 | child = child->next; | 
|  | 6159 | } | 
|  | 6160 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 6161 | ctxt->parentItem = NULL; | 
|  | 6162 | ctxt->ctxtType = NULL; | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6163 | } | 
|  | 6164 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6165 |  | 
|  | 6166 | /** | 
|  | 6167 | * xmlSchemaParseImport: | 
|  | 6168 | * @ctxt:  a schema validation context | 
|  | 6169 | * @schema:  the schema being built | 
|  | 6170 | * @node:  a subtree containing XML Schema informations | 
|  | 6171 | * | 
|  | 6172 | * parse a XML schema Import definition | 
|  | 6173 | * *WARNING* this interface is highly subject to change | 
|  | 6174 | * | 
|  | 6175 | * Returns 0 in case of success, a positive error code if | 
|  | 6176 | * not valid and -1 in case of an internal error. | 
|  | 6177 | */ | 
|  | 6178 | static int | 
|  | 6179 | xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
|  | 6180 | xmlNodePtr node) | 
|  | 6181 | { | 
|  | 6182 | xmlNodePtr child = NULL; | 
|  | 6183 | xmlSchemaImportPtr import = NULL; | 
|  | 6184 | const xmlChar *namespace = NULL, *ns; | 
|  | 6185 | const xmlChar *schemaLocation = NULL; | 
|  | 6186 | const xmlChar *targetNamespace, *oldTNS, *url; | 
|  | 6187 | xmlAttrPtr attr; | 
|  | 6188 | xmlDocPtr doc; | 
|  | 6189 | xmlNodePtr root; | 
|  | 6190 | xmlChar *base = NULL; | 
|  | 6191 | xmlChar *URI = NULL; | 
|  | 6192 | int flags; | 
|  | 6193 | xmlParserCtxtPtr parserCtxt; | 
|  | 6194 |  | 
|  | 6195 |  | 
|  | 6196 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 6197 | return (-1); | 
|  | 6198 |  | 
|  | 6199 | /* | 
|  | 6200 | * Check for illegal attributes. | 
|  | 6201 | */ | 
|  | 6202 | attr = node->properties; | 
|  | 6203 | while (attr != NULL) { | 
|  | 6204 | if (attr->ns == NULL) { | 
|  | 6205 | if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && | 
|  | 6206 | (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && | 
|  | 6207 | (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { | 
|  | 6208 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 6209 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 6210 | NULL, NULL, attr); | 
|  | 6211 | } | 
|  | 6212 | } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { | 
|  | 6213 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 6214 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 6215 | NULL, NULL, attr); | 
|  | 6216 | } | 
|  | 6217 | attr = attr->next; | 
|  | 6218 | } | 
|  | 6219 | /* | 
|  | 6220 | * Extract and validate attributes. | 
|  | 6221 | */ | 
|  | 6222 | if (xmlSchemaPValAttr(ctxt, NULL, NULL, node, | 
|  | 6223 | "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), | 
|  | 6224 | &namespace) != 0) { | 
|  | 6225 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 6226 | XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI, | 
|  | 6227 | NULL, NULL, node, | 
|  | 6228 | xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), | 
|  | 6229 | NULL, namespace, NULL, NULL, NULL); | 
|  | 6230 | return (XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI); | 
|  | 6231 | } | 
|  | 6232 |  | 
|  | 6233 | if (xmlSchemaPValAttr(ctxt, NULL, NULL, node, | 
|  | 6234 | "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), | 
|  | 6235 | &schemaLocation) != 0) { | 
|  | 6236 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 6237 | XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI, | 
|  | 6238 | NULL, NULL, node, | 
|  | 6239 | xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), | 
|  | 6240 | NULL, namespace, NULL, NULL, NULL); | 
|  | 6241 | return (XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI); | 
|  | 6242 | } | 
|  | 6243 | /* | 
|  | 6244 | * And now for the children... | 
|  | 6245 | */ | 
|  | 6246 | child = node->children; | 
|  | 6247 | if (IS_SCHEMA(child, "annotation")) { | 
|  | 6248 | /* | 
|  | 6249 | * the annotation here is simply discarded ... | 
|  | 6250 | */ | 
|  | 6251 | child = child->next; | 
|  | 6252 | } | 
|  | 6253 | if (child != NULL) { | 
|  | 6254 | xmlSchemaPContentErr(ctxt, | 
|  | 6255 | XML_SCHEMAP_UNKNOWN_IMPORT_CHILD, | 
|  | 6256 | NULL, NULL, node, child, NULL, | 
|  | 6257 | "(annotation?)"); | 
|  | 6258 | } | 
|  | 6259 | /* | 
|  | 6260 | * Apply additional constraints. | 
|  | 6261 | */ | 
|  | 6262 | if (namespace != NULL) { | 
|  | 6263 | /* | 
|  | 6264 | * 1.1 If the namespace [attribute] is present, then its ·actual value· | 
|  | 6265 | * must not match the ·actual value· of the enclosing <schema>'s | 
|  | 6266 | * targetNamespace [attribute]. | 
|  | 6267 | */ | 
|  | 6268 | if (xmlStrEqual(schema->targetNamespace, namespace)) { | 
|  | 6269 | xmlSchemaPCustomErr(ctxt, | 
|  | 6270 | XML_SCHEMAP_SRC_IMPORT_1_1, | 
|  | 6271 | NULL, NULL, node, | 
|  | 6272 | "The value of the attribute 'namespace' must not match " | 
|  | 6273 | "the target namespace '%s' of the importing schema", | 
|  | 6274 | schema->targetNamespace); | 
|  | 6275 | return (XML_SCHEMAP_SRC_IMPORT_1_1); | 
|  | 6276 | } | 
|  | 6277 | } else { | 
|  | 6278 | /* | 
|  | 6279 | * 1.2 If the namespace [attribute] is not present, then the enclosing | 
|  | 6280 | * <schema> must have a targetNamespace [attribute]. | 
|  | 6281 | */ | 
|  | 6282 | if (schema->targetNamespace == NULL) { | 
|  | 6283 | xmlSchemaPCustomErr(ctxt, | 
|  | 6284 | XML_SCHEMAP_SRC_IMPORT_1_2, | 
|  | 6285 | NULL, NULL, node, | 
|  | 6286 | "The attribute 'namespace' must be existent if " | 
|  | 6287 | "the importing schema has no target namespace", | 
|  | 6288 | NULL); | 
|  | 6289 | return (XML_SCHEMAP_SRC_IMPORT_1_2); | 
|  | 6290 | } | 
|  | 6291 | } | 
|  | 6292 |  | 
|  | 6293 | /* | 
|  | 6294 | * Given that the schemaLocation [attribute] is only a hint, it is open | 
|  | 6295 | * to applications to ignore all but the first <import> for a given | 
|  | 6296 | * namespace, regardless of the ·actual value· of schemaLocation, but | 
|  | 6297 | * such a strategy risks missing useful information when new | 
|  | 6298 | * schemaLocations are offered. | 
|  | 6299 | * | 
|  | 6300 | * XSV (ver 2.5-2) does use the first <import> which resolves to a valid schema. | 
|  | 6301 | * Xerces-J (ver 2.5.1) ignores all but the first given <import> - regardless if | 
|  | 6302 | * valid or not. | 
|  | 6303 | * We will follow XSV here. | 
|  | 6304 | */ | 
|  | 6305 | if (schemaLocation == NULL) { | 
|  | 6306 | /* | 
|  | 6307 | * Schema Document Location Strategy: | 
|  | 6308 | * | 
|  | 6309 | * 3 Based on the namespace name, identify an existing schema document, | 
|  | 6310 | * either as a resource which is an XML document or a <schema> element | 
|  | 6311 | * information item, in some local schema repository; | 
|  | 6312 | * | 
|  | 6313 | * 5 Attempt to resolve the namespace name to locate such a resource. | 
|  | 6314 | * | 
|  | 6315 | * NOTE: Those stategies are not supported, so we will skip. | 
|  | 6316 | */ | 
|  | 6317 | return (0); | 
|  | 6318 | } | 
|  | 6319 | if (namespace == NULL) | 
|  | 6320 | ns = XML_SCHEMAS_NO_NAMESPACE; | 
|  | 6321 | else | 
|  | 6322 | ns = namespace; | 
|  | 6323 |  | 
|  | 6324 | import = xmlHashLookup(schema->schemasImports, ns); | 
|  | 6325 | if (import != NULL) { | 
|  | 6326 | /* | 
|  | 6327 | * There was a valid resource for the specified namespace already | 
|  | 6328 | * defined, so skip. | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 6329 | * TODO: This might be changed someday to allow import of | 
|  | 6330 | * components from multiple documents for a single target namespace. | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6331 | */ | 
|  | 6332 | return (0); | 
|  | 6333 | } | 
|  | 6334 | /* | 
|  | 6335 | * Schema Document Location Strategy: | 
|  | 6336 | * | 
|  | 6337 | * 2 Based on the location URI, identify an existing schema document, | 
|  | 6338 | * either as a resource which is an XML document or a <schema> element | 
|  | 6339 | * information item, in some local schema repository; | 
|  | 6340 | * | 
|  | 6341 | * 4 Attempt to resolve the location URI, to locate a resource on the | 
|  | 6342 | * web which is or contains or references a <schema> element; | 
|  | 6343 | * TODO: Hmm, I don't know if the reference stuff in 4. will work. | 
|  | 6344 | * | 
|  | 6345 | */ | 
|  | 6346 |  | 
|  | 6347 | base = xmlNodeGetBase(node->doc, node); | 
|  | 6348 | if (base == NULL) { | 
|  | 6349 | URI = xmlBuildURI(schemaLocation, node->doc->URL); | 
|  | 6350 | } else { | 
|  | 6351 | URI = xmlBuildURI(schemaLocation, base); | 
|  | 6352 | xmlFree(base); | 
|  | 6353 | } | 
|  | 6354 | if (URI != NULL) { | 
|  | 6355 | schemaLocation = xmlDictLookup(ctxt->dict, URI, -1); | 
|  | 6356 | xmlFree(URI); | 
|  | 6357 | } | 
|  | 6358 |  | 
|  | 6359 | parserCtxt = xmlNewParserCtxt(); | 
|  | 6360 | if (parserCtxt == NULL) { | 
|  | 6361 | xmlSchemaPErrMemory(NULL, "xmlSchemaParseImport: " | 
|  | 6362 | "allocating a parser context", NULL); | 
|  | 6363 | return(-1); | 
|  | 6364 | } | 
|  | 6365 |  | 
|  | 6366 | doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation, | 
|  | 6367 | NULL, SCHEMAS_PARSE_OPTIONS); | 
|  | 6368 |  | 
|  | 6369 | /* | 
|  | 6370 | * 2.1 The referent is (a fragment of) a resource which is an | 
|  | 6371 | * XML document (see clause 1.1), which in turn corresponds to | 
|  | 6372 | * a <schema> element information item in a well-formed information | 
|  | 6373 | * set, which in turn corresponds to a valid schema. | 
|  | 6374 | * TODO: What to do with the "fragment" stuff? | 
|  | 6375 | * | 
|  | 6376 | * 2.2 The referent is a <schema> element information item in | 
|  | 6377 | * a well-formed information set, which in turn corresponds | 
|  | 6378 | * to a valid schema. | 
|  | 6379 | * NOTE: 2.2 won't apply, since only XML documents will be processed | 
|  | 6380 | * here. | 
|  | 6381 | */ | 
|  | 6382 | if (doc == NULL) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 6383 | xmlErrorPtr lerr; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6384 | /* | 
|  | 6385 | * It is *not* an error for the application schema reference | 
|  | 6386 | * strategy to fail. | 
|  | 6387 | * | 
|  | 6388 | * If the doc is NULL and the parser error is an IO error we | 
|  | 6389 | * will assume that the resource could not be located or accessed. | 
|  | 6390 | * | 
|  | 6391 | * TODO: Try to find specific error codes to react only on | 
|  | 6392 | * localisation failures. | 
|  | 6393 | * | 
|  | 6394 | * TODO, FIXME: Check the spec: is a namespace added to the imported | 
|  | 6395 | * namespaces, even if the schemaLocation did not provide | 
|  | 6396 | * a resource? I guess so, since omitting the "schemaLocation" | 
|  | 6397 | * attribute, imports a namespace as well. | 
|  | 6398 | */ | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 6399 | lerr = xmlGetLastError(); | 
|  | 6400 | if ((lerr != NULL) && (lerr->domain == XML_FROM_IO)) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6401 | xmlFreeParserCtxt(parserCtxt); | 
|  | 6402 | return(0); | 
|  | 6403 | } | 
|  | 6404 |  | 
|  | 6405 | xmlSchemaPCustomErr(ctxt, | 
|  | 6406 | XML_SCHEMAP_SRC_IMPORT_2_1, | 
|  | 6407 | NULL, NULL, node, | 
|  | 6408 | "Failed to parse the resource '%s' for import", | 
|  | 6409 | schemaLocation); | 
|  | 6410 | xmlFreeParserCtxt(parserCtxt); | 
|  | 6411 | return(XML_SCHEMAP_SRC_IMPORT_2_1); | 
|  | 6412 | } | 
|  | 6413 | xmlFreeParserCtxt(parserCtxt); | 
|  | 6414 |  | 
|  | 6415 | root = xmlDocGetRootElement(doc); | 
|  | 6416 | if (root == NULL) { | 
|  | 6417 | xmlSchemaPCustomErr(ctxt, | 
|  | 6418 | XML_SCHEMAP_SRC_IMPORT_2_1, | 
|  | 6419 | NULL, NULL, node, | 
|  | 6420 | "The XML document '%s' to be imported has no document " | 
|  | 6421 | "element", schemaLocation); | 
|  | 6422 | xmlFreeDoc(doc); | 
|  | 6423 | return (XML_SCHEMAP_SRC_IMPORT_2_1); | 
|  | 6424 | } | 
|  | 6425 |  | 
|  | 6426 | xmlSchemaCleanupDoc(ctxt, root); | 
|  | 6427 |  | 
|  | 6428 | if (!IS_SCHEMA(root, "schema")) { | 
|  | 6429 | xmlSchemaPCustomErr(ctxt, | 
|  | 6430 | XML_SCHEMAP_SRC_IMPORT_2_1, | 
|  | 6431 | NULL, NULL, node, | 
|  | 6432 | "The XML document '%s' to be imported is not a XML schema document", | 
|  | 6433 | schemaLocation); | 
|  | 6434 | xmlFreeDoc(doc); | 
|  | 6435 | return (XML_SCHEMAP_SRC_IMPORT_2_1); | 
|  | 6436 | } | 
|  | 6437 | targetNamespace = xmlSchemaGetProp(ctxt, root, "targetNamespace"); | 
|  | 6438 | /* | 
|  | 6439 | * Schema Representation Constraint: Import Constraints and Semantics | 
|  | 6440 | */ | 
|  | 6441 | if (namespace == NULL) { | 
|  | 6442 | if (targetNamespace != NULL) { | 
|  | 6443 | xmlSchemaPCustomErr(ctxt, | 
|  | 6444 | XML_SCHEMAP_SRC_IMPORT_3_2, | 
|  | 6445 | NULL, NULL, node, | 
|  | 6446 | "No 'namespace' attribute was " | 
|  | 6447 | "specified, thus the XML schema to be imported " | 
|  | 6448 | "must have no target namespace", NULL); | 
|  | 6449 | xmlFreeDoc(doc); | 
|  | 6450 | return (XML_SCHEMAP_SRC_IMPORT_3_2); | 
|  | 6451 | } | 
|  | 6452 | } else { | 
|  | 6453 | if (targetNamespace == NULL) { | 
|  | 6454 | xmlSchemaPCustomErr(ctxt, | 
|  | 6455 | XML_SCHEMAP_SRC_IMPORT_3_1, | 
|  | 6456 | NULL, NULL, node, | 
|  | 6457 | "The attribute 'namespace' requires the XML schema to be " | 
|  | 6458 | "imported to have a target namespace of '%s'", namespace); | 
|  | 6459 | xmlFreeDoc(doc); | 
|  | 6460 | return (XML_SCHEMAP_SRC_IMPORT_3_1); | 
|  | 6461 | } else if (!xmlStrEqual(targetNamespace, namespace)) { | 
|  | 6462 | xmlSchemaPCustomErrExt(ctxt, | 
|  | 6463 | XML_SCHEMAP_SRC_IMPORT_3_1, | 
|  | 6464 | NULL, NULL, node, | 
|  | 6465 | "The value '%s' of the attribute 'namespace' is not " | 
|  | 6466 | "identical to the target namespace '%s' of the " | 
|  | 6467 | "XML schema to be imported", | 
|  | 6468 | namespace, targetNamespace, NULL); | 
|  | 6469 | xmlFreeDoc(doc); | 
|  | 6470 | return (XML_SCHEMAP_SRC_IMPORT_3_1); | 
|  | 6471 | } | 
|  | 6472 | } | 
|  | 6473 | /* | 
|  | 6474 | * Finally, import the schema. | 
|  | 6475 | */ | 
|  | 6476 | if (schema->schemasImports == NULL) { | 
|  | 6477 | schema->schemasImports = xmlHashCreate(10); | 
|  | 6478 | if (schema->schemasImports == NULL) { | 
|  | 6479 | xmlSchemaPErr2(ctxt, node, child, | 
|  | 6480 | XML_SCHEMAP_FAILED_BUILD_IMPORT, | 
|  | 6481 | "Internal error: failed to build import table.\n", | 
|  | 6482 | NULL, NULL); | 
|  | 6483 | return (-1); | 
|  | 6484 | } | 
|  | 6485 | } | 
|  | 6486 | import = (xmlSchemaImport*) xmlMalloc(sizeof(xmlSchemaImport)); | 
|  | 6487 | if (import == NULL) { | 
|  | 6488 | xmlSchemaPErrMemory(NULL, "allocating imported schema", NULL); | 
|  | 6489 | xmlFreeDoc(doc); | 
|  | 6490 | return (-1); | 
|  | 6491 | } | 
|  | 6492 | memset(import, 0, sizeof(xmlSchemaImport)); | 
|  | 6493 | import->schemaLocation = schemaLocation; | 
|  | 6494 | import->doc = doc; | 
|  | 6495 | xmlHashAddEntry(schema->schemasImports, ns, import); | 
|  | 6496 | /* | 
|  | 6497 | * Save and reset the context & schema. | 
|  | 6498 | */ | 
|  | 6499 | url = ctxt->URL; | 
|  | 6500 | /* TODO: Check this. */ | 
|  | 6501 | ctxt->URL = schemaLocation; | 
|  | 6502 | flags = schema->flags; | 
|  | 6503 | oldTNS = schema->targetNamespace; | 
|  | 6504 |  | 
|  | 6505 | xmlSchemaClearSchemaDefaults(schema); | 
|  | 6506 | xmlSchemaParseSchemaDefaults(ctxt, schema, root); | 
|  | 6507 | schema->targetNamespace = targetNamespace; | 
|  | 6508 | xmlSchemaParseSchemaTopLevel(ctxt, schema, root->children); | 
|  | 6509 |  | 
|  | 6510 | /* | 
|  | 6511 | * Restore the context & schema. | 
|  | 6512 | */ | 
|  | 6513 | schema->flags = flags; | 
|  | 6514 | schema->targetNamespace = oldTNS; | 
|  | 6515 | ctxt->URL = url; | 
|  | 6516 |  | 
|  | 6517 | return (1); | 
|  | 6518 | } | 
|  | 6519 |  | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6520 | /** | 
|  | 6521 | * xmlSchemaParseInclude: | 
|  | 6522 | * @ctxt:  a schema validation context | 
|  | 6523 | * @schema:  the schema being built | 
|  | 6524 | * @node:  a subtree containing XML Schema informations | 
|  | 6525 | * | 
|  | 6526 | * parse a XML schema Include definition | 
|  | 6527 | * | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 6528 | * Returns -1 in case of error, 0 if the declaration is improper and | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6529 | *         1 in case of success. | 
|  | 6530 | */ | 
|  | 6531 | static int | 
|  | 6532 | xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
|  | 6533 | xmlNodePtr node) | 
|  | 6534 | { | 
|  | 6535 | xmlNodePtr child = NULL; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 6536 | const xmlChar *schemaLocation, *targetNamespace; | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6537 | xmlDocPtr doc; | 
|  | 6538 | xmlNodePtr root; | 
|  | 6539 | xmlSchemaIncludePtr include; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 6540 | int wasConvertingNs = 0; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6541 | xmlAttrPtr attr; | 
|  | 6542 | int saveFlags; | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6543 |  | 
|  | 6544 |  | 
|  | 6545 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 6546 | return (-1); | 
|  | 6547 |  | 
|  | 6548 | /* | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6549 | * Check for illegal attributes. | 
|  | 6550 | */ | 
|  | 6551 | attr = node->properties; | 
|  | 6552 | while (attr != NULL) { | 
|  | 6553 | if (attr->ns == NULL) { | 
|  | 6554 | if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && | 
|  | 6555 | (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { | 
|  | 6556 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 6557 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 6558 | NULL, NULL, attr); | 
|  | 6559 | } | 
|  | 6560 | } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { | 
|  | 6561 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 6562 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 6563 | NULL, NULL, attr); | 
|  | 6564 | } | 
|  | 6565 | attr = attr->next; | 
|  | 6566 | } | 
|  | 6567 | /* | 
|  | 6568 | * Extract and validate attributes. | 
|  | 6569 | */ | 
|  | 6570 | /* | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6571 | * Preliminary step, extract the URI-Reference for the include and | 
|  | 6572 | * make an URI from the base. | 
|  | 6573 | */ | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6574 | attr = xmlSchemaGetPropNode(node, "schemaLocation"); | 
|  | 6575 | if (attr != NULL) { | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6576 | xmlChar *base = NULL; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6577 | xmlChar *uri = NULL; | 
|  | 6578 |  | 
|  | 6579 | if (xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr, | 
|  | 6580 | xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), &schemaLocation) != 0) | 
|  | 6581 | return (-1); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6582 | base = xmlNodeGetBase(node->doc, node); | 
|  | 6583 | if (base == NULL) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6584 | uri = xmlBuildURI(schemaLocation, node->doc->URL); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6585 | } else { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6586 | uri = xmlBuildURI(schemaLocation, base); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6587 | xmlFree(base); | 
|  | 6588 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6589 | if (uri != NULL) { | 
|  | 6590 | schemaLocation = xmlDictLookup(ctxt->dict, uri, -1); | 
|  | 6591 | xmlFree(uri); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6592 | } | 
|  | 6593 | } else { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6594 | xmlSchemaPMissingAttrErr(ctxt, | 
|  | 6595 | XML_SCHEMAP_INCLUDE_SCHEMA_NO_URI, | 
|  | 6596 | NULL, NULL, node, "schemaLocation", NULL); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6597 | return (-1); | 
|  | 6598 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6599 | /* | 
|  | 6600 | * And now for the children... | 
|  | 6601 | */ | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6602 | child = node->children; | 
|  | 6603 | while (IS_SCHEMA(child, "annotation")) { | 
|  | 6604 | /* | 
|  | 6605 | * the annotations here are simply discarded ... | 
|  | 6606 | */ | 
|  | 6607 | child = child->next; | 
|  | 6608 | } | 
|  | 6609 | if (child != NULL) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6610 | xmlSchemaPContentErr(ctxt, | 
|  | 6611 | XML_SCHEMAP_UNKNOWN_INCLUDE_CHILD, | 
|  | 6612 | NULL, NULL, node, child, NULL, | 
|  | 6613 | "(annotation?)"); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6614 | } | 
|  | 6615 |  | 
|  | 6616 | /* | 
|  | 6617 | * First step is to parse the input document into an DOM/Infoset | 
|  | 6618 | */ | 
|  | 6619 | doc = xmlReadFile((const char *) schemaLocation, NULL, | 
|  | 6620 | SCHEMAS_PARSE_OPTIONS); | 
|  | 6621 | if (doc == NULL) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6622 | /* | 
|  | 6623 | * TODO: It is not an error for the ·actual value· of the | 
|  | 6624 | * schemaLocation [attribute] to fail to resolve it all, in which | 
|  | 6625 | * case no corresponding inclusion is performed. | 
|  | 6626 | * So do we need a warning report here? | 
|  | 6627 | */ | 
|  | 6628 | xmlSchemaPCustomErr(ctxt, | 
|  | 6629 | XML_SCHEMAP_FAILED_LOAD, | 
|  | 6630 | NULL, NULL, node, | 
|  | 6631 | "Failed to load the document '%s' for inclusion", schemaLocation); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6632 | return(-1); | 
|  | 6633 | } | 
|  | 6634 |  | 
|  | 6635 | /* | 
|  | 6636 | * Then extract the root of the schema | 
|  | 6637 | */ | 
|  | 6638 | root = xmlDocGetRootElement(doc); | 
|  | 6639 | if (root == NULL) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6640 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 6641 | XML_SCHEMAP_NOROOT, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6642 | NULL, NULL, node, | 
|  | 6643 | "The included document '%s' has no document " | 
|  | 6644 | "element", schemaLocation); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6645 | xmlFreeDoc(doc); | 
|  | 6646 | return (-1); | 
|  | 6647 | } | 
|  | 6648 |  | 
|  | 6649 | /* | 
|  | 6650 | * Remove all the blank text nodes | 
|  | 6651 | */ | 
|  | 6652 | xmlSchemaCleanupDoc(ctxt, root); | 
|  | 6653 |  | 
|  | 6654 | /* | 
|  | 6655 | * Check the schemas top level element | 
|  | 6656 | */ | 
|  | 6657 | if (!IS_SCHEMA(root, "schema")) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6658 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 6659 | XML_SCHEMAP_NOT_SCHEMA, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6660 | NULL, NULL, node, | 
|  | 6661 | "The document '%s' to be included is not a schema document", | 
|  | 6662 | schemaLocation); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6663 | xmlFreeDoc(doc); | 
|  | 6664 | return (-1); | 
|  | 6665 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 6666 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6667 | targetNamespace = xmlSchemaGetProp(ctxt, root, "targetNamespace"); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 6668 | /* | 
|  | 6669 | * 2.1 SII has a targetNamespace [attribute], and its ·actual | 
|  | 6670 | * value· is identical to the ·actual value· of the targetNamespace | 
|  | 6671 | * [attribute] of SIIÂ’ (which must have such an [attribute]). | 
|  | 6672 | */ | 
|  | 6673 | if (targetNamespace != NULL) { | 
|  | 6674 | if (schema->targetNamespace == NULL) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6675 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 6676 | XML_SCHEMAP_SRC_INCLUDE, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6677 | NULL, NULL, node, | 
|  | 6678 | "The target namespace of the included schema " | 
|  | 6679 | "'%s' has to be absent, since the including schema " | 
|  | 6680 | "has no target namespace", | 
|  | 6681 | schemaLocation); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 6682 | xmlFreeDoc(doc); | 
|  | 6683 | return (-1); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6684 | } else if (!xmlStrEqual(targetNamespace, schema->targetNamespace)) { | 
|  | 6685 | xmlSchemaPCustomErrExt(ctxt, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 6686 | XML_SCHEMAP_SRC_INCLUDE, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6687 | NULL, NULL, node, | 
|  | 6688 | "The target namespace '%s' of the included schema '%s' " | 
|  | 6689 | "differs from '%s' of the including schema", | 
|  | 6690 | targetNamespace, schemaLocation, schema->targetNamespace); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 6691 | xmlFreeDoc(doc); | 
|  | 6692 | return (-1); | 
|  | 6693 | } | 
|  | 6694 | } else if (schema->targetNamespace != NULL) { | 
|  | 6695 | if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) { | 
|  | 6696 | schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS; | 
|  | 6697 | } else | 
|  | 6698 | wasConvertingNs = 1; | 
|  | 6699 | } | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6700 | /* | 
|  | 6701 | * register the include | 
|  | 6702 | */ | 
|  | 6703 | include = (xmlSchemaIncludePtr) xmlMalloc(sizeof(xmlSchemaInclude)); | 
|  | 6704 | if (include == NULL) { | 
|  | 6705 | xmlSchemaPErrMemory(ctxt, "allocating included schema", NULL); | 
|  | 6706 | xmlFreeDoc(doc); | 
|  | 6707 | return (-1); | 
|  | 6708 | } | 
|  | 6709 |  | 
|  | 6710 | memset(include, 0, sizeof(xmlSchemaInclude)); | 
|  | 6711 | include->schemaLocation = xmlDictLookup(ctxt->dict, schemaLocation, -1); | 
|  | 6712 | include->doc = doc; | 
|  | 6713 | include->next = schema->includes; | 
|  | 6714 | schema->includes = include; | 
|  | 6715 |  | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6716 | /* | 
|  | 6717 | * parse the declarations in the included file like if they | 
|  | 6718 | * were in the original file. | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 6719 | */ | 
|  | 6720 | /* | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6721 | * TODO: The complete validation of the <schema> element is not done. | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 6722 | */ | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6723 | /* | 
|  | 6724 | * The default values ("blockDefault", "elementFormDefault", etc.) | 
|  | 6725 | * are set to the values of the included schema and restored afterwards. | 
|  | 6726 | */ | 
|  | 6727 | saveFlags = schema->flags; | 
|  | 6728 | xmlSchemaClearSchemaDefaults(schema); | 
|  | 6729 | xmlSchemaParseSchemaDefaults(ctxt, schema, root); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6730 | xmlSchemaParseSchemaTopLevel(ctxt, schema, root->children); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6731 | schema->flags = saveFlags; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 6732 | /* | 
|  | 6733 | * Remove the converting flag. | 
|  | 6734 | */ | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6735 | if ((wasConvertingNs == 0) && | 
|  | 6736 | (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS)) | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 6737 | schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS; | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 6738 | return (1); | 
|  | 6739 | } | 
|  | 6740 |  | 
|  | 6741 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6742 | * xmlSchemaParseChoice: | 
|  | 6743 | * @ctxt:  a schema validation context | 
|  | 6744 | * @schema:  the schema being built | 
|  | 6745 | * @node:  a subtree containing XML Schema informations | 
|  | 6746 | * | 
|  | 6747 | * parse a XML schema Choice definition | 
|  | 6748 | * *WARNING* this interface is highly subject to change | 
|  | 6749 | * | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 6750 | * Returns -1 in case of error, 0 if the declaration is improper and | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6751 | *         1 in case of success. | 
|  | 6752 | */ | 
|  | 6753 | static xmlSchemaTypePtr | 
|  | 6754 | xmlSchemaParseChoice(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 6755 | xmlNodePtr node) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6756 | { | 
|  | 6757 | xmlSchemaTypePtr type, subtype, last = NULL; | 
|  | 6758 | xmlNodePtr child = NULL; | 
|  | 6759 | xmlChar name[30]; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6760 | xmlAttrPtr attr; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6761 |  | 
|  | 6762 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 6763 | return (NULL); | 
|  | 6764 |  | 
|  | 6765 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 6766 | snprintf((char *) name, 30, "choice %d", ctxt->counter++ + 1); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6767 | type = xmlSchemaAddType(ctxt, schema, name, NULL, node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6768 | if (type == NULL) | 
|  | 6769 | return (NULL); | 
|  | 6770 | type->node = node; | 
|  | 6771 | type->type = XML_SCHEMA_TYPE_CHOICE; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6772 | /* | 
|  | 6773 | * Check for illegal attributes. | 
|  | 6774 | */ | 
|  | 6775 | attr = node->properties; | 
|  | 6776 | while (attr != NULL) { | 
|  | 6777 | if (attr->ns == NULL) { | 
|  | 6778 | if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && | 
|  | 6779 | (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && | 
|  | 6780 | (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) { | 
|  | 6781 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 6782 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 6783 | NULL, type, attr); | 
|  | 6784 | } | 
|  | 6785 | } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { | 
|  | 6786 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 6787 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 6788 | NULL, type, attr); | 
|  | 6789 | } | 
|  | 6790 | attr = attr->next; | 
|  | 6791 | } | 
|  | 6792 | /* | 
|  | 6793 | * Extract and validate attributes. | 
|  | 6794 | */ | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 6795 | type->id = xmlSchemaGetProp(ctxt, node, "id"); | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 6796 | type->minOccurs = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "nonNegativeInteger"); | 
|  | 6797 | type->maxOccurs = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, | 
|  | 6798 | "(nonNegativeInteger | unbounded)"); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6799 | /* | 
|  | 6800 | * And now for the children... | 
|  | 6801 | */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6802 | child = node->children; | 
|  | 6803 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 6804 | type->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 6805 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6806 | } | 
|  | 6807 | while ((IS_SCHEMA(child, "element")) || | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 6808 | (IS_SCHEMA(child, "group")) || | 
|  | 6809 | (IS_SCHEMA(child, "any")) || | 
|  | 6810 | (IS_SCHEMA(child, "choice")) || | 
|  | 6811 | (IS_SCHEMA(child, "sequence"))) { | 
|  | 6812 | subtype = NULL; | 
|  | 6813 | if (IS_SCHEMA(child, "element")) { | 
|  | 6814 | subtype = (xmlSchemaTypePtr) | 
|  | 6815 | xmlSchemaParseElement(ctxt, schema, child, 0); | 
|  | 6816 | } else if (IS_SCHEMA(child, "group")) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 6817 | subtype = xmlSchemaParseGroup(ctxt, schema, child, 0); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 6818 | } else if (IS_SCHEMA(child, "any")) { | 
|  | 6819 | subtype = xmlSchemaParseAny(ctxt, schema, child); | 
|  | 6820 | } else if (IS_SCHEMA(child, "sequence")) { | 
|  | 6821 | subtype = xmlSchemaParseSequence(ctxt, schema, child); | 
|  | 6822 | } else if (IS_SCHEMA(child, "choice")) { | 
|  | 6823 | subtype = xmlSchemaParseChoice(ctxt, schema, child); | 
|  | 6824 | } | 
|  | 6825 | if (subtype != NULL) { | 
|  | 6826 | if (last == NULL) { | 
|  | 6827 | type->subtypes = subtype; | 
|  | 6828 | last = subtype; | 
|  | 6829 | } else { | 
|  | 6830 | last->next = subtype; | 
|  | 6831 | last = subtype; | 
|  | 6832 | } | 
|  | 6833 | last->next = NULL; | 
|  | 6834 | } | 
|  | 6835 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6836 | } | 
|  | 6837 | if (child != NULL) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6838 | /* TODO: error code. */ | 
|  | 6839 | xmlSchemaPContentErr(ctxt, | 
|  | 6840 | XML_SCHEMAP_UNKNOWN_CHOICE_CHILD, | 
|  | 6841 | NULL, type, node, child, NULL, | 
|  | 6842 | "(annotation?, (element | group | choice | sequence | any)*)"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6843 | } | 
|  | 6844 |  | 
|  | 6845 | return (type); | 
|  | 6846 | } | 
|  | 6847 |  | 
|  | 6848 | /** | 
|  | 6849 | * xmlSchemaParseSequence: | 
|  | 6850 | * @ctxt:  a schema validation context | 
|  | 6851 | * @schema:  the schema being built | 
|  | 6852 | * @node:  a subtree containing XML Schema informations | 
|  | 6853 | * | 
|  | 6854 | * parse a XML schema Sequence definition | 
|  | 6855 | * *WARNING* this interface is highly subject to change | 
|  | 6856 | * | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 6857 | * Returns -1 in case of error, 0 if the declaration is improper and | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6858 | *         1 in case of success. | 
|  | 6859 | */ | 
|  | 6860 | static xmlSchemaTypePtr | 
|  | 6861 | xmlSchemaParseSequence(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 6862 | xmlNodePtr node) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6863 | { | 
|  | 6864 | xmlSchemaTypePtr type, subtype, last = NULL; | 
|  | 6865 | xmlNodePtr child = NULL; | 
|  | 6866 | xmlChar name[30]; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6867 | xmlAttrPtr attr; | 
|  | 6868 | const xmlChar *oldcontainer; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6869 |  | 
|  | 6870 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 6871 | return (NULL); | 
|  | 6872 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6873 | oldcontainer = ctxt->container; | 
|  | 6874 | snprintf((char *) name, 30, "#seq %d", ctxt->counter++ + 1); | 
|  | 6875 | type = xmlSchemaAddType(ctxt, schema, name, NULL, node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6876 | if (type == NULL) | 
|  | 6877 | return (NULL); | 
|  | 6878 | type->node = node; | 
|  | 6879 | type->type = XML_SCHEMA_TYPE_SEQUENCE; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6880 | /* | 
|  | 6881 | * Check for illegal attributes. | 
|  | 6882 | */ | 
|  | 6883 | attr = node->properties; | 
|  | 6884 | while (attr != NULL) { | 
|  | 6885 | if (attr->ns == NULL) { | 
|  | 6886 | if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && | 
|  | 6887 | (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && | 
|  | 6888 | (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) { | 
|  | 6889 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 6890 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 6891 | NULL, type, attr); | 
|  | 6892 | } | 
|  | 6893 | } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { | 
|  | 6894 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 6895 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 6896 | NULL, type, attr); | 
|  | 6897 | } | 
|  | 6898 | attr = attr->next; | 
|  | 6899 | } | 
|  | 6900 | /* | 
|  | 6901 | * Extract and validate attributes. | 
|  | 6902 | */ | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 6903 | type->id = xmlSchemaGetProp(ctxt, node, "id"); | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 6904 | type->minOccurs = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "nonNegativeInteger"); | 
|  | 6905 | type->maxOccurs = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, | 
|  | 6906 | "(nonNegativeInteger | unbounded)"); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6907 | /* | 
|  | 6908 | * And now for the children... | 
|  | 6909 | */ | 
|  | 6910 | ctxt->container = (const xmlChar *) name; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6911 | child = node->children; | 
|  | 6912 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 6913 | type->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 6914 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6915 | } | 
|  | 6916 | while ((IS_SCHEMA(child, "element")) || | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 6917 | (IS_SCHEMA(child, "group")) || | 
|  | 6918 | (IS_SCHEMA(child, "any")) || | 
|  | 6919 | (IS_SCHEMA(child, "choice")) || | 
|  | 6920 | (IS_SCHEMA(child, "sequence"))) { | 
|  | 6921 | subtype = NULL; | 
|  | 6922 | if (IS_SCHEMA(child, "element")) { | 
|  | 6923 | subtype = (xmlSchemaTypePtr) | 
|  | 6924 | xmlSchemaParseElement(ctxt, schema, child, 0); | 
|  | 6925 | } else if (IS_SCHEMA(child, "group")) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 6926 | subtype = xmlSchemaParseGroup(ctxt, schema, child, 0); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 6927 | } else if (IS_SCHEMA(child, "any")) { | 
|  | 6928 | subtype = xmlSchemaParseAny(ctxt, schema, child); | 
|  | 6929 | } else if (IS_SCHEMA(child, "choice")) { | 
|  | 6930 | subtype = xmlSchemaParseChoice(ctxt, schema, child); | 
|  | 6931 | } else if (IS_SCHEMA(child, "sequence")) { | 
|  | 6932 | subtype = xmlSchemaParseSequence(ctxt, schema, child); | 
|  | 6933 | } | 
|  | 6934 | if (subtype != NULL) { | 
|  | 6935 | if (last == NULL) { | 
|  | 6936 | type->subtypes = subtype; | 
|  | 6937 | last = subtype; | 
|  | 6938 | } else { | 
|  | 6939 | last->next = subtype; | 
|  | 6940 | last = subtype; | 
|  | 6941 | } | 
|  | 6942 | last->next = NULL; | 
|  | 6943 | } | 
|  | 6944 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6945 | } | 
|  | 6946 | if (child != NULL) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6947 | xmlSchemaPContentErr(ctxt, | 
|  | 6948 | XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD, | 
|  | 6949 | NULL, type, node, child, NULL, | 
|  | 6950 | "(annotation?, (element | group | choice | sequence | any)*)"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6951 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6952 | ctxt->container = oldcontainer; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6953 |  | 
|  | 6954 | return (type); | 
|  | 6955 | } | 
|  | 6956 |  | 
|  | 6957 | /** | 
|  | 6958 | * xmlSchemaParseRestriction: | 
|  | 6959 | * @ctxt:  a schema validation context | 
|  | 6960 | * @schema:  the schema being built | 
|  | 6961 | * @node:  a subtree containing XML Schema informations | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6962 | * | 
|  | 6963 | * parse a XML schema Restriction definition | 
|  | 6964 | * *WARNING* this interface is highly subject to change | 
|  | 6965 | * | 
|  | 6966 | * Returns the type definition or NULL in case of error | 
|  | 6967 | */ | 
|  | 6968 | static xmlSchemaTypePtr | 
|  | 6969 | xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 6970 | xmlNodePtr node) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6971 | { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 6972 | xmlSchemaTypePtr type, subtype; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6973 | xmlNodePtr child = NULL; | 
|  | 6974 | xmlChar name[30]; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 6975 | const xmlChar *oldcontainer; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6976 | xmlAttrPtr attr; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6977 |  | 
|  | 6978 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 6979 | return (NULL); | 
|  | 6980 |  | 
|  | 6981 | oldcontainer = ctxt->container; | 
|  | 6982 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6983 | snprintf((char *) name, 30, "#restr %d", ctxt->counter++ + 1); | 
|  | 6984 | type = xmlSchemaAddType(ctxt, schema, name, NULL, node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6985 | if (type == NULL) | 
|  | 6986 | return (NULL); | 
| Daniel Veillard | 4e5d665 | 2004-06-29 21:01:12 +0000 | [diff] [blame] | 6987 | type->type = XML_SCHEMA_TYPE_RESTRICTION; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 6988 | type->node = node; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 6989 | /* | 
|  | 6990 | * Check for illegal attributes. | 
|  | 6991 | */ | 
|  | 6992 | attr = node->properties; | 
|  | 6993 | while (attr != NULL) { | 
|  | 6994 | if (attr->ns == NULL) { | 
|  | 6995 | if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && | 
|  | 6996 | (!xmlStrEqual(attr->name, BAD_CAST "base"))) { | 
|  | 6997 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 6998 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 6999 | NULL, type, attr); | 
|  | 7000 | } | 
|  | 7001 | } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { | 
|  | 7002 | xmlSchemaPIllegalAttrErr(ctxt, | 
|  | 7003 | XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, | 
|  | 7004 | NULL, type, attr); | 
|  | 7005 | } | 
|  | 7006 | attr = attr->next; | 
|  | 7007 | } | 
|  | 7008 | /* | 
|  | 7009 | * Extract and validate attributes. | 
|  | 7010 | */ | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 7011 | type->id = xmlSchemaGetProp(ctxt, node, "id"); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 7012 | /* | 
|  | 7013 | * Attribute "base". | 
|  | 7014 | */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7015 | type->base = xmlGetQNameProp(ctxt, node, "base", &(type->baseNs)); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 7016 | if ((type->base == NULL) && | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 7017 | (ctxt->ctxtType->type == XML_SCHEMA_TYPE_COMPLEX)) { | 
|  | 7018 | /* TODO: Think about the error code. */ | 
|  | 7019 | xmlSchemaPMissingAttrErr(ctxt, | 
|  | 7020 | XML_SCHEMAP_RESTRICTION_NONAME_NOREF, | 
|  | 7021 | NULL, type, node, "base", NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7022 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 7023 | /* | 
|  | 7024 | * And now for the children... | 
|  | 7025 | */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7026 | ctxt->container = name; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7027 | child = node->children; | 
|  | 7028 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7029 | type->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 7030 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7031 | } | 
|  | 7032 | subtype = NULL; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 7033 | if (ctxt->parentItem->type == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { | 
|  | 7034 | if (IS_SCHEMA(child, "all")) { | 
|  | 7035 | subtype = (xmlSchemaTypePtr) | 
|  | 7036 | xmlSchemaParseAll(ctxt, schema, child); | 
|  | 7037 | child = child->next; | 
|  | 7038 | type->subtypes = subtype; | 
|  | 7039 | } else if (IS_SCHEMA(child, "choice")) { | 
|  | 7040 | subtype = xmlSchemaParseChoice(ctxt, schema, child); | 
|  | 7041 | child = child->next; | 
|  | 7042 | type->subtypes = subtype; | 
|  | 7043 | } else if (IS_SCHEMA(child, "sequence")) { | 
|  | 7044 | subtype = (xmlSchemaTypePtr) | 
|  | 7045 | xmlSchemaParseSequence(ctxt, schema, child); | 
|  | 7046 | child = child->next; | 
|  | 7047 | type->subtypes = subtype; | 
|  | 7048 | } else if (IS_SCHEMA(child, "group")) { | 
|  | 7049 | subtype = (xmlSchemaTypePtr) | 
|  | 7050 | xmlSchemaParseGroup(ctxt, schema, child, 0); | 
|  | 7051 | child = child->next; | 
|  | 7052 | type->subtypes = subtype; | 
|  | 7053 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 7054 | } else if (ctxt->ctxtType->type == XML_SCHEMA_TYPE_SIMPLE) { | 
|  | 7055 | if (IS_SCHEMA(child, "simpleType")) { | 
|  | 7056 | if (type->base != NULL) { | 
|  | 7057 | /* | 
|  | 7058 | * src-restriction-base-or-simpleType | 
|  | 7059 | * Either the base [attribute] or the simpleType [child] of the | 
|  | 7060 | * <restriction> element must be present, but not both. | 
|  | 7061 | */ | 
|  | 7062 | xmlSchemaPContentErr(ctxt, | 
|  | 7063 | XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, | 
|  | 7064 | NULL, NULL, type->node, child, | 
|  | 7065 | "The attribute 'base' and the <simpleType> child are " | 
|  | 7066 | "mutually exclusive", NULL); | 
|  | 7067 | } else { | 
|  | 7068 | subtype = (xmlSchemaTypePtr) | 
|  | 7069 | xmlSchemaParseSimpleType(ctxt, schema, child, 0); | 
|  | 7070 | type->baseType = subtype; | 
|  | 7071 | } | 
|  | 7072 | child = child->next; | 
|  | 7073 | } | 
|  | 7074 | } else if (ctxt->parentItem->type == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 7075 | if (IS_SCHEMA(child, "simpleType")) { | 
|  | 7076 | subtype = (xmlSchemaTypePtr) | 
|  | 7077 | xmlSchemaParseSimpleType(ctxt, schema, child, 0); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 7078 | type->subtypes = subtype; | 
|  | 7079 | child = child->next; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 7080 | } | 
|  | 7081 | } | 
|  | 7082 | if ((ctxt->ctxtType->type == XML_SCHEMA_TYPE_SIMPLE) || | 
|  | 7083 | (ctxt->parentItem->type == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) { | 
|  | 7084 | xmlSchemaFacetPtr facet, lastfacet = NULL; | 
|  | 7085 |  | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 7086 | /* | 
|  | 7087 | * Add the facets to the parent simpleType/complexType. | 
|  | 7088 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7089 | /* | 
|  | 7090 | * TODO: Datatypes: 4.1.3 Constraints on XML Representation of | 
|  | 7091 | * Simple Type Definition Schema Representation Constraint: | 
|  | 7092 | * *Single Facet Value* | 
|  | 7093 | */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 7094 | while ((IS_SCHEMA(child, "minInclusive")) || | 
|  | 7095 | (IS_SCHEMA(child, "minExclusive")) || | 
|  | 7096 | (IS_SCHEMA(child, "maxInclusive")) || | 
|  | 7097 | (IS_SCHEMA(child, "maxExclusive")) || | 
|  | 7098 | (IS_SCHEMA(child, "totalDigits")) || | 
|  | 7099 | (IS_SCHEMA(child, "fractionDigits")) || | 
|  | 7100 | (IS_SCHEMA(child, "pattern")) || | 
|  | 7101 | (IS_SCHEMA(child, "enumeration")) || | 
|  | 7102 | (IS_SCHEMA(child, "whiteSpace")) || | 
|  | 7103 | (IS_SCHEMA(child, "length")) || | 
|  | 7104 | (IS_SCHEMA(child, "maxLength")) || | 
|  | 7105 | (IS_SCHEMA(child, "minLength"))) { | 
|  | 7106 | facet = xmlSchemaParseFacet(ctxt, schema, child); | 
|  | 7107 | if (facet != NULL) { | 
|  | 7108 | if (lastfacet == NULL) | 
|  | 7109 | ctxt->ctxtType->facets = facet; | 
|  | 7110 | else | 
|  | 7111 | lastfacet->next = facet; | 
|  | 7112 | lastfacet = facet; | 
|  | 7113 | lastfacet->next = NULL; | 
|  | 7114 | } | 
|  | 7115 | child = child->next; | 
|  | 7116 | } | 
|  | 7117 | /* | 
|  | 7118 | * Create links for derivation and validation. | 
|  | 7119 | */ | 
|  | 7120 | if (lastfacet != NULL) { | 
|  | 7121 | xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL; | 
|  | 7122 |  | 
|  | 7123 | facet = ctxt->ctxtType->facets; | 
|  | 7124 | do { | 
|  | 7125 | facetLink = (xmlSchemaFacetLinkPtr) xmlMalloc(sizeof(xmlSchemaFacetLink)); | 
|  | 7126 | if (facetLink == NULL) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 7127 | xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 7128 | xmlFree(facetLink); | 
|  | 7129 | return (NULL); | 
|  | 7130 | } | 
|  | 7131 | facetLink->facet = facet; | 
|  | 7132 | facetLink->next = NULL; | 
|  | 7133 | if (lastFacetLink == NULL) | 
|  | 7134 | ctxt->ctxtType->facetSet = facetLink; | 
|  | 7135 | else | 
|  | 7136 | lastFacetLink->next = facetLink; | 
|  | 7137 | lastFacetLink = facetLink; | 
|  | 7138 | facet = facet->next; | 
|  | 7139 | } while (facet != NULL); | 
|  | 7140 | } | 
|  | 7141 | } | 
|  | 7142 | if (ctxt->ctxtType->type == XML_SCHEMA_TYPE_COMPLEX) | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 7143 | child = xmlSchemaParseAttrDecls(ctxt, schema, child, type); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7144 | if (child != NULL) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 7145 | /* TODO: Think about the error code. */ | 
|  | 7146 | if (ctxt->parentItem->type == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { | 
|  | 7147 | xmlSchemaPContentErr(ctxt, | 
|  | 7148 | XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD, | 
|  | 7149 | NULL, type, node, child, NULL, | 
|  | 7150 | "annotation?, (group | all | choice | sequence)?, " | 
|  | 7151 | "((attribute | attributeGroup)*, anyAttribute?))"); | 
|  | 7152 | } else if (ctxt->parentItem->type == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { | 
|  | 7153 | xmlSchemaPContentErr(ctxt, | 
|  | 7154 | XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD, | 
|  | 7155 | NULL, type, node, child, NULL, | 
|  | 7156 | "(annotation?, (simpleType?, (minExclusive | minInclusive | " | 
|  | 7157 | "maxExclusive | maxInclusive | totalDigits | fractionDigits | " | 
|  | 7158 | "length | minLength | maxLength | enumeration | whiteSpace | " | 
|  | 7159 | "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))"); | 
|  | 7160 | } else { | 
|  | 7161 | /* Simple type */ | 
|  | 7162 | xmlSchemaPContentErr(ctxt, | 
|  | 7163 | XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD, | 
|  | 7164 | NULL, type, node, child, NULL, | 
|  | 7165 | "(annotation?, (simpleType?, (minExclusive | minInclusive | " | 
|  | 7166 | "maxExclusive | maxInclusive | totalDigits | fractionDigits | " | 
|  | 7167 | "length | minLength | maxLength | enumeration | whiteSpace | " | 
|  | 7168 | "pattern)*))"); | 
|  | 7169 | } | 
|  | 7170 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7171 | ctxt->container = oldcontainer; | 
|  | 7172 | return (type); | 
|  | 7173 | } | 
|  | 7174 |  | 
|  | 7175 | /** | 
|  | 7176 | * xmlSchemaParseExtension: | 
|  | 7177 | * @ctxt:  a schema validation context | 
|  | 7178 | * @schema:  the schema being built | 
|  | 7179 | * @node:  a subtree containing XML Schema informations | 
|  | 7180 | * | 
|  | 7181 | * parse a XML schema Extension definition | 
|  | 7182 | * *WARNING* this interface is highly subject to change | 
|  | 7183 | * | 
|  | 7184 | * Returns the type definition or NULL in case of error | 
|  | 7185 | */ | 
|  | 7186 | static xmlSchemaTypePtr | 
|  | 7187 | xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7188 | xmlNodePtr node) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7189 | { | 
|  | 7190 | xmlSchemaTypePtr type, subtype; | 
|  | 7191 | xmlNodePtr child = NULL; | 
|  | 7192 | xmlChar name[30]; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 7193 | const xmlChar *oldcontainer; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7194 |  | 
|  | 7195 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 7196 | return (NULL); | 
|  | 7197 |  | 
|  | 7198 | oldcontainer = ctxt->container; | 
|  | 7199 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7200 | snprintf((char *) name, 30, "extension %d", ctxt->counter++ + 1); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 7201 | type = xmlSchemaAddType(ctxt, schema, name, NULL, node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7202 | if (type == NULL) | 
|  | 7203 | return (NULL); | 
| Daniel Veillard | 4e5d665 | 2004-06-29 21:01:12 +0000 | [diff] [blame] | 7204 | type->type = XML_SCHEMA_TYPE_EXTENSION; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7205 | type->node = node; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 7206 | type->id = xmlSchemaGetProp(ctxt, node, "id"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7207 | ctxt->container = name; | 
|  | 7208 |  | 
|  | 7209 | type->base = xmlGetQNameProp(ctxt, node, "base", &(type->baseNs)); | 
|  | 7210 | if (type->base == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7211 | xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_EXTENSION_NO_BASE, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7212 | "<extension>: The attribute \"base\" is missing.\n", | 
|  | 7213 | type->name, NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7214 | } | 
|  | 7215 | child = node->children; | 
|  | 7216 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7217 | type->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 7218 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7219 | } | 
|  | 7220 | subtype = NULL; | 
|  | 7221 |  | 
|  | 7222 | if (IS_SCHEMA(child, "all")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7223 | subtype = xmlSchemaParseAll(ctxt, schema, child); | 
|  | 7224 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7225 | } else if (IS_SCHEMA(child, "choice")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7226 | subtype = xmlSchemaParseChoice(ctxt, schema, child); | 
|  | 7227 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7228 | } else if (IS_SCHEMA(child, "sequence")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7229 | subtype = xmlSchemaParseSequence(ctxt, schema, child); | 
|  | 7230 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7231 | } else if (IS_SCHEMA(child, "group")) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 7232 | subtype = xmlSchemaParseGroup(ctxt, schema, child, 0); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7233 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7234 | } | 
|  | 7235 | if (subtype != NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7236 | type->subtypes = subtype; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7237 | child = xmlSchemaParseAttrDecls(ctxt, schema, child, type); | 
|  | 7238 | if (child != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7239 | xmlSchemaPErr2(ctxt, node, child, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7240 | XML_SCHEMAP_UNKNOWN_EXTENSION_CHILD, | 
|  | 7241 | "<extension> has unexpected content.\n", type->name, | 
|  | 7242 | NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7243 | } | 
|  | 7244 | ctxt->container = oldcontainer; | 
|  | 7245 | return (type); | 
|  | 7246 | } | 
|  | 7247 |  | 
|  | 7248 | /** | 
|  | 7249 | * xmlSchemaParseSimpleContent: | 
|  | 7250 | * @ctxt:  a schema validation context | 
|  | 7251 | * @schema:  the schema being built | 
|  | 7252 | * @node:  a subtree containing XML Schema informations | 
|  | 7253 | * | 
|  | 7254 | * parse a XML schema SimpleContent definition | 
|  | 7255 | * *WARNING* this interface is highly subject to change | 
|  | 7256 | * | 
|  | 7257 | * Returns the type definition or NULL in case of error | 
|  | 7258 | */ | 
|  | 7259 | static xmlSchemaTypePtr | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7260 | xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt, | 
|  | 7261 | xmlSchemaPtr schema, xmlNodePtr node) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7262 | { | 
|  | 7263 | xmlSchemaTypePtr type, subtype; | 
|  | 7264 | xmlNodePtr child = NULL; | 
|  | 7265 | xmlChar name[30]; | 
|  | 7266 |  | 
|  | 7267 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 7268 | return (NULL); | 
|  | 7269 |  | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 7270 | snprintf((char *) name, 30, "simpleContent %d", ctxt->counter++ + 1); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 7271 | type = xmlSchemaAddType(ctxt, schema, name, NULL, node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7272 | if (type == NULL) | 
|  | 7273 | return (NULL); | 
| Daniel Veillard | 4e5d665 | 2004-06-29 21:01:12 +0000 | [diff] [blame] | 7274 | type->type = XML_SCHEMA_TYPE_SIMPLE_CONTENT; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7275 | type->node = node; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 7276 | type->id = xmlSchemaGetProp(ctxt, node, "id"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7277 |  | 
|  | 7278 | child = node->children; | 
|  | 7279 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7280 | type->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 7281 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7282 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 7283 | ctxt->parentItem = type; | 
|  | 7284 | subtype = NULL; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7285 | if (IS_SCHEMA(child, "restriction")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7286 | subtype = (xmlSchemaTypePtr) | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 7287 | xmlSchemaParseRestriction(ctxt, schema, child); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7288 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7289 | } else if (IS_SCHEMA(child, "extension")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7290 | subtype = (xmlSchemaTypePtr) | 
|  | 7291 | xmlSchemaParseExtension(ctxt, schema, child); | 
|  | 7292 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7293 | } | 
|  | 7294 | type->subtypes = subtype; | 
|  | 7295 | if (child != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7296 | xmlSchemaPErr2(ctxt, node, child, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7297 | XML_SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD, | 
|  | 7298 | "<simpleContent> has unexpected content.\n", | 
|  | 7299 | NULL, NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7300 | } | 
|  | 7301 | return (type); | 
|  | 7302 | } | 
|  | 7303 |  | 
|  | 7304 | /** | 
|  | 7305 | * xmlSchemaParseComplexContent: | 
|  | 7306 | * @ctxt:  a schema validation context | 
|  | 7307 | * @schema:  the schema being built | 
|  | 7308 | * @node:  a subtree containing XML Schema informations | 
|  | 7309 | * | 
|  | 7310 | * parse a XML schema ComplexContent definition | 
|  | 7311 | * *WARNING* this interface is highly subject to change | 
|  | 7312 | * | 
|  | 7313 | * Returns the type definition or NULL in case of error | 
|  | 7314 | */ | 
|  | 7315 | static xmlSchemaTypePtr | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7316 | xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt, | 
|  | 7317 | xmlSchemaPtr schema, xmlNodePtr node) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7318 | { | 
|  | 7319 | xmlSchemaTypePtr type, subtype; | 
|  | 7320 | xmlNodePtr child = NULL; | 
|  | 7321 | xmlChar name[30]; | 
|  | 7322 |  | 
|  | 7323 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 7324 | return (NULL); | 
|  | 7325 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7326 | snprintf((char *) name, 30, "complexContent %d", ctxt->counter++ + 1); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 7327 | type = xmlSchemaAddType(ctxt, schema, name, NULL, node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7328 | if (type == NULL) | 
|  | 7329 | return (NULL); | 
| Daniel Veillard | 4e5d665 | 2004-06-29 21:01:12 +0000 | [diff] [blame] | 7330 | type->type = XML_SCHEMA_TYPE_COMPLEX_CONTENT; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 7331 | type->node = node; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 7332 | type->id = xmlSchemaGetProp(ctxt, node, "id"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7333 |  | 
|  | 7334 | child = node->children; | 
|  | 7335 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7336 | type->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 7337 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7338 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 7339 | ctxt->parentItem = type; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7340 | subtype = NULL; | 
|  | 7341 | if (IS_SCHEMA(child, "restriction")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7342 | subtype = (xmlSchemaTypePtr) | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 7343 | xmlSchemaParseRestriction(ctxt, schema, child); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7344 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7345 | } else if (IS_SCHEMA(child, "extension")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7346 | subtype = (xmlSchemaTypePtr) | 
|  | 7347 | xmlSchemaParseExtension(ctxt, schema, child); | 
|  | 7348 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7349 | } | 
|  | 7350 | type->subtypes = subtype; | 
|  | 7351 | if (child != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7352 | xmlSchemaPErr2(ctxt, node, child, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7353 | XML_SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD, | 
|  | 7354 | "<complexContent> has unexpected content.\n", | 
|  | 7355 | NULL, NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7356 | } | 
|  | 7357 | return (type); | 
|  | 7358 | } | 
|  | 7359 |  | 
|  | 7360 | /** | 
|  | 7361 | * xmlSchemaParseComplexType: | 
|  | 7362 | * @ctxt:  a schema validation context | 
|  | 7363 | * @schema:  the schema being built | 
|  | 7364 | * @node:  a subtree containing XML Schema informations | 
|  | 7365 | * | 
|  | 7366 | * parse a XML schema Complex Type definition | 
|  | 7367 | * *WARNING* this interface is highly subject to change | 
|  | 7368 | * | 
|  | 7369 | * Returns the type definition or NULL in case of error | 
|  | 7370 | */ | 
|  | 7371 | static xmlSchemaTypePtr | 
|  | 7372 | xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 7373 | xmlNodePtr node, int topLevel) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7374 | { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 7375 | xmlSchemaTypePtr type, subtype, ctxtType; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7376 | xmlNodePtr child = NULL; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 7377 | const xmlChar *name; | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 7378 | const xmlChar *oldcontainer; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 7379 | char buf[100]; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7380 |  | 
|  | 7381 | if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) | 
|  | 7382 | return (NULL); | 
|  | 7383 |  | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 7384 | ctxtType = ctxt->ctxtType; | 
|  | 7385 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7386 | oldcontainer = ctxt->container; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 7387 | name = xmlSchemaGetProp(ctxt, node, "name"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7388 | if (name == NULL) { | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 7389 | snprintf(buf, 99, "complexType %d", ctxt->counter++ + 1); | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 7390 | name = (const xmlChar *)buf; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 7391 | type = xmlSchemaAddType(ctxt, schema, name, NULL, node); | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 7392 | } else { | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 7393 |  | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 7394 | /* local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns); */ | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 7395 | type = xmlSchemaAddType(ctxt, schema, name, schema->targetNamespace, node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7396 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7397 | if (type == NULL) { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7398 | return (NULL); | 
|  | 7399 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7400 | if (xmlGetBooleanProp(ctxt, NULL, type, node, "mixed", 0)) | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 7401 | type->flags |= XML_SCHEMAS_TYPE_MIXED; | 
| Daniel Veillard | 1aefc86 | 2004-03-04 11:40:48 +0000 | [diff] [blame] | 7402 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7403 | type->node = node; | 
|  | 7404 | type->type = XML_SCHEMA_TYPE_COMPLEX; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 7405 | if (topLevel) | 
|  | 7406 | type->flags |= XML_SCHEMAS_TYPE_GLOBAL; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 7407 | type->id = xmlSchemaGetProp(ctxt, node, "id"); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7408 | ctxt->container = name; | 
|  | 7409 |  | 
|  | 7410 | child = node->children; | 
|  | 7411 | if (IS_SCHEMA(child, "annotation")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7412 | type->annot = xmlSchemaParseAnnotation(ctxt, schema, child); | 
|  | 7413 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7414 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 7415 | ctxt->ctxtType = type; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7416 | if (IS_SCHEMA(child, "simpleContent")) { | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 7417 | /* 3.4.3 : 2.2 | 
|  | 7418 | * Specifying mixed='true' when the <simpleContent> | 
|  | 7419 | * alternative is chosen has no effect | 
|  | 7420 | */ | 
|  | 7421 | if (type->flags & XML_SCHEMAS_TYPE_MIXED) | 
|  | 7422 | type->flags ^= XML_SCHEMAS_TYPE_MIXED; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7423 | type->subtypes = xmlSchemaParseSimpleContent(ctxt, schema, child); | 
|  | 7424 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7425 | } else if (IS_SCHEMA(child, "complexContent")) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7426 | type->subtypes = xmlSchemaParseComplexContent(ctxt, schema, child); | 
|  | 7427 | child = child->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7428 | } else { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7429 | subtype = NULL; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7430 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7431 | if (IS_SCHEMA(child, "all")) { | 
|  | 7432 | subtype = xmlSchemaParseAll(ctxt, schema, child); | 
|  | 7433 | child = child->next; | 
|  | 7434 | } else if (IS_SCHEMA(child, "choice")) { | 
|  | 7435 | subtype = xmlSchemaParseChoice(ctxt, schema, child); | 
|  | 7436 | child = child->next; | 
|  | 7437 | } else if (IS_SCHEMA(child, "sequence")) { | 
|  | 7438 | subtype = xmlSchemaParseSequence(ctxt, schema, child); | 
|  | 7439 | child = child->next; | 
|  | 7440 | } else if (IS_SCHEMA(child, "group")) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 7441 | subtype = xmlSchemaParseGroup(ctxt, schema, child, 0); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7442 | child = child->next; | 
|  | 7443 | } | 
|  | 7444 | if (subtype != NULL) | 
|  | 7445 | type->subtypes = subtype; | 
|  | 7446 | child = xmlSchemaParseAttrDecls(ctxt, schema, child, type); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7447 | } | 
|  | 7448 | if (child != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7449 | xmlSchemaPErr2(ctxt, node, child, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7450 | XML_SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD, | 
|  | 7451 | "Complex type definition \"%s\" has unexpected content.\n", | 
|  | 7452 | type->name, NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7453 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 7454 | if (type->attributeWildcard != NULL) | 
|  | 7455 | type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7456 | ctxt->container = oldcontainer; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 7457 | ctxt->ctxtType = ctxtType; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7458 | return (type); | 
|  | 7459 | } | 
|  | 7460 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7461 | /** | 
|  | 7462 | * xmlSchemaParseSchema: | 
|  | 7463 | * @ctxt:  a schema validation context | 
|  | 7464 | * @node:  a subtree containing XML Schema informations | 
|  | 7465 | * | 
|  | 7466 | * parse a XML schema definition from a node set | 
|  | 7467 | * *WARNING* this interface is highly subject to change | 
|  | 7468 | * | 
|  | 7469 | * Returns the internal XML Schema structure built from the resource or | 
|  | 7470 | *         NULL in case of error | 
|  | 7471 | */ | 
|  | 7472 | static xmlSchemaPtr | 
|  | 7473 | xmlSchemaParseSchema(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) | 
|  | 7474 | { | 
|  | 7475 | xmlSchemaPtr schema = NULL; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 7476 | const xmlChar *val; | 
| Daniel Veillard | 75bb3bb | 2003-05-12 15:25:56 +0000 | [diff] [blame] | 7477 | int nberrors; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7478 | xmlAttrPtr attr; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7479 |  | 
|  | 7480 | if ((ctxt == NULL) || (node == NULL)) | 
|  | 7481 | return (NULL); | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 7482 |  | 
| Daniel Veillard | 75bb3bb | 2003-05-12 15:25:56 +0000 | [diff] [blame] | 7483 | nberrors = ctxt->nberrors; | 
|  | 7484 | ctxt->nberrors = 0; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7485 | if (IS_SCHEMA(node, "schema")) { | 
|  | 7486 | schema = xmlSchemaNewSchema(ctxt); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7487 | if (schema == NULL) | 
|  | 7488 | return (NULL); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7489 | attr = xmlSchemaGetPropNode(node, "targetNamespace"); | 
|  | 7490 | if (attr != NULL) { | 
|  | 7491 | xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr, | 
|  | 7492 | xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), &val); | 
|  | 7493 | /* | 
|  | 7494 | * TODO: Should we proceed with an invalid target namespace? | 
|  | 7495 | */ | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 7496 | schema->targetNamespace = xmlDictLookup(ctxt->dict, val, -1); | 
|  | 7497 | } else { | 
|  | 7498 | schema->targetNamespace = NULL; | 
|  | 7499 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7500 | /* TODO: Check id. */ | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 7501 | schema->id = xmlSchemaGetProp(ctxt, node, "id"); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7502 | xmlSchemaPValAttr(ctxt, NULL, NULL, node, "version", | 
|  | 7503 | xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &(schema->version)); | 
|  | 7504 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 7505 | xmlSchemaParseSchemaDefaults(ctxt, schema, node); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 7506 | xmlSchemaParseSchemaTopLevel(ctxt, schema, node->children); | 
|  | 7507 | } else { | 
|  | 7508 | xmlDocPtr doc; | 
|  | 7509 |  | 
|  | 7510 | doc = node->doc; | 
|  | 7511 |  | 
|  | 7512 | if ((doc != NULL) && (doc->URL != NULL)) { | 
|  | 7513 | xmlSchemaPErr(ctxt, (xmlNodePtr) doc, | 
|  | 7514 | XML_SCHEMAP_NOT_SCHEMA, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7515 | "The file \"%s\" is not a XML schema.\n", doc->URL, NULL); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 7516 | } else { | 
|  | 7517 | xmlSchemaPErr(ctxt, (xmlNodePtr) doc, | 
|  | 7518 | XML_SCHEMAP_NOT_SCHEMA, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7519 | "The file is not a XML schema.\n", NULL, NULL); | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 7520 | } | 
|  | 7521 | return(NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7522 | } | 
| Daniel Veillard | 75bb3bb | 2003-05-12 15:25:56 +0000 | [diff] [blame] | 7523 | if (ctxt->nberrors != 0) { | 
|  | 7524 | if (schema != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7525 | xmlSchemaFree(schema); | 
|  | 7526 | schema = NULL; | 
|  | 7527 | } | 
| Daniel Veillard | 75bb3bb | 2003-05-12 15:25:56 +0000 | [diff] [blame] | 7528 | } | 
|  | 7529 | ctxt->nberrors = nberrors; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7530 | #ifdef DEBUG | 
|  | 7531 | if (schema == NULL) | 
|  | 7532 | xmlGenericError(xmlGenericErrorContext, | 
|  | 7533 | "xmlSchemaParse() failed\n"); | 
|  | 7534 | #endif | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7535 | return (schema); | 
|  | 7536 | } | 
|  | 7537 |  | 
|  | 7538 | /************************************************************************ | 
|  | 7539 | * 									* | 
|  | 7540 | * 			Validating using Schemas			* | 
|  | 7541 | * 									* | 
|  | 7542 | ************************************************************************/ | 
|  | 7543 |  | 
|  | 7544 | /************************************************************************ | 
|  | 7545 | * 									* | 
|  | 7546 | * 			Reading/Writing Schemas				* | 
|  | 7547 | * 									* | 
|  | 7548 | ************************************************************************/ | 
|  | 7549 |  | 
|  | 7550 | /** | 
|  | 7551 | * xmlSchemaNewParserCtxt: | 
|  | 7552 | * @URL:  the location of the schema | 
|  | 7553 | * | 
|  | 7554 | * Create an XML Schemas parse context for that file/resource expected | 
|  | 7555 | * to contain an XML Schemas file. | 
|  | 7556 | * | 
|  | 7557 | * Returns the parser context or NULL in case of error | 
|  | 7558 | */ | 
|  | 7559 | xmlSchemaParserCtxtPtr | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7560 | xmlSchemaNewParserCtxt(const char *URL) | 
|  | 7561 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7562 | xmlSchemaParserCtxtPtr ret; | 
|  | 7563 |  | 
|  | 7564 | if (URL == NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7565 | return (NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7566 |  | 
|  | 7567 | ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt)); | 
|  | 7568 | if (ret == NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7569 | xmlSchemaPErrMemory(NULL, "allocating schema parser context", | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7570 | NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7571 | return (NULL); | 
|  | 7572 | } | 
|  | 7573 | memset(ret, 0, sizeof(xmlSchemaParserCtxt)); | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 7574 | ret->dict = xmlDictCreate(); | 
|  | 7575 | ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1); | 
| Daniel Veillard | b0f397e | 2003-12-23 23:30:53 +0000 | [diff] [blame] | 7576 | ret->includes = 0; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7577 | return (ret); | 
|  | 7578 | } | 
|  | 7579 |  | 
|  | 7580 | /** | 
| Daniel Veillard | 6045c90 | 2002-10-09 21:13:59 +0000 | [diff] [blame] | 7581 | * xmlSchemaNewMemParserCtxt: | 
|  | 7582 | * @buffer:  a pointer to a char array containing the schemas | 
|  | 7583 | * @size:  the size of the array | 
|  | 7584 | * | 
|  | 7585 | * Create an XML Schemas parse context for that memory buffer expected | 
|  | 7586 | * to contain an XML Schemas file. | 
|  | 7587 | * | 
|  | 7588 | * Returns the parser context or NULL in case of error | 
|  | 7589 | */ | 
|  | 7590 | xmlSchemaParserCtxtPtr | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7591 | xmlSchemaNewMemParserCtxt(const char *buffer, int size) | 
|  | 7592 | { | 
| Daniel Veillard | 6045c90 | 2002-10-09 21:13:59 +0000 | [diff] [blame] | 7593 | xmlSchemaParserCtxtPtr ret; | 
|  | 7594 |  | 
|  | 7595 | if ((buffer == NULL) || (size <= 0)) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7596 | return (NULL); | 
| Daniel Veillard | 6045c90 | 2002-10-09 21:13:59 +0000 | [diff] [blame] | 7597 |  | 
|  | 7598 | ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt)); | 
|  | 7599 | if (ret == NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7600 | xmlSchemaPErrMemory(NULL, "allocating schema parser context", | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7601 | NULL); | 
| Daniel Veillard | 6045c90 | 2002-10-09 21:13:59 +0000 | [diff] [blame] | 7602 | return (NULL); | 
|  | 7603 | } | 
|  | 7604 | memset(ret, 0, sizeof(xmlSchemaParserCtxt)); | 
|  | 7605 | ret->buffer = buffer; | 
|  | 7606 | ret->size = size; | 
| William M. Brack | cf9eadf | 2003-12-25 13:24:05 +0000 | [diff] [blame] | 7607 | ret->dict = xmlDictCreate(); | 
| Daniel Veillard | 6045c90 | 2002-10-09 21:13:59 +0000 | [diff] [blame] | 7608 | return (ret); | 
|  | 7609 | } | 
|  | 7610 |  | 
|  | 7611 | /** | 
| Daniel Veillard | 9d75150 | 2003-10-29 13:21:47 +0000 | [diff] [blame] | 7612 | * xmlSchemaNewDocParserCtxt: | 
|  | 7613 | * @doc:  a preparsed document tree | 
|  | 7614 | * | 
|  | 7615 | * Create an XML Schemas parse context for that document. | 
|  | 7616 | * NB. The document may be modified during the parsing process. | 
|  | 7617 | * | 
|  | 7618 | * Returns the parser context or NULL in case of error | 
|  | 7619 | */ | 
|  | 7620 | xmlSchemaParserCtxtPtr | 
|  | 7621 | xmlSchemaNewDocParserCtxt(xmlDocPtr doc) | 
|  | 7622 | { | 
|  | 7623 | xmlSchemaParserCtxtPtr ret; | 
|  | 7624 |  | 
|  | 7625 | if (doc == NULL) | 
|  | 7626 | return (NULL); | 
|  | 7627 |  | 
|  | 7628 | ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt)); | 
|  | 7629 | if (ret == NULL) { | 
|  | 7630 | xmlSchemaPErrMemory(NULL, "allocating schema parser context", | 
|  | 7631 | NULL); | 
|  | 7632 | return (NULL); | 
|  | 7633 | } | 
|  | 7634 | memset(ret, 0, sizeof(xmlSchemaParserCtxt)); | 
|  | 7635 | ret->doc = doc; | 
| William M. Brack | cf9eadf | 2003-12-25 13:24:05 +0000 | [diff] [blame] | 7636 | ret->dict = xmlDictCreate(); | 
| Daniel Veillard | dda22c1 | 2004-01-24 08:31:30 +0000 | [diff] [blame] | 7637 | /* The application has responsibility for the document */ | 
|  | 7638 | ret->preserve = 1; | 
| Daniel Veillard | 9d75150 | 2003-10-29 13:21:47 +0000 | [diff] [blame] | 7639 |  | 
|  | 7640 | return (ret); | 
|  | 7641 | } | 
|  | 7642 |  | 
|  | 7643 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7644 | * xmlSchemaFreeParserCtxt: | 
|  | 7645 | * @ctxt:  the schema parser context | 
|  | 7646 | * | 
|  | 7647 | * Free the resources associated to the schema parser context | 
|  | 7648 | */ | 
|  | 7649 | void | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7650 | xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt) | 
|  | 7651 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7652 | if (ctxt == NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7653 | return; | 
| Daniel Veillard | dda22c1 | 2004-01-24 08:31:30 +0000 | [diff] [blame] | 7654 | if (ctxt->doc != NULL && !ctxt->preserve) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7655 | xmlFreeDoc(ctxt->doc); | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 7656 | xmlDictFree(ctxt->dict); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7657 | xmlFree(ctxt); | 
|  | 7658 | } | 
|  | 7659 |  | 
|  | 7660 | /************************************************************************ | 
|  | 7661 | *									* | 
|  | 7662 | *			Building the content models			* | 
|  | 7663 | *									* | 
|  | 7664 | ************************************************************************/ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7665 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7666 | /** | 
|  | 7667 | * xmlSchemaBuildAContentModel: | 
|  | 7668 | * @type:  the schema type definition | 
|  | 7669 | * @ctxt:  the schema parser context | 
|  | 7670 | * @name:  the element name whose content is being built | 
|  | 7671 | * | 
|  | 7672 | * Generate the automata sequence needed for that type | 
|  | 7673 | */ | 
|  | 7674 | static void | 
|  | 7675 | xmlSchemaBuildAContentModel(xmlSchemaTypePtr type, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7676 | xmlSchemaParserCtxtPtr ctxt, | 
|  | 7677 | const xmlChar * name) | 
|  | 7678 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7679 | if (type == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7680 | xmlGenericError(xmlGenericErrorContext, | 
|  | 7681 | "Found unexpected type = NULL in %s content model\n", | 
|  | 7682 | name); | 
|  | 7683 | return; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7684 | } | 
|  | 7685 | switch (type->type) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7686 | case XML_SCHEMA_TYPE_ANY: { | 
|  | 7687 | xmlAutomataStatePtr start, end; | 
|  | 7688 | xmlSchemaWildcardPtr wild; | 
|  | 7689 | xmlSchemaWildcardNsPtr ns; | 
| Daniel Veillard | 3237023 | 2002-10-16 14:08:14 +0000 | [diff] [blame] | 7690 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7691 | wild = type->attributeWildcard; | 
|  | 7692 |  | 
|  | 7693 | if (wild == NULL) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 7694 | xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_INTERNAL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7695 | "Internal error: xmlSchemaBuildAContentModel, " | 
|  | 7696 | "no wildcard on xsd:any.\n", NULL, NULL); | 
|  | 7697 | return; | 
|  | 7698 | } | 
|  | 7699 |  | 
|  | 7700 | start = ctxt->state; | 
|  | 7701 | end = xmlAutomataNewState(ctxt->am); | 
|  | 7702 |  | 
|  | 7703 | if (type->maxOccurs == 1) { | 
|  | 7704 | if (wild->any == 1) { | 
|  | 7705 | /* | 
|  | 7706 | * We need to add both transitions: | 
|  | 7707 | * | 
|  | 7708 | * 1. the {"*", "*"} for elements in a namespace. | 
|  | 7709 | */ | 
|  | 7710 | ctxt->state = | 
|  | 7711 | xmlAutomataNewTransition2(ctxt->am, | 
|  | 7712 | start, NULL, BAD_CAST "*", BAD_CAST "*", type); | 
|  | 7713 | xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end); | 
|  | 7714 | /* | 
|  | 7715 | * 2. the {"*"} for elements in no namespace. | 
|  | 7716 | */ | 
|  | 7717 | ctxt->state = | 
|  | 7718 | xmlAutomataNewTransition2(ctxt->am, | 
|  | 7719 | start, NULL, BAD_CAST "*", NULL, type); | 
|  | 7720 | xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end); | 
|  | 7721 |  | 
|  | 7722 | } else if (wild->nsSet != NULL) { | 
|  | 7723 | ns = wild->nsSet; | 
|  | 7724 | do { | 
|  | 7725 | ctxt->state = start; | 
|  | 7726 | ctxt->state = xmlAutomataNewTransition2(ctxt->am, | 
|  | 7727 | ctxt->state, NULL, BAD_CAST "*", ns->value, type); | 
|  | 7728 | xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end); | 
|  | 7729 | ns = ns->next; | 
|  | 7730 | } while (ns != NULL); | 
|  | 7731 |  | 
|  | 7732 | } else if (wild->negNsSet != NULL) { | 
|  | 7733 | xmlAutomataStatePtr deadEnd; | 
|  | 7734 |  | 
|  | 7735 | deadEnd = xmlAutomataNewState(ctxt->am); | 
|  | 7736 | ctxt->state = xmlAutomataNewTransition2(ctxt->am, | 
|  | 7737 | start, deadEnd, BAD_CAST "*", wild->negNsSet->value, type); | 
|  | 7738 | ctxt->state = xmlAutomataNewTransition2(ctxt->am, | 
|  | 7739 | start, NULL, BAD_CAST "*", BAD_CAST "*", type); | 
|  | 7740 | xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end); | 
|  | 7741 | } | 
|  | 7742 | } else { | 
|  | 7743 | int counter; | 
|  | 7744 | xmlAutomataStatePtr hop; | 
|  | 7745 | int maxOccurs = | 
|  | 7746 | type->maxOccurs == UNBOUNDED ? UNBOUNDED : type->maxOccurs - 1; | 
|  | 7747 | int minOccurs = | 
|  | 7748 | type->minOccurs < 1 ? 0 : type->minOccurs - 1; | 
|  | 7749 |  | 
|  | 7750 | counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs); | 
|  | 7751 | hop = xmlAutomataNewState(ctxt->am); | 
|  | 7752 | if (wild->any == 1) { | 
|  | 7753 | ctxt->state = | 
|  | 7754 | xmlAutomataNewTransition2(ctxt->am, | 
|  | 7755 | start, NULL, BAD_CAST "*", BAD_CAST "*", type); | 
|  | 7756 | xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop); | 
|  | 7757 | ctxt->state = | 
|  | 7758 | xmlAutomataNewTransition2(ctxt->am, | 
|  | 7759 | start, NULL, BAD_CAST "*", NULL, type); | 
|  | 7760 | xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop); | 
|  | 7761 | } else if (wild->nsSet != NULL) { | 
|  | 7762 | ns = wild->nsSet; | 
|  | 7763 | do { | 
|  | 7764 | ctxt->state = | 
|  | 7765 | xmlAutomataNewTransition2(ctxt->am, | 
|  | 7766 | start, NULL, BAD_CAST "*", ns->value, type); | 
|  | 7767 | xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop); | 
|  | 7768 | ns = ns->next; | 
|  | 7769 | } while (ns != NULL); | 
|  | 7770 |  | 
|  | 7771 | } else if (wild->negNsSet != NULL) { | 
|  | 7772 | xmlAutomataStatePtr deadEnd; | 
|  | 7773 |  | 
|  | 7774 | deadEnd = xmlAutomataNewState(ctxt->am); | 
|  | 7775 | ctxt->state = xmlAutomataNewTransition2(ctxt->am, | 
|  | 7776 | start, deadEnd, BAD_CAST "*", wild->negNsSet->value, type); | 
|  | 7777 | ctxt->state = xmlAutomataNewTransition2(ctxt->am, | 
|  | 7778 | start, NULL, BAD_CAST "*", BAD_CAST "*", type); | 
|  | 7779 | xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop); | 
|  | 7780 | } | 
|  | 7781 | xmlAutomataNewCountedTrans(ctxt->am, hop, start, counter); | 
|  | 7782 | xmlAutomataNewCounterTrans(ctxt->am, hop, end, counter); | 
|  | 7783 | } | 
|  | 7784 | if (type->minOccurs == 0) { | 
|  | 7785 | xmlAutomataNewEpsilon(ctxt->am, start, end); | 
|  | 7786 | } | 
|  | 7787 | ctxt->state = end; | 
|  | 7788 | break; | 
|  | 7789 | } | 
|  | 7790 | case XML_SCHEMA_TYPE_ELEMENT:{ | 
|  | 7791 | xmlSchemaElementPtr elem = (xmlSchemaElementPtr) type; | 
|  | 7792 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7793 | /* TODO : handle the namespace too */ | 
|  | 7794 | xmlAutomataStatePtr oldstate = ctxt->state; | 
| Daniel Veillard | 3237023 | 2002-10-16 14:08:14 +0000 | [diff] [blame] | 7795 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7796 | if (elem->maxOccurs >= UNBOUNDED) { | 
|  | 7797 | if (elem->minOccurs > 1) { | 
|  | 7798 | xmlAutomataStatePtr tmp; | 
|  | 7799 | int counter; | 
| Daniel Veillard | 3237023 | 2002-10-16 14:08:14 +0000 | [diff] [blame] | 7800 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7801 | ctxt->state = xmlAutomataNewEpsilon(ctxt->am, | 
|  | 7802 | oldstate, | 
|  | 7803 | NULL); | 
|  | 7804 | oldstate = ctxt->state; | 
| Daniel Veillard | 3237023 | 2002-10-16 14:08:14 +0000 | [diff] [blame] | 7805 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7806 | counter = xmlAutomataNewCounter(ctxt->am, | 
|  | 7807 | elem->minOccurs - | 
|  | 7808 | 1, UNBOUNDED); | 
| Daniel Veillard | 3237023 | 2002-10-16 14:08:14 +0000 | [diff] [blame] | 7809 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7810 | if (elem->refDecl != NULL) { | 
|  | 7811 | xmlSchemaBuildAContentModel((xmlSchemaTypePtr) | 
|  | 7812 | elem->refDecl, | 
|  | 7813 | ctxt, | 
|  | 7814 | elem->refDecl-> | 
|  | 7815 | name); | 
|  | 7816 | } else { | 
|  | 7817 | ctxt->state = | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7818 | xmlAutomataNewTransition2(ctxt->am, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7819 | ctxt->state, NULL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7820 | elem->name, | 
|  | 7821 | elem->targetNamespace, | 
|  | 7822 | type); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7823 | } | 
|  | 7824 | tmp = ctxt->state; | 
|  | 7825 | xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate, | 
|  | 7826 | counter); | 
|  | 7827 | ctxt->state = | 
|  | 7828 | xmlAutomataNewCounterTrans(ctxt->am, tmp, NULL, | 
|  | 7829 | counter); | 
| Daniel Veillard | 3237023 | 2002-10-16 14:08:14 +0000 | [diff] [blame] | 7830 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7831 | } else { | 
|  | 7832 | if (elem->refDecl != NULL) { | 
|  | 7833 | xmlSchemaBuildAContentModel((xmlSchemaTypePtr) | 
|  | 7834 | elem->refDecl, | 
|  | 7835 | ctxt, | 
|  | 7836 | elem->refDecl-> | 
|  | 7837 | name); | 
|  | 7838 | } else { | 
|  | 7839 | ctxt->state = | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7840 | xmlAutomataNewTransition2(ctxt->am, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7841 | ctxt->state, NULL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7842 | elem->name, | 
|  | 7843 | elem->targetNamespace, | 
|  | 7844 | type); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7845 | } | 
|  | 7846 | xmlAutomataNewEpsilon(ctxt->am, ctxt->state, | 
|  | 7847 | oldstate); | 
|  | 7848 | if (elem->minOccurs == 0) { | 
|  | 7849 | /* basically an elem* */ | 
|  | 7850 | xmlAutomataNewEpsilon(ctxt->am, oldstate, | 
|  | 7851 | ctxt->state); | 
|  | 7852 | } | 
|  | 7853 | } | 
|  | 7854 | } else if ((elem->maxOccurs > 1) || (elem->minOccurs > 1)) { | 
|  | 7855 | xmlAutomataStatePtr tmp; | 
|  | 7856 | int counter; | 
| Daniel Veillard | 3237023 | 2002-10-16 14:08:14 +0000 | [diff] [blame] | 7857 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7858 | ctxt->state = xmlAutomataNewEpsilon(ctxt->am, | 
|  | 7859 | oldstate, NULL); | 
|  | 7860 | oldstate = ctxt->state; | 
| Daniel Veillard | 3237023 | 2002-10-16 14:08:14 +0000 | [diff] [blame] | 7861 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7862 | counter = xmlAutomataNewCounter(ctxt->am, | 
|  | 7863 | elem->minOccurs - 1, | 
|  | 7864 | elem->maxOccurs - 1); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7865 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7866 | if (elem->refDecl != NULL) { | 
|  | 7867 | xmlSchemaBuildAContentModel((xmlSchemaTypePtr) | 
|  | 7868 | elem->refDecl, ctxt, | 
|  | 7869 | elem->refDecl->name); | 
|  | 7870 | } else { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7871 | ctxt->state = xmlAutomataNewTransition2(ctxt->am, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7872 | ctxt->state, | 
|  | 7873 | NULL, | 
|  | 7874 | elem->name, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7875 | elem->targetNamespace, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7876 | type); | 
|  | 7877 | } | 
|  | 7878 | tmp = ctxt->state; | 
|  | 7879 | xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate, | 
|  | 7880 | counter); | 
|  | 7881 | ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, tmp, | 
|  | 7882 | NULL, | 
|  | 7883 | counter); | 
|  | 7884 | if (elem->minOccurs == 0) { | 
|  | 7885 | /* basically an elem? */ | 
|  | 7886 | xmlAutomataNewEpsilon(ctxt->am, oldstate, | 
|  | 7887 | ctxt->state); | 
|  | 7888 | } | 
| Daniel Veillard | b39bc39 | 2002-10-26 19:29:51 +0000 | [diff] [blame] | 7889 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7890 | } else { | 
|  | 7891 | if (elem->refDecl != NULL) { | 
|  | 7892 | xmlSchemaBuildAContentModel((xmlSchemaTypePtr) | 
|  | 7893 | elem->refDecl, ctxt, | 
|  | 7894 | elem->refDecl->name); | 
|  | 7895 | } else { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7896 | ctxt->state = xmlAutomataNewTransition2(ctxt->am, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7897 | ctxt->state, | 
|  | 7898 | NULL, | 
|  | 7899 | elem->name, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 7900 | elem->targetNamespace, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7901 | type); | 
|  | 7902 | } | 
|  | 7903 | if (elem->minOccurs == 0) { | 
|  | 7904 | /* basically an elem? */ | 
|  | 7905 | xmlAutomataNewEpsilon(ctxt->am, oldstate, | 
|  | 7906 | ctxt->state); | 
|  | 7907 | } | 
|  | 7908 | } | 
|  | 7909 | break; | 
|  | 7910 | } | 
|  | 7911 | case XML_SCHEMA_TYPE_SEQUENCE:{ | 
|  | 7912 | xmlSchemaTypePtr subtypes; | 
| Daniel Veillard | b39bc39 | 2002-10-26 19:29:51 +0000 | [diff] [blame] | 7913 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7914 | /* | 
|  | 7915 | * If max and min occurances are default (1) then | 
|  | 7916 | * simply iterate over the subtypes | 
|  | 7917 | */ | 
|  | 7918 | if ((type->minOccurs == 1) && (type->maxOccurs == 1)) { | 
|  | 7919 | subtypes = type->subtypes; | 
|  | 7920 | while (subtypes != NULL) { | 
|  | 7921 | xmlSchemaBuildAContentModel(subtypes, ctxt, name); | 
|  | 7922 | subtypes = subtypes->next; | 
|  | 7923 | } | 
|  | 7924 | } else { | 
|  | 7925 | xmlAutomataStatePtr oldstate = ctxt->state; | 
| Daniel Veillard | b39bc39 | 2002-10-26 19:29:51 +0000 | [diff] [blame] | 7926 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7927 | if (type->maxOccurs >= UNBOUNDED) { | 
|  | 7928 | if (type->minOccurs > 1) { | 
|  | 7929 | xmlAutomataStatePtr tmp; | 
|  | 7930 | int counter; | 
| Daniel Veillard | b39bc39 | 2002-10-26 19:29:51 +0000 | [diff] [blame] | 7931 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7932 | ctxt->state = xmlAutomataNewEpsilon(ctxt->am, | 
|  | 7933 | oldstate, | 
|  | 7934 | NULL); | 
|  | 7935 | oldstate = ctxt->state; | 
| Daniel Veillard | b39bc39 | 2002-10-26 19:29:51 +0000 | [diff] [blame] | 7936 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7937 | counter = xmlAutomataNewCounter(ctxt->am, | 
|  | 7938 | type-> | 
|  | 7939 | minOccurs - 1, | 
|  | 7940 | UNBOUNDED); | 
| Daniel Veillard | b39bc39 | 2002-10-26 19:29:51 +0000 | [diff] [blame] | 7941 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7942 | subtypes = type->subtypes; | 
|  | 7943 | while (subtypes != NULL) { | 
|  | 7944 | xmlSchemaBuildAContentModel(subtypes, ctxt, | 
|  | 7945 | name); | 
|  | 7946 | subtypes = subtypes->next; | 
|  | 7947 | } | 
|  | 7948 | tmp = ctxt->state; | 
|  | 7949 | xmlAutomataNewCountedTrans(ctxt->am, tmp, | 
|  | 7950 | oldstate, counter); | 
|  | 7951 | ctxt->state = | 
|  | 7952 | xmlAutomataNewCounterTrans(ctxt->am, tmp, | 
|  | 7953 | NULL, counter); | 
| Daniel Veillard | b39bc39 | 2002-10-26 19:29:51 +0000 | [diff] [blame] | 7954 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7955 | } else { | 
|  | 7956 | subtypes = type->subtypes; | 
|  | 7957 | while (subtypes != NULL) { | 
|  | 7958 | xmlSchemaBuildAContentModel(subtypes, ctxt, | 
|  | 7959 | name); | 
|  | 7960 | subtypes = subtypes->next; | 
|  | 7961 | } | 
|  | 7962 | xmlAutomataNewEpsilon(ctxt->am, ctxt->state, | 
|  | 7963 | oldstate); | 
|  | 7964 | if (type->minOccurs == 0) { | 
|  | 7965 | xmlAutomataNewEpsilon(ctxt->am, oldstate, | 
|  | 7966 | ctxt->state); | 
|  | 7967 | } | 
|  | 7968 | } | 
|  | 7969 | } else if ((type->maxOccurs > 1) | 
|  | 7970 | || (type->minOccurs > 1)) { | 
|  | 7971 | xmlAutomataStatePtr tmp; | 
|  | 7972 | int counter; | 
| Daniel Veillard | b39bc39 | 2002-10-26 19:29:51 +0000 | [diff] [blame] | 7973 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7974 | ctxt->state = xmlAutomataNewEpsilon(ctxt->am, | 
|  | 7975 | oldstate, | 
|  | 7976 | NULL); | 
|  | 7977 | oldstate = ctxt->state; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7978 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7979 | counter = xmlAutomataNewCounter(ctxt->am, | 
|  | 7980 | type->minOccurs - | 
|  | 7981 | 1, | 
|  | 7982 | type->maxOccurs - | 
|  | 7983 | 1); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 7984 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 7985 | subtypes = type->subtypes; | 
|  | 7986 | while (subtypes != NULL) { | 
|  | 7987 | xmlSchemaBuildAContentModel(subtypes, ctxt, | 
|  | 7988 | name); | 
|  | 7989 | subtypes = subtypes->next; | 
|  | 7990 | } | 
|  | 7991 | tmp = ctxt->state; | 
|  | 7992 | xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate, | 
|  | 7993 | counter); | 
|  | 7994 | ctxt->state = | 
|  | 7995 | xmlAutomataNewCounterTrans(ctxt->am, tmp, NULL, | 
|  | 7996 | counter); | 
|  | 7997 | if (type->minOccurs == 0) { | 
|  | 7998 | xmlAutomataNewEpsilon(ctxt->am, oldstate, | 
|  | 7999 | ctxt->state); | 
|  | 8000 | } | 
| Daniel Veillard | b509f15 | 2002-04-17 16:28:10 +0000 | [diff] [blame] | 8001 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8002 | } else { | 
|  | 8003 | subtypes = type->subtypes; | 
|  | 8004 | while (subtypes != NULL) { | 
|  | 8005 | xmlSchemaBuildAContentModel(subtypes, ctxt, | 
|  | 8006 | name); | 
|  | 8007 | subtypes = subtypes->next; | 
|  | 8008 | } | 
|  | 8009 | if (type->minOccurs == 0) { | 
|  | 8010 | xmlAutomataNewEpsilon(ctxt->am, oldstate, | 
|  | 8011 | ctxt->state); | 
|  | 8012 | } | 
|  | 8013 | } | 
|  | 8014 | } | 
|  | 8015 | break; | 
|  | 8016 | } | 
|  | 8017 | case XML_SCHEMA_TYPE_CHOICE:{ | 
|  | 8018 | xmlSchemaTypePtr subtypes; | 
|  | 8019 | xmlAutomataStatePtr start, end; | 
| Daniel Veillard | b509f15 | 2002-04-17 16:28:10 +0000 | [diff] [blame] | 8020 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8021 | start = ctxt->state; | 
|  | 8022 | end = xmlAutomataNewState(ctxt->am); | 
| Daniel Veillard | 7646b18 | 2002-04-20 06:41:40 +0000 | [diff] [blame] | 8023 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8024 | /* | 
|  | 8025 | * iterate over the subtypes and remerge the end with an | 
|  | 8026 | * epsilon transition | 
|  | 8027 | */ | 
|  | 8028 | if (type->maxOccurs == 1) { | 
|  | 8029 | subtypes = type->subtypes; | 
|  | 8030 | while (subtypes != NULL) { | 
|  | 8031 | ctxt->state = start; | 
|  | 8032 | xmlSchemaBuildAContentModel(subtypes, ctxt, name); | 
|  | 8033 | xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end); | 
|  | 8034 | subtypes = subtypes->next; | 
|  | 8035 | } | 
|  | 8036 | } else { | 
|  | 8037 | int counter; | 
|  | 8038 | xmlAutomataStatePtr hop; | 
|  | 8039 | int maxOccurs = type->maxOccurs == UNBOUNDED ? | 
|  | 8040 | UNBOUNDED : type->maxOccurs - 1; | 
|  | 8041 | int minOccurs = | 
|  | 8042 | type->minOccurs < 1 ? 0 : type->minOccurs - 1; | 
| Daniel Veillard | 7646b18 | 2002-04-20 06:41:40 +0000 | [diff] [blame] | 8043 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8044 | /* | 
|  | 8045 | * use a counter to keep track of the number of transtions | 
|  | 8046 | * which went through the choice. | 
|  | 8047 | */ | 
|  | 8048 | counter = | 
|  | 8049 | xmlAutomataNewCounter(ctxt->am, minOccurs, | 
|  | 8050 | maxOccurs); | 
|  | 8051 | hop = xmlAutomataNewState(ctxt->am); | 
| Daniel Veillard | 6231e84 | 2002-04-18 11:54:04 +0000 | [diff] [blame] | 8052 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8053 | subtypes = type->subtypes; | 
|  | 8054 | while (subtypes != NULL) { | 
|  | 8055 | ctxt->state = start; | 
|  | 8056 | xmlSchemaBuildAContentModel(subtypes, ctxt, name); | 
|  | 8057 | xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop); | 
|  | 8058 | subtypes = subtypes->next; | 
|  | 8059 | } | 
|  | 8060 | xmlAutomataNewCountedTrans(ctxt->am, hop, start, | 
|  | 8061 | counter); | 
|  | 8062 | xmlAutomataNewCounterTrans(ctxt->am, hop, end, | 
|  | 8063 | counter); | 
|  | 8064 | } | 
|  | 8065 | if (type->minOccurs == 0) { | 
|  | 8066 | xmlAutomataNewEpsilon(ctxt->am, start, end); | 
|  | 8067 | } | 
|  | 8068 | ctxt->state = end; | 
|  | 8069 | break; | 
|  | 8070 | } | 
|  | 8071 | case XML_SCHEMA_TYPE_ALL:{ | 
|  | 8072 | xmlAutomataStatePtr start; | 
|  | 8073 | xmlSchemaTypePtr subtypes; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8074 |  | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8075 | xmlSchemaElementPtr elem; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8076 | int lax; | 
|  | 8077 |  | 
|  | 8078 | subtypes = type->subtypes; | 
|  | 8079 | if (subtypes == NULL) | 
|  | 8080 | break; | 
|  | 8081 | start = ctxt->state; | 
|  | 8082 | while (subtypes != NULL) { | 
|  | 8083 | ctxt->state = start; | 
| William M. Brack | 9989c7d | 2004-05-12 14:39:38 +0000 | [diff] [blame] | 8084 | /* | 
|  | 8085 | * the following 'if' was needed to fix bug 139897 | 
|  | 8086 | * not quite sure why it only needs to be done for | 
|  | 8087 | * elements with a 'ref', but it seems to work ok. | 
|  | 8088 | */ | 
|  | 8089 | if (subtypes->ref != NULL) | 
|  | 8090 | xmlSchemaBuildAContentModel(subtypes, ctxt, name); | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 8091 | elem = (xmlSchemaElementPtr) subtypes; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8092 | /* TODO : handle the namespace too */ | 
|  | 8093 | if ((elem->minOccurs == 1) && (elem->maxOccurs == 1)) { | 
|  | 8094 | xmlAutomataNewOnceTrans(ctxt->am, ctxt->state, | 
|  | 8095 | ctxt->state, elem->name, 1, | 
|  | 8096 | 1, subtypes); | 
|  | 8097 | } else { | 
|  | 8098 | xmlAutomataNewCountTrans(ctxt->am, ctxt->state, | 
|  | 8099 | ctxt->state, elem->name, | 
|  | 8100 | elem->minOccurs, | 
|  | 8101 | elem->maxOccurs, | 
|  | 8102 | subtypes); | 
|  | 8103 | } | 
|  | 8104 | subtypes = subtypes->next; | 
|  | 8105 | } | 
|  | 8106 | lax = type->minOccurs == 0; | 
|  | 8107 | ctxt->state = | 
|  | 8108 | xmlAutomataNewAllTrans(ctxt->am, ctxt->state, NULL, | 
|  | 8109 | lax); | 
|  | 8110 | break; | 
|  | 8111 | } | 
|  | 8112 | case XML_SCHEMA_TYPE_RESTRICTION: | 
|  | 8113 | if (type->subtypes != NULL) | 
|  | 8114 | xmlSchemaBuildAContentModel(type->subtypes, ctxt, name); | 
|  | 8115 | break; | 
|  | 8116 | case XML_SCHEMA_TYPE_EXTENSION: | 
|  | 8117 | if (type->baseType != NULL) { | 
|  | 8118 | xmlSchemaTypePtr subtypes; | 
|  | 8119 |  | 
| Daniel Veillard | f762755 | 2004-04-22 07:15:40 +0000 | [diff] [blame] | 8120 | if (type->recurse) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8121 | /* TODO: Change the error code. */ | 
|  | 8122 | xmlSchemaPCustomErr(ctxt, | 
|  | 8123 | XML_SCHEMAP_UNKNOWN_BASE_TYPE, | 
|  | 8124 | NULL, type, type->node, | 
|  | 8125 | "This item is circular", NULL); | 
| Daniel Veillard | f762755 | 2004-04-22 07:15:40 +0000 | [diff] [blame] | 8126 | return; | 
|  | 8127 | } | 
|  | 8128 | type->recurse = 1; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8129 | xmlSchemaBuildAContentModel(type->baseType, ctxt, name); | 
| Daniel Veillard | f762755 | 2004-04-22 07:15:40 +0000 | [diff] [blame] | 8130 | type->recurse = 0; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8131 | subtypes = type->subtypes; | 
|  | 8132 | while (subtypes != NULL) { | 
|  | 8133 | xmlSchemaBuildAContentModel(subtypes, ctxt, name); | 
|  | 8134 | subtypes = subtypes->next; | 
|  | 8135 | } | 
|  | 8136 | } else if (type->subtypes != NULL) | 
|  | 8137 | xmlSchemaBuildAContentModel(type->subtypes, ctxt, name); | 
|  | 8138 | break; | 
|  | 8139 | case XML_SCHEMA_TYPE_GROUP: | 
|  | 8140 | if (type->subtypes == NULL) { | 
| William M. Brack | 29aa772 | 2004-05-12 00:27:56 +0000 | [diff] [blame] | 8141 | xmlSchemaTypePtr rgroup; | 
|  | 8142 | if (type->ref != NULL) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8143 | rgroup = xmlSchemaGetGroup(ctxt->schema, type->ref, | 
| William M. Brack | 29aa772 | 2004-05-12 00:27:56 +0000 | [diff] [blame] | 8144 | type->refNs); | 
|  | 8145 | if (rgroup == NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8146 | xmlSchemaPResCompAttrErr(ctxt, | 
|  | 8147 | XML_SCHEMAP_SRC_RESOLVE, | 
|  | 8148 | NULL, type, NULL, | 
|  | 8149 | "ref", type->ref, type->refNs, | 
|  | 8150 | XML_SCHEMA_TYPE_GROUP, NULL); | 
| William M. Brack | 29aa772 | 2004-05-12 00:27:56 +0000 | [diff] [blame] | 8151 | return; | 
|  | 8152 | } | 
|  | 8153 | xmlSchemaBuildAContentModel(rgroup, ctxt, name); | 
|  | 8154 | break; | 
|  | 8155 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8156 | } | 
|  | 8157 | case XML_SCHEMA_TYPE_COMPLEX: | 
|  | 8158 | case XML_SCHEMA_TYPE_COMPLEX_CONTENT: | 
|  | 8159 | if (type->subtypes != NULL) | 
|  | 8160 | xmlSchemaBuildAContentModel(type->subtypes, ctxt, name); | 
|  | 8161 | break; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 8162 | case XML_SCHEMA_TYPE_SIMPLE_CONTENT: | 
|  | 8163 | break; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8164 | default: | 
|  | 8165 | xmlGenericError(xmlGenericErrorContext, | 
|  | 8166 | "Found unexpected type %d in %s content model\n", | 
|  | 8167 | type->type, name); | 
|  | 8168 | return; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8169 | } | 
|  | 8170 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8171 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8172 | /** | 
|  | 8173 | * xmlSchemaBuildContentModel: | 
| Daniel Veillard | a84c0b3 | 2003-06-02 16:58:46 +0000 | [diff] [blame] | 8174 | * @elem:  the element | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8175 | * @ctxt:  the schema parser context | 
| Daniel Veillard | a84c0b3 | 2003-06-02 16:58:46 +0000 | [diff] [blame] | 8176 | * @name:  the element name | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8177 | * | 
| Daniel Veillard | a84c0b3 | 2003-06-02 16:58:46 +0000 | [diff] [blame] | 8178 | * Builds the content model of the element. | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8179 | */ | 
|  | 8180 | static void | 
|  | 8181 | xmlSchemaBuildContentModel(xmlSchemaElementPtr elem, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8182 | xmlSchemaParserCtxtPtr ctxt, | 
|  | 8183 | const xmlChar * name) | 
|  | 8184 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8185 | xmlAutomataStatePtr start; | 
|  | 8186 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8187 | if (elem->contModel != NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8188 | return; | 
| Daniel Veillard | 88c5891 | 2002-04-23 07:12:20 +0000 | [diff] [blame] | 8189 | if (elem->subtypes == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8190 | elem->contentType = XML_SCHEMA_CONTENT_ANY; | 
|  | 8191 | return; | 
| Daniel Veillard | 88c5891 | 2002-04-23 07:12:20 +0000 | [diff] [blame] | 8192 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8193 | if (elem->subtypes->type != XML_SCHEMA_TYPE_COMPLEX) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8194 | return; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 8195 | if ((elem->subtypes->contentType == XML_SCHEMA_CONTENT_BASIC) || | 
|  | 8196 | (elem->subtypes->contentType == XML_SCHEMA_CONTENT_SIMPLE)) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8197 | return; | 
| Daniel Veillard | decd64d | 2002-04-18 14:41:51 +0000 | [diff] [blame] | 8198 |  | 
|  | 8199 | #ifdef DEBUG_CONTENT | 
|  | 8200 | xmlGenericError(xmlGenericErrorContext, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8201 | "Building content model for %s\n", name); | 
| Daniel Veillard | decd64d | 2002-04-18 14:41:51 +0000 | [diff] [blame] | 8202 | #endif | 
|  | 8203 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8204 | ctxt->am = xmlNewAutomata(); | 
|  | 8205 | if (ctxt->am == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8206 | xmlGenericError(xmlGenericErrorContext, | 
|  | 8207 | "Cannot create automata for elem %s\n", name); | 
|  | 8208 | return; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8209 | } | 
|  | 8210 | start = ctxt->state = xmlAutomataGetInitState(ctxt->am); | 
|  | 8211 | xmlSchemaBuildAContentModel(elem->subtypes, ctxt, name); | 
|  | 8212 | xmlAutomataSetFinalState(ctxt->am, ctxt->state); | 
| Daniel Veillard | 4402ab4 | 2002-09-12 16:02:56 +0000 | [diff] [blame] | 8213 | elem->contModel = xmlAutomataCompile(ctxt->am); | 
| Daniel Veillard | a84c0b3 | 2003-06-02 16:58:46 +0000 | [diff] [blame] | 8214 | if (elem->contModel == NULL) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 8215 | xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8216 | NULL, (xmlSchemaTypePtr) elem, NULL, | 
|  | 8217 | "Failed to compile the content model", NULL); | 
| Daniel Veillard | a84c0b3 | 2003-06-02 16:58:46 +0000 | [diff] [blame] | 8218 | } else if (xmlRegexpIsDeterminist(elem->contModel) != 1) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 8219 | xmlSchemaPCustomErr(ctxt, | 
|  | 8220 | XML_SCHEMAP_NOT_DETERMINISTIC, | 
|  | 8221 | /* XML_SCHEMAS_ERR_NOTDETERMINIST, */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8222 | NULL, (xmlSchemaTypePtr) elem, NULL, | 
|  | 8223 | "The content model is not determinist", NULL); | 
| Daniel Veillard | e19fc23 | 2002-04-22 16:01:24 +0000 | [diff] [blame] | 8224 | } else { | 
| Daniel Veillard | 118aed7 | 2002-09-24 14:13:13 +0000 | [diff] [blame] | 8225 | #ifdef DEBUG_CONTENT_REGEXP | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8226 | xmlGenericError(xmlGenericErrorContext, | 
|  | 8227 | "Content model of %s:\n", name); | 
|  | 8228 | xmlRegexpPrint(stderr, elem->contModel); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8229 | #endif | 
| Daniel Veillard | e19fc23 | 2002-04-22 16:01:24 +0000 | [diff] [blame] | 8230 | } | 
| Daniel Veillard | a84c0b3 | 2003-06-02 16:58:46 +0000 | [diff] [blame] | 8231 | ctxt->state = NULL; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8232 | xmlFreeAutomata(ctxt->am); | 
|  | 8233 | ctxt->am = NULL; | 
|  | 8234 | } | 
|  | 8235 |  | 
|  | 8236 | /** | 
|  | 8237 | * xmlSchemaRefFixupCallback: | 
|  | 8238 | * @elem:  the schema element context | 
|  | 8239 | * @ctxt:  the schema parser context | 
|  | 8240 | * | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8241 | * Resolves the references of an element declaration | 
|  | 8242 | * or particle, which has an element declaration as it's | 
|  | 8243 | * term. | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8244 | */ | 
|  | 8245 | static void | 
|  | 8246 | xmlSchemaRefFixupCallback(xmlSchemaElementPtr elem, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8247 | xmlSchemaParserCtxtPtr ctxt, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8248 | const xmlChar * name ATTRIBUTE_UNUSED, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8249 | const xmlChar * context ATTRIBUTE_UNUSED, | 
|  | 8250 | const xmlChar * namespace ATTRIBUTE_UNUSED) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8251 | { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8252 | if ((ctxt == NULL) || (elem == NULL) || | 
|  | 8253 | ((elem != NULL) && (elem->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED))) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8254 | return; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8255 | elem->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8256 | if (elem->ref != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 8257 | xmlSchemaElementPtr elemDecl; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8258 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8259 | /* | 
|  | 8260 | * TODO: Evaluate, what errors could occur if the declaration is not | 
|  | 8261 | * found. It might be possible that the "typefixup" might crash if | 
|  | 8262 | * no ref declaration was found. | 
|  | 8263 | */ | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 8264 | elemDecl = xmlSchemaGetElem(ctxt->schema, elem->ref, elem->refNs); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8265 | if (elemDecl == NULL) { | 
|  | 8266 | xmlSchemaPResCompAttrErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8267 | XML_SCHEMAP_SRC_RESOLVE, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8268 | NULL, (xmlSchemaTypePtr) elem, elem->node, | 
|  | 8269 | "ref", elem->ref, elem->refNs, | 
|  | 8270 | XML_SCHEMA_TYPE_ELEMENT, NULL); | 
|  | 8271 | } else | 
|  | 8272 | elem->refDecl = elemDecl; | 
|  | 8273 | } else { | 
|  | 8274 | if ((elem->subtypes == NULL) && (elem->namedType != NULL)) { | 
|  | 8275 | xmlSchemaTypePtr type; | 
|  | 8276 |  | 
|  | 8277 | /* (type definition) ... otherwise the type definition ·resolved· | 
|  | 8278 | * to by the ·actual value· of the type [attribute] ... | 
|  | 8279 | */ | 
|  | 8280 | type = xmlSchemaGetType(ctxt->schema, elem->namedType, | 
|  | 8281 | elem->namedTypeNs); | 
|  | 8282 | if (type == NULL) { | 
|  | 8283 | xmlSchemaPResCompAttrErr(ctxt, | 
|  | 8284 | XML_SCHEMAP_SRC_RESOLVE, | 
|  | 8285 | NULL, (xmlSchemaTypePtr) elem, elem->node, | 
|  | 8286 | "type", elem->namedType, elem->namedTypeNs, | 
|  | 8287 | XML_SCHEMA_TYPE_BASIC, "type definition"); | 
|  | 8288 | } else | 
|  | 8289 | elem->subtypes = type; | 
|  | 8290 | } | 
|  | 8291 | if (elem->substGroup != NULL) { | 
|  | 8292 | xmlSchemaElementPtr substHead; | 
|  | 8293 |  | 
|  | 8294 | /* | 
|  | 8295 | * FIXME TODO: Do we need a new field in _xmlSchemaElement for | 
|  | 8296 | * substitutionGroup? | 
|  | 8297 | */ | 
|  | 8298 | substHead = xmlSchemaGetElem(ctxt->schema, elem->substGroup, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 8299 | elem->substGroupNs); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8300 | if (substHead == NULL) { | 
|  | 8301 | xmlSchemaPResCompAttrErr(ctxt, | 
|  | 8302 | XML_SCHEMAP_SRC_RESOLVE, | 
|  | 8303 | NULL, (xmlSchemaTypePtr) elem, NULL, | 
|  | 8304 | "substitutionGroup", elem->substGroup, elem->substGroupNs, | 
|  | 8305 | XML_SCHEMA_TYPE_ELEMENT, NULL); | 
|  | 8306 | } else { | 
|  | 8307 | xmlSchemaRefFixupCallback(substHead, ctxt, NULL, NULL, NULL); | 
|  | 8308 | /* | 
|  | 8309 | * (type definition)...otherwise the {type definition} of the | 
|  | 8310 | * element declaration ·resolved· to by the ·actual value· of | 
|  | 8311 | * the substitutionGroup [attribute], if present | 
|  | 8312 | */ | 
|  | 8313 | if (elem->subtypes == NULL) | 
|  | 8314 | elem->subtypes = substHead->subtypes; | 
|  | 8315 | } | 
|  | 8316 | } | 
|  | 8317 | if ((elem->subtypes == NULL) && (elem->namedType == NULL) && | 
|  | 8318 | (elem->substGroup == NULL)) | 
|  | 8319 | elem->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); | 
|  | 8320 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8321 | } | 
|  | 8322 |  | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 8323 | /** | 
|  | 8324 | * xmlSchemaParseListRefFixup: | 
|  | 8325 | * @type:  the schema type definition | 
|  | 8326 | * @ctxt:  the schema parser context | 
|  | 8327 | * | 
|  | 8328 | * Fixup of the itemType reference of the list type. | 
|  | 8329 | */ | 
| Daniel Veillard | 377e1a9 | 2004-04-16 16:30:05 +0000 | [diff] [blame] | 8330 | static void | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 8331 | xmlSchemaParseListRefFixup(xmlSchemaTypePtr type, xmlSchemaParserCtxtPtr ctxt) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8332 | { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8333 |  | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8334 | if (((type->base == NULL) && | 
|  | 8335 | (type->subtypes == NULL)) || | 
|  | 8336 | ((type->base != NULL) && | 
|  | 8337 | (type->subtypes != NULL))) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8338 | /* | 
|  | 8339 | * src-list-itemType-or-simpleType | 
|  | 8340 | * Either the itemType [attribute] or the <simpleType> [child] of | 
|  | 8341 | * the <list> element must be present, but not both. | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8342 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8343 | /* | 
|  | 8344 | * TODO: Move this to the parse function. | 
|  | 8345 | */ | 
|  | 8346 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8347 | XML_SCHEMAP_SRC_LIST_ITEMTYPE_OR_SIMPLETYPE, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8348 | NULL, type, type->node, | 
|  | 8349 | "The attribute 'itemType' and the <simpleType> child " | 
|  | 8350 | "are mutually exclusive", NULL); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8351 | } else if (type->base!= NULL) { | 
|  | 8352 | type->subtypes = xmlSchemaGetType(ctxt->schema, type->base, type->baseNs); | 
|  | 8353 | if (type->subtypes == NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8354 | xmlSchemaPResCompAttrErr(ctxt, | 
|  | 8355 | XML_SCHEMAP_SRC_RESOLVE, | 
|  | 8356 | NULL, type, type->node, | 
|  | 8357 | "itemType", type->base, type->baseNs, | 
|  | 8358 | XML_SCHEMA_TYPE_SIMPLE, NULL); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8359 | } | 
|  | 8360 | } | 
|  | 8361 | if ((type->subtypes != NULL) && | 
|  | 8362 | (type->subtypes->contentType == XML_SCHEMA_CONTENT_UNKNOWN)) | 
|  | 8363 | xmlSchemaTypeFixup(type->subtypes, ctxt, NULL); | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 8364 | } | 
|  | 8365 |  | 
|  | 8366 | /** | 
|  | 8367 | * xmlSchemaParseUnionRefCheck: | 
|  | 8368 | * @typeDecl:  the schema type definition | 
|  | 8369 | * @ctxt:  the schema parser context | 
|  | 8370 | * | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8371 | * Checks and builds the memberTypes of the union type. | 
|  | 8372 | * Returns -1 in case of an internal error, 0 otherwise. | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 8373 | */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8374 | static int | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 8375 | xmlSchemaParseUnionRefCheck(xmlSchemaTypePtr type, | 
| Daniel Veillard | 377e1a9 | 2004-04-16 16:30:05 +0000 | [diff] [blame] | 8376 | xmlSchemaParserCtxtPtr ctxt) | 
|  | 8377 | { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8378 |  | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8379 | xmlSchemaTypeLinkPtr link, lastLink = NULL, prevLink, subLink, newLink; | 
|  | 8380 | xmlSchemaTypePtr memberType, ctxtType; | 
| Daniel Veillard | 377e1a9 | 2004-04-16 16:30:05 +0000 | [diff] [blame] | 8381 |  | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8382 | /* 1 If the <union> alternative is chosen, then [Definition:] | 
|  | 8383 | * define the explicit members as the type definitions ·resolved· | 
|  | 8384 | * to by the items in the ·actual value· of the memberTypes [attribute], | 
|  | 8385 | * if any, followed by the type definitions corresponding to the | 
|  | 8386 | * <simpleType>s among the [children] of <union>, if any. | 
|  | 8387 | */ | 
| Daniel Veillard | 377e1a9 | 2004-04-16 16:30:05 +0000 | [diff] [blame] | 8388 |  | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8389 | if (type->type != XML_SCHEMA_TYPE_UNION) | 
|  | 8390 | return (-1); | 
|  | 8391 | if (ctxt->ctxtType == NULL) { | 
|  | 8392 | xmlSchemaPErr(ctxt, type->node, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 8393 | XML_SCHEMAP_INTERNAL, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8394 | "Internal error: xmlSchemaParseUnionRefCheck, no parent type " | 
|  | 8395 | "available", NULL, NULL); | 
|  | 8396 | return (-1); | 
|  | 8397 | } | 
|  | 8398 | /* | 
|  | 8399 | * src-union-memberTypes-or-simpleTypes | 
|  | 8400 | * Either the memberTypes [attribute] of the <union> element must | 
|  | 8401 | * be non-empty or there must be at least one simpleType [child]. | 
|  | 8402 | */ | 
|  | 8403 | if ((type->base == NULL) && | 
|  | 8404 | (type->subtypes == NULL)) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8405 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8406 | XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8407 | NULL, NULL, type->node, | 
|  | 8408 | "Either the attribute 'memberTypes' must be non-empty " | 
|  | 8409 | "or there must be at least one <simpleType> child", NULL); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8410 | } | 
|  | 8411 |  | 
|  | 8412 | ctxtType = ctxt->ctxtType; | 
|  | 8413 | if (type->base != NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8414 | xmlAttrPtr attr; | 
|  | 8415 | const xmlChar *cur, *end; | 
|  | 8416 | xmlChar *tmp; | 
|  | 8417 | const xmlChar *localName, *uri; | 
|  | 8418 |  | 
|  | 8419 | attr = xmlSchemaGetPropNode(type->node, "memberTypes"); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8420 | cur = type->base; | 
|  | 8421 | do { | 
|  | 8422 | while (IS_BLANK_CH(*cur)) | 
|  | 8423 | cur++; | 
|  | 8424 | end = cur; | 
|  | 8425 | while ((*end != 0) && (!(IS_BLANK_CH(*end)))) | 
|  | 8426 | end++; | 
|  | 8427 | if (end == cur) | 
|  | 8428 | break; | 
|  | 8429 | tmp = xmlStrndup(cur, end - cur); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8430 | xmlSchemaPValAttrNodeQNameValue(ctxt, ctxt->schema, NULL, | 
|  | 8431 | NULL, attr, BAD_CAST tmp, &uri, NULL, &localName); | 
|  | 8432 | memberType = xmlSchemaGetType(ctxt->schema, localName, uri); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8433 | if (memberType == NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8434 | xmlSchemaPResCompAttrErr(ctxt, | 
|  | 8435 | XML_SCHEMAP_UNKNOWN_MEMBER_TYPE, | 
|  | 8436 | NULL, NULL, type->node, "memberTypes", localName, uri, | 
|  | 8437 | XML_SCHEMA_TYPE_SIMPLE, NULL); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8438 | } else { | 
|  | 8439 | if (memberType->contentType == XML_SCHEMA_CONTENT_UNKNOWN) | 
|  | 8440 | xmlSchemaTypeFixup(memberType, ctxt, NULL); | 
|  | 8441 | link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink)); | 
|  | 8442 | if (link == NULL) { | 
|  | 8443 | xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL); | 
|  | 8444 | return (-1); | 
|  | 8445 | } | 
|  | 8446 | link->type = memberType; | 
|  | 8447 | link->next = NULL; | 
|  | 8448 | if (lastLink == NULL) | 
|  | 8449 | ctxtType->memberTypes = link; | 
|  | 8450 | else | 
|  | 8451 | lastLink->next = link; | 
|  | 8452 | lastLink = link; | 
|  | 8453 | } | 
|  | 8454 | xmlFree(tmp); | 
|  | 8455 | cur = end; | 
|  | 8456 | } while (*cur != 0); | 
|  | 8457 | } | 
|  | 8458 | /* | 
|  | 8459 | * Add local simple types, | 
|  | 8460 | */ | 
|  | 8461 | memberType = type->subtypes; | 
|  | 8462 | while (memberType != NULL) { | 
|  | 8463 | if (memberType->contentType == XML_SCHEMA_CONTENT_UNKNOWN) | 
|  | 8464 | xmlSchemaTypeFixup(memberType, ctxt, NULL); | 
|  | 8465 | link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink)); | 
|  | 8466 | if (link == NULL) { | 
|  | 8467 | xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL); | 
|  | 8468 | return (-1); | 
|  | 8469 | } | 
|  | 8470 | link->type = memberType; | 
|  | 8471 | link->next = NULL; | 
|  | 8472 | if (lastLink == NULL) | 
|  | 8473 | ctxtType->memberTypes = link; | 
|  | 8474 | else | 
|  | 8475 | lastLink->next = link; | 
|  | 8476 | lastLink = link; | 
|  | 8477 | memberType = memberType->next; | 
|  | 8478 | } | 
|  | 8479 | /* | 
|  | 8480 | * The actual value is then formed by replacing any union type | 
|  | 8481 | * definition in the ·explicit members· with the members of their | 
|  | 8482 | * {member type definitions}, in order. | 
|  | 8483 | */ | 
|  | 8484 | link = ctxtType->memberTypes; | 
|  | 8485 | while (link != NULL) { | 
|  | 8486 | if (link->type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) { | 
|  | 8487 | subLink = link->type->memberTypes; | 
|  | 8488 | if (subLink != NULL) { | 
|  | 8489 | link->type = subLink->type; | 
|  | 8490 | if (subLink->next != NULL) { | 
|  | 8491 | lastLink = link->next; | 
|  | 8492 | subLink = subLink->next; | 
|  | 8493 | prevLink = link; | 
|  | 8494 | while (subLink != NULL) { | 
|  | 8495 | newLink = (xmlSchemaTypeLinkPtr) | 
|  | 8496 | xmlMalloc(sizeof(xmlSchemaTypeLink)); | 
|  | 8497 | if (newLink == NULL) { | 
|  | 8498 | xmlSchemaPErrMemory(ctxt, "allocating a type link", | 
|  | 8499 | NULL); | 
|  | 8500 | return (-1); | 
|  | 8501 | } | 
|  | 8502 | newLink->type = memberType; | 
|  | 8503 | prevLink->next = newLink; | 
|  | 8504 | prevLink = newLink; | 
|  | 8505 | newLink->next = lastLink; | 
|  | 8506 |  | 
|  | 8507 | subLink = subLink->next; | 
|  | 8508 | } | 
|  | 8509 | } | 
|  | 8510 | } | 
|  | 8511 | } | 
|  | 8512 | link = link->next; | 
|  | 8513 | } | 
|  | 8514 |  | 
|  | 8515 | return (0); | 
| Daniel Veillard | 377e1a9 | 2004-04-16 16:30:05 +0000 | [diff] [blame] | 8516 | } | 
|  | 8517 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 8518 | /** | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8519 | * xmlSchemaIsDerivedFromBuiltInType: | 
|  | 8520 | * @ctxt:  the schema parser context | 
|  | 8521 | * @type:  the type definition | 
|  | 8522 | * @valType: the value type | 
|  | 8523 | * | 
|  | 8524 | * | 
|  | 8525 | * Returns 1 if the type has the given value type, or | 
|  | 8526 | * is derived from such a type. | 
|  | 8527 | */ | 
| William M. Brack | 803812b | 2004-06-03 02:11:24 +0000 | [diff] [blame] | 8528 | static int | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8529 | xmlSchemaIsDerivedFromBuiltInType(xmlSchemaParserCtxtPtr ctxt, | 
|  | 8530 | xmlSchemaTypePtr type, int valType) | 
|  | 8531 | { | 
|  | 8532 | /* TODO: Check if this works in every case. */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8533 | if ((type->type == XML_SCHEMA_TYPE_BASIC) && | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8534 | (type->contentType == XML_SCHEMA_CONTENT_BASIC)) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8535 | if (type->builtInType == valType) | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8536 | return(1); | 
|  | 8537 | } else if (type->type == XML_SCHEMA_TYPE_ATTRIBUTE) { | 
|  | 8538 | if (((xmlSchemaAttributePtr) type)->subtypes != NULL) | 
|  | 8539 | return(xmlSchemaIsDerivedFromBuiltInType(ctxt, | 
|  | 8540 | ((xmlSchemaAttributePtr) type)->subtypes, valType)); | 
|  | 8541 | } else if ((type->type == XML_SCHEMA_TYPE_RESTRICTION) || | 
|  | 8542 | (type->type == XML_SCHEMA_TYPE_EXTENSION)) { | 
|  | 8543 | if (type->baseType != NULL) | 
|  | 8544 | return(xmlSchemaIsDerivedFromBuiltInType(ctxt, type->baseType, | 
|  | 8545 | valType)); | 
|  | 8546 | } else if ((type->subtypes != NULL) && | 
|  | 8547 | ((type->subtypes->type == XML_SCHEMA_TYPE_COMPLEX) || | 
|  | 8548 | (type->subtypes->type == XML_SCHEMA_TYPE_COMPLEX_CONTENT) || | 
|  | 8549 | (type->subtypes->type == XML_SCHEMA_TYPE_SIMPLE) || | 
|  | 8550 | (type->subtypes->type == XML_SCHEMA_TYPE_SIMPLE_CONTENT))) { | 
|  | 8551 | return(xmlSchemaIsDerivedFromBuiltInType(ctxt, type->subtypes, | 
|  | 8552 | valType)); | 
|  | 8553 | } | 
|  | 8554 |  | 
|  | 8555 | return (0); | 
|  | 8556 | } | 
|  | 8557 |  | 
|  | 8558 | /** | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 8559 | * xmlSchemaIsDerivedFromBuiltInType: | 
|  | 8560 | * @type:  the simpleType definition | 
|  | 8561 | * | 
|  | 8562 | * Returns the primitive type of the given type or | 
|  | 8563 | * NULL in case of error. | 
|  | 8564 | */ | 
|  | 8565 | static xmlSchemaTypePtr | 
|  | 8566 | xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type) | 
|  | 8567 | { | 
|  | 8568 | while (type != NULL) { | 
|  | 8569 | if (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE) | 
|  | 8570 | return (type); | 
|  | 8571 | type = type->baseType; | 
|  | 8572 | } | 
|  | 8573 |  | 
|  | 8574 | return (NULL); | 
|  | 8575 | } | 
|  | 8576 |  | 
|  | 8577 |  | 
|  | 8578 | /** | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8579 | * xmlSchemaBuildAttributeUsesOwned: | 
|  | 8580 | * @ctxt:  the schema parser context | 
|  | 8581 | * @type:  the complex type definition | 
|  | 8582 | * @cur: the attribute declaration list | 
|  | 8583 | * @lastUse: the top of the attribute use list | 
|  | 8584 | * | 
|  | 8585 | * Builds the attribute uses list on the given complex type. | 
|  | 8586 | * This one is supposed to be called by | 
|  | 8587 | * xmlSchemaBuildAttributeValidation only. | 
|  | 8588 | */ | 
|  | 8589 | static int | 
|  | 8590 | xmlSchemaBuildAttributeUsesOwned(xmlSchemaParserCtxtPtr ctxt, | 
|  | 8591 | xmlSchemaAttributePtr cur, | 
|  | 8592 | xmlSchemaAttributeLinkPtr *uses, | 
|  | 8593 | xmlSchemaAttributeLinkPtr *lastUse) | 
|  | 8594 | { | 
|  | 8595 | xmlSchemaAttributeLinkPtr tmp; | 
|  | 8596 | while (cur != NULL) { | 
|  | 8597 | if (cur->type == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) { | 
|  | 8598 | /* | 
|  | 8599 | * W3C: "2 The {attribute uses} of the attribute groups ·resolved· | 
|  | 8600 | * to by the ·actual value·s of the ref [attribute] of the | 
|  | 8601 | * <attributeGroup> [children], if any." | 
|  | 8602 | */ | 
|  | 8603 | if (xmlSchemaBuildAttributeUsesOwned(ctxt, | 
|  | 8604 | ((xmlSchemaAttributeGroupPtr) cur)->attributes, uses, | 
|  | 8605 | lastUse) == -1) { | 
|  | 8606 | return (-1); | 
|  | 8607 | } | 
|  | 8608 | } else { | 
|  | 8609 | /* W3C: "1 The set of attribute uses corresponding to the | 
|  | 8610 | * <attribute> [children], if any." | 
|  | 8611 | */ | 
|  | 8612 | tmp = (xmlSchemaAttributeLinkPtr) | 
|  | 8613 | xmlMalloc(sizeof(xmlSchemaAttributeLink)); | 
|  | 8614 | if (tmp == NULL) { | 
|  | 8615 | xmlSchemaPErrMemory(ctxt, "building attribute uses", NULL); | 
|  | 8616 | return (-1); | 
|  | 8617 | } | 
|  | 8618 | tmp->attr = cur; | 
|  | 8619 | tmp->next = NULL; | 
|  | 8620 | if (*uses == NULL) | 
|  | 8621 | *uses = tmp; | 
|  | 8622 | else | 
|  | 8623 | (*lastUse)->next = tmp; | 
|  | 8624 | *lastUse = tmp; | 
|  | 8625 | } | 
|  | 8626 | cur = cur->next; | 
|  | 8627 | } | 
|  | 8628 | return (0); | 
|  | 8629 | } | 
|  | 8630 |  | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 8631 | /** | 
|  | 8632 | * xmlSchemaCloneWildcardNsConstraints: | 
|  | 8633 | * @ctxt:  the schema parser context | 
|  | 8634 | * @dest:  the destination wildcard | 
|  | 8635 | * @source: the source wildcard | 
|  | 8636 | * | 
|  | 8637 | * Clones the namespace constraints of source | 
|  | 8638 | * and assignes them to dest. | 
|  | 8639 | * Returns -1 on internal error, 0 otherwise. | 
|  | 8640 | */ | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8641 | static int | 
|  | 8642 | xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt, | 
|  | 8643 | xmlSchemaWildcardPtr *dest, | 
|  | 8644 | xmlSchemaWildcardPtr source) | 
|  | 8645 | { | 
|  | 8646 | xmlSchemaWildcardNsPtr cur, tmp, last; | 
|  | 8647 |  | 
|  | 8648 | if ((source == NULL) || (*dest == NULL)) | 
|  | 8649 | return(-1); | 
|  | 8650 | (*dest)->any = source->any; | 
|  | 8651 | cur = source->nsSet; | 
|  | 8652 | last = NULL; | 
|  | 8653 | while (cur != NULL) { | 
|  | 8654 | tmp = xmlSchemaNewWildcardNsConstraint(ctxt); | 
|  | 8655 | if (tmp == NULL) | 
|  | 8656 | return(-1); | 
|  | 8657 | tmp->value = cur->value; | 
|  | 8658 | if (last == NULL) | 
|  | 8659 | (*dest)->nsSet = tmp; | 
|  | 8660 | else | 
|  | 8661 | last->next = tmp; | 
|  | 8662 | last = tmp; | 
|  | 8663 | cur = cur->next; | 
|  | 8664 | } | 
|  | 8665 | if ((*dest)->negNsSet != NULL) | 
|  | 8666 | xmlSchemaFreeWildcardNsSet((*dest)->negNsSet); | 
|  | 8667 | if (source->negNsSet != NULL) { | 
|  | 8668 | (*dest)->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); | 
|  | 8669 | if ((*dest)->negNsSet == NULL) | 
|  | 8670 | return(-1); | 
|  | 8671 | (*dest)->negNsSet->value = source->negNsSet->value; | 
|  | 8672 | } else | 
|  | 8673 | (*dest)->negNsSet = NULL; | 
|  | 8674 | return(0); | 
|  | 8675 | } | 
|  | 8676 |  | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 8677 | /** | 
|  | 8678 | * xmlSchemaUnionWildcards: | 
|  | 8679 | * @ctxt:  the schema parser context | 
|  | 8680 | * @completeWild:  the first wildcard | 
|  | 8681 | * @curWild: the second wildcard | 
|  | 8682 | * | 
|  | 8683 | * Unions the namespace constraints of the given wildcards. | 
|  | 8684 | * @completeWild will hold the resulting union. | 
|  | 8685 | * Returns a positive error code on failure, -1 in case of an | 
|  | 8686 | * internal error, 0 otherwise. | 
|  | 8687 | */ | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8688 | static int | 
|  | 8689 | xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, | 
|  | 8690 | xmlSchemaWildcardPtr completeWild, | 
|  | 8691 | xmlSchemaWildcardPtr curWild) | 
|  | 8692 | { | 
|  | 8693 | xmlSchemaWildcardNsPtr cur, curB, tmp; | 
|  | 8694 |  | 
|  | 8695 | /* | 
|  | 8696 | * 1 If O1 and O2 are the same value, then that value must be the | 
|  | 8697 | * value. | 
|  | 8698 | */ | 
|  | 8699 | if ((completeWild->any == curWild->any) && | 
|  | 8700 | ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && | 
|  | 8701 | ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { | 
|  | 8702 |  | 
|  | 8703 | if ((completeWild->negNsSet == NULL) || | 
|  | 8704 | (completeWild->negNsSet->value == curWild->negNsSet->value)) { | 
|  | 8705 |  | 
|  | 8706 | if (completeWild->nsSet != NULL) { | 
| William M. Brack | 803812b | 2004-06-03 02:11:24 +0000 | [diff] [blame] | 8707 | int found = 0; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8708 |  | 
|  | 8709 | /* | 
|  | 8710 | * Check equality of sets. | 
|  | 8711 | */ | 
|  | 8712 | cur = completeWild->nsSet; | 
|  | 8713 | while (cur != NULL) { | 
|  | 8714 | found = 0; | 
|  | 8715 | curB = curWild->nsSet; | 
|  | 8716 | while (curB != NULL) { | 
|  | 8717 | if (cur->value == curB->value) { | 
|  | 8718 | found = 1; | 
|  | 8719 | break; | 
|  | 8720 | } | 
|  | 8721 | curB = curB->next; | 
|  | 8722 | } | 
|  | 8723 | if (!found) | 
|  | 8724 | break; | 
|  | 8725 | cur = cur->next; | 
|  | 8726 | } | 
|  | 8727 | if (found) | 
|  | 8728 | return(0); | 
|  | 8729 | } else | 
|  | 8730 | return(0); | 
|  | 8731 | } | 
|  | 8732 | } | 
|  | 8733 | /* | 
|  | 8734 | * 2 If either O1 or O2 is any, then any must be the value | 
|  | 8735 | */ | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 8736 | if (completeWild->any != curWild->any) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8737 | if (completeWild->any == 0) { | 
|  | 8738 | completeWild->any = 1; | 
|  | 8739 | if (completeWild->nsSet != NULL) { | 
|  | 8740 | xmlSchemaFreeWildcardNsSet(completeWild->nsSet); | 
|  | 8741 | completeWild->nsSet = NULL; | 
|  | 8742 | } | 
|  | 8743 | if (completeWild->negNsSet != NULL) { | 
|  | 8744 | xmlFree(completeWild->negNsSet); | 
|  | 8745 | completeWild->negNsSet = NULL; | 
|  | 8746 | } | 
|  | 8747 | } | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 8748 | return (0); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8749 | } | 
|  | 8750 | /* | 
|  | 8751 | * 3 If both O1 and O2 are sets of (namespace names or ·absent·), | 
|  | 8752 | * then the union of those sets must be the value. | 
|  | 8753 | */ | 
|  | 8754 | if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { | 
|  | 8755 | int found; | 
|  | 8756 | xmlSchemaWildcardNsPtr start; | 
|  | 8757 |  | 
|  | 8758 | cur = curWild->nsSet; | 
|  | 8759 | start = completeWild->nsSet; | 
|  | 8760 | while (cur != NULL) { | 
|  | 8761 | found = 0; | 
|  | 8762 | curB = start; | 
|  | 8763 | while (curB != NULL) { | 
|  | 8764 | if (cur->value == curB->value) { | 
|  | 8765 | found = 1; | 
|  | 8766 | break; | 
|  | 8767 | } | 
|  | 8768 | curB = curB->next; | 
|  | 8769 | } | 
|  | 8770 | if (!found) { | 
|  | 8771 | tmp = xmlSchemaNewWildcardNsConstraint(ctxt); | 
|  | 8772 | if (tmp == NULL) | 
|  | 8773 | return (-1); | 
|  | 8774 | tmp->value = cur->value; | 
|  | 8775 | tmp->next = completeWild->nsSet; | 
|  | 8776 | completeWild->nsSet = tmp; | 
|  | 8777 | } | 
|  | 8778 | cur = cur->next; | 
|  | 8779 | } | 
|  | 8780 |  | 
|  | 8781 | return(0); | 
|  | 8782 | } | 
|  | 8783 | /* | 
|  | 8784 | * 4 If the two are negations of different values (namespace names | 
|  | 8785 | * or ·absent·), then a pair of not and ·absent· must be the value. | 
|  | 8786 | */ | 
|  | 8787 | if ((completeWild->negNsSet != NULL) && | 
|  | 8788 | (curWild->negNsSet != NULL) && | 
|  | 8789 | (completeWild->negNsSet->value != curWild->negNsSet->value)) { | 
|  | 8790 | completeWild->negNsSet->value = NULL; | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 8791 |  | 
|  | 8792 | return(0); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8793 | } | 
|  | 8794 | /* | 
|  | 8795 | * 5. | 
|  | 8796 | */ | 
|  | 8797 | if (((completeWild->negNsSet != NULL) && | 
|  | 8798 | (completeWild->negNsSet->value != NULL) && | 
|  | 8799 | (curWild->nsSet != NULL)) || | 
|  | 8800 | ((curWild->negNsSet != NULL) && | 
|  | 8801 | (curWild->negNsSet->value != NULL) && | 
|  | 8802 | (completeWild->nsSet != NULL))) { | 
|  | 8803 |  | 
|  | 8804 | int nsFound, absentFound = 0; | 
|  | 8805 |  | 
|  | 8806 | if (completeWild->nsSet != NULL) { | 
|  | 8807 | cur = completeWild->nsSet; | 
|  | 8808 | curB = curWild->negNsSet; | 
|  | 8809 | } else { | 
|  | 8810 | cur = curWild->nsSet; | 
|  | 8811 | curB = completeWild->negNsSet; | 
|  | 8812 | } | 
|  | 8813 | nsFound = 0; | 
|  | 8814 | while (cur != NULL) { | 
|  | 8815 | if (cur->value == NULL) | 
|  | 8816 | absentFound = 1; | 
|  | 8817 | else if (cur->value == curB->value) | 
|  | 8818 | nsFound = 1; | 
|  | 8819 | if (nsFound && absentFound) | 
|  | 8820 | break; | 
|  | 8821 | cur = cur->next; | 
|  | 8822 | } | 
|  | 8823 |  | 
|  | 8824 | if (nsFound && absentFound) { | 
|  | 8825 | /* | 
|  | 8826 | * 5.1 If the set S includes both the negated namespace | 
|  | 8827 | * name and ·absent·, then any must be the value. | 
|  | 8828 | */ | 
|  | 8829 | completeWild->any = 1; | 
|  | 8830 | if (completeWild->nsSet != NULL) { | 
|  | 8831 | xmlSchemaFreeWildcardNsSet(completeWild->nsSet); | 
|  | 8832 | completeWild->nsSet = NULL; | 
|  | 8833 | } | 
|  | 8834 | if (completeWild->negNsSet != NULL) { | 
|  | 8835 | xmlFree(completeWild->negNsSet); | 
|  | 8836 | completeWild->negNsSet = NULL; | 
|  | 8837 | } | 
|  | 8838 | } else if (nsFound && (!absentFound)) { | 
|  | 8839 | /* | 
|  | 8840 | * 5.2 If the set S includes the negated namespace name | 
|  | 8841 | * but not ·absent·, then a pair of not and ·absent· must | 
|  | 8842 | * be the value. | 
|  | 8843 | */ | 
|  | 8844 | if (completeWild->nsSet != NULL) { | 
|  | 8845 | xmlSchemaFreeWildcardNsSet(completeWild->nsSet); | 
|  | 8846 | completeWild->nsSet = NULL; | 
|  | 8847 | } | 
|  | 8848 | if (completeWild->negNsSet == NULL) { | 
|  | 8849 | completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); | 
|  | 8850 | if (completeWild->negNsSet == NULL) | 
|  | 8851 | return (-1); | 
|  | 8852 | } | 
|  | 8853 | completeWild->negNsSet->value = NULL; | 
|  | 8854 | } else if ((!nsFound) && absentFound) { | 
|  | 8855 | /* | 
|  | 8856 | * 5.3 If the set S includes ·absent· but not the negated | 
|  | 8857 | * namespace name, then the union is not expressible. | 
|  | 8858 | */ | 
|  | 8859 | xmlSchemaPErr(ctxt, completeWild->node, | 
|  | 8860 | XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 8861 | "The union of the wilcard is not expressible.\n", | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8862 | NULL, NULL); | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 8863 | return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8864 | } else if ((!nsFound) && (!absentFound)) { | 
|  | 8865 | /* | 
|  | 8866 | * 5.4 If the set S does not include either the negated namespace | 
|  | 8867 | * name or ·absent·, then whichever of O1 or O2 is a pair of not | 
|  | 8868 | * and a namespace name must be the value. | 
|  | 8869 | */ | 
|  | 8870 | if (completeWild->negNsSet == NULL) { | 
|  | 8871 | if (completeWild->nsSet != NULL) { | 
|  | 8872 | xmlSchemaFreeWildcardNsSet(completeWild->nsSet); | 
|  | 8873 | completeWild->nsSet = NULL; | 
|  | 8874 | } | 
|  | 8875 | completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); | 
|  | 8876 | if (completeWild->negNsSet == NULL) | 
|  | 8877 | return (-1); | 
|  | 8878 | completeWild->negNsSet->value = curWild->negNsSet->value; | 
|  | 8879 | } | 
|  | 8880 | } | 
|  | 8881 | return (0); | 
|  | 8882 | } | 
|  | 8883 | /* | 
|  | 8884 | * 6. | 
|  | 8885 | */ | 
|  | 8886 | if (((completeWild->negNsSet != NULL) && | 
|  | 8887 | (completeWild->negNsSet->value == NULL) && | 
|  | 8888 | (curWild->nsSet != NULL)) || | 
|  | 8889 | ((curWild->negNsSet != NULL) && | 
|  | 8890 | (curWild->negNsSet->value == NULL) && | 
|  | 8891 | (completeWild->nsSet != NULL))) { | 
|  | 8892 |  | 
|  | 8893 | if (completeWild->nsSet != NULL) { | 
|  | 8894 | cur = completeWild->nsSet; | 
|  | 8895 | } else { | 
|  | 8896 | cur = curWild->nsSet; | 
|  | 8897 | } | 
|  | 8898 | while (cur != NULL) { | 
|  | 8899 | if (cur->value == NULL) { | 
|  | 8900 | /* | 
|  | 8901 | * 6.1 If the set S includes ·absent·, then any must be the | 
|  | 8902 | * value. | 
|  | 8903 | */ | 
|  | 8904 | completeWild->any = 1; | 
|  | 8905 | if (completeWild->nsSet != NULL) { | 
|  | 8906 | xmlSchemaFreeWildcardNsSet(completeWild->nsSet); | 
|  | 8907 | completeWild->nsSet = NULL; | 
|  | 8908 | } | 
|  | 8909 | if (completeWild->negNsSet != NULL) { | 
|  | 8910 | xmlFree(completeWild->negNsSet); | 
|  | 8911 | completeWild->negNsSet = NULL; | 
|  | 8912 | } | 
|  | 8913 | return (0); | 
|  | 8914 | } | 
|  | 8915 | cur = cur->next; | 
|  | 8916 | } | 
|  | 8917 | if (completeWild->negNsSet == NULL) { | 
|  | 8918 | /* | 
|  | 8919 | * 6.2 If the set S does not include ·absent·, then a pair of not | 
|  | 8920 | * and ·absent· must be the value. | 
|  | 8921 | */ | 
|  | 8922 | if (completeWild->nsSet != NULL) { | 
|  | 8923 | xmlSchemaFreeWildcardNsSet(completeWild->nsSet); | 
|  | 8924 | completeWild->nsSet = NULL; | 
|  | 8925 | } | 
|  | 8926 | completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); | 
|  | 8927 | if (completeWild->negNsSet == NULL) | 
|  | 8928 | return (-1); | 
|  | 8929 | completeWild->negNsSet->value = NULL; | 
|  | 8930 | } | 
|  | 8931 | return (0); | 
|  | 8932 | } | 
|  | 8933 | return (0); | 
|  | 8934 |  | 
|  | 8935 | } | 
|  | 8936 |  | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 8937 | /** | 
|  | 8938 | * xmlSchemaIntersectWildcards: | 
|  | 8939 | * @ctxt:  the schema parser context | 
|  | 8940 | * @completeWild:  the first wildcard | 
|  | 8941 | * @curWild: the second wildcard | 
|  | 8942 | * | 
|  | 8943 | * Intersects the namespace constraints of the given wildcards. | 
|  | 8944 | * @completeWild will hold the resulting intersection. | 
|  | 8945 | * Returns a positive error code on failure, -1 in case of an | 
|  | 8946 | * internal error, 0 otherwise. | 
|  | 8947 | */ | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8948 | static int | 
|  | 8949 | xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt, | 
|  | 8950 | xmlSchemaWildcardPtr completeWild, | 
|  | 8951 | xmlSchemaWildcardPtr curWild) | 
|  | 8952 | { | 
| William M. Brack | 803812b | 2004-06-03 02:11:24 +0000 | [diff] [blame] | 8953 | xmlSchemaWildcardNsPtr cur, curB, prev,  tmp; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8954 |  | 
|  | 8955 | /* | 
|  | 8956 | * 1 If O1 and O2 are the same value, then that value must be the | 
|  | 8957 | * value. | 
|  | 8958 | */ | 
|  | 8959 | if ((completeWild->any == curWild->any) && | 
|  | 8960 | ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && | 
|  | 8961 | ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { | 
|  | 8962 |  | 
|  | 8963 | if ((completeWild->negNsSet == NULL) || | 
|  | 8964 | (completeWild->negNsSet->value == curWild->negNsSet->value)) { | 
|  | 8965 |  | 
|  | 8966 | if (completeWild->nsSet != NULL) { | 
| William M. Brack | 803812b | 2004-06-03 02:11:24 +0000 | [diff] [blame] | 8967 | int found = 0; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 8968 |  | 
|  | 8969 | /* | 
|  | 8970 | * Check equality of sets. | 
|  | 8971 | */ | 
|  | 8972 | cur = completeWild->nsSet; | 
|  | 8973 | while (cur != NULL) { | 
|  | 8974 | found = 0; | 
|  | 8975 | curB = curWild->nsSet; | 
|  | 8976 | while (curB != NULL) { | 
|  | 8977 | if (cur->value == curB->value) { | 
|  | 8978 | found = 1; | 
|  | 8979 | break; | 
|  | 8980 | } | 
|  | 8981 | curB = curB->next; | 
|  | 8982 | } | 
|  | 8983 | if (!found) | 
|  | 8984 | break; | 
|  | 8985 | cur = cur->next; | 
|  | 8986 | } | 
|  | 8987 | if (found) | 
|  | 8988 | return(0); | 
|  | 8989 | } else | 
|  | 8990 | return(0); | 
|  | 8991 | } | 
|  | 8992 | } | 
|  | 8993 | /* | 
|  | 8994 | * 2 If either O1 or O2 is any, then the other must be the value. | 
|  | 8995 | */ | 
|  | 8996 | if ((completeWild->any != curWild->any) && (completeWild->any)) { | 
|  | 8997 | if (xmlSchemaCloneWildcardNsConstraints(ctxt, &completeWild, curWild) == -1) | 
|  | 8998 | return(-1); | 
|  | 8999 | return(0); | 
|  | 9000 | } | 
|  | 9001 | /* | 
|  | 9002 | * 3 If either O1 or O2 is a pair of not and a value (a namespace | 
|  | 9003 | * name or ·absent·) and the other is a set of (namespace names or | 
|  | 9004 | * ·absent·), then that set, minus the negated value if it was in | 
|  | 9005 | * the set, minus ·absent· if it was in the set, must be the value. | 
|  | 9006 | */ | 
|  | 9007 | if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) || | 
|  | 9008 | ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) { | 
|  | 9009 | const xmlChar *neg; | 
|  | 9010 |  | 
|  | 9011 | if (completeWild->nsSet == NULL) { | 
|  | 9012 | neg = completeWild->negNsSet->value; | 
|  | 9013 | if (xmlSchemaCloneWildcardNsConstraints(ctxt, &completeWild, curWild) == -1) | 
|  | 9014 | return(-1); | 
|  | 9015 | } else | 
|  | 9016 | neg = curWild->negNsSet->value; | 
|  | 9017 | /* | 
|  | 9018 | * Remove absent and negated. | 
|  | 9019 | */ | 
|  | 9020 | prev = NULL; | 
|  | 9021 | cur = completeWild->nsSet; | 
|  | 9022 | while (cur != NULL) { | 
|  | 9023 | if (cur->value == NULL) { | 
|  | 9024 | if (prev == NULL) | 
|  | 9025 | completeWild->nsSet = cur->next; | 
|  | 9026 | else | 
|  | 9027 | prev->next = cur->next; | 
|  | 9028 | xmlFree(cur); | 
|  | 9029 | break; | 
|  | 9030 | } | 
|  | 9031 | prev = cur; | 
|  | 9032 | cur = cur->next; | 
|  | 9033 | } | 
|  | 9034 | if (neg != NULL) { | 
|  | 9035 | prev = NULL; | 
|  | 9036 | cur = completeWild->nsSet; | 
|  | 9037 | while (cur != NULL) { | 
|  | 9038 | if (cur->value == neg) { | 
|  | 9039 | if (prev == NULL) | 
|  | 9040 | completeWild->nsSet = cur->next; | 
|  | 9041 | else | 
|  | 9042 | prev->next = cur->next; | 
|  | 9043 | xmlFree(cur); | 
|  | 9044 | break; | 
|  | 9045 | } | 
|  | 9046 | prev = cur; | 
|  | 9047 | cur = cur->next; | 
|  | 9048 | } | 
|  | 9049 | } | 
|  | 9050 |  | 
|  | 9051 | return(0); | 
|  | 9052 | } | 
|  | 9053 | /* | 
|  | 9054 | * 4 If both O1 and O2 are sets of (namespace names or ·absent·), | 
|  | 9055 | * then the intersection of those sets must be the value. | 
|  | 9056 | */ | 
|  | 9057 | if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { | 
|  | 9058 | int found; | 
|  | 9059 |  | 
|  | 9060 | cur = completeWild->nsSet; | 
|  | 9061 | prev = NULL; | 
|  | 9062 | while (cur != NULL) { | 
|  | 9063 | found = 0; | 
|  | 9064 | curB = curWild->nsSet; | 
|  | 9065 | while (curB != NULL) { | 
|  | 9066 | if (cur->value == curB->value) { | 
|  | 9067 | found = 1; | 
|  | 9068 | break; | 
|  | 9069 | } | 
|  | 9070 | curB = curB->next; | 
|  | 9071 | } | 
|  | 9072 | if (!found) { | 
|  | 9073 | if (prev == NULL) | 
|  | 9074 | completeWild->nsSet = cur->next; | 
|  | 9075 | else | 
|  | 9076 | prev->next = cur->next; | 
|  | 9077 | tmp = cur->next; | 
|  | 9078 | xmlFree(cur); | 
|  | 9079 | cur = tmp; | 
|  | 9080 | continue; | 
|  | 9081 | } | 
|  | 9082 | prev = cur; | 
|  | 9083 | cur = cur->next; | 
|  | 9084 | } | 
|  | 9085 |  | 
|  | 9086 | return(0); | 
|  | 9087 | } | 
|  | 9088 | /* 5 If the two are negations of different namespace names, | 
|  | 9089 | * then the intersection is not expressible | 
|  | 9090 | */ | 
|  | 9091 | if ((completeWild->negNsSet != NULL) && | 
|  | 9092 | (curWild->negNsSet != NULL) && | 
|  | 9093 | (completeWild->negNsSet->value != curWild->negNsSet->value) && | 
|  | 9094 | (completeWild->negNsSet->value != NULL) && | 
|  | 9095 | (curWild->negNsSet->value != NULL)) { | 
|  | 9096 |  | 
|  | 9097 | xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9098 | "The intersection of the wilcard is not expressible.\n", | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9099 | NULL, NULL); | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9100 | return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9101 | } | 
|  | 9102 | /* | 
|  | 9103 | * 6 If the one is a negation of a namespace name and the other | 
|  | 9104 | * is a negation of ·absent·, then the one which is the negation | 
|  | 9105 | * of a namespace name must be the value. | 
|  | 9106 | */ | 
|  | 9107 | if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) && | 
|  | 9108 | (completeWild->negNsSet->value != curWild->negNsSet->value) && | 
|  | 9109 | (completeWild->negNsSet->value == NULL)) { | 
|  | 9110 | completeWild->negNsSet->value =  curWild->negNsSet->value; | 
|  | 9111 | } | 
|  | 9112 | return(0); | 
|  | 9113 | } | 
|  | 9114 |  | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9115 | /** | 
|  | 9116 | * xmlSchemaIsWildcardNsConstraintSubset: | 
|  | 9117 | * @ctxt:  the schema parser context | 
|  | 9118 | * @wildA:  the first wildcard | 
|  | 9119 | * @wildB: the second wildcard | 
|  | 9120 | * | 
|  | 9121 | * Returns 1 if the namespace constraint of @wildA is an intensional | 
|  | 9122 | * subset of @wildB, 0 otherwise. | 
|  | 9123 | */ | 
|  | 9124 | static int | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9125 | xmlSchemaIsWildcardNsConstraintSubset(xmlSchemaWildcardPtr wildA, | 
|  | 9126 | xmlSchemaWildcardPtr wildB) | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9127 | { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9128 |  | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9129 | /* | 
|  | 9130 | * Schema Component Constraint: Wildcard Subset | 
|  | 9131 | */ | 
|  | 9132 | /* | 
|  | 9133 | * 1 super must be any. | 
|  | 9134 | */ | 
|  | 9135 | if (wildB->any) | 
|  | 9136 | return (1); | 
|  | 9137 | /* | 
|  | 9138 | * 2.1 sub must be a pair of not and a namespace name or ·absent·. | 
|  | 9139 | * 2.2 super must be a pair of not and the same value. | 
|  | 9140 | */ | 
|  | 9141 | if ((wildA->negNsSet != NULL) && | 
|  | 9142 | (wildB->negNsSet != NULL) && | 
|  | 9143 | (wildA->negNsSet->value == wildA->negNsSet->value)) | 
|  | 9144 | return (1); | 
|  | 9145 | /* | 
|  | 9146 | * 3.1 sub must be a set whose members are either namespace names or ·absent·. | 
|  | 9147 | */ | 
|  | 9148 | if (wildA->nsSet != NULL) { | 
|  | 9149 | /* | 
|  | 9150 | * 3.2.1 super must be the same set or a superset thereof. | 
|  | 9151 | */ | 
|  | 9152 | if (wildB->nsSet != NULL) { | 
|  | 9153 | xmlSchemaWildcardNsPtr cur, curB; | 
|  | 9154 | int found = 0; | 
|  | 9155 |  | 
|  | 9156 | cur = wildA->nsSet; | 
|  | 9157 | while (cur != NULL) { | 
|  | 9158 | found = 0; | 
|  | 9159 | curB = wildB->nsSet; | 
|  | 9160 | while (curB != NULL) { | 
|  | 9161 | if (cur->value == curB->value) { | 
|  | 9162 | found = 1; | 
|  | 9163 | break; | 
|  | 9164 | } | 
|  | 9165 | curB = curB->next; | 
|  | 9166 | } | 
|  | 9167 | if (!found) | 
|  | 9168 | return (0); | 
|  | 9169 | cur = cur->next; | 
|  | 9170 | } | 
|  | 9171 | if (found) | 
|  | 9172 | return (1); | 
|  | 9173 | } else if (wildB->negNsSet != NULL) { | 
|  | 9174 | xmlSchemaWildcardNsPtr cur; | 
|  | 9175 | /* | 
|  | 9176 | * 3.2.2 super must be a pair of not and a namespace name or | 
|  | 9177 | * ·absent· and that value must not be in sub's set. | 
|  | 9178 | */ | 
|  | 9179 | cur = wildA->nsSet; | 
|  | 9180 | while (cur != NULL) { | 
|  | 9181 | if (cur->value == wildB->negNsSet->value) | 
|  | 9182 | return (0); | 
|  | 9183 | cur = cur->next; | 
|  | 9184 | } | 
|  | 9185 | return (1); | 
|  | 9186 | } | 
|  | 9187 | } | 
|  | 9188 | return (0); | 
|  | 9189 | } | 
|  | 9190 |  | 
|  | 9191 | /** | 
|  | 9192 | * xmlSchemaBuildCompleteAttributeWildcard: | 
|  | 9193 | * @ctxt:  the schema parser context | 
|  | 9194 | * @attrs: the attribute list | 
|  | 9195 | * @completeWild: the resulting complete wildcard | 
|  | 9196 | * | 
|  | 9197 | * Returns -1 in case of an internal error, 0 otherwise. | 
|  | 9198 | */ | 
|  | 9199 | static int | 
|  | 9200 | xmlSchemaBuildCompleteAttributeWildcard(xmlSchemaParserCtxtPtr ctxt, | 
|  | 9201 | xmlSchemaAttributePtr attrs, | 
|  | 9202 | xmlSchemaWildcardPtr *completeWild) | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9203 | { | 
|  | 9204 | while (attrs != NULL) { | 
|  | 9205 | if (attrs->type == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) { | 
|  | 9206 | xmlSchemaAttributeGroupPtr group; | 
|  | 9207 |  | 
|  | 9208 | group = (xmlSchemaAttributeGroupPtr) attrs; | 
|  | 9209 | if ((group->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) { | 
|  | 9210 | if (group->attributes != NULL) { | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9211 | if (xmlSchemaBuildCompleteAttributeWildcard(ctxt, | 
|  | 9212 | group->attributes, &group->attributeWildcard) == -1) | 
|  | 9213 | return (-1); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9214 | } | 
|  | 9215 | group->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED; | 
|  | 9216 | } | 
|  | 9217 | if (group->attributeWildcard != NULL) { | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9218 | if (*completeWild == NULL) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9219 | /* | 
|  | 9220 | * Copy the first encountered wildcard as context, except for the annotation. | 
|  | 9221 | */ | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9222 | *completeWild = xmlSchemaAddWildcard(ctxt); | 
|  | 9223 | (*completeWild)->type = XML_SCHEMA_TYPE_ANY_ATTRIBUTE; | 
|  | 9224 | if (xmlSchemaCloneWildcardNsConstraints(ctxt, | 
|  | 9225 | completeWild, group->attributeWildcard) == -1) | 
|  | 9226 | return (-1); | 
|  | 9227 | (*completeWild)->processContents = group->attributeWildcard->processContents; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9228 | /* | 
|  | 9229 | * Although the complete wildcard might not correspond to any | 
|  | 9230 | * node in the schema, we will save this context node. | 
|  | 9231 | */ | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9232 | (*completeWild)->node = group->attributeWildcard->node; | 
|  | 9233 |  | 
|  | 9234 | } else if (xmlSchemaIntersectWildcards(ctxt, *completeWild, group->attributeWildcard) == -1) { | 
|  | 9235 | xmlSchemaFreeWildcard(*completeWild); | 
|  | 9236 | return (-1); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9237 | } | 
|  | 9238 | } | 
|  | 9239 | } | 
|  | 9240 | attrs = attrs->next; | 
|  | 9241 | } | 
|  | 9242 |  | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9243 | return (0); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9244 | } | 
|  | 9245 |  | 
|  | 9246 | /** | 
|  | 9247 | * xmlSchemaMatchesWildcardNs: | 
|  | 9248 | * @wild:  the wildcard | 
|  | 9249 | * @ns:  the namespace | 
|  | 9250 | * | 
|  | 9251 | * | 
|  | 9252 | * Returns 1 if the given namespace matches the wildcard, | 
|  | 9253 | * 0 otherwise. | 
|  | 9254 | */ | 
|  | 9255 | static int | 
|  | 9256 | xmlSchemaMatchesWildcardNs(xmlSchemaWildcardPtr wild, const xmlChar* ns) | 
|  | 9257 | { | 
|  | 9258 | if (wild == NULL) | 
|  | 9259 | return(0); | 
|  | 9260 |  | 
|  | 9261 | if (wild->any) | 
|  | 9262 | return(1); | 
|  | 9263 | else if (wild->nsSet != NULL) { | 
|  | 9264 | xmlSchemaWildcardNsPtr cur; | 
|  | 9265 |  | 
|  | 9266 | cur = wild->nsSet; | 
|  | 9267 | while (cur != NULL) { | 
|  | 9268 | if (xmlStrEqual(cur->value, ns)) | 
|  | 9269 | return(1); | 
|  | 9270 | cur = cur->next; | 
|  | 9271 | } | 
|  | 9272 | } else if ((wild->negNsSet != NULL) && (ns != NULL) && | 
|  | 9273 | (!xmlStrEqual(wild->negNsSet->value, ns))) | 
|  | 9274 | return(1); | 
|  | 9275 |  | 
|  | 9276 | return(0); | 
|  | 9277 | } | 
|  | 9278 |  | 
|  | 9279 | /** | 
|  | 9280 | * xmlSchemaBuildAttributeValidation: | 
|  | 9281 | * @ctxt:  the schema parser context | 
|  | 9282 | * @type:  the complex type definition | 
|  | 9283 | * | 
|  | 9284 | * | 
|  | 9285 | * Builds the wildcard and the attribute uses on the given complex type. | 
|  | 9286 | * Returns -1 if an internal error occurs, 0 otherwise. | 
|  | 9287 | */ | 
|  | 9288 | static int | 
|  | 9289 | xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaTypePtr type) | 
|  | 9290 | { | 
|  | 9291 | xmlSchemaTypePtr baseType = NULL; | 
|  | 9292 | xmlSchemaAttributeLinkPtr cur, base, tmp, id = NULL, prev = NULL, uses = NULL, | 
| William M. Brack | 803812b | 2004-06-03 02:11:24 +0000 | [diff] [blame] | 9293 | lastUse = NULL, lastBaseUse = NULL; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9294 | xmlSchemaAttributePtr attrs; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9295 | xmlSchemaTypePtr anyType; | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9296 | int baseIsAnyType = 0; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9297 | xmlChar *str = NULL; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9298 |  | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9299 | anyType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9300 | /* | 
|  | 9301 | * Complex Type Definition with complex content Schema Component. | 
|  | 9302 | * | 
|  | 9303 | * Attribute uses. | 
|  | 9304 | */ | 
|  | 9305 | if (type->attributeUses != NULL) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 9306 | xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_INTERNAL, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9307 | "Internal error: xmlSchemaBuildAttributeValidation: " | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9308 | "attribute uses already builded.\n", | 
|  | 9309 | NULL, NULL); | 
|  | 9310 | return (-1); | 
|  | 9311 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9312 | if (type->baseType == NULL) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 9313 | xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_INTERNAL, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9314 | "Internal error: xmlSchemaBuildAttributeValidation: " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9315 | "complex type '%s' has no base type.\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9316 | type->name, NULL); | 
|  | 9317 | return (-1); | 
|  | 9318 | } | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 9319 | baseType = type->baseType; | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 9320 | if (baseType == anyType) | 
|  | 9321 | baseIsAnyType = 1; | 
|  | 9322 | /* | 
|  | 9323 | * Inherit the attribute uses of the base type. | 
|  | 9324 | */ | 
|  | 9325 | /* | 
|  | 9326 | * NOTE: It is allowed to "extend" the anyType complex type. | 
|  | 9327 | */ | 
|  | 9328 | if (!baseIsAnyType) { | 
|  | 9329 | if (baseType != NULL) { | 
|  | 9330 | for (cur = baseType->attributeUses; cur != NULL; cur = cur->next) { | 
|  | 9331 | tmp = (xmlSchemaAttributeLinkPtr) | 
|  | 9332 | xmlMalloc(sizeof(xmlSchemaAttributeLink)); | 
|  | 9333 | if (tmp == NULL) { | 
|  | 9334 | xmlSchemaPErrMemory(ctxt, | 
|  | 9335 | "building attribute uses of complexType", NULL); | 
|  | 9336 | return (-1); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9337 | } | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 9338 | tmp->attr = cur->attr; | 
|  | 9339 | tmp->next = NULL; | 
|  | 9340 | if (type->attributeUses == NULL) { | 
|  | 9341 | type->attributeUses = tmp; | 
|  | 9342 | } else | 
|  | 9343 | lastBaseUse->next = tmp; | 
|  | 9344 | lastBaseUse = tmp; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9345 | } | 
|  | 9346 | } | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 9347 | } | 
|  | 9348 | if ((type->subtypes != NULL) && | 
|  | 9349 | ((type->subtypes->type == XML_SCHEMA_TYPE_COMPLEX_CONTENT) || | 
|  | 9350 | (type->subtypes->type == XML_SCHEMA_TYPE_SIMPLE_CONTENT))) { | 
|  | 9351 | attrs = type->subtypes->subtypes->attributes; | 
|  | 9352 | type->attributeWildcard = type->subtypes->subtypes->attributeWildcard; | 
|  | 9353 | } else { | 
|  | 9354 | /* Short hand form of the complexType. */ | 
|  | 9355 | attrs = type->attributes; | 
|  | 9356 | } | 
|  | 9357 | /* | 
|  | 9358 | * Handle attribute wildcards. | 
|  | 9359 | */ | 
|  | 9360 | if (xmlSchemaBuildCompleteAttributeWildcard(ctxt, | 
|  | 9361 | attrs, &type->attributeWildcard) == -1) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9362 | if ((type->attributeWildcard != NULL) && | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9363 | /* Either we used the short hand form... */ | 
|  | 9364 | ((type->subtypes == NULL) || | 
|  | 9365 | /* Or complexType -> restriction/extension */ | 
|  | 9366 | (type->attributeWildcard != type->subtypes->subtypes->attributeWildcard))) | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9367 | type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD; | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 9368 | return (-1); | 
|  | 9369 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9370 | /* | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 9371 | * TODO: This "onwed_attr_wildcard" is quite sensless: we should | 
|  | 9372 | * create the wildcard right from the start on the complexType, | 
|  | 9373 | * rather than on the <restriction>/<extension>. | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9374 | */ | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 9375 | if ((type->attributeWildcard != NULL) && | 
|  | 9376 | /* Either we used the short hand form... */ | 
|  | 9377 | ((type->subtypes == NULL) || | 
|  | 9378 | /* Or complexType -> restriction/extension */ | 
|  | 9379 | (type->attributeWildcard != type->subtypes->subtypes->attributeWildcard))) | 
|  | 9380 | type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD; | 
|  | 9381 |  | 
|  | 9382 | if ((type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) && | 
|  | 9383 | ((baseIsAnyType) || | 
|  | 9384 | ((baseType != NULL) && | 
|  | 9385 | (baseType->type == XML_SCHEMA_TYPE_COMPLEX) && | 
|  | 9386 | (baseType->attributeWildcard != NULL)))) { | 
|  | 9387 | if (type->attributeWildcard != NULL) { | 
|  | 9388 | /* | 
|  | 9389 | * Union the complete wildcard with the base wildcard. | 
|  | 9390 | */ | 
|  | 9391 | if (xmlSchemaUnionWildcards(ctxt, type->attributeWildcard, | 
|  | 9392 | baseType->attributeWildcard) == -1) | 
|  | 9393 | return (-1); | 
|  | 9394 | } else { | 
|  | 9395 | /* | 
|  | 9396 | * Just inherit the wildcard. | 
|  | 9397 | */ | 
|  | 9398 | type->attributeWildcard = baseType->attributeWildcard; | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9399 | } | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 9400 | } | 
|  | 9401 |  | 
|  | 9402 | if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) { | 
|  | 9403 | if (type->attributeWildcard != NULL) { | 
|  | 9404 | /* | 
|  | 9405 | * Derivation Valid (Restriction, Complex) | 
|  | 9406 | * 4.1 The {base type definition} must also have one. | 
|  | 9407 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9408 | if (baseType->attributeWildcard == NULL) { | 
|  | 9409 | xmlSchemaPCustomErr(ctxt, | 
|  | 9410 | XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, | 
|  | 9411 | NULL, type, NULL, | 
|  | 9412 | "The type has an attribute wildcard, " | 
|  | 9413 | "but the base type %s does not have one", | 
|  | 9414 | xmlSchemaFormatItemForReport(&str, NULL, baseType, NULL, 1)); | 
|  | 9415 | FREE_AND_NULL(str) | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 9416 | return (1); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9417 | } else if (xmlSchemaIsWildcardNsConstraintSubset( | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 9418 | type->attributeWildcard, baseType->attributeWildcard) == 0) { | 
|  | 9419 | /* 4.2 */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9420 | xmlSchemaPCustomErr(ctxt, | 
|  | 9421 | XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, | 
|  | 9422 | NULL, type, NULL, | 
|  | 9423 | "The attribute wildcard is not a valid " | 
|  | 9424 | "subset of the wildcard in the base type %s", | 
|  | 9425 | xmlSchemaFormatItemForReport(&str, NULL, baseType, NULL, 1)); | 
|  | 9426 | FREE_AND_NULL(str) | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 9427 | return (1); | 
|  | 9428 | } | 
|  | 9429 | /* 4.3 Unless the {base type definition} is the ·ur-type | 
|  | 9430 | * definition·, the complex type definition's {attribute | 
|  | 9431 | * wildcard}'s {process contents} must be identical to or | 
|  | 9432 | * stronger than the {base type definition}'s {attribute | 
|  | 9433 | * wildcard}'s {process contents}, where strict is stronger | 
|  | 9434 | * than lax is stronger than skip. | 
|  | 9435 | */ | 
|  | 9436 | if ((type->baseType != anyType) && | 
|  | 9437 | (type->attributeWildcard->processContents < | 
|  | 9438 | baseType->attributeWildcard->processContents)) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9439 | xmlSchemaPCustomErr(ctxt, | 
|  | 9440 | XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, | 
|  | 9441 | NULL, type, NULL, | 
|  | 9442 | "The 'process contents' of the attribute wildcard is weaker than " | 
|  | 9443 | "the one in the base type %s", | 
|  | 9444 | xmlSchemaFormatItemForReport(&str, NULL, baseType, NULL, 1)); | 
|  | 9445 | FREE_AND_NULL(str) | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 9446 | return (1); | 
|  | 9447 | } | 
|  | 9448 | } | 
|  | 9449 | } else if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) { | 
|  | 9450 | /* | 
|  | 9451 | * Derivation Valid (Extension) | 
|  | 9452 | * At this point the type and the base have both, either | 
|  | 9453 | * no wildcard or a wildcard. | 
|  | 9454 | */ | 
|  | 9455 | if ((baseType->attributeWildcard != NULL) && | 
|  | 9456 | (baseType->attributeWildcard != type->attributeWildcard)) { | 
|  | 9457 | /* 1.3 */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9458 | if (xmlSchemaIsWildcardNsConstraintSubset( | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 9459 | baseType->attributeWildcard, type->attributeWildcard) == 0) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9460 | xmlSchemaPCustomErr(ctxt, | 
|  | 9461 | XML_SCHEMAP_COS_CT_EXTENDS_1_3, | 
|  | 9462 | NULL, type, NULL, | 
|  | 9463 | "The attribute wildcard is not a valid " | 
|  | 9464 | "superset of the one in the base type %s", | 
|  | 9465 | xmlSchemaFormatItemForReport(&str, NULL, baseType, NULL, 1)); | 
|  | 9466 | FREE_AND_NULL(str) | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 9467 | return (1); | 
|  | 9468 | } | 
|  | 9469 | } | 
|  | 9470 | } | 
|  | 9471 |  | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9472 | /* | 
|  | 9473 | * Gather attribute uses defined by this type. | 
|  | 9474 | */ | 
|  | 9475 | if (attrs != NULL) { | 
|  | 9476 | if (xmlSchemaBuildAttributeUsesOwned(ctxt, attrs, | 
|  | 9477 | &uses, &lastUse) == -1) { | 
|  | 9478 | return (-1); | 
|  | 9479 | } | 
|  | 9480 | } | 
|  | 9481 | /* 3.4.6 -> Complex Type Definition Properties Correct 4. | 
|  | 9482 | * "Two distinct attribute declarations in the {attribute uses} must | 
|  | 9483 | * not have identical {name}s and {target namespace}s." | 
|  | 9484 | * | 
|  | 9485 | * For "extension" this is done further down. | 
|  | 9486 | */ | 
|  | 9487 | if ((uses != NULL) && ((type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) == 0)) { | 
|  | 9488 | cur = uses; | 
|  | 9489 | while (cur != NULL) { | 
|  | 9490 | tmp = cur->next; | 
|  | 9491 | while (tmp != NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9492 | if ((xmlStrEqual(xmlSchemaGetAttrName(cur->attr), | 
|  | 9493 | xmlSchemaGetAttrName(tmp->attr))) && | 
|  | 9494 | (xmlStrEqual(xmlSchemaGetAttrTargetNsURI(cur->attr ), | 
|  | 9495 | xmlSchemaGetAttrTargetNsURI(tmp->attr)))) { | 
|  | 9496 |  | 
|  | 9497 | xmlSchemaPAttrUseErr(ctxt, | 
|  | 9498 | XML_SCHEMAP_CT_PROPS_CORRECT_4, | 
|  | 9499 | NULL, type, NULL, cur->attr, | 
|  | 9500 | "Duplicate attribute use %s specified", | 
|  | 9501 | xmlSchemaFormatNsUriLocal(&str, | 
|  | 9502 | xmlSchemaGetAttrTargetNsURI(tmp->attr), | 
|  | 9503 | xmlSchemaGetAttrName(tmp->attr)) | 
|  | 9504 | ); | 
|  | 9505 | FREE_AND_NULL(str) | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9506 | break; | 
|  | 9507 | } | 
|  | 9508 | tmp = tmp->next; | 
|  | 9509 | } | 
|  | 9510 | cur = cur->next; | 
|  | 9511 | } | 
|  | 9512 | } | 
|  | 9513 | if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) { | 
|  | 9514 | /* | 
|  | 9515 | * Derive by restriction. | 
|  | 9516 | */ | 
|  | 9517 | if (baseIsAnyType) { | 
|  | 9518 | type->attributeUses = uses; | 
|  | 9519 | } else { | 
|  | 9520 | int found; | 
|  | 9521 |  | 
|  | 9522 | cur = uses; | 
|  | 9523 | while (cur != NULL) { | 
|  | 9524 | found = 0; | 
|  | 9525 | base = type->attributeUses; | 
|  | 9526 | while (base != NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9527 | if (xmlStrEqual(xmlSchemaGetAttrName(cur->attr), | 
|  | 9528 | xmlSchemaGetAttrName(base->attr)) && | 
|  | 9529 | xmlStrEqual(xmlSchemaGetAttrTargetNsURI(cur->attr), | 
|  | 9530 | xmlSchemaGetAttrTargetNsURI(base->attr))) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9531 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9532 | found = 1; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9533 | if ((cur->attr->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && | 
|  | 9534 | (base->attr->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED)) { | 
|  | 9535 | /* | 
|  | 9536 | * derivation-ok-restriction 2.1.1 | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9537 | */ | 
|  | 9538 | xmlSchemaPAttrUseErr(ctxt, | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9539 | XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9540 | NULL, type, NULL, cur->attr, | 
|  | 9541 | "The 'optional' use is inconsistent with a matching " | 
|  | 9542 | "'required' use of the base type", NULL); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9543 | } else if ((cur->attr->occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) && | 
|  | 9544 | (base->attr->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED)) { | 
|  | 9545 | /* | 
|  | 9546 | * derivation-ok-restriction 3 | 
|  | 9547 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9548 | xmlSchemaPCustomErr(ctxt, | 
|  | 9549 | XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3, | 
|  | 9550 | NULL, type, NULL, | 
|  | 9551 | "A matching attribute use for the 'required' " | 
|  | 9552 | "attribute use %s of the base type is missing", | 
|  | 9553 | xmlSchemaFormatNsUriLocal(&str, | 
|  | 9554 | xmlSchemaGetAttrTargetNsURI(base->attr), | 
|  | 9555 | xmlSchemaGetAttrName(base->attr))); | 
|  | 9556 | FREE_AND_NULL(str) | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9557 | } else { | 
|  | 9558 | /* | 
|  | 9559 | * Override the attribute use. | 
|  | 9560 | */ | 
|  | 9561 | base->attr = cur->attr; | 
|  | 9562 | } | 
|  | 9563 | /* | 
|  | 9564 | * TODO: derivation-ok-restriction  2.1.2 ({type definition} must be validly derived) | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9565 | * TODO: derivation-ok-restriction  2.1.3 | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9566 | */ | 
|  | 9567 | break; | 
|  | 9568 | } | 
|  | 9569 | base = base->next; | 
|  | 9570 | } | 
|  | 9571 |  | 
|  | 9572 | if (!found) { | 
|  | 9573 | if (cur->attr->occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) { | 
|  | 9574 | /* | 
|  | 9575 | * derivation-ok-restriction  2.2 | 
|  | 9576 | */ | 
|  | 9577 | if ((type->attributeWildcard != NULL) && | 
|  | 9578 | xmlSchemaMatchesWildcardNs(type->attributeWildcard, | 
|  | 9579 | cur->attr->targetNamespace)) | 
|  | 9580 | found = 1; | 
|  | 9581 |  | 
|  | 9582 | if (!found) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9583 | xmlSchemaPAttrUseErr(ctxt, | 
|  | 9584 | XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2, | 
|  | 9585 | NULL, type, NULL, cur->attr, | 
|  | 9586 | "Neither a matching attribute use, " | 
|  | 9587 | "nor a matching wildcard in the base type does exist", | 
|  | 9588 | NULL); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9589 | } else { | 
|  | 9590 | /* | 
|  | 9591 | * Add the attribute use. | 
|  | 9592 | * | 
|  | 9593 | * Note that this may lead to funny derivation error reports, if | 
|  | 9594 | * multiple equal attribute uses exist; but this is not | 
|  | 9595 | * allowed anyway, and it will be reported beforehand. | 
|  | 9596 | */ | 
|  | 9597 | tmp = cur; | 
|  | 9598 | if (prev != NULL) | 
|  | 9599 | prev->next = cur->next; | 
|  | 9600 | else | 
|  | 9601 | uses = cur->next; | 
|  | 9602 | cur = cur->next; | 
|  | 9603 | if (type->attributeUses == NULL) { | 
|  | 9604 | type->attributeUses = tmp; | 
|  | 9605 | } else | 
|  | 9606 | lastBaseUse->next = tmp; | 
|  | 9607 | lastBaseUse = tmp; | 
|  | 9608 |  | 
|  | 9609 | continue; | 
|  | 9610 | } | 
|  | 9611 | } | 
|  | 9612 | } | 
|  | 9613 | prev = cur; | 
|  | 9614 | cur = cur->next; | 
|  | 9615 | } | 
|  | 9616 | if (uses != NULL) | 
|  | 9617 | xmlSchemaFreeAttributeUseList(uses); | 
|  | 9618 | } | 
|  | 9619 | } else if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) { | 
|  | 9620 | /* | 
|  | 9621 | * The spec allows only appending, and not other kinds of extensions. | 
|  | 9622 | * | 
|  | 9623 | * This ensures: Schema Component Constraint: Derivation Valid (Extension) : 1.2 | 
|  | 9624 | */ | 
|  | 9625 | if (uses != NULL) { | 
|  | 9626 | if (type->attributeUses == NULL) { | 
|  | 9627 | type->attributeUses = uses; | 
|  | 9628 | } else | 
|  | 9629 | lastBaseUse->next = uses; | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9630 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9631 | } else { | 
|  | 9632 | /* | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9633 | * Derive implicitely from the ur-type. | 
|  | 9634 | */ | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9635 | type->attributeUses = uses; | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9636 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9637 | /* | 
|  | 9638 | * 3.4.6 -> Complex Type Definition Properties Correct | 
|  | 9639 | */ | 
|  | 9640 | if (type->attributeUses != NULL) { | 
|  | 9641 | cur = type->attributeUses; | 
|  | 9642 | prev = NULL; | 
|  | 9643 | while (cur != NULL) { | 
|  | 9644 | /* | 
|  | 9645 | * 4. Two distinct attribute declarations in the {attribute uses} must | 
|  | 9646 | * not have identical {name}s and {target namespace}s. | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9647 | * | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9648 | * Note that this was already done for "restriction" and types derived from | 
|  | 9649 | * the ur-type. | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9650 | */ | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9651 | if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) { | 
|  | 9652 | tmp = cur->next; | 
|  | 9653 | while (tmp != NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9654 | if ((xmlStrEqual(xmlSchemaGetAttrName(cur->attr), | 
|  | 9655 | xmlSchemaGetAttrName(tmp->attr))) && | 
|  | 9656 | (xmlStrEqual(xmlSchemaGetAttrTargetNsURI(cur->attr ), | 
|  | 9657 | xmlSchemaGetAttrTargetNsURI(tmp->attr)))) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9658 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9659 | xmlSchemaPAttrUseErr(ctxt, | 
|  | 9660 | XML_SCHEMAP_CT_PROPS_CORRECT_4, | 
|  | 9661 | NULL, type, NULL, tmp->attr, | 
|  | 9662 | "Duplicate attribute use specified", NULL); | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9663 | break; | 
|  | 9664 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9665 | tmp = tmp->next; | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9666 | } | 
|  | 9667 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9668 | /* | 
|  | 9669 | * 5. Two distinct attribute declarations in the {attribute uses} must | 
|  | 9670 | * not have {type definition}s which are or are derived from ID. | 
|  | 9671 | */ | 
|  | 9672 | if ((cur->attr->subtypes != NULL) && | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9673 | (xmlSchemaIsDerivedFromBuiltInType(ctxt, (xmlSchemaTypePtr) cur->attr, XML_SCHEMAS_ID))) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9674 | if (id != NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9675 | xmlSchemaPAttrUseErr(ctxt, | 
|  | 9676 | XML_SCHEMAP_CT_PROPS_CORRECT_5, | 
|  | 9677 | NULL, type, NULL, cur->attr, | 
|  | 9678 | "There must not exist more than one attribute use, " | 
|  | 9679 | "declared of type 'ID' or derived from it", | 
|  | 9680 | NULL); | 
|  | 9681 | FREE_AND_NULL(str) | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9682 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9683 | id = cur; | 
|  | 9684 | } | 
|  | 9685 | /* | 
|  | 9686 | * Remove "prohibited" attribute uses. The reason this is done at this late | 
|  | 9687 | * stage is to be able to catch dublicate attribute uses. So we had to keep | 
|  | 9688 | * prohibited uses in the list as well. | 
|  | 9689 | */ | 
|  | 9690 | if (cur->attr->occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) { | 
|  | 9691 | tmp = cur; | 
|  | 9692 | if (prev == NULL) | 
|  | 9693 | type->attributeUses = cur->next; | 
|  | 9694 | else | 
|  | 9695 | prev->next = cur->next; | 
|  | 9696 | cur = cur->next; | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 9697 | xmlFree(tmp); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9698 | } else { | 
|  | 9699 | prev = cur; | 
|  | 9700 | cur = cur->next; | 
|  | 9701 | } | 
|  | 9702 | } | 
|  | 9703 | } | 
|  | 9704 | /* | 
|  | 9705 | * TODO: This check should be removed if we are 100% sure of | 
|  | 9706 | * the base type attribute uses already being built. | 
|  | 9707 | */ | 
|  | 9708 | if ((baseType != NULL) && (!baseIsAnyType) && | 
|  | 9709 | (baseType->type == XML_SCHEMA_TYPE_COMPLEX) && | 
|  | 9710 | (baseType->contentType == XML_SCHEMA_CONTENT_UNKNOWN)) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 9711 | xmlSchemaPErr(ctxt, baseType->node, XML_SCHEMAP_INTERNAL, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9712 | "Internal error: xmlSchemaBuildAttributeValidation: " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9713 | "attribute uses not builded on base type '%s'.\n", | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 9714 | baseType->name, NULL); | 
|  | 9715 | } | 
|  | 9716 | return (0); | 
|  | 9717 | } | 
|  | 9718 |  | 
|  | 9719 | /** | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9720 | * xmlSchemaTypeFinalContains: | 
|  | 9721 | * @schema:  the schema | 
|  | 9722 | * @type:  the type definition | 
|  | 9723 | * @final: the final | 
|  | 9724 | * | 
|  | 9725 | * Evaluates if a type definition contains the given "final". | 
|  | 9726 | * This does take "finalDefault" into account as well. | 
|  | 9727 | * | 
|  | 9728 | * Returns 1 if the type does containt the given "final", | 
|  | 9729 | * 0 otherwise. | 
|  | 9730 | */ | 
|  | 9731 | static int | 
|  | 9732 | xmlSchemaTypeFinalContains(xmlSchemaPtr schema, xmlSchemaTypePtr type, int final) | 
|  | 9733 | { | 
|  | 9734 | int tfinal = final, tflags = type->flags; | 
|  | 9735 |  | 
|  | 9736 | if (type == NULL) | 
|  | 9737 | return (0); | 
|  | 9738 | if (type->flags & XML_SCHEMAS_TYPE_FINAL_DEFAULT) { | 
|  | 9739 | switch (final) { | 
|  | 9740 | case XML_SCHEMAS_TYPE_FINAL_RESTRICTION: | 
|  | 9741 | tfinal = XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION; | 
|  | 9742 | break; | 
|  | 9743 | case XML_SCHEMAS_TYPE_FINAL_EXTENSION: | 
|  | 9744 | tfinal = XML_SCHEMAS_FINAL_DEFAULT_EXTENSION; | 
|  | 9745 | break; | 
|  | 9746 | case XML_SCHEMAS_TYPE_FINAL_LIST: | 
|  | 9747 | tfinal = XML_SCHEMAS_FINAL_DEFAULT_LIST; | 
|  | 9748 | break; | 
|  | 9749 | case XML_SCHEMAS_TYPE_FINAL_UNION: | 
|  | 9750 | tfinal = XML_SCHEMAS_FINAL_DEFAULT_UNION; | 
|  | 9751 | break; | 
|  | 9752 | } | 
|  | 9753 | tflags = schema->flags; | 
|  | 9754 | } | 
|  | 9755 | if (tflags & tfinal) | 
|  | 9756 | return (1); | 
|  | 9757 | else | 
|  | 9758 | return (0); | 
|  | 9759 |  | 
|  | 9760 | } | 
|  | 9761 |  | 
|  | 9762 | /** | 
|  | 9763 | * xmlSchemaGetUnionSimpleTypeMemberTypes: | 
|  | 9764 | * @type:  the Union Simple Type | 
|  | 9765 | * | 
|  | 9766 | * Returns a list of member types of @type if existing, | 
|  | 9767 | * returns NULL otherwise. | 
|  | 9768 | */ | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 9769 | static xmlSchemaTypeLinkPtr | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9770 | xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type) | 
|  | 9771 | { | 
|  | 9772 | while (type != NULL) { | 
|  | 9773 | if (type->memberTypes != NULL) | 
|  | 9774 | return (type->memberTypes); | 
|  | 9775 | else | 
|  | 9776 | type = type->baseType; | 
|  | 9777 | } | 
|  | 9778 | return (NULL); | 
|  | 9779 | } | 
|  | 9780 |  | 
|  | 9781 | /** | 
|  | 9782 | * xmlSchemaGetListSimpleTypeItemType: | 
|  | 9783 | * @type:  the simple type definition | 
|  | 9784 | * | 
|  | 9785 | * Returns the item type definition of the list simple type. | 
|  | 9786 | */ | 
|  | 9787 | static xmlSchemaTypePtr | 
|  | 9788 | xmlSchemaGetListSimpleTypeItemType(xmlSchemaTypePtr type) | 
|  | 9789 | { | 
|  | 9790 | if ((type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) == 0) | 
|  | 9791 | return (NULL); | 
|  | 9792 | /* | 
|  | 9793 | * Note: In libxml2, the built-in types do not reflect | 
|  | 9794 | * the datatype hierarchy (yet?) - we have to treat them | 
|  | 9795 | * in a special way. | 
|  | 9796 | */ | 
|  | 9797 | if (type->type == XML_SCHEMA_TYPE_BASIC) | 
|  | 9798 | return (xmlSchemaGetBuiltInListSimpleTypeItemType(type)); | 
|  | 9799 | if (type->subtypes->type == XML_SCHEMA_TYPE_LIST) | 
|  | 9800 | /* 1 If the <list> alternative is chosen, then the type | 
|  | 9801 | * definition ·resolved· to by the ·actual value· of the | 
|  | 9802 | * itemType [attribute] of <list>, if present, otherwise | 
|  | 9803 | * the type definition corresponding to the <simpleType> | 
|  | 9804 | * among the [children] of <list>. | 
|  | 9805 | */ | 
|  | 9806 | return (type->subtypes->subtypes); | 
|  | 9807 | else { | 
|  | 9808 | /* 2 If the <restriction> option is chosen, then the | 
|  | 9809 | * {item type definition} of the {base type definition}. | 
|  | 9810 | */ | 
|  | 9811 | return (xmlSchemaGetListSimpleTypeItemType(type->baseType)); | 
|  | 9812 | } | 
|  | 9813 | } | 
|  | 9814 |  | 
|  | 9815 | /** | 
|  | 9816 | * xmlSchemaCheckCOSSTDerivedOK: | 
|  | 9817 | * @type:  the derived simple type definition | 
|  | 9818 | * @baseType:  the base type definition | 
|  | 9819 | * | 
|  | 9820 | * Checks wheter @type can be validly | 
|  | 9821 | * derived from @baseType. | 
|  | 9822 | * | 
|  | 9823 | * Returns 0 on success, an positive error code otherwise. | 
|  | 9824 | */ | 
|  | 9825 | static int | 
|  | 9826 | xmlSchemaCheckCOSSTDerivedOK(xmlSchemaPtr schema, | 
|  | 9827 | xmlSchemaTypePtr type, | 
|  | 9828 | xmlSchemaTypePtr baseType, | 
|  | 9829 | int subset) | 
|  | 9830 | { | 
|  | 9831 | /* | 
|  | 9832 | * Schema Component Constraint: Type Derivation OK (Simple) | 
|  | 9833 | * | 
|  | 9834 | * | 
|  | 9835 | * 1 They are the same type definition. | 
|  | 9836 | * TODO: The identy check might have to be more complex than this. | 
|  | 9837 | */ | 
|  | 9838 | if (type == baseType) | 
|  | 9839 | return (0); | 
|  | 9840 | /* | 
|  | 9841 | * 2.1 restriction is not in the subset, or in the {final} | 
|  | 9842 | * of its own {base type definition}; | 
|  | 9843 | */ | 
|  | 9844 | if ((subset & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) || | 
|  | 9845 | (xmlSchemaTypeFinalContains(schema, | 
|  | 9846 | type->baseType, XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) { | 
|  | 9847 | return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1); | 
|  | 9848 | } | 
|  | 9849 | /* 2.2 */ | 
|  | 9850 | if (type->baseType == baseType) { | 
|  | 9851 | /* | 
|  | 9852 | * 2.2.1 D's ·base type definition· is B. | 
|  | 9853 | */ | 
|  | 9854 | return (0); | 
|  | 9855 | } | 
|  | 9856 | /* | 
|  | 9857 | * 2.2.2 D's ·base type definition· is not the ·ur-type definition· | 
|  | 9858 | * and is validly derived from B given the subset, as defined by this | 
|  | 9859 | * constraint. | 
|  | 9860 | */ | 
|  | 9861 | if ((type->baseType != xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE)) && | 
|  | 9862 | (xmlSchemaCheckCOSSTDerivedOK(schema, type->baseType, baseType, subset) == 0)) { | 
|  | 9863 | return (0); | 
|  | 9864 | } | 
|  | 9865 | /* | 
|  | 9866 | * 2.2.3 D's {variety} is list or union and B is the ·simple ur-type | 
|  | 9867 | * definition·. | 
|  | 9868 | */ | 
|  | 9869 | if (((type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) || | 
|  | 9870 | (type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)) && | 
|  | 9871 | (baseType == xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE))) { | 
|  | 9872 | return (0); | 
|  | 9873 | } | 
|  | 9874 | /* | 
|  | 9875 | * 2.2.4 B's {variety} is union and D is validly derived from a type | 
|  | 9876 | * definition in B's {member type definitions} given the subset, as | 
|  | 9877 | * defined by this constraint. | 
|  | 9878 | * | 
|  | 9879 | * NOTE: This seems not to involve built-in types, since there is no | 
|  | 9880 | * built-in Union Simple Type. | 
|  | 9881 | */ | 
|  | 9882 | if (baseType->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) { | 
|  | 9883 | xmlSchemaTypeLinkPtr cur; | 
|  | 9884 |  | 
|  | 9885 | cur = baseType->memberTypes; | 
|  | 9886 | while (cur != NULL) { | 
|  | 9887 | if (xmlSchemaCheckCOSSTDerivedOK(schema, type, | 
|  | 9888 | cur->type, subset) == 0) | 
|  | 9889 | return (0); | 
|  | 9890 | cur = cur->next; | 
|  | 9891 | } | 
|  | 9892 | } | 
|  | 9893 |  | 
|  | 9894 | return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2); | 
|  | 9895 | } | 
|  | 9896 |  | 
|  | 9897 |  | 
|  | 9898 | /** | 
|  | 9899 | * xmlSchemaCheckSTPropsCorrect: | 
|  | 9900 | * @ctxt:  the schema parser context | 
|  | 9901 | * @type:  the simple type definition | 
|  | 9902 | * | 
|  | 9903 | * Checks st-props-correct. | 
|  | 9904 | * | 
|  | 9905 | * Returns 0 if the properties are correct, | 
|  | 9906 | * if not, a positive error code and -1 on internal | 
|  | 9907 | * errors. | 
|  | 9908 | */ | 
|  | 9909 | static int | 
|  | 9910 | xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt, | 
|  | 9911 | xmlSchemaTypePtr type) | 
|  | 9912 | { | 
|  | 9913 | xmlSchemaTypePtr baseType = type->baseType, anySimpleType, | 
|  | 9914 | anyType; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9915 | xmlChar *str = NULL; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9916 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9917 | /* STATE: error funcs converted. */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9918 | /* | 
|  | 9919 | * Schema Component Constraint: Simple Type Definition Properties Correct | 
|  | 9920 | * | 
|  | 9921 | * NOTE: This is somehow redundant, since we actually built a simple type | 
|  | 9922 | * to have all the needed information; this acts as an self test. | 
|  | 9923 | */ | 
|  | 9924 | anySimpleType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); | 
|  | 9925 | anyType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); | 
|  | 9926 | /* | 
|  | 9927 | * TODO: 1 The values of the properties of a simple type definition must be as | 
|  | 9928 | * described in the property tableau in Datatype definition, modulo the | 
|  | 9929 | * impact of Missing Sub-components (§5.3). | 
|  | 9930 | */ | 
|  | 9931 | /* Base type: If the datatype has been ·derived· by ·restriction· | 
|  | 9932 | * then the Simple Type Definition component from which it is ·derived·, | 
|  | 9933 | * otherwise the Simple Type Definition for anySimpleType (§4.1.6). | 
|  | 9934 | */ | 
|  | 9935 | if (baseType == NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9936 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9937 | XML_SCHEMAP_ST_PROPS_CORRECT_1, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9938 | NULL, type, NULL, | 
|  | 9939 | "No base type existent", NULL); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9940 | return (XML_SCHEMAP_ST_PROPS_CORRECT_1); | 
|  | 9941 | } | 
|  | 9942 | if ((baseType->type != XML_SCHEMA_TYPE_SIMPLE) && | 
|  | 9943 | ((baseType->type != XML_SCHEMA_TYPE_BASIC) || | 
|  | 9944 | (baseType == anyType))) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9945 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9946 | XML_SCHEMAP_ST_PROPS_CORRECT_1, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9947 | NULL, type, NULL, | 
|  | 9948 | "The base type %s is not a simple type", | 
|  | 9949 | xmlSchemaFormatItemForReport(&str, NULL, baseType, NULL, 1)); | 
|  | 9950 | FREE_AND_NULL(str) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9951 | return (XML_SCHEMAP_ST_PROPS_CORRECT_1); | 
|  | 9952 | } | 
|  | 9953 | if ((baseType != anySimpleType) && | 
|  | 9954 | (type->subtypes->type != XML_SCHEMA_TYPE_RESTRICTION)) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9955 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9956 | XML_SCHEMAP_ST_PROPS_CORRECT_1, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9957 | NULL, type, NULL, | 
|  | 9958 | "A type, derived by list or union, must have" | 
|  | 9959 | "the simple ur-type definition as base type, not %s", | 
|  | 9960 | xmlSchemaFormatItemForReport(&str, NULL, baseType, NULL, 1)); | 
|  | 9961 | FREE_AND_NULL(str) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9962 | return (XML_SCHEMAP_ST_PROPS_CORRECT_1); | 
|  | 9963 | } | 
|  | 9964 | /* | 
|  | 9965 | * Variety: One of {atomic, list, union}. | 
|  | 9966 | */ | 
|  | 9967 | if (((type->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) == 0) && | 
|  | 9968 | ((type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) == 0) && | 
|  | 9969 | ((type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) == 0)) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9970 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9971 | XML_SCHEMAP_ST_PROPS_CORRECT_1, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9972 | NULL, type, NULL, | 
|  | 9973 | "The variety is absent", NULL); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9974 | return (XML_SCHEMAP_ST_PROPS_CORRECT_1); | 
|  | 9975 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9976 | /* TODO: Finish this. Hmm, is this finished? */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9977 |  | 
|  | 9978 | /* | 
|  | 9979 | * 2 All simple type definitions must be derived ultimately from the ·simple | 
|  | 9980 | * ur-type definition (so· circular definitions are disallowed). That is, it | 
|  | 9981 | * must be possible to reach a built-in primitive datatype or the ·simple | 
|  | 9982 | * ur-type definition· by repeatedly following the {base type definition}. | 
|  | 9983 | */ | 
|  | 9984 | baseType = type->baseType; | 
|  | 9985 | while ((baseType != NULL) && (baseType->type != XML_SCHEMA_TYPE_BASIC)) { | 
|  | 9986 | if (baseType->contentType == XML_SCHEMA_CONTENT_UNKNOWN) | 
|  | 9987 | xmlSchemaTypeFixup(baseType, ctxt,  NULL); | 
|  | 9988 | if (baseType == anySimpleType) | 
|  | 9989 | break; | 
|  | 9990 | else if (baseType == type) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 9991 | xmlSchemaPCustomErr(ctxt, | 
|  | 9992 | XML_SCHEMAP_ST_PROPS_CORRECT_2, | 
|  | 9993 | NULL, type, NULL, | 
|  | 9994 | "The definition is circular", NULL); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 9995 | return (XML_SCHEMAP_ST_PROPS_CORRECT_2); | 
|  | 9996 | } | 
|  | 9997 | baseType = baseType->baseType; | 
|  | 9998 | } | 
|  | 9999 | /* | 
|  | 10000 | * 3 The {final} of the {base type definition} must not contain restriction. | 
|  | 10001 | */ | 
|  | 10002 | if (xmlSchemaTypeFinalContains(ctxt->schema, baseType, | 
|  | 10003 | XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10004 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10005 | XML_SCHEMAP_ST_PROPS_CORRECT_3, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10006 | NULL, type, NULL, | 
|  | 10007 | "The 'final' of its base type %s must not contain " | 
|  | 10008 | "'restriction'", | 
|  | 10009 | xmlSchemaFormatItemForReport(&str, NULL, baseType, NULL, 1)); | 
|  | 10010 | FREE_AND_NULL(str) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10011 | return (XML_SCHEMAP_ST_PROPS_CORRECT_3); | 
|  | 10012 | } | 
|  | 10013 | return (0); | 
|  | 10014 | } | 
|  | 10015 |  | 
|  | 10016 | /** | 
|  | 10017 | * xmlSchemaCheckDerivationValidSimpleRestriction: | 
|  | 10018 | * @ctxt:  the schema parser context | 
|  | 10019 | * @type:  the simple type definition | 
|  | 10020 | * | 
|  | 10021 | * Checks if the given @type (simpleType) is derived | 
|  | 10022 | * validly by restriction. | 
|  | 10023 | * | 
|  | 10024 | * Returns -1 on internal errors, 0 if the type is validly derived, | 
|  | 10025 | * a positive error code otherwise. | 
|  | 10026 | */ | 
|  | 10027 | static int | 
|  | 10028 | xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr ctxt, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10029 | xmlSchemaTypePtr type) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10030 | { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10031 | xmlChar *str = NULL; | 
|  | 10032 |  | 
|  | 10033 | /* STATE: error funcs converted. */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10034 |  | 
|  | 10035 | if (type->type != XML_SCHEMA_TYPE_SIMPLE) { | 
|  | 10036 | xmlSchemaPErr(ctxt, type->node, | 
|  | 10037 | XML_ERR_INTERNAL_ERROR, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10038 | "xmlSchemaCheckDerivationValidSimpleRestriction: The given " | 
|  | 10039 | "type '%s' is not a user-derived simpleType.\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10040 | type->name, NULL); | 
|  | 10041 | return (-1); | 
|  | 10042 | } | 
|  | 10043 |  | 
|  | 10044 | if (type->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) { | 
|  | 10045 | xmlSchemaTypePtr primitive; | 
|  | 10046 | /* | 
|  | 10047 | * 1.1 The {base type definition} must be an atomic simple | 
|  | 10048 | * type definition or a built-in primitive datatype. | 
|  | 10049 | */ | 
|  | 10050 | if ((type->baseType->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) == 0) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10051 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10052 | XML_SCHEMAP_COS_ST_RESTRICTS_1_1, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10053 | NULL, type, NULL, | 
|  | 10054 | "The base type %s is not an atomic simple type", | 
|  | 10055 | xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1)); | 
|  | 10056 | FREE_AND_NULL(str) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10057 | return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1); | 
|  | 10058 | } | 
|  | 10059 | /* 1.2 The {final} of the {base type definition} must not contain | 
|  | 10060 | * restriction. | 
|  | 10061 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10062 | /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10063 | if (xmlSchemaTypeFinalContains(ctxt->schema, type->baseType, | 
|  | 10064 | XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10065 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10066 | XML_SCHEMAP_COS_ST_RESTRICTS_1_2, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10067 | NULL, type, NULL, | 
|  | 10068 | "The final of its base type %s must not contain 'restriction'", | 
|  | 10069 | xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1)); | 
|  | 10070 | FREE_AND_NULL(str) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10071 | return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2); | 
|  | 10072 | } | 
|  | 10073 |  | 
|  | 10074 | /* | 
|  | 10075 | * 1.3.1 DF must be an allowed constraining facet for the {primitive | 
|  | 10076 | * type definition}, as specified in the appropriate subsection of 3.2 | 
|  | 10077 | * Primitive datatypes. | 
|  | 10078 | */ | 
|  | 10079 | if (type->facets != NULL) { | 
|  | 10080 | xmlSchemaFacetPtr facet; | 
|  | 10081 | int ok = 1; | 
|  | 10082 |  | 
|  | 10083 | primitive = xmlSchemaGetPrimitiveType(type); | 
|  | 10084 | if (primitive == NULL) { | 
|  | 10085 | xmlSchemaPErr(ctxt, type->node, | 
|  | 10086 | XML_ERR_INTERNAL_ERROR, | 
|  | 10087 | "xmlSchemaCheckDerivationValidSimpleRestriction: failed " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10088 | "to get primitive type of type '%s'.\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10089 | type->name, NULL); | 
|  | 10090 | return (-1); | 
|  | 10091 | } | 
|  | 10092 | facet = type->facets; | 
|  | 10093 | do { | 
|  | 10094 | if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10095 | ok = 0; | 
|  | 10096 | xmlSchemaPIllegalFacetAtomicErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10097 | XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10098 | NULL, type, primitive, facet); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10099 | } | 
|  | 10100 | facet = facet->next; | 
|  | 10101 | } while (facet != NULL); | 
|  | 10102 | if (ok == 0) | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10103 | return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10104 | } | 
|  | 10105 | /* | 
|  | 10106 | * TODO: 1.3.2 (facet derivation) | 
|  | 10107 | */ | 
|  | 10108 | } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) { | 
|  | 10109 | xmlSchemaTypePtr itemType = NULL; | 
|  | 10110 |  | 
|  | 10111 | itemType = xmlSchemaGetListSimpleTypeItemType(type); | 
|  | 10112 | if (itemType == NULL) { | 
|  | 10113 | xmlSchemaPErr(ctxt, type->node, | 
|  | 10114 | XML_ERR_INTERNAL_ERROR, | 
|  | 10115 | "Internal error: xmlSchemaCheckDerivationValidSimpleRestriction: " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10116 | "failed to evaluate the item type of type '%s'.\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10117 | type->name, NULL); | 
|  | 10118 | return (-1); | 
|  | 10119 | } | 
|  | 10120 | /* | 
|  | 10121 | * 2.1 The {item type definition} must have a {variety} of atomic or | 
|  | 10122 | * union (in which case all the {member type definitions} | 
|  | 10123 | * must be atomic). | 
|  | 10124 | */ | 
|  | 10125 | if (((itemType->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) == 0) && | 
|  | 10126 | ((itemType->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) == 0)) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10127 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10128 | XML_SCHEMAP_COS_ST_RESTRICTS_2_1, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10129 | NULL, type, NULL, | 
|  | 10130 | "The item type %s must have a variety of atomic or union", | 
|  | 10131 | xmlSchemaFormatItemForReport(&str, NULL, itemType, NULL, 1)); | 
|  | 10132 | FREE_AND_NULL(str) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10133 | return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); | 
|  | 10134 | } else if (itemType->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) { | 
|  | 10135 | xmlSchemaTypeLinkPtr member; | 
|  | 10136 |  | 
|  | 10137 | member = itemType->memberTypes; | 
|  | 10138 | while (member != NULL) { | 
|  | 10139 | if ((member->type->flags & | 
|  | 10140 | XML_SCHEMAS_TYPE_VARIETY_ATOMIC) == 0) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10141 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10142 | XML_SCHEMAP_COS_ST_RESTRICTS_2_1, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10143 | NULL, type, NULL, | 
|  | 10144 | "The item type is a union type, but the " | 
|  | 10145 | "member type %s of this item type is not atomic", | 
|  | 10146 | xmlSchemaFormatItemForReport(&str, NULL, member->type, NULL, 1)); | 
|  | 10147 | FREE_AND_NULL(str) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10148 | return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); | 
|  | 10149 | } | 
|  | 10150 | member = member->next; | 
|  | 10151 | } | 
|  | 10152 | } | 
|  | 10153 |  | 
|  | 10154 | if (type->baseType == xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE)) { | 
|  | 10155 | xmlSchemaFacetPtr facet; | 
|  | 10156 | /* | 
|  | 10157 | * This is the case if we have: <simpleType><list .. | 
|  | 10158 | */ | 
|  | 10159 | /* | 
|  | 10160 | * 2.3.1 | 
|  | 10161 | * 2.3.1.1 The {final} of the {item type definition} must not | 
|  | 10162 | * contain list. | 
|  | 10163 | */ | 
|  | 10164 | if (xmlSchemaTypeFinalContains(ctxt->schema, | 
|  | 10165 | itemType, XML_SCHEMAS_TYPE_FINAL_LIST)) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10166 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10167 | XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10168 | NULL, type, NULL, | 
|  | 10169 | "The final of its item type %s must not contain 'list'", | 
|  | 10170 | xmlSchemaFormatItemForReport(&str, NULL, itemType, NULL, 1)); | 
|  | 10171 | FREE_AND_NULL(str) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10172 | return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1); | 
|  | 10173 | } | 
|  | 10174 | /* | 
|  | 10175 | * 2.3.1.2 The {facets} must only contain the whiteSpace | 
|  | 10176 | * facet component. | 
|  | 10177 | */ | 
|  | 10178 | if (type->facets != NULL) { | 
|  | 10179 | facet = type->facets; | 
|  | 10180 | do { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10181 | if (facet->type != XML_SCHEMA_FACET_WHITESPACE) { | 
|  | 10182 | xmlSchemaPIllegalFacetListUnionErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10183 | XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10184 | NULL, type, facet); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10185 | return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2); | 
|  | 10186 | } | 
|  | 10187 | facet = facet->next; | 
|  | 10188 | } while (facet != NULL); | 
|  | 10189 | } | 
|  | 10190 | /* | 
|  | 10191 | * TODO: Datatypes states: | 
|  | 10192 | * A ·list· datatype can be ·derived· from an ·atomic· datatype | 
|  | 10193 | * whose ·lexical space· allows space (such as string or anyURI)or | 
|  | 10194 | * a ·union· datatype any of whose {member type definitions}'s | 
|  | 10195 | * ·lexical space· allows space. | 
|  | 10196 | */ | 
|  | 10197 | } else { | 
|  | 10198 | /* | 
|  | 10199 | * This is the case if we have: <simpleType><restriction ... | 
|  | 10200 | */ | 
|  | 10201 | /* | 
|  | 10202 | * 2.3.2 | 
|  | 10203 | * 2.3.2.1 The {base type definition} must have a {variety} of list. | 
|  | 10204 | */ | 
|  | 10205 | if ((type->baseType->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) == 0) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10206 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10207 | XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10208 | NULL, type, NULL, | 
|  | 10209 | "The base type %s must be a list type", | 
|  | 10210 | xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1)); | 
|  | 10211 | FREE_AND_NULL(str) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10212 | return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1); | 
|  | 10213 | } | 
|  | 10214 | /* | 
|  | 10215 | * 2.3.2.2 The {final} of the {base type definition} must not | 
|  | 10216 | * contain restriction. | 
|  | 10217 | */ | 
|  | 10218 | if (xmlSchemaTypeFinalContains(ctxt->schema, type->baseType, | 
|  | 10219 | XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10220 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10221 | XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10222 | NULL, type, NULL, | 
|  | 10223 | "The final of the base type %s must not contain 'restriction'", | 
|  | 10224 | xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1)); | 
|  | 10225 | FREE_AND_NULL(str) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10226 | return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2); | 
|  | 10227 | } | 
|  | 10228 | /* | 
|  | 10229 | * 2.3.2.3 The {item type definition} must be validly derived | 
|  | 10230 | * from the {base type definition}'s {item type definition} given | 
|  | 10231 | * the empty set, as defined in Type Derivation OK (Simple) (§3.14.6). | 
|  | 10232 | */ | 
|  | 10233 | { | 
|  | 10234 | xmlSchemaTypePtr baseItemType; | 
|  | 10235 |  | 
|  | 10236 | baseItemType = xmlSchemaGetListSimpleTypeItemType(type->baseType); | 
|  | 10237 | if (baseItemType == NULL) { | 
|  | 10238 | xmlSchemaPErr(ctxt, type->node, | 
|  | 10239 | XML_ERR_INTERNAL_ERROR, | 
|  | 10240 | "xmlSchemaCheckDerivationValidSimpleRestriction: " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10241 | "List simple type '%s': Failed to " | 
|  | 10242 | "evaluate the item type of its base type '%s'.\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10243 | type->name, type->baseType->name); | 
|  | 10244 | return (-1); | 
|  | 10245 | } | 
|  | 10246 | if ((itemType != baseItemType) && | 
|  | 10247 | (xmlSchemaCheckCOSSTDerivedOK(ctxt->schema, itemType, | 
|  | 10248 | baseItemType, 0) != 0)) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10249 | xmlChar *strBIT = NULL, *strBT = NULL; | 
|  | 10250 | xmlSchemaPCustomErrExt(ctxt, | 
|  | 10251 | XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, | 
|  | 10252 | NULL, type, NULL, | 
|  | 10253 | "The item type %s is not validly derived from the " | 
|  | 10254 | "item type %s of the base type %s", | 
|  | 10255 | xmlSchemaFormatItemForReport(&str, NULL, itemType, NULL, 1), | 
|  | 10256 | xmlSchemaFormatItemForReport(&strBIT, NULL, baseItemType, NULL, 1), | 
|  | 10257 | xmlSchemaFormatItemForReport(&strBT, NULL, type->baseType, NULL, 1)); | 
|  | 10258 |  | 
|  | 10259 | FREE_AND_NULL(str) | 
|  | 10260 | FREE_AND_NULL(strBIT) | 
|  | 10261 | FREE_AND_NULL(strBT) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10262 | return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3); | 
|  | 10263 | } | 
|  | 10264 | } | 
|  | 10265 |  | 
|  | 10266 | if (type->facets != NULL) { | 
|  | 10267 | xmlSchemaFacetPtr facet; | 
|  | 10268 | int ok = 1; | 
|  | 10269 | /* | 
|  | 10270 | * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern | 
|  | 10271 | * and enumeration facet components are allowed among the {facets}. | 
|  | 10272 | */ | 
|  | 10273 | facet = type->facets; | 
|  | 10274 | do { | 
|  | 10275 | switch (facet->type) { | 
|  | 10276 | case XML_SCHEMA_FACET_LENGTH: | 
|  | 10277 | case XML_SCHEMA_FACET_MINLENGTH: | 
|  | 10278 | case XML_SCHEMA_FACET_MAXLENGTH: | 
|  | 10279 | case XML_SCHEMA_FACET_WHITESPACE: | 
|  | 10280 | /* | 
|  | 10281 | * TODO: 2.5.1.2 List datatypes | 
|  | 10282 | * The value of ·whiteSpace· is fixed to the value collapse. | 
|  | 10283 | */ | 
|  | 10284 | case XML_SCHEMA_FACET_PATTERN: | 
|  | 10285 | case XML_SCHEMA_FACET_ENUMERATION: | 
|  | 10286 | break; | 
|  | 10287 | default: { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10288 | xmlSchemaPIllegalFacetListUnionErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10289 | XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10290 | NULL, type, facet); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10291 | /* | 
|  | 10292 | * We could return, but it's nicer to report all | 
|  | 10293 | * invalid facets. | 
|  | 10294 | */ | 
|  | 10295 | ok = 0; | 
|  | 10296 | } | 
|  | 10297 | } | 
|  | 10298 | facet = facet->next; | 
|  | 10299 | } while (facet != NULL); | 
|  | 10300 | if (ok == 0) | 
|  | 10301 | return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4); | 
|  | 10302 | /* | 
|  | 10303 | * TODO: 2.3.2.5 For each facet in the {facets} (call this DF), if there | 
|  | 10304 | * is a facet of the same kind in the {facets} of the {base type | 
|  | 10305 | * definition} (call this BF),then the DF's {value} must be a valid | 
|  | 10306 | * restriction of BF's {value} as defined in [XML Schemas: Datatypes]. | 
|  | 10307 | */ | 
|  | 10308 | } | 
|  | 10309 |  | 
|  | 10310 |  | 
|  | 10311 | } | 
|  | 10312 | } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) { | 
|  | 10313 | /* | 
|  | 10314 | * 3.1 The {member type definitions} must all have {variety} of | 
|  | 10315 | * atomic or list. | 
|  | 10316 | */ | 
|  | 10317 | xmlSchemaTypeLinkPtr member; | 
|  | 10318 |  | 
|  | 10319 | member = type->memberTypes; | 
|  | 10320 | while (member != NULL) { | 
|  | 10321 | if (((member->type->flags & | 
|  | 10322 | XML_SCHEMAS_TYPE_VARIETY_ATOMIC) == 0) && | 
|  | 10323 | ((member->type->flags & | 
|  | 10324 | XML_SCHEMAS_TYPE_VARIETY_LIST) == 0)) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10325 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10326 | XML_SCHEMAP_COS_ST_RESTRICTS_3_1, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10327 | NULL, type, NULL, | 
|  | 10328 | "The member type %s is neither an atomic, nor a list type", | 
|  | 10329 | xmlSchemaFormatItemForReport(&str, NULL, member->type, NULL, 1)); | 
|  | 10330 | FREE_AND_NULL(str) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10331 | return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1); | 
|  | 10332 | } | 
|  | 10333 | member = member->next; | 
|  | 10334 | } | 
|  | 10335 | /* | 
|  | 10336 | * 3.3.1 If the {base type definition} is the ·simple ur-type | 
|  | 10337 | * definition· | 
|  | 10338 | */ | 
|  | 10339 | if (type->baseType == xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE)) { | 
|  | 10340 | /* | 
|  | 10341 | * 3.3.1.1 All of the {member type definitions} must have a | 
|  | 10342 | * {final} which does not contain union. | 
|  | 10343 | */ | 
|  | 10344 | member = type->memberTypes; | 
|  | 10345 | while (member != NULL) { | 
|  | 10346 | if (xmlSchemaTypeFinalContains(ctxt->schema, member->type, | 
|  | 10347 | XML_SCHEMAS_TYPE_FINAL_UNION)) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10348 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10349 | XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10350 | NULL, type, NULL, | 
|  | 10351 | "The final of member type %s contains 'union'", | 
|  | 10352 | xmlSchemaFormatItemForReport(&str, NULL, member->type, NULL, 1)); | 
|  | 10353 | FREE_AND_NULL(str) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10354 | return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1); | 
|  | 10355 | } | 
|  | 10356 | member = member->next; | 
|  | 10357 | } | 
|  | 10358 | /* | 
|  | 10359 | * 3.3.1.2 The {facets} must be empty. | 
|  | 10360 | */ | 
|  | 10361 | if (type->facetSet != NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10362 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10363 | XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10364 | NULL, type, NULL, | 
|  | 10365 | "No facets allowed", NULL); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10366 | return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2); | 
|  | 10367 | } | 
|  | 10368 | } else { | 
|  | 10369 | /* | 
|  | 10370 | * 3.3.2.1 The {base type definition} must have a {variety} of union. | 
|  | 10371 | */ | 
|  | 10372 | if ((type->baseType->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) == 0) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10373 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10374 | XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10375 | NULL, type, NULL, | 
|  | 10376 | "The base type %s is not a union type", | 
|  | 10377 | xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1)); | 
|  | 10378 | FREE_AND_NULL(str) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10379 | return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1); | 
|  | 10380 | } | 
|  | 10381 | /* | 
|  | 10382 | * 3.3.2.2 The {final} of the {base type definition} must not contain restriction. | 
|  | 10383 | */ | 
|  | 10384 | if (xmlSchemaTypeFinalContains(ctxt->schema, type->baseType, | 
|  | 10385 | XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10386 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10387 | XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10388 | NULL, type, NULL, | 
|  | 10389 | "The final of its base type %s must not contain 'restriction'", | 
|  | 10390 | xmlSchemaFormatItemForReport(&str, NULL, type->baseType, NULL, 1)); | 
|  | 10391 | FREE_AND_NULL(str) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10392 | return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2); | 
|  | 10393 | } | 
|  | 10394 | /* | 
|  | 10395 | * 3.3.2.3 The {member type definitions}, in order, must be validly | 
|  | 10396 | * derived from the corresponding type definitions in the {base | 
|  | 10397 | * type definition}'s {member type definitions} given the empty set, | 
|  | 10398 | * as defined in Type Derivation OK (Simple) (§3.14.6). | 
|  | 10399 | */ | 
|  | 10400 | { | 
|  | 10401 | xmlSchemaTypeLinkPtr baseMember; | 
|  | 10402 |  | 
|  | 10403 | /* | 
|  | 10404 | * OPTIMIZE: if the type is restricting, it has no local defined | 
|  | 10405 | * member types and inherits the member types of the base type; | 
|  | 10406 | * thus a check for equality can be skipped. | 
|  | 10407 | */ | 
|  | 10408 | /* | 
|  | 10409 | * TODO: Even worse: I cannot see a scenario where a restricting | 
|  | 10410 | * union simple type can have other member types as the member | 
|  | 10411 | * types of it's base type. This check seems not necessary with | 
|  | 10412 | * respect to the derivation process in libxml2. | 
|  | 10413 | */ | 
|  | 10414 | if (type->memberTypes != NULL) { | 
|  | 10415 | member = type->memberTypes; | 
|  | 10416 | baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType); | 
|  | 10417 | if ((member == NULL) && (baseMember != NULL)) { | 
|  | 10418 | xmlSchemaPErr(ctxt, type->node, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 10419 | XML_SCHEMAP_INTERNAL, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10420 | "Internal error: " | 
|  | 10421 | "xmlSchemaCheckDerivationValidSimpleRestriction " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10422 | "(3.3.2.3), union simple type '%s', unequal number " | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10423 | "of member types in the base type\n", | 
|  | 10424 | type->name, NULL); | 
|  | 10425 | } | 
|  | 10426 | while (member != NULL) { | 
|  | 10427 | if (baseMember == NULL) { | 
|  | 10428 | xmlSchemaPErr(ctxt, type->node, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 10429 | XML_SCHEMAP_INTERNAL, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10430 | "Internal error: " | 
|  | 10431 | "xmlSchemaCheckDerivationValidSimpleRestriction " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10432 | "(3.3.2.3), union simple type '%s', unequal number " | 
|  | 10433 | "of member types in the base type.\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10434 | type->name, NULL); | 
|  | 10435 | } | 
|  | 10436 | if ((member->type != baseMember->type) && | 
|  | 10437 | (xmlSchemaCheckCOSSTDerivedOK(ctxt->schema, | 
|  | 10438 | member->type, baseMember->type, 0) != 0)) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10439 | xmlChar *strBMT = NULL, *strBT = NULL; | 
|  | 10440 |  | 
|  | 10441 | xmlSchemaPCustomErrExt(ctxt, | 
|  | 10442 | XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, | 
|  | 10443 | NULL, type, NULL, | 
|  | 10444 | "The member type %s is not validly derived from its " | 
|  | 10445 | "corresponding member type %s of the base type %s", | 
|  | 10446 | xmlSchemaFormatItemForReport(&str, NULL, member->type, NULL, 1), | 
|  | 10447 | xmlSchemaFormatItemForReport(&strBMT, NULL, baseMember->type, NULL, 1), | 
|  | 10448 | xmlSchemaFormatItemForReport(&strBT, NULL, type->baseType, NULL, 1)); | 
|  | 10449 | FREE_AND_NULL(str) | 
|  | 10450 | FREE_AND_NULL(strBMT) | 
|  | 10451 | FREE_AND_NULL(strBT) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10452 | return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3); | 
|  | 10453 | } | 
|  | 10454 | member = member->next; | 
|  | 10455 | baseMember = baseMember->next; | 
|  | 10456 | } | 
|  | 10457 | } | 
|  | 10458 | } | 
|  | 10459 | /* | 
|  | 10460 | * 3.3.2.4 Only pattern and enumeration facet components are | 
|  | 10461 | * allowed among the {facets}. | 
|  | 10462 | */ | 
|  | 10463 | if (type->facets != NULL) { | 
|  | 10464 | xmlSchemaFacetPtr facet; | 
|  | 10465 | int ok = 1; | 
|  | 10466 |  | 
|  | 10467 | facet = type->facets; | 
|  | 10468 | do { | 
|  | 10469 | if ((facet->type != XML_SCHEMA_FACET_PATTERN) && | 
|  | 10470 | (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10471 | xmlSchemaPIllegalFacetListUnionErr(ctxt, | 
|  | 10472 | XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4, | 
|  | 10473 | NULL, type, facet); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10474 | ok = 0; | 
|  | 10475 | } | 
|  | 10476 | facet = facet->next; | 
|  | 10477 | } while (facet != NULL); | 
|  | 10478 | if (ok == 0) | 
|  | 10479 | return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4); | 
|  | 10480 |  | 
|  | 10481 | } | 
|  | 10482 | /* | 
|  | 10483 | * TODO: 3.3.2.5 (facet derivation) | 
|  | 10484 | */ | 
|  | 10485 | } | 
|  | 10486 | } | 
|  | 10487 |  | 
|  | 10488 | return (0); | 
|  | 10489 | } | 
|  | 10490 |  | 
|  | 10491 | /** | 
|  | 10492 | * xmlSchemaCheckSRCSimpleType: | 
|  | 10493 | * @ctxt:  the schema parser context | 
|  | 10494 | * @type:  the simple type definition | 
|  | 10495 | * | 
|  | 10496 | * Checks crc-simple-type constraints. | 
|  | 10497 | * | 
|  | 10498 | * Returns 0 if the constraints are satisfied, | 
|  | 10499 | * if not a positive error code and -1 on internal | 
|  | 10500 | * errors. | 
|  | 10501 | */ | 
|  | 10502 | static int | 
|  | 10503 | xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt, | 
|  | 10504 | xmlSchemaTypePtr type) | 
|  | 10505 | { | 
|  | 10506 | /* | 
|  | 10507 | * NOTE: src-simple-type 2-4 are redundant, since the checks | 
|  | 10508 | * were are done for the corresponding <restriction>, <list> and <union> | 
|  | 10509 | * elements, but W3C wants a <simpleType> error as well, so it gets one. | 
|  | 10510 | * Maby this can be skipped in the future, if we get sure it's not needed. | 
|  | 10511 | */ | 
|  | 10512 | if (type->subtypes == NULL) { | 
|  | 10513 | xmlSchemaPErr(ctxt, type->node, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 10514 | XML_SCHEMAP_INTERNAL, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10515 | "Internal error: xmlSchemaCheckSRCSimpleType, " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10516 | "no subtype on simple type '%s'.\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10517 | type->name, NULL); | 
|  | 10518 | return (-1); | 
|  | 10519 | } | 
|  | 10520 | /* | 
|  | 10521 | * src-simple-type.1 The corresponding simple type definition, if any, | 
|  | 10522 | * must satisfy the conditions set out in Constraints on Simple Type | 
|  | 10523 | * Definition Schema Components (§3.14.6). | 
|  | 10524 | */ | 
|  | 10525 | if ((xmlSchemaCheckSTPropsCorrect(ctxt, type) != 0) || | 
|  | 10526 | (xmlSchemaCheckCOSSTRestricts(ctxt, type) != 0)) { | 
|  | 10527 | /* | 
|  | 10528 | * TODO: Removed this, since it got annoying to get an | 
|  | 10529 | * extra error report, if anything failed until now. | 
|  | 10530 | * Enable this if needed. | 
|  | 10531 | */ | 
|  | 10532 | /* | 
|  | 10533 | xmlSchemaPErr(ctxt, type->node, | 
|  | 10534 | XML_SCHEMAP_SRC_SIMPLE_TYPE_1, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10535 | "Simple type '%s' does not satisfy the constraints " | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10536 | "on simple type definitions.\n", | 
|  | 10537 | type->name, NULL); | 
|  | 10538 | */ | 
|  | 10539 | return (XML_SCHEMAP_SRC_SIMPLE_TYPE_1); | 
|  | 10540 | } | 
|  | 10541 |  | 
|  | 10542 | if (type->subtypes->type == XML_SCHEMA_TYPE_RESTRICTION) { | 
|  | 10543 | /* | 
|  | 10544 | * src-simple-type.2 If the <restriction> alternative is chosen, | 
|  | 10545 | * either it must have a base [attribute] or a <simpleType> among its | 
|  | 10546 | * [children], but not both. | 
|  | 10547 | */ | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 10548 | /* | 
|  | 10549 | * XML_SCHEMAP_SRC_SIMPLE_TYPE_2 | 
|  | 10550 | * NOTE: This was removed, since this will be already handled | 
|  | 10551 | * in the parse function for <restriction>. | 
|  | 10552 | */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10553 | } else if (type->subtypes->type == XML_SCHEMA_TYPE_LIST) { | 
|  | 10554 | /* src-simple-type.3 If the <list> alternative is chosen, either it must have | 
|  | 10555 | * an itemType [attribute] or a <simpleType> among its [children], | 
|  | 10556 | * but not both. | 
|  | 10557 | * NOTE: baseType is set to the local simple type definiton, | 
|  | 10558 | * if existent, at parse time. This is a hack and not nice. | 
|  | 10559 | */ | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 10560 | /* | 
|  | 10561 | * TODO: Remove this, and add the check to the parse function of <list>. | 
|  | 10562 | */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10563 | if (((type->subtypes->base == NULL) && | 
|  | 10564 | (type->baseType == NULL)) || | 
|  | 10565 | ((type->subtypes->base != NULL) && | 
|  | 10566 | (type->subtypes->baseType != NULL))) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10567 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10568 | XML_SCHEMAP_SRC_SIMPLE_TYPE_3, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10569 | NULL, type, NULL, | 
|  | 10570 | "Either the attribute 'itemType' or the <simpleType> child " | 
|  | 10571 | "must be present on the <list> child ", NULL); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10572 | return (XML_SCHEMAP_SRC_SIMPLE_TYPE_3); | 
|  | 10573 | } | 
|  | 10574 |  | 
|  | 10575 |  | 
|  | 10576 | } else if (type->subtypes->type == XML_SCHEMA_TYPE_UNION) { | 
|  | 10577 | xmlSchemaTypeLinkPtr member; | 
|  | 10578 | xmlSchemaTypePtr ancestor, anySimpleType; | 
|  | 10579 |  | 
|  | 10580 | anySimpleType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); | 
|  | 10581 |  | 
|  | 10582 | /* src-simple-type.4 Circular union type definition is disallowed. That is, if | 
|  | 10583 | * the <union> alternative is chosen, there must not be any entries | 
|  | 10584 | * in the memberTypes [attribute] at any depth which resolve to the | 
|  | 10585 | * component corresponding to the <simpleType>. | 
|  | 10586 | */ | 
|  | 10587 | member = type->memberTypes; | 
|  | 10588 | while (member != NULL) { | 
|  | 10589 | ancestor = member->type; | 
|  | 10590 | while ((ancestor != NULL) && (ancestor->type != XML_SCHEMA_TYPE_BASIC)) { | 
|  | 10591 | if (ancestor->contentType == XML_SCHEMA_CONTENT_UNKNOWN) | 
|  | 10592 | xmlSchemaTypeFixup(ancestor, ctxt,  NULL); | 
|  | 10593 | if (ancestor == anySimpleType) | 
|  | 10594 | break; | 
|  | 10595 | else if (ancestor == type) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10596 | xmlSchemaPCustomErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10597 | XML_SCHEMAP_SRC_SIMPLE_TYPE_4, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10598 | NULL, type, NULL, | 
|  | 10599 | "The definition is circular", NULL); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10600 | return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4); | 
|  | 10601 | } else if (ancestor->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) { | 
|  | 10602 | /* | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 10603 | * TODO, FIXME: Although a list simple type must not have a union ST | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10604 | * type as item type, which in turn has a list ST as member | 
|  | 10605 | * type, we will assume this here as well, since this check | 
|  | 10606 | * was not yet performed. | 
|  | 10607 | */ | 
|  | 10608 |  | 
|  | 10609 | } | 
|  | 10610 | ancestor = ancestor->baseType; | 
|  | 10611 | } | 
|  | 10612 | member = member->next; | 
|  | 10613 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10614 | } | 
|  | 10615 |  | 
|  | 10616 | return (0); | 
|  | 10617 | } | 
|  | 10618 |  | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 10619 | #if 0 /* Not yet used code for CT schema validation */ | 
|  | 10620 | static int | 
|  | 10621 | xmlSchemaCheckCVCSimpleType(xmlSchemaValidCtxtPtr ctxt, | 
|  | 10622 | const xmlChar * value, | 
|  | 10623 | xmlSchemaTypePtr type, | 
|  | 10624 | int fireErrors) | 
|  | 10625 | { | 
|  | 10626 | int ret; | 
|  | 10627 | /* | 
|  | 10628 | * 3.14.4 Simple Type Definition Validation Rules | 
|  | 10629 | * Validation Rule: String Valid | 
|  | 10630 | */ | 
|  | 10631 | /* | 
|  | 10632 | * 1 It is schema-valid with respect to that definition as defined | 
|  | 10633 | * by Datatype Valid in [XML Schemas: Datatypes]. | 
|  | 10634 | */ | 
|  | 10635 | ctxt->type = type; | 
|  | 10636 | ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, fireErrors, 1, 1); | 
|  | 10637 | return (ret); | 
|  | 10638 | /* | 
|  | 10639 | * 2.1 If The definition is ENTITY or is validly derived from ENTITY given | 
|  | 10640 | * the empty set, as defined in Type Derivation OK (Simple) (§3.14.6), then | 
|  | 10641 | * the string must be a ·declared entity name·. | 
|  | 10642 | */ | 
|  | 10643 | /* | 
|  | 10644 | * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES | 
|  | 10645 | * given the empty set, as defined in Type Derivation OK (Simple) (§3.14.6), | 
|  | 10646 | * then every whitespace-delimited substring of the string must be a ·declared | 
|  | 10647 | * entity name·. | 
|  | 10648 | */ | 
|  | 10649 | /* | 
|  | 10650 | * 2.3 otherwise no further condition applies. | 
|  | 10651 | */ | 
|  | 10652 |  | 
|  | 10653 | return (0); | 
|  | 10654 | } | 
|  | 10655 |  | 
|  | 10656 |  | 
|  | 10657 | static int | 
|  | 10658 | xmlSchemaCheckCOSValidDefault(xmlSchemaParserCtxtPtr ctxt, | 
|  | 10659 | xmlSchemaElementPtr elemDecl) | 
|  | 10660 | { | 
|  | 10661 | xmlSchemaTypePtr typeDef; | 
|  | 10662 | if (elemDecl->value == NULL) | 
|  | 10663 | return (0); | 
|  | 10664 | if (elemDecl->subtypes == NULL) { | 
|  | 10665 | xmlSchemaPCustomErr(ctxt, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 10666 | XML_SCHEMAP_INTERNAL, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 10667 | NULL, (xmlSchemaTypePtr) elemDecl, elemDecl->node, | 
|  | 10668 | "Internal error: xmlSchemaCheckCOSValidDefault, " | 
|  | 10669 | "the element decl. '%s' has no type assigned", elemDecl->name); | 
|  | 10670 | return (-1); | 
|  | 10671 | } | 
|  | 10672 | typeDef = elemDecl->subtypes; | 
|  | 10673 | if ((typeDef->type == XML_SCHEMA_TYPE_SIMPLE) || | 
|  | 10674 | ((typeDef->type == XML_SCHEMA_TYPE_COMPLEX) && | 
|  | 10675 | ((typeDef->contentType == XML_SCHEMA_CONTENT_SIMPLE) || | 
|  | 10676 | (typeDef->contentType == XML_SCHEMA_CONTENT_BASIC)))) { | 
|  | 10677 | xmlSchemaValidCtxtPtr vctxt; | 
|  | 10678 | xmlAttrPtr attr; | 
|  | 10679 | int ret = 0; | 
|  | 10680 | /* | 
|  | 10681 | * 1 If the type definition is a simple type definition, then the string | 
|  | 10682 | * must be ·valid· with respect to that definition as defined by String | 
|  | 10683 | * Valid (§3.14.4). | 
|  | 10684 | */ | 
|  | 10685 | /* | 
|  | 10686 | * 2.2.1 If the {content type} is a simple type definition, then the | 
|  | 10687 | * string must be ·valid· with respect to that simple type definition | 
|  | 10688 | * as defined by String Valid (§3.14.4). | 
|  | 10689 | */ | 
|  | 10690 | /* | 
|  | 10691 | * TODO: ? | 
|  | 10692 | */ | 
|  | 10693 |  | 
|  | 10694 | vctxt = xmlSchemaNewValidCtxt(NULL); | 
|  | 10695 | if (vctxt == NULL) { | 
|  | 10696 | xmlSchemaPErr(ctxt, elemDecl->node, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 10697 | XML_SCHEMAP_INTERNAL, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 10698 | "Internal error: xmlSchemaCheckCOSValidDefault, " | 
|  | 10699 | "creation of a new validation context failed.\n", | 
|  | 10700 | NULL, NULL); | 
|  | 10701 | return (-1); | 
|  | 10702 | } | 
|  | 10703 | /* | 
|  | 10704 | * TODO: This won't work. | 
|  | 10705 | */ | 
|  | 10706 | if (typeDef->type == XML_SCHEMA_TYPE_SIMPLE) | 
|  | 10707 | ret = xmlSchemaCheckCVCSimpleType(vctxt, elemDecl->value, typeDef, 0); | 
|  | 10708 | if (ret > 0) { | 
|  | 10709 | if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) | 
|  | 10710 | attr = xmlSchemaGetPropNode(elemDecl->node, "fixed"); | 
|  | 10711 | else | 
|  | 10712 | attr = xmlSchemaGetPropNode(elemDecl->node, "default"); | 
|  | 10713 | if (ctxt != NULL) { | 
|  | 10714 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 10715 | XML_SCHEMAP_COS_VALID_DEFAULT_2_1, | 
|  | 10716 | NULL, (xmlSchemaTypePtr) elemDecl, (xmlNodePtr) attr, | 
|  | 10717 | elemDecl->subtypes, NULL, elemDecl->value, | 
|  | 10718 | NULL, NULL, NULL); | 
|  | 10719 | return (ctxt->err); | 
|  | 10720 | } | 
|  | 10721 | ret = ctxt->err; | 
|  | 10722 | } else if (ret < 0) { | 
|  | 10723 | xmlSchemaPErr(ctxt, elemDecl->node, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 10724 | XML_SCHEMAP_INTERNAL, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 10725 | "Internal error: xmlSchemaCheckCOSValidDefault, " | 
|  | 10726 | "while validating the default/fixed value.\n", | 
|  | 10727 | NULL, NULL); | 
|  | 10728 | } | 
|  | 10729 | xmlSchemaFreeValidCtxt(vctxt); | 
|  | 10730 | return (ret); | 
|  | 10731 | } else { | 
|  | 10732 | /* | 
|  | 10733 | * Complex type. | 
|  | 10734 | * | 
|  | 10735 | * 2.1 its {content type} must be a simple type definition or mixed. | 
|  | 10736 | */ | 
|  | 10737 | if ((elemDecl->subtypes->contentType != XML_SCHEMA_CONTENT_SIMPLE) && | 
|  | 10738 | (elemDecl->subtypes->contentType != XML_SCHEMA_CONTENT_BASIC) && | 
|  | 10739 | (elemDecl->subtypes->contentType == XML_SCHEMA_CONTENT_MIXED)) { | 
|  | 10740 | xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_COS_VALID_DEFAULT_2_1, | 
|  | 10741 | NULL, (xmlSchemaTypePtr) elemDecl, NULL, | 
|  | 10742 | "The content type must be a simple type definition or mixed.", | 
|  | 10743 | NULL); | 
|  | 10744 | return(ctxt->err); | 
|  | 10745 | } | 
|  | 10746 | if ((elemDecl->subtypes->contentType != XML_SCHEMA_CONTENT_SIMPLE) && | 
|  | 10747 | (elemDecl->subtypes->contentType != XML_SCHEMA_CONTENT_BASIC)) { | 
|  | 10748 | xmlSchemaValidCtxtPtr vctxt; | 
|  | 10749 | xmlAttrPtr attr; | 
|  | 10750 | int ret; | 
|  | 10751 |  | 
|  | 10752 | /* TODO: Avoid creation of a new context. */ | 
|  | 10753 | vctxt = xmlSchemaNewValidCtxt(NULL); | 
|  | 10754 | if (vctxt == NULL) { | 
|  | 10755 | xmlSchemaPErr(ctxt, elemDecl->node, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 10756 | XML_SCHEMAP_INTERNAL, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 10757 | "Internal error: xmlSchemaCheckCOSValidDefault, " | 
|  | 10758 | "creation of a new validation context failed.\n", | 
|  | 10759 | NULL, NULL); | 
|  | 10760 | return (-1); | 
|  | 10761 | } | 
|  | 10762 | vctxt->type = elemDecl->subtypes; | 
|  | 10763 | ret = xmlSchemaValidateSimpleTypeValue(vctxt, elemDecl->value, 0, 1, 1); | 
|  | 10764 | if (ret > 0) { | 
|  | 10765 | if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) | 
|  | 10766 | attr = xmlSchemaGetPropNode(elemDecl->node, "fixed"); | 
|  | 10767 | else | 
|  | 10768 | attr = xmlSchemaGetPropNode(elemDecl->node, "default"); | 
|  | 10769 | if (ctxt != NULL) { | 
|  | 10770 | xmlSchemaPSimpleTypeErr(ctxt, | 
|  | 10771 | XML_SCHEMAP_COS_VALID_DEFAULT_2_1, | 
|  | 10772 | NULL, (xmlSchemaTypePtr) elemDecl, (xmlNodePtr) attr, | 
|  | 10773 | elemDecl->subtypes, NULL, elemDecl->value, | 
|  | 10774 | NULL, NULL, NULL); | 
|  | 10775 | return (ctxt->err); | 
|  | 10776 | } | 
|  | 10777 | ret = ctxt->err; | 
|  | 10778 | } else if (ret < 0) { | 
|  | 10779 | xmlSchemaPErr(ctxt, elemDecl->node, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 10780 | XML_SCHEMAP_INTERNAL, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 10781 | "Internal error: xmlSchemaCheckCOSValidDefault, " | 
|  | 10782 | "while validating the default/fixed value.\n", | 
|  | 10783 | NULL, NULL); | 
|  | 10784 | } | 
|  | 10785 | xmlSchemaFreeValidCtxt(vctxt); | 
|  | 10786 | return (ret); | 
|  | 10787 | } else { | 
|  | 10788 | /* | 
|  | 10789 | * 2.2.2 If the {content type} is mixed, then the {content type}'s | 
|  | 10790 | * particle must be ·emptiable· as defined by Particle Emptiable | 
|  | 10791 | * (§3.9.6). | 
|  | 10792 | */ | 
|  | 10793 | /* | 
|  | 10794 | * TODO: Implement this. | 
|  | 10795 | */ | 
|  | 10796 | } | 
|  | 10797 | } | 
|  | 10798 |  | 
|  | 10799 | return (0); | 
|  | 10800 | } | 
|  | 10801 |  | 
|  | 10802 | /** | 
|  | 10803 | * xmlSchemaGetSTContentOfCT: | 
|  | 10804 | * @ctxt:  the schema parser context | 
|  | 10805 | * @type:  the complex type definition | 
|  | 10806 | * | 
|  | 10807 | * | 
|  | 10808 | * Returns the corresponding simple type for the content of | 
|  | 10809 | * the complex type. | 
|  | 10810 | */ | 
|  | 10811 | static xmlSchemaTypePtr | 
|  | 10812 | xmlSchemaGetSTContentOfCT(xmlSchemaParserCtxtPtr ctxt, | 
|  | 10813 | xmlSchemaTypePtr type) | 
|  | 10814 | { | 
|  | 10815 | xmlSchemaTypePtr orig = type, anyType; | 
|  | 10816 |  | 
|  | 10817 | anyType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); | 
|  | 10818 | while ((type != NULL) && (type != anyType) && | 
|  | 10819 | (type->type == XML_SCHEMA_TYPE_COMPLEX)) { | 
|  | 10820 | if (type->type == XML_SCHEMA_TYPE_SIMPLE) | 
|  | 10821 | return(type); | 
|  | 10822 | type = type->baseType; | 
|  | 10823 | } | 
|  | 10824 | xmlSchemaPCustomErr(ctxt, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 10825 | XML_SCHEMAP_INTERNAL, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 10826 | NULL, orig, NULL, | 
|  | 10827 | "Internal error: xmlSchemaGetSTContentTypeOfCT, " | 
|  | 10828 | "no simple type for the content of complex type '%s' could be " | 
|  | 10829 | "computed", orig->name); | 
|  | 10830 | return (NULL); | 
|  | 10831 | } | 
|  | 10832 |  | 
|  | 10833 |  | 
|  | 10834 | static xmlSchemaTypePtr | 
|  | 10835 | xmlSchemaGetContentType(xmlSchemaParserCtxtPtr ctxt, | 
|  | 10836 | xmlSchemaTypePtr type) | 
|  | 10837 | { | 
|  | 10838 | if (type->baseType == NULL) { | 
|  | 10839 | xmlSchemaPCustomErr(ctxt, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 10840 | XML_SCHEMAP_INTERNAL, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 10841 | NULL, type, NULL, | 
|  | 10842 | "Internal error: xmlSchemaGetContentType, " | 
|  | 10843 | "the complex type '%s' has no base type", type->name); | 
|  | 10844 | return (NULL); | 
|  | 10845 | } | 
|  | 10846 | if (type->subtypes->type == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { | 
|  | 10847 | if ((type->baseType->type == XML_SCHEMA_TYPE_COMPLEX) && | 
|  | 10848 | ((type->baseType->contentType == XML_SCHEMA_CONTENT_SIMPLE) || | 
|  | 10849 | (type->baseType->contentType == XML_SCHEMA_CONTENT_BASIC)) && | 
|  | 10850 | (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)) { | 
|  | 10851 | /* | 
|  | 10852 | * 1 If the type definition ·resolved· to by the ·actual value· of | 
|  | 10853 | * the base [attribute] is a complex type definition whose own | 
|  | 10854 | * {content type} is a simple type definition and the <restriction> | 
|  | 10855 | * alternative is chosen | 
|  | 10856 | */ | 
|  | 10857 |  | 
|  | 10858 |  | 
|  | 10859 | } | 
|  | 10860 | } else { | 
|  | 10861 |  | 
|  | 10862 | } | 
|  | 10863 | } | 
|  | 10864 |  | 
|  | 10865 | /** | 
|  | 10866 | * xmlSchemaCheckCOSCTExtends: | 
|  | 10867 | * @ctxt:  the schema parser context | 
|  | 10868 | * @type:  the complex type definition | 
|  | 10869 | * | 
|  | 10870 | * Schema Component Constraint: Derivation Valid (Extension) | 
|  | 10871 | * | 
|  | 10872 | * Returns 0 if the constraints are satisfied, a positive | 
|  | 10873 | * error code if not and -1 if an internal error occured. | 
|  | 10874 | */ | 
|  | 10875 | static int | 
|  | 10876 | xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt, | 
|  | 10877 | xmlSchemaTypePtr type) | 
|  | 10878 | { | 
|  | 10879 | xmlSchemaTypePtr base; | 
|  | 10880 | /* | 
|  | 10881 | * 1 If the {base type definition} is a complex type definition, | 
|  | 10882 | * then all of the following must be true: | 
|  | 10883 | */ | 
|  | 10884 | base = type->baseType; | 
|  | 10885 | if (base == NULL) { | 
|  | 10886 | xmlSchemaPCustomErr(ctxt, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 10887 | XML_SCHEMAP_INTERNAL, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 10888 | NULL, type, NULL, | 
|  | 10889 | "Internal error: xmlSchemaCheckCOSCTExtends, " | 
|  | 10890 | "the complex type '%s' has no base type", type->name); | 
|  | 10891 | return (-1); | 
|  | 10892 | } | 
|  | 10893 | if (base->type == XML_SCHEMA_TYPE_COMPLEX) { | 
|  | 10894 | /* | 
|  | 10895 | * 1.1 The {final} of the {base type definition} must not | 
|  | 10896 | * contain extension. | 
|  | 10897 | */ | 
|  | 10898 | if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { | 
|  | 10899 | xmlSchemaPCustomErr(ctxt, | 
|  | 10900 | XML_SCHEMAP_COS_CT_EXTENDS_1_1, | 
|  | 10901 | NULL, type, NULL, | 
|  | 10902 | "The 'final' of the base type definition " | 
|  | 10903 | "contains extension", NULL); | 
|  | 10904 | return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); | 
|  | 10905 | } | 
|  | 10906 | /* | 
|  | 10907 | * 1.2 Its {attribute uses} must be a subset of the {attribute uses} | 
|  | 10908 | * of the complex type definition itself, that is, for every attribute | 
|  | 10909 | * use in the {attribute uses} of the {base type definition}, there | 
|  | 10910 | * must be an attribute use in the {attribute uses} of the complex | 
|  | 10911 | * type definition itself whose {attribute declaration} has the same | 
|  | 10912 | * {name}, {target namespace} and {type definition} as its attribute | 
|  | 10913 | * declaration | 
|  | 10914 | * | 
|  | 10915 | * NOTE: This will be already satisfied by the way the attribute uses | 
|  | 10916 | * are extended in xmlSchemaBuildAttributeValidation; thus this check | 
|  | 10917 | * is not needed. | 
|  | 10918 | */ | 
|  | 10919 |  | 
|  | 10920 | /* | 
|  | 10921 | * 1.3 If it has an {attribute wildcard}, the complex type definition | 
|  | 10922 | * must also have one, and the base type definition's {attribute | 
|  | 10923 | * wildcard}'s {namespace constraint} must be a subset of the complex | 
|  | 10924 | * type definition's {attribute wildcard}'s {namespace constraint}, | 
|  | 10925 | * as defined by Wildcard Subset (§3.10.6). | 
|  | 10926 | * | 
|  | 10927 | * This is already checked in xmlSchemaBuildAttributeValidation; thus | 
|  | 10928 | * this check is not needed. | 
|  | 10929 | */ | 
|  | 10930 |  | 
|  | 10931 | /* | 
|  | 10932 | * 1.4 One of the following must be true: | 
|  | 10933 | * | 
|  | 10934 | * 1.4.1 The {content type} of the {base type definition} and the | 
|  | 10935 | * {content type} of the complex type definition itself must be the same | 
|  | 10936 | * simple type definition | 
|  | 10937 | */ | 
|  | 10938 |  | 
|  | 10939 |  | 
|  | 10940 |  | 
|  | 10941 | } else { | 
|  | 10942 | /* | 
|  | 10943 | * 2 If the {base type definition} is a simple type definition, | 
|  | 10944 | * then all of the following must be true: | 
|  | 10945 | */ | 
|  | 10946 | /* | 
|  | 10947 | * 2.1 The {content type} must be the same simple type definition. | 
|  | 10948 | */ | 
|  | 10949 | /* | 
|  | 10950 | * 2.2 The {final} of the {base type definition} must not contain | 
|  | 10951 | * extension | 
|  | 10952 | */ | 
|  | 10953 | } | 
|  | 10954 |  | 
|  | 10955 | } | 
|  | 10956 |  | 
|  | 10957 | #endif | 
|  | 10958 |  | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10959 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 10960 | * xmlSchemaTypeFixup: | 
|  | 10961 | * @typeDecl:  the schema type definition | 
|  | 10962 | * @ctxt:  the schema parser context | 
|  | 10963 | * | 
|  | 10964 | * Fixes the content model of the type. | 
|  | 10965 | */ | 
|  | 10966 | static void | 
|  | 10967 | xmlSchemaTypeFixup(xmlSchemaTypePtr typeDecl, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 10968 | xmlSchemaParserCtxtPtr ctxt, const xmlChar * name) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 10969 | { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10970 | xmlSchemaTypePtr ctxtType; | 
|  | 10971 |  | 
| Daniel Veillard | 82bbbd4 | 2003-05-11 20:16:09 +0000 | [diff] [blame] | 10972 | if (typeDecl == NULL) | 
|  | 10973 | return; | 
| Daniel Veillard | 4e5d665 | 2004-06-29 21:01:12 +0000 | [diff] [blame] | 10974 | /* | 
|  | 10975 | * Do not allow the following types to be typefixed, prior to | 
|  | 10976 | * the corresponding simple/complex types. | 
|  | 10977 | */ | 
|  | 10978 | if (ctxt->ctxtType == NULL) { | 
|  | 10979 | switch (typeDecl->type) { | 
|  | 10980 | case XML_SCHEMA_TYPE_SIMPLE_CONTENT: | 
|  | 10981 | case XML_SCHEMA_TYPE_COMPLEX_CONTENT: | 
|  | 10982 | case XML_SCHEMA_TYPE_UNION: | 
|  | 10983 | case XML_SCHEMA_TYPE_RESTRICTION: | 
|  | 10984 | case XML_SCHEMA_TYPE_EXTENSION: | 
|  | 10985 | return; | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 10986 | default: | 
|  | 10987 | break; | 
| Daniel Veillard | 4e5d665 | 2004-06-29 21:01:12 +0000 | [diff] [blame] | 10988 | } | 
|  | 10989 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 10990 | if (name == NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 10991 | name = typeDecl->name; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 10992 | if (typeDecl->contentType == XML_SCHEMA_CONTENT_UNKNOWN) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 10993 | switch (typeDecl->type) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 10994 | case XML_SCHEMA_TYPE_SIMPLE_CONTENT:{ | 
|  | 10995 | if (typeDecl->subtypes != NULL) { | 
|  | 10996 | if (typeDecl->subtypes->contentType == | 
|  | 10997 | XML_SCHEMA_CONTENT_UNKNOWN) { | 
|  | 10998 | xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, | 
|  | 10999 | NULL); | 
|  | 11000 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11001 | typeDecl->contentType = | 
|  | 11002 | typeDecl->subtypes->contentType; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11003 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11004 | break; | 
|  | 11005 | } | 
|  | 11006 | case XML_SCHEMA_TYPE_RESTRICTION:{ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11007 | xmlSchemaTypePtr base = NULL; | 
|  | 11008 |  | 
|  | 11009 | ctxt->ctxtType->flags |= | 
|  | 11010 | XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 11011 | if (typeDecl->baseType != NULL) | 
|  | 11012 | base = typeDecl->baseType; | 
|  | 11013 | else if (typeDecl->base != NULL) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11014 | base = | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11015 | xmlSchemaGetType(ctxt->schema, typeDecl->base, | 
|  | 11016 | typeDecl->baseNs); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11017 | if (base == NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11018 | xmlSchemaPResCompAttrErr(ctxt, | 
|  | 11019 | XML_SCHEMAP_SRC_RESOLVE, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 11020 | NULL, NULL, | 
|  | 11021 | (xmlNodePtr) xmlSchemaGetPropNode(typeDecl->node, "base"), | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11022 | "base", typeDecl->base, typeDecl->baseNs, | 
|  | 11023 | XML_SCHEMA_TYPE_BASIC, "type definition"); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11024 | } else if (base->contentType == | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 11025 | XML_SCHEMA_CONTENT_UNKNOWN) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11026 | xmlSchemaTypeFixup(base, ctxt, NULL); | 
|  | 11027 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 11028 | } | 
|  | 11029 | ctxt->ctxtType->baseType = base; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11030 | if (ctxt->ctxtType->type == XML_SCHEMA_TYPE_COMPLEX) { | 
|  | 11031 | /* | 
|  | 11032 | * ComplexType restriction. | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 11033 | */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11034 | /* | 
|  | 11035 | * Content type. | 
|  | 11036 | */ | 
|  | 11037 | if (typeDecl->subtypes == NULL) | 
|  | 11038 | /* 1.1.1 */ | 
|  | 11039 | typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY; | 
|  | 11040 | else if ((typeDecl->subtypes->subtypes == NULL) && | 
|  | 11041 | ((typeDecl->subtypes->type == | 
|  | 11042 | XML_SCHEMA_TYPE_ALL) | 
|  | 11043 | || (typeDecl->subtypes->type == | 
|  | 11044 | XML_SCHEMA_TYPE_SEQUENCE))) | 
|  | 11045 | /* 1.1.2 */ | 
|  | 11046 | typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY; | 
|  | 11047 | else if ((typeDecl->subtypes->type == | 
|  | 11048 | XML_SCHEMA_TYPE_CHOICE) | 
|  | 11049 | && (typeDecl->subtypes->subtypes == NULL)) | 
|  | 11050 | /* 1.1.3 */ | 
|  | 11051 | typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY; | 
|  | 11052 | else { | 
|  | 11053 | /* 1.2 and 2.X are applied at the other layer */ | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 11054 | typeDecl->contentType = | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11055 | XML_SCHEMA_CONTENT_ELEMENTS; | 
|  | 11056 | } | 
|  | 11057 | } else { | 
|  | 11058 | /* | 
|  | 11059 | * SimpleType restriction. | 
|  | 11060 | */ | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 11061 | /* TODO: Nothing? */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11062 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11063 | break; | 
|  | 11064 | } | 
|  | 11065 | case XML_SCHEMA_TYPE_EXTENSION:{ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11066 | xmlSchemaTypePtr base = NULL; | 
|  | 11067 | xmlSchemaContentType explicitContentType; | 
|  | 11068 |  | 
|  | 11069 | /* | 
|  | 11070 | * An extension does exist on a complexType only. | 
|  | 11071 | */ | 
|  | 11072 | ctxt->ctxtType->flags |= | 
|  | 11073 | XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION; | 
|  | 11074 | if (typeDecl->recurse) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 11075 | /* TODO: The word "recursive" should be changed to "circular" here. */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11076 | xmlSchemaPCustomErr(ctxt, | 
|  | 11077 | XML_SCHEMAP_UNKNOWN_BASE_TYPE, | 
|  | 11078 | NULL, typeDecl, typeDecl->node, | 
|  | 11079 | "This item is circular", NULL); | 
| Daniel Veillard | 2582a33 | 2004-04-18 19:49:46 +0000 | [diff] [blame] | 11080 | return; | 
|  | 11081 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11082 | if (typeDecl->base != NULL) { | 
|  | 11083 | base = | 
|  | 11084 | xmlSchemaGetType(ctxt->schema, typeDecl->base, | 
|  | 11085 | typeDecl->baseNs); | 
|  | 11086 | if (base == NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11087 | xmlSchemaPResCompAttrErr(ctxt, | 
|  | 11088 | XML_SCHEMAP_SRC_RESOLVE, | 
|  | 11089 | NULL, typeDecl, typeDecl->node, | 
|  | 11090 | "base", typeDecl->base, typeDecl->baseNs, | 
|  | 11091 | XML_SCHEMA_TYPE_BASIC, "type definition"); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11092 | } else if (base->contentType == | 
|  | 11093 | XML_SCHEMA_CONTENT_UNKNOWN) { | 
|  | 11094 | typeDecl->recurse = 1; | 
|  | 11095 | xmlSchemaTypeFixup(base, ctxt, NULL); | 
|  | 11096 | typeDecl->recurse = 0; | 
|  | 11097 | } | 
|  | 11098 | /* | 
|  | 11099 | * The type definition ·resolved· to by the ·actual | 
|  | 11100 | * value· of the base [attribute] | 
|  | 11101 | */ | 
|  | 11102 | ctxt->ctxtType->baseType = base; | 
|  | 11103 | /* | 
|  | 11104 | * TODO: This one is still needed for computation of | 
|  | 11105 | * the content model by xmlSchemaBuildAContentModel. | 
|  | 11106 | * Try to get rid of it. | 
|  | 11107 | */ | 
|  | 11108 | typeDecl->baseType = base; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11109 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11110 | if ((typeDecl->subtypes != NULL) && | 
|  | 11111 | (typeDecl->subtypes->contentType == XML_SCHEMA_CONTENT_UNKNOWN)) | 
|  | 11112 | xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL); | 
|  | 11113 |  | 
|  | 11114 | explicitContentType = XML_SCHEMA_CONTENT_ELEMENTS; | 
|  | 11115 | if (typeDecl->subtypes == NULL) | 
|  | 11116 | /* 1.1.1 */ | 
|  | 11117 | explicitContentType = XML_SCHEMA_CONTENT_EMPTY; | 
|  | 11118 | else if ((typeDecl->subtypes->subtypes == NULL) && | 
|  | 11119 | ((typeDecl->subtypes->type == | 
|  | 11120 | XML_SCHEMA_TYPE_ALL) | 
|  | 11121 | || (typeDecl->subtypes->type == | 
|  | 11122 | XML_SCHEMA_TYPE_SEQUENCE))) | 
|  | 11123 | /* 1.1.2 */ | 
|  | 11124 | explicitContentType = XML_SCHEMA_CONTENT_EMPTY; | 
|  | 11125 | else if ((typeDecl->subtypes->type == | 
|  | 11126 | XML_SCHEMA_TYPE_CHOICE) | 
|  | 11127 | && (typeDecl->subtypes->subtypes == NULL)) | 
|  | 11128 | /* 1.1.3 */ | 
|  | 11129 | explicitContentType = XML_SCHEMA_CONTENT_EMPTY; | 
|  | 11130 | if (base != NULL) { | 
|  | 11131 | /* It will be reported later, if the base is missing. */ | 
|  | 11132 | if (explicitContentType == XML_SCHEMA_CONTENT_EMPTY) { | 
|  | 11133 | /* 2.1 */ | 
|  | 11134 | typeDecl->contentType = base->contentType; | 
|  | 11135 | } else if (base->contentType == | 
|  | 11136 | XML_SCHEMA_CONTENT_EMPTY) { | 
|  | 11137 | /* 2.2 imbitable ! */ | 
|  | 11138 | typeDecl->contentType = | 
|  | 11139 | XML_SCHEMA_CONTENT_ELEMENTS; | 
|  | 11140 | } else { | 
|  | 11141 | /* 2.3 imbitable pareil ! */ | 
|  | 11142 | typeDecl->contentType = | 
|  | 11143 | XML_SCHEMA_CONTENT_ELEMENTS; | 
|  | 11144 | } | 
|  | 11145 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11146 | break; | 
|  | 11147 | } | 
|  | 11148 | case XML_SCHEMA_TYPE_COMPLEX:{ | 
| Daniel Veillard | 4e5d665 | 2004-06-29 21:01:12 +0000 | [diff] [blame] | 11149 | ctxtType = ctxt->ctxtType; | 
|  | 11150 | ctxt->ctxtType = typeDecl; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11151 | if ((typeDecl->subtypes == NULL) || | 
|  | 11152 | ((typeDecl->subtypes->type != | 
|  | 11153 | XML_SCHEMA_TYPE_SIMPLE_CONTENT) && | 
|  | 11154 | (typeDecl->subtypes->type != | 
|  | 11155 | XML_SCHEMA_TYPE_COMPLEX_CONTENT))) { | 
|  | 11156 | /* | 
|  | 11157 | * This case is understood as shorthand for complex | 
|  | 11158 | * content restricting the ur-type definition, and | 
|  | 11159 | * the details of the mappings should be modified as | 
|  | 11160 | * necessary. | 
|  | 11161 | */ | 
|  | 11162 | typeDecl->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); | 
|  | 11163 | typeDecl->flags |= | 
|  | 11164 | XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; | 
|  | 11165 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11166 | if (typeDecl->subtypes == NULL) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11167 | typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY; | 
| Daniel Veillard | 1aefc86 | 2004-03-04 11:40:48 +0000 | [diff] [blame] | 11168 | if (typeDecl->flags & XML_SCHEMAS_TYPE_MIXED) | 
|  | 11169 | typeDecl->contentType = | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11170 | XML_SCHEMA_CONTENT_MIXED; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11171 | } else { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11172 | if ((typeDecl->subtypes != NULL) && | 
|  | 11173 | (typeDecl->subtypes->contentType == | 
| Daniel Veillard | 4e5d665 | 2004-06-29 21:01:12 +0000 | [diff] [blame] | 11174 | XML_SCHEMA_CONTENT_UNKNOWN)) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11175 | xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, | 
| Daniel Veillard | 4e5d665 | 2004-06-29 21:01:12 +0000 | [diff] [blame] | 11176 | NULL); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11177 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 11178 | if (typeDecl->flags & XML_SCHEMAS_TYPE_MIXED) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11179 | typeDecl->contentType = | 
|  | 11180 | XML_SCHEMA_CONTENT_MIXED; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11181 | } else { | 
|  | 11182 | if (typeDecl->subtypes != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11183 | typeDecl->contentType = | 
|  | 11184 | typeDecl->subtypes->contentType; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11185 | } | 
|  | 11186 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 11187 | } | 
|  | 11188 | xmlSchemaBuildAttributeValidation(ctxt, typeDecl); | 
| Daniel Veillard | 4e5d665 | 2004-06-29 21:01:12 +0000 | [diff] [blame] | 11189 | ctxt->ctxtType = ctxtType; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11190 | break; | 
|  | 11191 | } | 
|  | 11192 | case XML_SCHEMA_TYPE_COMPLEX_CONTENT:{ | 
|  | 11193 | if (typeDecl->subtypes == NULL) { | 
|  | 11194 | typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY; | 
| Daniel Veillard | 1aefc86 | 2004-03-04 11:40:48 +0000 | [diff] [blame] | 11195 | if (typeDecl->flags & XML_SCHEMAS_TYPE_MIXED) | 
|  | 11196 | typeDecl->contentType = | 
|  | 11197 | XML_SCHEMA_CONTENT_MIXED; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11198 | } else { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 11199 | if (typeDecl->flags & XML_SCHEMAS_TYPE_MIXED) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11200 | typeDecl->contentType = | 
|  | 11201 | XML_SCHEMA_CONTENT_MIXED; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 11202 | } else { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11203 | xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, | 
|  | 11204 | NULL); | 
|  | 11205 | if (typeDecl->subtypes != NULL) | 
|  | 11206 | typeDecl->contentType = | 
|  | 11207 | typeDecl->subtypes->contentType; | 
|  | 11208 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 11209 | /* | 
|  | 11210 | * Removed due to implementation of the build of attribute uses. | 
|  | 11211 | */ | 
|  | 11212 | /* | 
| Daniel Veillard | f2a1283 | 2003-11-24 13:04:35 +0000 | [diff] [blame] | 11213 | if (typeDecl->attributes == NULL) | 
|  | 11214 | typeDecl->attributes = | 
|  | 11215 | typeDecl->subtypes->attributes; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 11216 | */ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11217 | } | 
|  | 11218 | break; | 
|  | 11219 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11220 | case XML_SCHEMA_TYPE_SIMPLE: | 
|  | 11221 | /* | 
|  | 11222 | * Simple Type Definition Schema Component | 
|  | 11223 | * | 
|  | 11224 | */ | 
| Daniel Veillard | 4e5d665 | 2004-06-29 21:01:12 +0000 | [diff] [blame] | 11225 | ctxtType = ctxt->ctxtType; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11226 | typeDecl->contentType = XML_SCHEMA_CONTENT_SIMPLE; | 
|  | 11227 | if (typeDecl->subtypes->contentType == | 
|  | 11228 | XML_SCHEMA_CONTENT_UNKNOWN) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11229 | ctxt->ctxtType = typeDecl; | 
|  | 11230 | xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11231 | } | 
|  | 11232 | /* Fixup base type */ | 
|  | 11233 | if ((typeDecl->baseType != NULL) && | 
|  | 11234 | (typeDecl->baseType->contentType == | 
|  | 11235 | XML_SCHEMA_CONTENT_UNKNOWN)) { | 
|  | 11236 | /* OPTIMIZE: Actually this one will never by hit, since | 
|  | 11237 | * the base type is already type-fixed in <restriction>. | 
|  | 11238 | */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11239 | ctxt->ctxtType = typeDecl; | 
|  | 11240 | xmlSchemaTypeFixup(typeDecl->baseType, ctxt, NULL); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11241 | } | 
|  | 11242 | /* Base type: | 
|  | 11243 | * 2 If the <list> or <union> alternative is chosen, | 
|  | 11244 | * then the ·simple ur-type definition·. | 
|  | 11245 | */ | 
|  | 11246 | if (typeDecl->subtypes->type == | 
|  | 11247 | XML_SCHEMA_TYPE_LIST) { | 
|  | 11248 | typeDecl->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); | 
|  | 11249 | typeDecl->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; | 
|  | 11250 | } else if (typeDecl->subtypes->type == | 
|  | 11251 | XML_SCHEMA_TYPE_UNION) { | 
|  | 11252 | typeDecl->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); | 
|  | 11253 | typeDecl->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; | 
|  | 11254 | } else if (typeDecl->subtypes->type == | 
|  | 11255 | XML_SCHEMA_TYPE_RESTRICTION) { | 
|  | 11256 | xmlSchemaFacetLinkPtr facet, cur, last = NULL; | 
|  | 11257 |  | 
|  | 11258 | /* | 
|  | 11259 | * Variety | 
|  | 11260 | * If the <restriction> alternative is chosen, then the | 
|  | 11261 | * {variety} of the {base type definition}. | 
|  | 11262 | */ | 
|  | 11263 | if (typeDecl->baseType != NULL) { | 
|  | 11264 | if (typeDecl->baseType->flags & | 
|  | 11265 | XML_SCHEMAS_TYPE_VARIETY_ATOMIC) | 
|  | 11266 | typeDecl->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC; | 
|  | 11267 | else if (typeDecl->baseType->flags & | 
|  | 11268 | XML_SCHEMAS_TYPE_VARIETY_LIST) | 
|  | 11269 | typeDecl->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; | 
|  | 11270 | else if (typeDecl->baseType->flags & | 
|  | 11271 | XML_SCHEMAS_TYPE_VARIETY_UNION) | 
|  | 11272 | typeDecl->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; | 
|  | 11273 | /* | 
|  | 11274 | * Schema Component Constraint: Simple Type Restriction | 
|  | 11275 | * (Facets) | 
|  | 11276 | * NOTE: Satisfaction of 1 and 2 arise from the fixup | 
|  | 11277 | * applied beforehand. | 
|  | 11278 | * | 
|  | 11279 | * 3 The {facets} of R are the union of S and the {facets} | 
|  | 11280 | * of B, eliminating duplicates. To eliminate duplicates, | 
|  | 11281 | * when a facet of the same kind occurs in both S and the | 
|  | 11282 | * {facets} of B, the one in the {facets} of B is not | 
|  | 11283 | * included, with the exception of enumeration and pattern | 
|  | 11284 | * facets, for which multiple occurrences with distinct values | 
|  | 11285 | * are allowed. | 
|  | 11286 | */ | 
|  | 11287 | if (typeDecl->baseType->facetSet != NULL) { | 
|  | 11288 | last = typeDecl->facetSet; | 
|  | 11289 | if (last != NULL) | 
|  | 11290 | while (last->next != NULL) | 
|  | 11291 | last = last->next; | 
|  | 11292 | cur = typeDecl->baseType->facetSet; | 
|  | 11293 | for (; cur != NULL; cur = cur->next) { | 
|  | 11294 | /* | 
|  | 11295 | * Base patterns won't be add here: | 
|  | 11296 | * they are ORed in a type and | 
|  | 11297 | * ANDed in derived types. This will | 
|  | 11298 | * happed at validation level by | 
|  | 11299 | * walking the base axis of the type. | 
|  | 11300 | */ | 
|  | 11301 | if (cur->facet->type == | 
|  | 11302 | XML_SCHEMA_FACET_PATTERN) | 
|  | 11303 | continue; | 
|  | 11304 | facet = NULL; | 
|  | 11305 | if ((typeDecl->facetSet != NULL) && | 
|  | 11306 | (cur->facet->type != | 
|  | 11307 | XML_SCHEMA_FACET_PATTERN) && | 
|  | 11308 | (cur->facet->type != | 
|  | 11309 | XML_SCHEMA_FACET_ENUMERATION)) { | 
|  | 11310 | facet = typeDecl->facetSet; | 
|  | 11311 | do { | 
|  | 11312 | if (cur->facet->type == | 
|  | 11313 | facet->facet->type) | 
|  | 11314 | break; | 
|  | 11315 | facet = facet->next; | 
|  | 11316 | } while (facet != NULL); | 
|  | 11317 | } | 
|  | 11318 | if (facet == NULL) { | 
|  | 11319 | facet = (xmlSchemaFacetLinkPtr) | 
|  | 11320 | xmlMalloc(sizeof(xmlSchemaFacetLink)); | 
|  | 11321 | if (facet == NULL) { | 
|  | 11322 | xmlSchemaPErrMemory(ctxt, | 
|  | 11323 | "fixing simpleType", NULL); | 
|  | 11324 | return; | 
|  | 11325 | } | 
|  | 11326 | facet->facet = cur->facet; | 
|  | 11327 | facet->next = NULL; | 
|  | 11328 | if (last == NULL) | 
|  | 11329 | typeDecl->facetSet = facet; | 
|  | 11330 | else | 
|  | 11331 | last->next = facet; | 
|  | 11332 | last = facet; | 
|  | 11333 | } | 
|  | 11334 | } | 
|  | 11335 | } | 
|  | 11336 | } | 
|  | 11337 | } | 
|  | 11338 | /* | 
|  | 11339 | * Check constraints. | 
|  | 11340 | */ | 
|  | 11341 | xmlSchemaCheckSRCSimpleType(ctxt, typeDecl); | 
| Daniel Veillard | 4e5d665 | 2004-06-29 21:01:12 +0000 | [diff] [blame] | 11342 | ctxt->ctxtType = ctxtType; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11343 | break; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11344 | case XML_SCHEMA_TYPE_SEQUENCE: | 
|  | 11345 | case XML_SCHEMA_TYPE_GROUP: | 
|  | 11346 | case XML_SCHEMA_TYPE_ALL: | 
|  | 11347 | case XML_SCHEMA_TYPE_CHOICE: | 
|  | 11348 | typeDecl->contentType = XML_SCHEMA_CONTENT_ELEMENTS; | 
|  | 11349 | break; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11350 | case XML_SCHEMA_TYPE_LIST: | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 11351 | xmlSchemaParseListRefFixup(typeDecl, ctxt); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11352 | typeDecl->contentType = XML_SCHEMA_CONTENT_SIMPLE; | 
|  | 11353 | break; | 
|  | 11354 | case XML_SCHEMA_TYPE_UNION: | 
|  | 11355 | xmlSchemaParseUnionRefCheck(typeDecl, ctxt); | 
|  | 11356 | typeDecl->contentType = XML_SCHEMA_CONTENT_SIMPLE; | 
|  | 11357 | break; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11358 | case XML_SCHEMA_TYPE_BASIC: | 
|  | 11359 | case XML_SCHEMA_TYPE_ANY: | 
|  | 11360 | case XML_SCHEMA_TYPE_FACET: | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11361 | case XML_SCHEMA_TYPE_UR: | 
|  | 11362 | case XML_SCHEMA_TYPE_ELEMENT: | 
|  | 11363 | case XML_SCHEMA_TYPE_ATTRIBUTE: | 
|  | 11364 | case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: | 
| William M. Brack | 29aa772 | 2004-05-12 00:27:56 +0000 | [diff] [blame] | 11365 | case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11366 | case XML_SCHEMA_TYPE_NOTATION: | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11367 | case XML_SCHEMA_FACET_MININCLUSIVE: | 
|  | 11368 | case XML_SCHEMA_FACET_MINEXCLUSIVE: | 
|  | 11369 | case XML_SCHEMA_FACET_MAXINCLUSIVE: | 
|  | 11370 | case XML_SCHEMA_FACET_MAXEXCLUSIVE: | 
|  | 11371 | case XML_SCHEMA_FACET_TOTALDIGITS: | 
|  | 11372 | case XML_SCHEMA_FACET_FRACTIONDIGITS: | 
|  | 11373 | case XML_SCHEMA_FACET_PATTERN: | 
|  | 11374 | case XML_SCHEMA_FACET_ENUMERATION: | 
|  | 11375 | case XML_SCHEMA_FACET_WHITESPACE: | 
|  | 11376 | case XML_SCHEMA_FACET_LENGTH: | 
|  | 11377 | case XML_SCHEMA_FACET_MAXLENGTH: | 
|  | 11378 | case XML_SCHEMA_FACET_MINLENGTH: | 
|  | 11379 | typeDecl->contentType = XML_SCHEMA_CONTENT_SIMPLE; | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 11380 | if (typeDecl->subtypes != NULL) | 
|  | 11381 | xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11382 | break; | 
|  | 11383 | } | 
|  | 11384 | } | 
| Daniel Veillard | 8651f53 | 2002-04-17 09:06:27 +0000 | [diff] [blame] | 11385 | #ifdef DEBUG_TYPE | 
| Daniel Veillard | decd64d | 2002-04-18 14:41:51 +0000 | [diff] [blame] | 11386 | if (typeDecl->node != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11387 | xmlGenericError(xmlGenericErrorContext, | 
|  | 11388 | "Type of %s : %s:%d :", name, | 
|  | 11389 | typeDecl->node->doc->URL, | 
|  | 11390 | xmlGetLineNo(typeDecl->node)); | 
| Daniel Veillard | decd64d | 2002-04-18 14:41:51 +0000 | [diff] [blame] | 11391 | } else { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11392 | xmlGenericError(xmlGenericErrorContext, "Type of %s :", name); | 
| Daniel Veillard | decd64d | 2002-04-18 14:41:51 +0000 | [diff] [blame] | 11393 | } | 
| Daniel Veillard | 8651f53 | 2002-04-17 09:06:27 +0000 | [diff] [blame] | 11394 | switch (typeDecl->contentType) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11395 | case XML_SCHEMA_CONTENT_SIMPLE: | 
|  | 11396 | xmlGenericError(xmlGenericErrorContext, "simple\n"); | 
|  | 11397 | break; | 
|  | 11398 | case XML_SCHEMA_CONTENT_ELEMENTS: | 
|  | 11399 | xmlGenericError(xmlGenericErrorContext, "elements\n"); | 
|  | 11400 | break; | 
| Daniel Veillard | 8651f53 | 2002-04-17 09:06:27 +0000 | [diff] [blame] | 11401 | case XML_SCHEMA_CONTENT_UNKNOWN: | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11402 | xmlGenericError(xmlGenericErrorContext, "unknown !!!\n"); | 
|  | 11403 | break; | 
| Daniel Veillard | 8651f53 | 2002-04-17 09:06:27 +0000 | [diff] [blame] | 11404 | case XML_SCHEMA_CONTENT_EMPTY: | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11405 | xmlGenericError(xmlGenericErrorContext, "empty\n"); | 
|  | 11406 | break; | 
| Daniel Veillard | 8651f53 | 2002-04-17 09:06:27 +0000 | [diff] [blame] | 11407 | case XML_SCHEMA_CONTENT_MIXED: | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11408 | xmlGenericError(xmlGenericErrorContext, "mixed\n"); | 
|  | 11409 | break; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11410 | /* Removed, since not used. */ | 
|  | 11411 | /* | 
| Daniel Veillard | 8651f53 | 2002-04-17 09:06:27 +0000 | [diff] [blame] | 11412 | case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11413 | xmlGenericError(xmlGenericErrorContext, "mixed or elems\n"); | 
|  | 11414 | break; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11415 | */ | 
| Daniel Veillard | 8651f53 | 2002-04-17 09:06:27 +0000 | [diff] [blame] | 11416 | case XML_SCHEMA_CONTENT_BASIC: | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11417 | xmlGenericError(xmlGenericErrorContext, "basic\n"); | 
|  | 11418 | break; | 
|  | 11419 | default: | 
|  | 11420 | xmlGenericError(xmlGenericErrorContext, | 
|  | 11421 | "not registered !!!\n"); | 
|  | 11422 | break; | 
| Daniel Veillard | 8651f53 | 2002-04-17 09:06:27 +0000 | [diff] [blame] | 11423 | } | 
|  | 11424 | #endif | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11425 | } | 
|  | 11426 |  | 
|  | 11427 | /** | 
| Daniel Veillard | 8bc6cf9 | 2003-02-27 17:42:22 +0000 | [diff] [blame] | 11428 | * xmlSchemaCheckFacet: | 
|  | 11429 | * @facet:  the facet | 
|  | 11430 | * @typeDecl:  the schema type definition | 
|  | 11431 | * @ctxt:  the schema parser context or NULL | 
|  | 11432 | * @name: name of the type | 
|  | 11433 | * | 
|  | 11434 | * Checks the default values types, especially for facets | 
|  | 11435 | * | 
|  | 11436 | * Returns 0 if okay or -1 in cae of error | 
|  | 11437 | */ | 
|  | 11438 | int | 
|  | 11439 | xmlSchemaCheckFacet(xmlSchemaFacetPtr facet, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11440 | xmlSchemaTypePtr typeDecl, | 
|  | 11441 | xmlSchemaParserCtxtPtr ctxt, const xmlChar * name) | 
| Daniel Veillard | 8bc6cf9 | 2003-02-27 17:42:22 +0000 | [diff] [blame] | 11442 | { | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 11443 | xmlSchemaTypePtr nonNegativeIntegerType = NULL; | 
| Daniel Veillard | 8bc6cf9 | 2003-02-27 17:42:22 +0000 | [diff] [blame] | 11444 | int ret = 0; | 
|  | 11445 |  | 
|  | 11446 | if (nonNegativeIntegerType == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11447 | nonNegativeIntegerType = | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11448 | xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER); | 
| Daniel Veillard | 8bc6cf9 | 2003-02-27 17:42:22 +0000 | [diff] [blame] | 11449 | } | 
|  | 11450 | switch (facet->type) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11451 | case XML_SCHEMA_FACET_MININCLUSIVE: | 
|  | 11452 | case XML_SCHEMA_FACET_MINEXCLUSIVE: | 
|  | 11453 | case XML_SCHEMA_FACET_MAXINCLUSIVE: | 
| Daniel Veillard | f4b05d0 | 2004-07-05 13:10:37 +0000 | [diff] [blame] | 11454 | case XML_SCHEMA_FACET_MAXEXCLUSIVE: | 
|  | 11455 | case XML_SCHEMA_FACET_ENUMERATION: { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11456 | /* | 
|  | 11457 | * Okay we need to validate the value | 
|  | 11458 | * at that point. | 
|  | 11459 | */ | 
|  | 11460 | xmlSchemaValidCtxtPtr vctxt; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11461 | xmlSchemaTypePtr base; | 
| Daniel Veillard | f4b05d0 | 2004-07-05 13:10:37 +0000 | [diff] [blame] | 11462 |  | 
|  | 11463 | /* 4.3.5.5 Constraints on enumeration Schema Components | 
|  | 11464 | * Schema Component Constraint: enumeration valid restriction | 
|  | 11465 | * It is an ·error· if any member of {value} is not in the | 
|  | 11466 | * ·value space· of {base type definition}. | 
|  | 11467 | * | 
|  | 11468 | * minInclusive, maxInclusive, minExclusive, maxExclusive: | 
|  | 11469 | * The value ·must· be in the | 
|  | 11470 | * ·value space· of the ·base type·. | 
|  | 11471 | */ | 
|  | 11472 | /* | 
|  | 11473 | * This function is intended to deliver a compiled value | 
|  | 11474 | * on the facet. In XML Schemas the type holding a facet, | 
|  | 11475 | * cannot be a built-in type. Thus to ensure that other API | 
|  | 11476 | * calls (relaxng) do work, if the given type is a built-in | 
|  | 11477 | * type, we will assume that the given built-in type *is | 
|  | 11478 | * already* the base type. | 
|  | 11479 | */ | 
|  | 11480 | if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) { | 
|  | 11481 | base = typeDecl->baseType; | 
|  | 11482 | if (base == NULL) { | 
|  | 11483 | xmlSchemaPErr(ctxt, typeDecl->node, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 11484 | XML_SCHEMAP_INTERNAL, | 
| Daniel Veillard | f4b05d0 | 2004-07-05 13:10:37 +0000 | [diff] [blame] | 11485 | "Internal error: xmlSchemaCheckFacet, " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11486 | "the type '%s' has no base type.\n", | 
| Daniel Veillard | f4b05d0 | 2004-07-05 13:10:37 +0000 | [diff] [blame] | 11487 | typeDecl->name, NULL); | 
|  | 11488 | return (-1); | 
|  | 11489 | } | 
|  | 11490 | } else | 
|  | 11491 | base = typeDecl; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11492 | /* | 
|  | 11493 | * TODO: Try to avoid creating a new context. | 
|  | 11494 | */ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11495 | vctxt = xmlSchemaNewValidCtxt(NULL); | 
| Daniel Veillard | f4b05d0 | 2004-07-05 13:10:37 +0000 | [diff] [blame] | 11496 | if (vctxt == NULL) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11497 | xmlSchemaPErr(ctxt, typeDecl->node, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 11498 | XML_SCHEMAP_INTERNAL, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11499 | "Internal error: xmlSchemaCheckFacet, " | 
| Daniel Veillard | f4b05d0 | 2004-07-05 13:10:37 +0000 | [diff] [blame] | 11500 | "creating a new validation context.\n", | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 11501 | NULL, NULL); | 
| Daniel Veillard | f4b05d0 | 2004-07-05 13:10:37 +0000 | [diff] [blame] | 11502 | return (-1); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11503 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11504 | vctxt->type = base; | 
|  | 11505 | ret = xmlSchemaValidateSimpleTypeValue(vctxt, facet->value, 0, 1, 1); | 
| Daniel Veillard | f4b05d0 | 2004-07-05 13:10:37 +0000 | [diff] [blame] | 11506 | facet->val = vctxt->value; | 
|  | 11507 | vctxt->value = NULL; | 
|  | 11508 | if (ret > 0) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11509 | /* error code */ | 
|  | 11510 | if (ctxt != NULL) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11511 | xmlSchemaPErrExt(ctxt, facet->node, | 
|  | 11512 | XML_SCHEMAP_INVALID_FACET, | 
|  | 11513 | NULL, NULL, NULL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11514 | "Type definition '%s': The value '%s' of the " | 
|  | 11515 | "facet '%s' is not valid.\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11516 | name, facet->value, | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 11517 | BAD_CAST xmlSchemaFacetTypeToString(facet->type), | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11518 | NULL, NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11519 | } | 
|  | 11520 | ret = -1; | 
| Daniel Veillard | f4b05d0 | 2004-07-05 13:10:37 +0000 | [diff] [blame] | 11521 | } else if (ret < 0) { | 
|  | 11522 | xmlSchemaPErrExt(ctxt, facet->node, | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 11523 | XML_SCHEMAP_INTERNAL, | 
| Daniel Veillard | f4b05d0 | 2004-07-05 13:10:37 +0000 | [diff] [blame] | 11524 | NULL, NULL, NULL, | 
|  | 11525 | "Internal error: xmlSchemaCheckFacet, " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11526 | "failed to validate the value '%s' name of the " | 
|  | 11527 | "facet '%s' against the base type '%s'.\n", | 
| Daniel Veillard | f4b05d0 | 2004-07-05 13:10:37 +0000 | [diff] [blame] | 11528 | facet->value, | 
|  | 11529 | BAD_CAST xmlSchemaFacetTypeToString(facet->type), | 
|  | 11530 | base->name, NULL, NULL); | 
|  | 11531 | ret = -1; | 
|  | 11532 | } | 
|  | 11533 | xmlSchemaFreeValidCtxt(vctxt); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11534 | break; | 
|  | 11535 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11536 | case XML_SCHEMA_FACET_PATTERN: | 
|  | 11537 | facet->regexp = xmlRegexpCompile(facet->value); | 
|  | 11538 | if (facet->regexp == NULL) { | 
|  | 11539 | xmlSchemaPErr(ctxt, typeDecl->node, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11540 | XML_SCHEMAP_REGEXP_INVALID, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11541 | "Type definition '%s': The value '%s' of the " | 
|  | 11542 | "facet 'pattern' is not valid.\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11543 | name, facet->value); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11544 | ret = -1; | 
|  | 11545 | } | 
|  | 11546 | break; | 
|  | 11547 | case XML_SCHEMA_FACET_TOTALDIGITS: | 
|  | 11548 | case XML_SCHEMA_FACET_FRACTIONDIGITS: | 
|  | 11549 | case XML_SCHEMA_FACET_LENGTH: | 
|  | 11550 | case XML_SCHEMA_FACET_MAXLENGTH: | 
|  | 11551 | case XML_SCHEMA_FACET_MINLENGTH:{ | 
|  | 11552 | int tmp; | 
| Daniel Veillard | 8bc6cf9 | 2003-02-27 17:42:22 +0000 | [diff] [blame] | 11553 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11554 | tmp = | 
|  | 11555 | xmlSchemaValidatePredefinedType(nonNegativeIntegerType, | 
|  | 11556 | facet->value, | 
| Kasimier T. Buchcik | b4a9e64 | 2004-08-30 10:56:53 +0000 | [diff] [blame^] | 11557 | &(facet->val)); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11558 | if (tmp != 0) { | 
|  | 11559 | /* error code */ | 
|  | 11560 | if (ctxt != NULL) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11561 | xmlSchemaPErrExt(ctxt, facet->node, | 
|  | 11562 | XML_SCHEMAP_INVALID_FACET_VALUE, | 
|  | 11563 | NULL, NULL, NULL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11564 | "Type definition '%s': The value '%s' of the " | 
|  | 11565 | "facet '%s' is not valid.\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11566 | name, facet->value, | 
| Daniel Veillard | b7c6ac4 | 2004-06-29 22:01:27 +0000 | [diff] [blame] | 11567 | BAD_CAST xmlSchemaFacetTypeToString(facet->type), | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11568 | NULL, NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11569 | } | 
|  | 11570 | ret = -1; | 
|  | 11571 | } | 
|  | 11572 | break; | 
|  | 11573 | } | 
|  | 11574 | case XML_SCHEMA_FACET_WHITESPACE:{ | 
|  | 11575 | if (xmlStrEqual(facet->value, BAD_CAST "preserve")) { | 
|  | 11576 | facet->whitespace = XML_SCHEMAS_FACET_PRESERVE; | 
|  | 11577 | } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) { | 
|  | 11578 | facet->whitespace = XML_SCHEMAS_FACET_REPLACE; | 
|  | 11579 | } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) { | 
|  | 11580 | facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE; | 
|  | 11581 | } else { | 
|  | 11582 | if (ctxt != NULL) { | 
|  | 11583 | xmlSchemaPErr(ctxt, facet->node, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11584 | XML_SCHEMAP_INVALID_WHITE_SPACE, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11585 | "Type definition '%s': The value '%s' of the " | 
|  | 11586 | "facet 'whiteSpace' is not valid.\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11587 | name, facet->value); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11588 | } | 
|  | 11589 | ret = -1; | 
|  | 11590 | } | 
|  | 11591 | } | 
|  | 11592 | default: | 
|  | 11593 | break; | 
| Daniel Veillard | 8bc6cf9 | 2003-02-27 17:42:22 +0000 | [diff] [blame] | 11594 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11595 | return (ret); | 
| Daniel Veillard | 8bc6cf9 | 2003-02-27 17:42:22 +0000 | [diff] [blame] | 11596 | } | 
|  | 11597 |  | 
|  | 11598 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11599 | * xmlSchemaCheckDefaults: | 
|  | 11600 | * @typeDecl:  the schema type definition | 
|  | 11601 | * @ctxt:  the schema parser context | 
|  | 11602 | * | 
|  | 11603 | * Checks the default values types, especially for facets | 
|  | 11604 | */ | 
|  | 11605 | static void | 
|  | 11606 | xmlSchemaCheckDefaults(xmlSchemaTypePtr typeDecl, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11607 | xmlSchemaParserCtxtPtr ctxt, const xmlChar * name) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11608 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11609 | if (name == NULL) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11610 | name = typeDecl->name; | 
|  | 11611 | /* | 
|  | 11612 | * NOTE: It is intended to use the facets list, instead | 
|  | 11613 | * of facetSet. | 
|  | 11614 | */ | 
|  | 11615 | if (typeDecl->facets != NULL) { | 
|  | 11616 | xmlSchemaFacetPtr facet = typeDecl->facets; | 
|  | 11617 |  | 
|  | 11618 | while (facet != NULL) { | 
|  | 11619 | xmlSchemaCheckFacet(facet, typeDecl, ctxt, name); | 
|  | 11620 | facet = facet->next; | 
|  | 11621 | } | 
|  | 11622 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11623 | } | 
|  | 11624 |  | 
|  | 11625 | /** | 
| Daniel Veillard | 13e04c6 | 2002-04-23 17:51:29 +0000 | [diff] [blame] | 11626 | * xmlSchemaAttrGrpFixup: | 
|  | 11627 | * @attrgrpDecl:  the schema attribute definition | 
|  | 11628 | * @ctxt:  the schema parser context | 
|  | 11629 | * @name:  the attribute name | 
|  | 11630 | * | 
|  | 11631 | * Fixes finish doing the computations on the attributes definitions | 
|  | 11632 | */ | 
|  | 11633 | static void | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 11634 | xmlSchemaAttrGrpFixup(xmlSchemaAttributeGroupPtr attrgrp, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11635 | xmlSchemaParserCtxtPtr ctxt, const xmlChar * name) | 
| Daniel Veillard | 13e04c6 | 2002-04-23 17:51:29 +0000 | [diff] [blame] | 11636 | { | 
|  | 11637 | if (name == NULL) | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 11638 | name = attrgrp->name; | 
|  | 11639 | if (attrgrp->attributes != NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11640 | return; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 11641 | if (attrgrp->ref != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11642 | xmlSchemaAttributeGroupPtr ref; | 
| Daniel Veillard | 13e04c6 | 2002-04-23 17:51:29 +0000 | [diff] [blame] | 11643 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11644 | ref = xmlSchemaGetAttributeGroup(ctxt->schema, attrgrp->ref, | 
|  | 11645 | attrgrp->refNs); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11646 | if (ref == NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11647 | xmlSchemaPResCompAttrErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11648 | XML_SCHEMAP_SRC_RESOLVE, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11649 | NULL, (xmlSchemaTypePtr) attrgrp, attrgrp->node, | 
|  | 11650 | "ref", attrgrp->ref, attrgrp->refNs, | 
|  | 11651 | XML_SCHEMA_TYPE_ATTRIBUTEGROUP, NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11652 | return; | 
|  | 11653 | } | 
|  | 11654 | xmlSchemaAttrGrpFixup(ref, ctxt, NULL); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 11655 | attrgrp->attributes = ref->attributes; | 
|  | 11656 | attrgrp->attributeWildcard = ref->attributeWildcard; | 
|  | 11657 | } | 
| Daniel Veillard | 13e04c6 | 2002-04-23 17:51:29 +0000 | [diff] [blame] | 11658 | } | 
|  | 11659 |  | 
|  | 11660 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11661 | * xmlSchemaAttrFixup: | 
|  | 11662 | * @attrDecl:  the schema attribute definition | 
|  | 11663 | * @ctxt:  the schema parser context | 
|  | 11664 | * @name:  the attribute name | 
|  | 11665 | * | 
|  | 11666 | * Fixes finish doing the computations on the attributes definitions | 
|  | 11667 | */ | 
|  | 11668 | static void | 
|  | 11669 | xmlSchemaAttrFixup(xmlSchemaAttributePtr attrDecl, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11670 | xmlSchemaParserCtxtPtr ctxt, const xmlChar * name) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11671 | { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11672 | /* | 
|  | 11673 | * TODO: If including this is done twice (!) for every attribute. | 
|  | 11674 | */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11675 | /* | 
|  | 11676 | * The simple type definition corresponding to the <simpleType> element | 
|  | 11677 | * information item in the [children], if present, otherwise the simple | 
|  | 11678 | * type definition ·resolved· to by the ·actual value· of the type | 
|  | 11679 | * [attribute], if present, otherwise the ·simple ur-type definition·. | 
|  | 11680 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11681 | if (attrDecl->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED) | 
|  | 11682 | return; | 
|  | 11683 | attrDecl->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11684 | if (name == NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11685 | name = attrDecl->name; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11686 | if (attrDecl->subtypes != NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11687 | return; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11688 | if (attrDecl->typeName != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11689 | xmlSchemaTypePtr type; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11690 |  | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11691 | type = xmlSchemaGetType(ctxt->schema, attrDecl->typeName, | 
|  | 11692 | attrDecl->typeNs); | 
|  | 11693 | if (type == NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11694 | xmlSchemaPResCompAttrErr(ctxt, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11695 | XML_SCHEMAP_SRC_RESOLVE, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11696 | NULL, (xmlSchemaTypePtr) attrDecl, attrDecl->node, | 
|  | 11697 | "type", attrDecl->typeName, attrDecl->typeNs, | 
|  | 11698 | XML_SCHEMA_TYPE_BASIC, "type definition"); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11699 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11700 | attrDecl->subtypes = type; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11701 | } else if (attrDecl->ref != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11702 | xmlSchemaAttributePtr ref; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11703 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11704 | /* | 
|  | 11705 | * TODO: Evaluate, what errors could occur if the declaration is not | 
|  | 11706 | * found. It might be possible that the "typefixup" might crash if | 
|  | 11707 | * no ref declaration was found. | 
|  | 11708 | */ | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 11709 | ref = xmlSchemaGetAttribute(ctxt->schema, attrDecl->ref, attrDecl->refNs); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11710 | if (ref == NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11711 | xmlSchemaPResCompAttrErr(ctxt, | 
|  | 11712 | XML_SCHEMAP_SRC_RESOLVE, | 
|  | 11713 | NULL, (xmlSchemaTypePtr) attrDecl, attrDecl->node, | 
|  | 11714 | "ref", attrDecl->ref, attrDecl->refNs, | 
|  | 11715 | XML_SCHEMA_TYPE_ATTRIBUTE, NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11716 | return; | 
|  | 11717 | } | 
|  | 11718 | xmlSchemaAttrFixup(ref, ctxt, NULL); | 
|  | 11719 | attrDecl->subtypes = ref->subtypes; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 11720 | } else { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 11721 | attrDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11722 | } | 
|  | 11723 | } | 
|  | 11724 |  | 
|  | 11725 | /** | 
|  | 11726 | * xmlSchemaParse: | 
|  | 11727 | * @ctxt:  a schema validation context | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11728 | * | 
| Daniel Veillard | 01c13b5 | 2002-12-10 15:19:08 +0000 | [diff] [blame] | 11729 | * parse a schema definition resource and build an internal | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11730 | * XML Shema struture which can be used to validate instances. | 
|  | 11731 | * *WARNING* this interface is highly subject to change | 
|  | 11732 | * | 
|  | 11733 | * Returns the internal XML Schema structure built from the resource or | 
|  | 11734 | *         NULL in case of error | 
|  | 11735 | */ | 
|  | 11736 | xmlSchemaPtr | 
|  | 11737 | xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt) | 
|  | 11738 | { | 
|  | 11739 | xmlSchemaPtr ret = NULL; | 
|  | 11740 | xmlDocPtr doc; | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 11741 | xmlNodePtr root; | 
| Daniel Veillard | 75bb3bb | 2003-05-12 15:25:56 +0000 | [diff] [blame] | 11742 | int nberrors; | 
| Daniel Veillard | dda22c1 | 2004-01-24 08:31:30 +0000 | [diff] [blame] | 11743 | int preserve = 0; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11744 |  | 
|  | 11745 | xmlSchemaInitTypes(); | 
|  | 11746 |  | 
| Daniel Veillard | 6045c90 | 2002-10-09 21:13:59 +0000 | [diff] [blame] | 11747 | if (ctxt == NULL) | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11748 | return (NULL); | 
|  | 11749 |  | 
| Daniel Veillard | 75bb3bb | 2003-05-12 15:25:56 +0000 | [diff] [blame] | 11750 | nberrors = ctxt->nberrors; | 
|  | 11751 | ctxt->nberrors = 0; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11752 | ctxt->counter = 0; | 
|  | 11753 | ctxt->container = NULL; | 
|  | 11754 |  | 
|  | 11755 | /* | 
|  | 11756 | * First step is to parse the input document into an DOM/Infoset | 
|  | 11757 | */ | 
| Daniel Veillard | 6045c90 | 2002-10-09 21:13:59 +0000 | [diff] [blame] | 11758 | if (ctxt->URL != NULL) { | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 11759 | doc = xmlReadFile((const char *) ctxt->URL, NULL, | 
|  | 11760 | SCHEMAS_PARSE_OPTIONS); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11761 | if (doc == NULL) { | 
|  | 11762 | xmlSchemaPErr(ctxt, NULL, | 
|  | 11763 | XML_SCHEMAP_FAILED_LOAD, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11764 | "xmlSchemaParse: could not load '%s'.\n", | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11765 | ctxt->URL, NULL); | 
|  | 11766 | return (NULL); | 
|  | 11767 | } | 
| Daniel Veillard | 6045c90 | 2002-10-09 21:13:59 +0000 | [diff] [blame] | 11768 | } else if (ctxt->buffer != NULL) { | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 11769 | doc = xmlReadMemory(ctxt->buffer, ctxt->size, NULL, NULL, | 
|  | 11770 | SCHEMAS_PARSE_OPTIONS); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11771 | if (doc == NULL) { | 
|  | 11772 | xmlSchemaPErr(ctxt, NULL, | 
|  | 11773 | XML_SCHEMAP_FAILED_PARSE, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11774 | "xmlSchemaParse: could not parse.\n", | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11775 | NULL, NULL); | 
|  | 11776 | return (NULL); | 
|  | 11777 | } | 
|  | 11778 | doc->URL = xmlStrdup(BAD_CAST "in_memory_buffer"); | 
| Daniel Veillard | 6576528 | 2004-01-08 16:59:30 +0000 | [diff] [blame] | 11779 | ctxt->URL = xmlDictLookup(ctxt->dict, BAD_CAST "in_memory_buffer", -1); | 
| Daniel Veillard | 9d75150 | 2003-10-29 13:21:47 +0000 | [diff] [blame] | 11780 | } else if (ctxt->doc != NULL) { | 
|  | 11781 | doc = ctxt->doc; | 
| Daniel Veillard | dda22c1 | 2004-01-24 08:31:30 +0000 | [diff] [blame] | 11782 | preserve = 1; | 
| Daniel Veillard | 6045c90 | 2002-10-09 21:13:59 +0000 | [diff] [blame] | 11783 | } else { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11784 | xmlSchemaPErr(ctxt, NULL, | 
|  | 11785 | XML_SCHEMAP_NOTHING_TO_PARSE, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11786 | "xmlSchemaParse: could not parse.\n", | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11787 | NULL, NULL); | 
|  | 11788 | return (NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11789 | } | 
|  | 11790 |  | 
|  | 11791 | /* | 
|  | 11792 | * Then extract the root and Schema parse it | 
|  | 11793 | */ | 
|  | 11794 | root = xmlDocGetRootElement(doc); | 
|  | 11795 | if (root == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11796 | xmlSchemaPErr(ctxt, (xmlNodePtr) doc, | 
|  | 11797 | XML_SCHEMAP_NOROOT, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11798 | "The schema has no document element.\n", NULL, NULL); | 
| Daniel Veillard | dda22c1 | 2004-01-24 08:31:30 +0000 | [diff] [blame] | 11799 | if (!preserve) { | 
|  | 11800 | xmlFreeDoc(doc); | 
|  | 11801 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11802 | return (NULL); | 
|  | 11803 | } | 
|  | 11804 |  | 
|  | 11805 | /* | 
|  | 11806 | * Remove all the blank text nodes | 
|  | 11807 | */ | 
| Daniel Veillard | bd2904b | 2003-11-25 15:38:59 +0000 | [diff] [blame] | 11808 | xmlSchemaCleanupDoc(ctxt, root); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11809 |  | 
|  | 11810 | /* | 
|  | 11811 | * Then do the parsing for good | 
|  | 11812 | */ | 
|  | 11813 | ret = xmlSchemaParseSchema(ctxt, root); | 
| Daniel Veillard | 1d91386 | 2003-11-21 00:28:39 +0000 | [diff] [blame] | 11814 | if (ret == NULL) { | 
| Daniel Veillard | dda22c1 | 2004-01-24 08:31:30 +0000 | [diff] [blame] | 11815 | if (!preserve) { | 
|  | 11816 | xmlFreeDoc(doc); | 
|  | 11817 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11818 | return (NULL); | 
| Daniel Veillard | 1d91386 | 2003-11-21 00:28:39 +0000 | [diff] [blame] | 11819 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11820 | ret->doc = doc; | 
| Daniel Veillard | dda22c1 | 2004-01-24 08:31:30 +0000 | [diff] [blame] | 11821 | ret->preserve = preserve; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11822 | ctxt->schema = ret; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11823 | ctxt->ctxtType = NULL; | 
|  | 11824 | ctxt->parentItem = NULL; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11825 | /* | 
| Daniel Veillard | f2a1283 | 2003-11-24 13:04:35 +0000 | [diff] [blame] | 11826 | * Then fixup all attributes declarations | 
|  | 11827 | */ | 
|  | 11828 | xmlHashScan(ret->attrDecl, (xmlHashScanner) xmlSchemaAttrFixup, ctxt); | 
|  | 11829 |  | 
|  | 11830 | /* | 
|  | 11831 | * Then fixup all attributes group declarations | 
|  | 11832 | */ | 
|  | 11833 | xmlHashScan(ret->attrgrpDecl, (xmlHashScanner) xmlSchemaAttrGrpFixup, | 
|  | 11834 | ctxt); | 
|  | 11835 |  | 
|  | 11836 | /* | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11837 | * Then fixup all types properties | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11838 | */ | 
|  | 11839 | xmlHashScan(ret->typeDecl, (xmlHashScanner) xmlSchemaTypeFixup, ctxt); | 
|  | 11840 |  | 
|  | 11841 | /* | 
|  | 11842 | * Then fix references of element declaration; apply constraints. | 
|  | 11843 | */ | 
|  | 11844 | xmlHashScanFull(ret->elemDecl, | 
|  | 11845 | (xmlHashScannerFull) xmlSchemaRefFixupCallback, ctxt); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11846 |  | 
|  | 11847 | /* | 
|  | 11848 | * Then build the content model for all elements | 
|  | 11849 | */ | 
|  | 11850 | xmlHashScan(ret->elemDecl, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11851 | (xmlHashScanner) xmlSchemaBuildContentModel, ctxt); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11852 |  | 
|  | 11853 | /* | 
|  | 11854 | * Then check the defaults part of the type like facets values | 
|  | 11855 | */ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11856 | xmlHashScan(ret->typeDecl, (xmlHashScanner) xmlSchemaCheckDefaults, | 
|  | 11857 | ctxt); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11858 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11859 |  | 
| Daniel Veillard | 75bb3bb | 2003-05-12 15:25:56 +0000 | [diff] [blame] | 11860 | if (ctxt->nberrors != 0) { | 
|  | 11861 | xmlSchemaFree(ret); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11862 | ret = NULL; | 
| Daniel Veillard | 75bb3bb | 2003-05-12 15:25:56 +0000 | [diff] [blame] | 11863 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11864 | return (ret); | 
|  | 11865 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11866 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11867 | /** | 
| Daniel Veillard | 01c13b5 | 2002-12-10 15:19:08 +0000 | [diff] [blame] | 11868 | * xmlSchemaSetParserErrors: | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11869 | * @ctxt:  a schema validation context | 
| Daniel Veillard | 01c13b5 | 2002-12-10 15:19:08 +0000 | [diff] [blame] | 11870 | * @err:  the error callback | 
|  | 11871 | * @warn:  the warning callback | 
|  | 11872 | * @ctx:  contextual data for the callbacks | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11873 | * | 
| Daniel Veillard | 01c13b5 | 2002-12-10 15:19:08 +0000 | [diff] [blame] | 11874 | * Set the callback functions used to handle errors for a validation context | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11875 | */ | 
|  | 11876 | void | 
|  | 11877 | xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11878 | xmlSchemaValidityErrorFunc err, | 
|  | 11879 | xmlSchemaValidityWarningFunc warn, void *ctx) | 
|  | 11880 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11881 | if (ctxt == NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11882 | return; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 11883 | ctxt->error = err; | 
|  | 11884 | ctxt->warning = warn; | 
|  | 11885 | ctxt->userData = ctx; | 
|  | 11886 | } | 
|  | 11887 |  | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 11888 | /** | 
| Daniel Veillard | 259f0df | 2004-08-18 09:13:18 +0000 | [diff] [blame] | 11889 | * xmlSchemaGetParserErrors: | 
|  | 11890 | * @ctxt:  a XMl-Schema parser context | 
|  | 11891 | * @err: the error callback result | 
|  | 11892 | * @warn: the warning callback result | 
|  | 11893 | * @ctx: contextual data for the callbacks result | 
|  | 11894 | * | 
|  | 11895 | * Get the callback information used to handle errors for a parser context | 
|  | 11896 | * | 
|  | 11897 | * Returns -1 in case of failure, 0 otherwise | 
|  | 11898 | */ | 
|  | 11899 | int | 
|  | 11900 | xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt, | 
|  | 11901 | xmlSchemaValidityErrorFunc * err, | 
|  | 11902 | xmlSchemaValidityWarningFunc * warn, void **ctx) | 
|  | 11903 | { | 
|  | 11904 | if (ctxt == NULL) | 
|  | 11905 | return(-1); | 
|  | 11906 | if (err != NULL) | 
|  | 11907 | *err = ctxt->error; | 
|  | 11908 | if (warn != NULL) | 
|  | 11909 | *warn = ctxt->warning; | 
|  | 11910 | if (ctx != NULL) | 
|  | 11911 | *ctx = ctxt->userData; | 
|  | 11912 | return(0); | 
|  | 11913 | } | 
|  | 11914 |  | 
|  | 11915 | /** | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 11916 | * xmlSchemaFacetTypeToString: | 
|  | 11917 | * @type:  the facet type | 
|  | 11918 | * | 
|  | 11919 | * Convert the xmlSchemaTypeType to a char string. | 
|  | 11920 | * | 
|  | 11921 | * Returns the char string representation of the facet type if the | 
|  | 11922 | *     type is a facet and an "Internal Error" string otherwise. | 
|  | 11923 | */ | 
|  | 11924 | static const char * | 
|  | 11925 | xmlSchemaFacetTypeToString(xmlSchemaTypeType type) | 
|  | 11926 | { | 
|  | 11927 | switch (type) { | 
|  | 11928 | case XML_SCHEMA_FACET_PATTERN: | 
|  | 11929 | return ("pattern"); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11930 | case XML_SCHEMA_FACET_MAXEXCLUSIVE: | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 11931 | return ("maxExclusive"); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11932 | case XML_SCHEMA_FACET_MAXINCLUSIVE: | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 11933 | return ("maxInclusive"); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11934 | case XML_SCHEMA_FACET_MINEXCLUSIVE: | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 11935 | return ("minExclusive"); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11936 | case XML_SCHEMA_FACET_MININCLUSIVE: | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 11937 | return ("minInclusive"); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11938 | case XML_SCHEMA_FACET_WHITESPACE: | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 11939 | return ("whiteSpace"); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11940 | case XML_SCHEMA_FACET_ENUMERATION: | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 11941 | return ("enumeration"); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11942 | case XML_SCHEMA_FACET_LENGTH: | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 11943 | return ("length"); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11944 | case XML_SCHEMA_FACET_MAXLENGTH: | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 11945 | return ("maxLength"); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11946 | case XML_SCHEMA_FACET_MINLENGTH: | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 11947 | return ("minLength"); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11948 | case XML_SCHEMA_FACET_TOTALDIGITS: | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 11949 | return ("totalDigits"); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 11950 | case XML_SCHEMA_FACET_FRACTIONDIGITS: | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 11951 | return ("fractionDigits"); | 
|  | 11952 | default: | 
|  | 11953 | break; | 
|  | 11954 | } | 
|  | 11955 | return ("Internal Error"); | 
|  | 11956 | } | 
|  | 11957 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 11958 | static xmlChar * | 
|  | 11959 | xmlSchemaWhiteSpaceReplace(const xmlChar *value) { | 
|  | 11960 | const xmlChar *cur = value; | 
|  | 11961 | xmlChar *ret = NULL, *mcur; | 
|  | 11962 |  | 
|  | 11963 | if (value == NULL) | 
|  | 11964 | return(NULL); | 
|  | 11965 |  | 
|  | 11966 | while ((*cur != 0) && | 
|  | 11967 | (((*cur) != 0xd) && ((*cur) != 0x9) && ((*cur) != 0xa))) { | 
|  | 11968 | cur++; | 
|  | 11969 | } | 
|  | 11970 | if (*cur == 0) | 
|  | 11971 | return (NULL); | 
|  | 11972 | ret = xmlStrdup(value); | 
|  | 11973 | /* TODO FIXME: I guess gcc will bark at this. */ | 
|  | 11974 | mcur = (xmlChar *)  (ret + (cur - value)); | 
|  | 11975 | do { | 
|  | 11976 | if ( ((*mcur) == 0xd) || ((*mcur) == 0x9) || ((*mcur) == 0xa) ) | 
|  | 11977 | *mcur = ' '; | 
|  | 11978 | mcur++; | 
|  | 11979 | } while (*mcur != 0); | 
|  | 11980 | return(ret); | 
|  | 11981 | } | 
|  | 11982 |  | 
|  | 11983 | static int | 
|  | 11984 | xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type) | 
|  | 11985 | { | 
|  | 11986 | xmlSchemaTypePtr anc; | 
|  | 11987 |  | 
|  | 11988 | /* | 
|  | 11989 | * The normalization type can be changed only for types which are derived | 
|  | 11990 | * from xsd:string. | 
|  | 11991 | */ | 
|  | 11992 | if (type->type == XML_SCHEMA_TYPE_BASIC) { | 
|  | 11993 | if ((type->builtInType == XML_SCHEMAS_STRING) && | 
|  | 11994 | (type->builtInType == XML_SCHEMAS_NORMSTRING)) | 
|  | 11995 |  | 
|  | 11996 | return(XML_SCHEMAS_VAL_WTSP_PRESERVE); | 
|  | 11997 | else { | 
|  | 11998 | /* | 
|  | 11999 | * For all ·atomic· datatypes other than string (and types ·derived· | 
|  | 12000 | * by ·restriction· from it) the value of whiteSpace is fixed to | 
|  | 12001 | * collapse | 
|  | 12002 | */ | 
|  | 12003 | return(XML_SCHEMAS_VAL_WTSP_COLLAPSE); | 
|  | 12004 | } | 
|  | 12005 | } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) { | 
|  | 12006 | /* | 
|  | 12007 | * For list types the facet "whiteSpace" is fixed to "collapse". | 
|  | 12008 | */ | 
|  | 12009 | return (XML_SCHEMAS_VAL_WTSP_COLLAPSE); | 
|  | 12010 | } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) { | 
|  | 12011 | return (-1); | 
|  | 12012 | } else if (type->facetSet != NULL) { | 
|  | 12013 | xmlSchemaTypePtr anyST; | 
|  | 12014 | xmlSchemaFacetLinkPtr lin; | 
|  | 12015 |  | 
|  | 12016 | /* | 
|  | 12017 | * Atomic types. | 
|  | 12018 | */ | 
|  | 12019 | anyST = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); | 
|  | 12020 | anc = type->baseType; | 
|  | 12021 | do { | 
|  | 12022 | /* | 
|  | 12023 | * For all ·atomic· datatypes other than string (and types ·derived· | 
|  | 12024 | * by ·restriction· from it) the value of whiteSpace is fixed to | 
|  | 12025 | * collapse | 
|  | 12026 | */ | 
|  | 12027 | if ((anc->type == XML_SCHEMA_TYPE_BASIC) && | 
|  | 12028 | (anc->builtInType == XML_SCHEMAS_STRING)) { | 
|  | 12029 |  | 
|  | 12030 | lin = type->facetSet; | 
|  | 12031 | do { | 
|  | 12032 | if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) { | 
|  | 12033 | if (lin->facet->whitespace == | 
|  | 12034 | XML_SCHEMAS_FACET_COLLAPSE) { | 
|  | 12035 | return(XML_SCHEMAS_VAL_WTSP_COLLAPSE); | 
|  | 12036 | } else if (lin->facet->whitespace == | 
|  | 12037 | XML_SCHEMAS_FACET_REPLACE) { | 
|  | 12038 | return(XML_SCHEMAS_VAL_WTSP_REPLACE); | 
|  | 12039 | } else | 
|  | 12040 | return(XML_SCHEMAS_VAL_WTSP_PRESERVE); | 
|  | 12041 | break; | 
|  | 12042 | } | 
|  | 12043 | lin = lin->next; | 
|  | 12044 | } while (lin != NULL); | 
|  | 12045 | break; | 
|  | 12046 | } | 
|  | 12047 | anc = anc->baseType; | 
|  | 12048 | } while (anc != anyST); | 
|  | 12049 | return (XML_SCHEMAS_VAL_WTSP_COLLAPSE); | 
|  | 12050 | } | 
|  | 12051 | return (-1); | 
|  | 12052 | } | 
|  | 12053 |  | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 12054 | /** | 
| Daniel Veillard | 377e1a9 | 2004-04-16 16:30:05 +0000 | [diff] [blame] | 12055 | * xmlSchemaValidateFacetsInternal: | 
|  | 12056 | * @ctxt:  a schema validation context | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12057 | * @type:  the type holding the facets | 
| Daniel Veillard | 377e1a9 | 2004-04-16 16:30:05 +0000 | [diff] [blame] | 12058 | * @facets:  the list of facets to check | 
|  | 12059 | * @value:  the lexical repr of the value to validate | 
|  | 12060 | * @val:  the precomputed value | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 12061 | * @fireErrors:  if 0, only internal errors will be fired; | 
|  | 12062 | *		 otherwise all errors will be fired. | 
| Daniel Veillard | 377e1a9 | 2004-04-16 16:30:05 +0000 | [diff] [blame] | 12063 | * | 
|  | 12064 | * Check a value against all facet conditions | 
|  | 12065 | * | 
|  | 12066 | * Returns 0 if the element is schemas valid, a positive error code | 
|  | 12067 | *     number otherwise and -1 in case of internal or API error. | 
|  | 12068 | */ | 
|  | 12069 | static int | 
|  | 12070 | xmlSchemaValidateFacetsInternal(xmlSchemaValidCtxtPtr ctxt, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12071 | xmlSchemaTypePtr type, | 
|  | 12072 | const xmlChar * value, | 
|  | 12073 | unsigned long length, | 
|  | 12074 | int fireErrors) | 
| Daniel Veillard | 377e1a9 | 2004-04-16 16:30:05 +0000 | [diff] [blame] | 12075 | { | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 12076 | int ret = 0; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12077 | xmlSchemaTypePtr  biType; /* The build-in type. */ | 
|  | 12078 | xmlSchemaTypePtr tmpType; | 
|  | 12079 | xmlSchemaFacetLinkPtr facetLink; | 
|  | 12080 | int retFacet, hasFacet; | 
|  | 12081 | xmlSchemaFacetPtr facet; | 
|  | 12082 | unsigned long len = 0; | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 12083 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12084 | #ifdef DEBUG_UNION_VALIDATION | 
|  | 12085 | printf("Facets of type: '%s'\n", (const char *) type->name); | 
|  | 12086 | printf("  fireErrors: %d\n", fireErrors); | 
|  | 12087 | #endif | 
|  | 12088 |  | 
|  | 12089 | /* | 
|  | 12090 | * NOTE: Do not jump away, if the facetSet of the given type is | 
|  | 12091 | * empty: until now, "pattern" facets of the *base types* need to | 
|  | 12092 | * be checked as well. | 
|  | 12093 | */ | 
|  | 12094 | biType = type->baseType; | 
|  | 12095 | while ((biType != NULL) && (biType->type != XML_SCHEMA_TYPE_BASIC)) | 
|  | 12096 | biType = biType->baseType; | 
|  | 12097 | if (biType == NULL) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12098 | xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12099 | "Internal error: xmlSchemaValidateFacetsInternal, " | 
|  | 12100 | "the base type axis of the given type '%s' does not resolve to " | 
|  | 12101 | "a built-in type.\n", | 
|  | 12102 | type->name, NULL); | 
|  | 12103 | return (-1); | 
|  | 12104 | } | 
|  | 12105 |  | 
|  | 12106 | if (type->facetSet != NULL) { | 
|  | 12107 | facetLink = type->facetSet; | 
|  | 12108 | while (facetLink != NULL) { | 
|  | 12109 | facet = facetLink->facet; | 
|  | 12110 | /* | 
|  | 12111 | * Skip the pattern "whiteSpace": it is used to | 
|  | 12112 | * format the character content beforehand. | 
|  | 12113 | */ | 
|  | 12114 | switch (facet->type) { | 
|  | 12115 | case XML_SCHEMA_FACET_WHITESPACE: | 
|  | 12116 | case XML_SCHEMA_FACET_PATTERN: | 
|  | 12117 | case XML_SCHEMA_FACET_ENUMERATION: | 
|  | 12118 | break; | 
|  | 12119 | case XML_SCHEMA_FACET_LENGTH: | 
|  | 12120 | case XML_SCHEMA_FACET_MINLENGTH: | 
|  | 12121 | case XML_SCHEMA_FACET_MAXLENGTH: | 
|  | 12122 | if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) { | 
|  | 12123 | ret = xmlSchemaValidateListSimpleTypeFacet(facet, | 
|  | 12124 | value, length, 0); | 
|  | 12125 | len = length; | 
|  | 12126 | } else | 
|  | 12127 | ret = xmlSchemaValidateLengthFacet(biType, facet, | 
|  | 12128 | value, ctxt->value, &len); | 
|  | 12129 | break; | 
|  | 12130 | default: | 
|  | 12131 | ret = xmlSchemaValidateFacet(biType, facet, value, | 
|  | 12132 | ctxt->value); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12133 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12134 | if (ret < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12135 | xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12136 | "Internal error: xmlSchemaValidateFacetsInternal, " | 
|  | 12137 | "validating facet of type '%s'.\n", | 
|  | 12138 | type->name, NULL); | 
|  | 12139 | break; | 
|  | 12140 | } else if ((ret > 0) && (fireErrors)) { | 
|  | 12141 | xmlSchemaVFacetErr(ctxt, ret, ctxt->cur, value, len, | 
|  | 12142 | type, facet, NULL, NULL, NULL, NULL); | 
|  | 12143 | } | 
|  | 12144 |  | 
|  | 12145 | facetLink = facetLink->next; | 
|  | 12146 | } | 
|  | 12147 | if (ret >= 0) { | 
|  | 12148 | /* | 
|  | 12149 | * Process enumerations. | 
|  | 12150 | */ | 
|  | 12151 | retFacet = 0; | 
|  | 12152 | facetLink = type->facetSet; | 
|  | 12153 | while (facetLink != NULL) { | 
|  | 12154 | if (facetLink->facet->type == XML_SCHEMA_FACET_ENUMERATION) { | 
|  | 12155 | retFacet = xmlSchemaValidateFacet(biType, facetLink->facet, | 
|  | 12156 | value, ctxt->value); | 
|  | 12157 | if (retFacet <= 0) | 
|  | 12158 | break; | 
|  | 12159 | } | 
|  | 12160 | facetLink = facetLink->next; | 
|  | 12161 | } | 
|  | 12162 | if (retFacet > 0) { | 
|  | 12163 | ret = XML_SCHEMAV_CVC_ENUMERATION_VALID; | 
|  | 12164 | if (fireErrors) | 
|  | 12165 | xmlSchemaVFacetErr(ctxt, ret, ctxt->cur, | 
|  | 12166 | value, 0, type, NULL, NULL, NULL, NULL, NULL); | 
|  | 12167 | } else if (retFacet < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12168 | xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12169 | "Internal error: xmlSchemaValidateFacetsInternal, " | 
|  | 12170 | "validating facet of type '%s'.\n", | 
|  | 12171 | BAD_CAST "enumeration", NULL); | 
|  | 12172 | ret = -1; | 
|  | 12173 | } | 
|  | 12174 | } | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 12175 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12176 | if (ret >= 0) { | 
|  | 12177 | /* | 
|  | 12178 | * Process patters. Pattern facets are ORed at type level | 
|  | 12179 | * and ANDed if derived. Walk the base type axis. | 
|  | 12180 | */ | 
|  | 12181 | hasFacet = 0; | 
|  | 12182 | tmpType = type; | 
|  | 12183 | facet = NULL; | 
|  | 12184 | do { | 
|  | 12185 | retFacet = 0; | 
|  | 12186 | for (facetLink = tmpType->facetSet; facetLink != NULL; | 
|  | 12187 | facetLink = facetLink->next) { | 
|  | 12188 | if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN) | 
|  | 12189 | continue; | 
|  | 12190 | retFacet = xmlSchemaValidateFacet(biType, facetLink->facet, | 
|  | 12191 | value, ctxt->value); | 
|  | 12192 | if (retFacet <= 0) | 
|  | 12193 | break; | 
|  | 12194 | else | 
|  | 12195 | /* Save the last non-validating facet. */ | 
|  | 12196 | facet = facetLink->facet; | 
|  | 12197 | } | 
|  | 12198 | if (retFacet != 0) | 
|  | 12199 | break; | 
|  | 12200 | tmpType = tmpType->baseType; | 
|  | 12201 | } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC)); | 
|  | 12202 | if (retFacet < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12203 | xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12204 | "Internal error: xmlSchemaValidateSimpleTypeValue, " | 
|  | 12205 | "validating 'pattern' facets of type '%s'.\n", | 
|  | 12206 | tmpType->name, NULL); | 
|  | 12207 | ret = -1; | 
|  | 12208 | } else if (retFacet > 0) { | 
|  | 12209 | ret = XML_SCHEMAV_CVC_PATTERN_VALID; | 
|  | 12210 | if (fireErrors) { | 
|  | 12211 | xmlSchemaVFacetErr(ctxt, ret, ctxt->cur, value, 0, type, facet, | 
|  | 12212 | NULL, NULL, NULL, NULL); | 
|  | 12213 | } | 
|  | 12214 | } | 
|  | 12215 | } | 
|  | 12216 |  | 
| Daniel Veillard | d3b9cd8 | 2003-04-09 11:24:17 +0000 | [diff] [blame] | 12217 | return (ret); | 
|  | 12218 | } | 
|  | 12219 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12220 | /************************************************************************ | 
|  | 12221 | * 									* | 
|  | 12222 | * 			Simple type validation				* | 
|  | 12223 | * 									* | 
|  | 12224 | ************************************************************************/ | 
| Daniel Veillard | 377e1a9 | 2004-04-16 16:30:05 +0000 | [diff] [blame] | 12225 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12226 |  | 
|  | 12227 | /************************************************************************ | 
|  | 12228 | * 									* | 
|  | 12229 | * 			DOM Validation code				* | 
|  | 12230 | * 									* | 
|  | 12231 | ************************************************************************/ | 
|  | 12232 |  | 
|  | 12233 | static int xmlSchemaValidateContent(xmlSchemaValidCtxtPtr ctxt, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12234 | xmlNodePtr node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12235 | static int xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12236 | xmlNodePtr elem, | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 12237 | xmlSchemaTypePtr type); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12238 | static int xmlSchemaValidateType(xmlSchemaValidCtxtPtr ctxt, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12239 | xmlNodePtr elem, | 
|  | 12240 | xmlSchemaElementPtr elemDecl, | 
|  | 12241 | xmlSchemaTypePtr type); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12242 |  | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 12243 |  | 
|  | 12244 | /** | 
|  | 12245 | * xmlSchemaFreeAttrStates: | 
|  | 12246 | * @state:  a list of attribute states | 
|  | 12247 | * | 
|  | 12248 | * Free the given list of attribute states | 
|  | 12249 | * | 
|  | 12250 | */ | 
|  | 12251 | static void | 
|  | 12252 | xmlSchemaFreeAttributeStates(xmlSchemaAttrStatePtr state) | 
|  | 12253 | { | 
|  | 12254 | xmlSchemaAttrStatePtr tmp; | 
|  | 12255 | while (state != NULL) { | 
|  | 12256 | tmp = state; | 
|  | 12257 | state = state->next; | 
|  | 12258 | xmlFree(tmp); | 
|  | 12259 | } | 
|  | 12260 | } | 
|  | 12261 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12262 | /** | 
|  | 12263 | * xmlSchemaRegisterAttributes: | 
|  | 12264 | * @ctxt:  a schema validation context | 
|  | 12265 | * @attrs:  a list of attributes | 
|  | 12266 | * | 
|  | 12267 | * Register the list of attributes as the set to be validated on that element | 
|  | 12268 | * | 
|  | 12269 | * Returns -1 in case of error, 0 otherwise | 
|  | 12270 | */ | 
|  | 12271 | static int | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12272 | xmlSchemaRegisterAttributes(xmlSchemaValidCtxtPtr ctxt, xmlAttrPtr attrs) | 
|  | 12273 | { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 12274 | xmlSchemaAttrStatePtr tmp; | 
|  | 12275 |  | 
|  | 12276 | ctxt->attr = NULL; | 
|  | 12277 | ctxt->attrTop = NULL; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12278 | while (attrs != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12279 | if ((attrs->ns != NULL) && | 
|  | 12280 | (xmlStrEqual(attrs->ns->href, xmlSchemaInstanceNs))) { | 
|  | 12281 | attrs = attrs->next; | 
|  | 12282 | continue; | 
|  | 12283 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12284 | tmp = (xmlSchemaAttrStatePtr) | 
|  | 12285 | xmlMalloc(sizeof(xmlSchemaAttrState)); | 
|  | 12286 | if (tmp == NULL) { | 
|  | 12287 | xmlSchemaVErrMemory(ctxt, "registering attributes", NULL); | 
|  | 12288 | return (-1); | 
|  | 12289 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 12290 | tmp->attr = attrs; | 
|  | 12291 | tmp->state = XML_SCHEMAS_ATTR_UNKNOWN; | 
|  | 12292 | tmp->next = NULL; | 
|  | 12293 | if (ctxt->attr == NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12294 | ctxt->attr = tmp; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 12295 | else | 
|  | 12296 | ctxt->attrTop->next = tmp; | 
|  | 12297 | ctxt->attrTop = tmp; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12298 | attrs = attrs->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12299 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12300 | return (0); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12301 | } | 
|  | 12302 |  | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12303 | #if 0 /* Currently not used */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12304 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12305 | * xmlSchemaValidateCheckNodeList | 
|  | 12306 | * @nodelist: the list of nodes | 
|  | 12307 | * | 
|  | 12308 | * Check the node list is only made of text nodes and entities pointing | 
|  | 12309 | * to text nodes | 
|  | 12310 | * | 
|  | 12311 | * Returns 1 if true, 0 if false and -1 in case of error | 
|  | 12312 | */ | 
|  | 12313 | static int | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12314 | xmlSchemaValidateCheckNodeList(xmlNodePtr nodelist) | 
|  | 12315 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12316 | while (nodelist != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12317 | if (nodelist->type == XML_ENTITY_REF_NODE) { | 
|  | 12318 | TODO                /* implement recursion in the entity content */ | 
|  | 12319 | } | 
|  | 12320 | if ((nodelist->type != XML_TEXT_NODE) && | 
|  | 12321 | (nodelist->type != XML_COMMENT_NODE) && | 
|  | 12322 | (nodelist->type != XML_PI_NODE) && | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 12323 | (nodelist->type != XML_CDATA_SECTION_NODE)) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12324 | return (0); | 
|  | 12325 | } | 
|  | 12326 | nodelist = nodelist->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12327 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12328 | return (1); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12329 | } | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12330 | #endif | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12331 |  | 
|  | 12332 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12333 | * xmlSchemaValidateCallback: | 
|  | 12334 | * @ctxt:  a schema validation context | 
|  | 12335 | * @name:  the name of the element detected (might be NULL) | 
|  | 12336 | * @type:  the type | 
|  | 12337 | * | 
|  | 12338 | * A transition has been made in the automata associated to an element | 
|  | 12339 | * content model | 
|  | 12340 | */ | 
|  | 12341 | static void | 
|  | 12342 | xmlSchemaValidateCallback(xmlSchemaValidCtxtPtr ctxt, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12343 | const xmlChar * name ATTRIBUTE_UNUSED, | 
|  | 12344 | xmlSchemaTypePtr type, xmlNodePtr node) | 
|  | 12345 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12346 | xmlSchemaTypePtr oldtype = ctxt->type; | 
|  | 12347 | xmlNodePtr oldnode = ctxt->node; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12348 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12349 | #ifdef DEBUG_CONTENT | 
| Daniel Veillard | 8651f53 | 2002-04-17 09:06:27 +0000 | [diff] [blame] | 12350 | xmlGenericError(xmlGenericErrorContext, | 
|  | 12351 | "xmlSchemaValidateCallback: %s, %s, %s\n", | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12352 | name, type->name, node->name); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12353 | #endif | 
|  | 12354 | ctxt->type = type; | 
|  | 12355 | ctxt->node = node; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12356 | xmlSchemaValidateContent(ctxt, node); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12357 | ctxt->type = oldtype; | 
|  | 12358 | ctxt->node = oldnode; | 
|  | 12359 | } | 
|  | 12360 |  | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12361 | /** | 
|  | 12362 | * xmlSchemaValidateSimpleTypeValue: | 
|  | 12363 | * @ctxt:  a schema validation context | 
|  | 12364 | * @value: the value to be validated | 
|  | 12365 | * @fireErrors: shall errors be reported? | 
|  | 12366 | * @applyFacets: shall facets be applied? | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12367 | * @normalize: shall the value be normalized? | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12368 | * | 
|  | 12369 | * Validates a value by the given type (user derived or built-in). | 
|  | 12370 | * | 
|  | 12371 | * Returns 0 if the value is valid, a positive error code | 
|  | 12372 | * number otherwise and -1 in case of an internal or API error. | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12373 | */ | 
|  | 12374 | static int | 
|  | 12375 | xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt, | 
|  | 12376 | const xmlChar *value, | 
|  | 12377 | int fireErrors, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12378 | int applyFacets, | 
|  | 12379 | int normalize) | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12380 | { | 
|  | 12381 | xmlSchemaTypePtr type; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12382 | int ret = 0; | 
|  | 12383 | xmlChar *normValue = NULL; | 
|  | 12384 | int wtsp; | 
|  | 12385 |  | 
|  | 12386 | type = ctxt->type; | 
|  | 12387 | wtsp = ctxt->valueWS; | 
|  | 12388 | /* | 
|  | 12389 | * Normalize the value. | 
|  | 12390 | */ | 
|  | 12391 | if (normalize && | 
|  | 12392 | (ctxt->valueWS != XML_SCHEMAS_VAL_WTSP_COLLAPSE)) { | 
|  | 12393 | int norm = xmlSchemaGetWhiteSpaceFacetValue(type); | 
|  | 12394 |  | 
|  | 12395 | if ((norm != -1) && (norm > ctxt->valueWS)) { | 
|  | 12396 | if (norm == XML_SCHEMAS_VAL_WTSP_COLLAPSE) | 
|  | 12397 | normValue = xmlSchemaCollapseString(value); | 
|  | 12398 | else | 
|  | 12399 | normValue = xmlSchemaWhiteSpaceReplace(value); | 
|  | 12400 | ctxt->valueWS = norm; | 
|  | 12401 | if (normValue != NULL) | 
|  | 12402 | value = (const xmlChar *) normValue; | 
|  | 12403 | } | 
|  | 12404 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 12405 | if (type->type == XML_SCHEMA_TYPE_COMPLEX) { | 
|  | 12406 | xmlSchemaTypePtr base, anyType; | 
|  | 12407 |  | 
|  | 12408 | anyType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); | 
|  | 12409 |  | 
|  | 12410 | base = type->baseType; | 
|  | 12411 | while ((base != NULL) && | 
|  | 12412 | (base->type != XML_SCHEMA_TYPE_SIMPLE) && | 
|  | 12413 | (base->type != XML_SCHEMA_TYPE_BASIC) && | 
|  | 12414 | (base != anyType)) { | 
|  | 12415 | base = base->baseType; | 
|  | 12416 | } | 
|  | 12417 | ctxt->type = base; | 
|  | 12418 | ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 1, 0, 1); | 
|  | 12419 | ctxt->type = type; | 
|  | 12420 | if (ret < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12421 | xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_INTERNAL, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 12422 | "Internal error: xmlSchemaValidateSimpleTypeValue, " | 
|  | 12423 | "validating complex type '%s'\n", | 
|  | 12424 | type->name, NULL); | 
|  | 12425 | } else if ((ret == 0) && (applyFacets) && (type->facetSet != NULL)) { | 
|  | 12426 | /* | 
|  | 12427 | * Check facets. | 
|  | 12428 | */ | 
|  | 12429 | /* | 
|  | 12430 | * This is somehow not nice, since if an error occurs | 
|  | 12431 | * the reported type will be the complex type; the spec | 
|  | 12432 | * wants a simple type to be created on the complex type | 
|  | 12433 | * if it has a simple content. For now we have to live with | 
|  | 12434 | * it. | 
|  | 12435 | */ | 
|  | 12436 | ret = xmlSchemaValidateFacetsInternal(ctxt, type, | 
|  | 12437 | value, 0, fireErrors); | 
|  | 12438 | if (ret < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12439 | xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_INTERNAL, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 12440 | "Internal error: xmlSchemaValidateSimpleTypeValue, " | 
|  | 12441 | "validating facets of complex type '%s'\n", | 
|  | 12442 | type->name, NULL); | 
|  | 12443 | } else if (ret > 0) { | 
|  | 12444 | ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; | 
|  | 12445 | /* | 
|  | 12446 | Disabled, since the facet validation already reports errors. | 
|  | 12447 | if (fireErrors) | 
|  | 12448 | xmlSchemaVSimpleTypeErr(ctxt, ret, ctxt->cur, value, type); | 
|  | 12449 | */ | 
|  | 12450 | } | 
|  | 12451 | } | 
|  | 12452 | } else if (type->type == XML_SCHEMA_TYPE_BASIC) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12453 | xmlNodePtr child; | 
|  | 12454 |  | 
|  | 12455 | if (ctxt->value != NULL) { | 
|  | 12456 | xmlSchemaFreeValue(ctxt->value); | 
|  | 12457 | ctxt->value = NULL; | 
|  | 12458 | } | 
|  | 12459 | child = ctxt->node; | 
|  | 12460 | while (child != NULL) { | 
|  | 12461 | switch (child->type) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12462 | case XML_TEXT_NODE: | 
|  | 12463 | case XML_CDATA_SECTION_NODE: | 
|  | 12464 | case XML_PI_NODE: | 
|  | 12465 | case XML_COMMENT_NODE: | 
|  | 12466 | case XML_XINCLUDE_START: | 
|  | 12467 | case XML_XINCLUDE_END: | 
|  | 12468 | break; | 
|  | 12469 | case XML_ENTITY_REF_NODE: | 
|  | 12470 | case XML_ENTITY_NODE: | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12471 | /* TODO: Scour the entities for illegal nodes. */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12472 | TODO break; | 
|  | 12473 | case XML_ELEMENT_NODE: { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12474 | /* NOTE: Changed to an internal error, since the | 
|  | 12475 | * existence of an element node will be already checked in | 
|  | 12476 | * xmlSchemaValidateSimpleTypeElement and in | 
|  | 12477 | * xmlSchemaValidateComplexType. | 
|  | 12478 | */ | 
|  | 12479 | xmlSchemaVCustomErr(ctxt, | 
|  | 12480 | XML_SCHEMAV_INTERNAL, | 
|  | 12481 | /* XML_SCHEMAS_ERR_INVALIDELEM, */ | 
|  | 12482 | ctxt->cur, type, | 
|  | 12483 | "Element found in content", NULL); | 
|  | 12484 | return (XML_SCHEMAV_INTERNAL); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12485 | } | 
|  | 12486 | case XML_ATTRIBUTE_NODE: | 
|  | 12487 | case XML_DOCUMENT_NODE: | 
|  | 12488 | case XML_DOCUMENT_TYPE_NODE: | 
|  | 12489 | case XML_DOCUMENT_FRAG_NODE: | 
|  | 12490 | case XML_NOTATION_NODE: | 
|  | 12491 | case XML_HTML_DOCUMENT_NODE: | 
|  | 12492 | case XML_DTD_NODE: | 
|  | 12493 | case XML_ELEMENT_DECL: | 
|  | 12494 | case XML_ATTRIBUTE_DECL: | 
|  | 12495 | case XML_ENTITY_DECL: | 
|  | 12496 | case XML_NAMESPACE_DECL: | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12497 | #ifdef LIBXML_DOCB_ENABLED | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12498 | case XML_DOCB_DOCUMENT_NODE: | 
|  | 12499 | #endif | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12500 | { | 
|  | 12501 | xmlSchemaVCustomErr(ctxt, | 
|  | 12502 | XML_SCHEMAV_INTERNAL, | 
|  | 12503 | /* XML_SCHEMAS_ERR_INVALIDELEM, */ | 
|  | 12504 | ctxt->cur, NULL, | 
|  | 12505 | "Node of unexpected type found in content", | 
|  | 12506 | NULL); | 
|  | 12507 | return (XML_SCHEMAV_INTERNAL); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12508 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12509 | } | 
|  | 12510 | child = child->next; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12511 |  | 
|  | 12512 | } | 
|  | 12513 | ret = xmlSchemaValPredefTypeNodeNoNorm(type, value, &(ctxt->value), ctxt->cur); | 
|  | 12514 | if (ret > 0) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12515 | if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) | 
|  | 12516 | ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; | 
|  | 12517 | else | 
|  | 12518 | ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12519 | if (fireErrors) | 
|  | 12520 | xmlSchemaVSimpleTypeErr(ctxt, ret, ctxt->cur, value, type); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12521 | } else if (ret < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12522 | xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12523 | "Internal error: xmlSchemaValidateSimpleTypeValue, " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12524 | "validating built-in type '%s'\n", type->name, NULL); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12525 | } | 
|  | 12526 | } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) { | 
|  | 12527 | /* 1.2.1 if {variety} is ·atomic· then the string must ·match· | 
|  | 12528 | * a literal in the ·lexical space· of {base type definition} | 
|  | 12529 | */ | 
|  | 12530 | ctxt->type = type->baseType; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12531 | ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 0, 0, 0); | 
|  | 12532 | ctxt->type = type; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12533 | if (ret < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12534 | xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12535 | "Internal error: xmlSchemaValidateSimpleTypeValue, " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12536 | "validating atomic simple type '%s'\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12537 | type->name, NULL); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12538 | } else if (ret > 0) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12539 | ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12540 | if (fireErrors) | 
|  | 12541 | xmlSchemaVSimpleTypeErr(ctxt, ret, ctxt->cur, value, type); | 
|  | 12542 | } else if ((applyFacets) && (type->facetSet != NULL)) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12543 | /* | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12544 | * Check facets. | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12545 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12546 | ret = xmlSchemaValidateFacetsInternal(ctxt, type, | 
|  | 12547 | value, 0, fireErrors); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12548 | if (ret < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12549 | xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12550 | "Internal error: xmlSchemaValidateSimpleTypeValue, " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12551 | "validating facets of atomic simple type '%s'\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12552 | type->name, NULL); | 
|  | 12553 | } else if (ret > 0) { | 
|  | 12554 | ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12555 | /* | 
|  | 12556 | Disabled, since the facet validation already reports errors. | 
|  | 12557 | if (fireErrors) | 
|  | 12558 | xmlSchemaVSimpleTypeErr(ctxt, ret, ctxt->cur, value, type); | 
|  | 12559 | */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12560 | } | 
|  | 12561 | } | 
|  | 12562 | } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) { | 
|  | 12563 |  | 
|  | 12564 | xmlSchemaTypePtr tmpType; | 
|  | 12565 | const xmlChar *cur, *end; | 
|  | 12566 | xmlChar *tmp; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12567 | unsigned long len = 0; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12568 |  | 
|  | 12569 | /* 1.2.2 if {variety} is ·list· then the string must be a sequence | 
|  | 12570 | * of white space separated tokens, each of which ·match·es a literal | 
|  | 12571 | * in the ·lexical space· of {item type definition} | 
|  | 12572 | */ | 
|  | 12573 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12574 | tmpType = xmlSchemaGetListSimpleTypeItemType(type); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12575 | cur = value; | 
|  | 12576 | do { | 
|  | 12577 | while (IS_BLANK_CH(*cur)) | 
|  | 12578 | cur++; | 
|  | 12579 | end = cur; | 
|  | 12580 | while ((*end != 0) && (!(IS_BLANK_CH(*end)))) | 
|  | 12581 | end++; | 
|  | 12582 | if (end == cur) | 
|  | 12583 | break; | 
|  | 12584 | tmp = xmlStrndup(cur, end - cur); | 
|  | 12585 | len++; | 
|  | 12586 | ctxt->type = tmpType; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12587 | ret = xmlSchemaValidateSimpleTypeValue(ctxt, tmp, 0, 1, 0); | 
|  | 12588 | ctxt->type = type; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12589 | xmlFree(tmp); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12590 | if (ret < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12591 | xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12592 | "Internal error: xmlSchemaValidateSimpleTypeValue, " | 
|  | 12593 | "validating an item of list simple type '%s'\n", | 
|  | 12594 | type->name, NULL); | 
|  | 12595 | break; | 
|  | 12596 | } else if (ret > 0) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12597 | ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12598 | if (fireErrors) | 
|  | 12599 | xmlSchemaVSimpleTypeErr(ctxt, ret, ctxt->cur, value, type); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12600 | break; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12601 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12602 | cur = end; | 
|  | 12603 | } while (*cur != 0); | 
|  | 12604 | /* | 
|  | 12605 | * Check facets. | 
|  | 12606 | */ | 
|  | 12607 | if (ret < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12608 | xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12609 | "Internal error: xmlSchemaValidateSimpleTypeValue, " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12610 | "validating list simple type '%s'\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12611 | type->name, NULL); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12612 | } else if ((ret == 0) && (applyFacets)) { | 
|  | 12613 | ret = xmlSchemaValidateFacetsInternal(ctxt, type, | 
|  | 12614 | value, len, fireErrors); | 
|  | 12615 | if (ret < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12616 | xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12617 | "Internal error: xmlSchemaValidateSimpleTypeValue, " | 
|  | 12618 | "validating facets of list simple type '%s'\n", | 
|  | 12619 | type->name, NULL); | 
|  | 12620 | } else if (ret > 0) { | 
|  | 12621 | ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12622 | /* | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12623 | Disabled, since the facet validation already reports errors. | 
|  | 12624 | if (fireErrors) | 
|  | 12625 | xmlSchemaVSimpleTypeErr(ctxt, ret, ctxt->cur, value, type); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12626 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12627 | } | 
|  | 12628 |  | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12629 | } | 
|  | 12630 | } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) { | 
|  | 12631 | xmlSchemaTypeLinkPtr memberLink; | 
|  | 12632 |  | 
|  | 12633 | /* | 
|  | 12634 | * TODO: For all datatypes ·derived· by ·union·  whiteSpace does | 
|  | 12635 | * not apply directly; however, the normalization behavior of ·union· | 
|  | 12636 | * types is controlled by the value of whiteSpace on that one of the | 
|  | 12637 | * ·memberTypes· against which the ·union· is successfully validated. | 
|  | 12638 | * | 
|  | 12639 | * This means that the value is normalized by the first validating | 
|  | 12640 | * member type, then the facets of the union type are applied. This | 
|  | 12641 | * needs changing of the value! | 
|  | 12642 | */ | 
|  | 12643 |  | 
|  | 12644 | /* | 
|  | 12645 | * 1.2.3 if {variety} is ·union· then the string must ·match· a | 
|  | 12646 | * literal in the ·lexical space· of at least one member of | 
|  | 12647 | * {member type definitions} | 
|  | 12648 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12649 | #ifdef DEBUG_UNION_VALIDATION | 
|  | 12650 | printf("Union ST     : '%s'\n", (const char *) type->name); | 
|  | 12651 | printf("  fireErrors : %d\n", fireErrors); | 
|  | 12652 | printf("  applyFacets: %d\n", applyFacets); | 
|  | 12653 | #endif | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12654 | memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type); | 
|  | 12655 | if (memberLink == NULL) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12656 | xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12657 | "Internal error: xmlSchemaValidateSimpleTypeValue, " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12658 | "union simple type '%s' has no member types\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12659 | type->name, NULL); | 
|  | 12660 | ret = -1; | 
|  | 12661 | } | 
|  | 12662 | if (ret == 0) { | 
|  | 12663 | while (memberLink != NULL) { | 
|  | 12664 | ctxt->type = memberLink->type; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12665 | ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 0, 1, 1); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12666 | if ((ret <= 0) || (ret == 0)) | 
|  | 12667 | break; | 
|  | 12668 | memberLink = memberLink->next; | 
|  | 12669 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12670 | ctxt->type = type; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12671 | if (ret < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12672 | xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12673 | "Internal error: xmlSchemaValidateSimpleTypeValue, " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12674 | "validating members of union simple type '%s'\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12675 | type->name, NULL); | 
|  | 12676 | } else if (ret > 0) { | 
|  | 12677 | ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12678 | if (fireErrors) | 
|  | 12679 | xmlSchemaVSimpleTypeErr(ctxt, ret, ctxt->cur, value, type); | 
|  | 12680 | } | 
|  | 12681 | } | 
|  | 12682 | /* | 
|  | 12683 | * Apply facets (pattern, enumeration). | 
|  | 12684 | */ | 
|  | 12685 | if ((ret == 0) && (applyFacets) && (type->facetSet != NULL)) { | 
|  | 12686 | int mws; | 
|  | 12687 | /* | 
|  | 12688 | * The normalization behavior of ·union· types is controlled by | 
|  | 12689 | * the value of whiteSpace on that one of the ·memberTypes· | 
|  | 12690 | * against which the ·union· is successfully validated. | 
|  | 12691 | */ | 
|  | 12692 | if (normValue != NULL) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12693 | xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12694 | "Internal error: xmlSchemaValidateSimpleTypeValue, " | 
|  | 12695 | "the value was already normalized for the union simple " | 
|  | 12696 | "type '%s'.\n", type->name, NULL); | 
|  | 12697 | } | 
|  | 12698 | mws = xmlSchemaGetWhiteSpaceFacetValue(memberLink->type); | 
|  | 12699 | if (mws > ctxt->valueWS) { | 
|  | 12700 | if (mws == XML_SCHEMAS_VAL_WTSP_COLLAPSE) | 
|  | 12701 | normValue = xmlSchemaCollapseString(value); | 
|  | 12702 | else | 
|  | 12703 | normValue = xmlSchemaWhiteSpaceReplace(value); | 
|  | 12704 | if (normValue != NULL) | 
|  | 12705 | value = (const xmlChar *) normValue; | 
|  | 12706 | } | 
|  | 12707 |  | 
|  | 12708 | ret = xmlSchemaValidateFacetsInternal(ctxt, type, | 
|  | 12709 | value, 0, fireErrors); | 
|  | 12710 | if (ret < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12711 | xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12712 | "Internal error: xmlSchemaValidateSimpleTypeValue, " | 
|  | 12713 | "validating facets of union simple type '%s'\n", | 
|  | 12714 | type->name, NULL); | 
|  | 12715 | } else if (ret > 0) { | 
|  | 12716 | ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3; | 
|  | 12717 | /* | 
|  | 12718 | if (fireErrors) | 
|  | 12719 | xmlSchemaVSimpleTypeErr(ctxt, ret, ctxt->cur, value, type); | 
|  | 12720 | */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12721 | } | 
|  | 12722 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12723 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12724 | ctxt->type = type; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12725 | ctxt->valueWS = wtsp; | 
|  | 12726 | if (normValue != NULL) | 
|  | 12727 | xmlFree(normValue); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12728 | return (ret); | 
|  | 12729 | } | 
|  | 12730 |  | 
|  | 12731 | /** | 
|  | 12732 | * xmlSchemaValidateSimpleTypeElement: | 
|  | 12733 | * @ctxt:  a schema validation context | 
|  | 12734 | * @node:  the element node to be validated. | 
|  | 12735 | * | 
|  | 12736 | * Validate the element against a simple type. | 
|  | 12737 | * | 
|  | 12738 | * Returns 0 if the element is valid, a positive error code | 
|  | 12739 | * number otherwise and -1 in case of an internal or API error. | 
|  | 12740 | */ | 
|  | 12741 | static int | 
|  | 12742 | xmlSchemaValidateSimpleTypeElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node) | 
|  | 12743 | { | 
|  | 12744 | xmlNodePtr child; | 
|  | 12745 | xmlSchemaTypePtr type; | 
|  | 12746 | xmlAttrPtr attr; | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12747 | int ret = 0; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12748 | xmlChar *value; | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12749 | xmlNodePtr cur; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12750 |  | 
|  | 12751 |  | 
|  | 12752 | child = ctxt->node; | 
|  | 12753 | type = ctxt->type; | 
|  | 12754 |  | 
|  | 12755 | if ((ctxt == NULL) || (type == NULL)) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12756 | xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12757 | "Internal error: xmlSchemaValidateSimpleTypeElement %s\n", | 
|  | 12758 | node->name, NULL); | 
|  | 12759 | return (-1); | 
|  | 12760 | } | 
|  | 12761 |  | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12762 | /* | 
|  | 12763 | * cvc-type: 3.1.2 The element information item must have no element | 
|  | 12764 | * information item [children]. | 
|  | 12765 | */ | 
|  | 12766 | cur = child; | 
|  | 12767 | while (cur != NULL) { | 
|  | 12768 | if (cur->type == XML_ELEMENT_NODE) { | 
|  | 12769 | xmlSchemaVCustomErr(ctxt, | 
|  | 12770 | XML_SCHEMAV_CVC_TYPE_3_1_2, | 
|  | 12771 | node, type, | 
|  | 12772 | "No element content allowed", NULL); | 
|  | 12773 | return (XML_SCHEMAV_CVC_TYPE_3_1_2); | 
|  | 12774 | } | 
|  | 12775 | cur = cur->next; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12776 | } | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12777 |  | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12778 | /* | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12779 | * cvc-type 3.1.1: | 
|  | 12780 | * | 
|  | 12781 | * The attributes of must be empty, excepting those whose namespace name | 
|  | 12782 | * is identical to http://www.w3.org/2001/XMLSchema-instance and whose local | 
|  | 12783 | * name is one of type, nil, schemaLocation or noNamespaceSchemaLocation. | 
|  | 12784 | */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12785 | attr = node->properties; | 
|  | 12786 | while (attr != NULL) { | 
|  | 12787 | if ((attr->ns == NULL) || | 
|  | 12788 | (!xmlStrEqual(attr->ns->href, xmlSchemaInstanceNs)) || | 
|  | 12789 | ((!xmlStrEqual(attr->name, BAD_CAST "type")) && | 
|  | 12790 | (!xmlStrEqual(attr->name, BAD_CAST "nil")) && | 
|  | 12791 | (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation")) && | 
|  | 12792 | (!xmlStrEqual | 
|  | 12793 | (attr->name, BAD_CAST "noNamespaceSchemaLocation")))) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12794 | xmlSchemaVIllegalAttrErr(ctxt, | 
|  | 12795 | XML_SCHEMAV_CVC_TYPE_3_1_1, attr); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12796 | return (ctxt->err); | 
|  | 12797 | } | 
|  | 12798 | attr = attr->next; | 
|  | 12799 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 12800 | if ((type->type != XML_SCHEMA_TYPE_BASIC) || | 
|  | 12801 | (type->builtInType != XML_SCHEMAS_ANYSIMPLETYPE)) { | 
|  | 12802 | value = xmlNodeGetContent(child); | 
|  | 12803 | ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 1, 1, 1); | 
|  | 12804 | if (value != NULL) | 
|  | 12805 | xmlFree(value); | 
|  | 12806 | ctxt->type = type; | 
|  | 12807 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12808 | return (ret); | 
|  | 12809 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12810 |  | 
|  | 12811 | /** | 
|  | 12812 | * xmlSchemaValidateElementType: | 
|  | 12813 | * @ctxt:  a schema validation context | 
|  | 12814 | * @node:  the top node. | 
|  | 12815 | * | 
|  | 12816 | * Validate the content of an element type. | 
|  | 12817 | * Validation Rule: Element Locally Valid (Complex Type) | 
|  | 12818 | * | 
|  | 12819 | * Returns 0 if the element is schemas valid, a positive error code | 
|  | 12820 | *     number otherwise and -1 in case of internal or API error. | 
|  | 12821 | */ | 
|  | 12822 | static int | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12823 | xmlSchemaValidateElementType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node) | 
|  | 12824 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12825 | xmlNodePtr child; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12826 | xmlRegExecCtxtPtr oldregexp;        /* cont model of the parent */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12827 | xmlSchemaElementPtr decl; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 12828 | int ret; | 
|  | 12829 | xmlSchemaAttrStatePtr attrs = NULL, attrTop = NULL; | 
|  | 12830 |  | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 12831 | /* This one is called by xmlSchemaValidateContent only. */ | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 12832 | /* | 
|  | 12833 | * TODO: Look into "xmlSchemaValidateElement" for missing parts, which should | 
|  | 12834 | * go in here as well. | 
|  | 12835 | */ | 
|  | 12836 |  | 
|  | 12837 | /* TODO: Is this one called always with an element declaration as the | 
|  | 12838 | * context's type? | 
|  | 12839 | */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12840 |  | 
|  | 12841 | oldregexp = ctxt->regexp; | 
|  | 12842 |  | 
|  | 12843 | child = ctxt->node; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12844 | decl = (xmlSchemaElementPtr) ctxt->type; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12845 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12846 | if ((ctxt == NULL) || (decl == NULL)) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12847 | xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL, | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 12848 | "Internal error: xmlSchemaValidateElementType\n", | 
|  | 12849 | node->name, NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12850 | return (-1); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12851 | } | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12852 | /* | 
|  | 12853 | * TODO: Since this should be already checked by the content model automaton, | 
|  | 12854 | * and we want to get rid of the XML_SCHEMAS_ERR... types, the error code | 
|  | 12855 | * has been changed to XML_SCHEMAV_INTERNAL. | 
|  | 12856 | */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12857 | if (child == NULL) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12858 | if (decl->minOccurs > 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12859 | xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL, | 
|  | 12860 | /* XML_SCHEMAS_ERR_MISSING, */ | 
|  | 12861 | "Element %s: missing child %s\n", | 
|  | 12862 | node->name, decl->name); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12863 | } | 
|  | 12864 | return (ctxt->err); | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12865 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12866 |  | 
|  | 12867 | /* | 
|  | 12868 | * Verify the element matches | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12869 | * TODO, FIXME: Can this still happen here? Isn't this already checked | 
|  | 12870 | * by the content model automaton? | 
|  | 12871 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12872 | if (!xmlStrEqual(child->name, decl->name)) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12873 | xmlSchemaVErr3(ctxt, node, XML_SCHEMAV_INTERNAL, | 
|  | 12874 | /* XML_SCHEMAS_ERR_WRONGELEM, */ | 
|  | 12875 | "Element %s: missing child %s found %s\n", | 
|  | 12876 | node->name, decl->name, child->name); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12877 | return (ctxt->err); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12878 | } | 
|  | 12879 | /* | 
|  | 12880 | * Verify the attributes | 
|  | 12881 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12882 | /* | 
|  | 12883 | * TODO: This "attrTop" thing is not needed any more. | 
|  | 12884 | */ | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 12885 | attrs = ctxt->attr; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12886 | attrTop = ctxt->attrTop; | 
|  | 12887 | xmlSchemaRegisterAttributes(ctxt, child->properties); | 
|  | 12888 | xmlSchemaValidateAttributes(ctxt, child, decl->subtypes); | 
|  | 12889 | if (ctxt->attr != NULL) | 
|  | 12890 | xmlSchemaFreeAttributeStates(ctxt->attr); | 
|  | 12891 | ctxt->attr = attrs; | 
|  | 12892 | ctxt->attrTop = attrTop; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 12893 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12894 | /* | 
|  | 12895 | * Verify the element content recursively | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12896 | */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12897 | oldregexp = ctxt->regexp; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12898 | /* | 
|  | 12899 | * FIXME TODO: This one creates a regexp even if no content | 
|  | 12900 | * model was defined. Somehow ->contModel is always not NULL | 
|  | 12901 | * for complex types, even if they are empty. | 
|  | 12902 | */ | 
|  | 12903 | if (decl->contModel != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12904 | ctxt->regexp = xmlRegNewExecCtxt(decl->contModel, | 
|  | 12905 | (xmlRegExecCallbacks) | 
|  | 12906 | xmlSchemaValidateCallback, ctxt); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12907 | #ifdef DEBUG_AUTOMATA | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12908 | xmlGenericError(xmlGenericErrorContext, "====> %s\n", node->name); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12909 | #endif | 
|  | 12910 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12911 | xmlSchemaValidateType(ctxt, child, decl, decl->subtypes); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12912 |  | 
|  | 12913 | if (decl->contModel != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12914 | ret = xmlRegExecPushString(ctxt->regexp, NULL, NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12915 | #ifdef DEBUG_AUTOMATA | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12916 | xmlGenericError(xmlGenericErrorContext, | 
|  | 12917 | "====> %s : %d\n", node->name, ret); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12918 | #endif | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12919 | if (ret == 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12920 | xmlSchemaVCustomErr(ctxt, XML_SCHEMAV_ELEMENT_CONTENT, | 
|  | 12921 | node, decl->subtypes, "The element content is not valid", NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12922 | } else if (ret < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12923 | xmlSchemaVCustomErr(ctxt, XML_SCHEMAV_ELEMENT_CONTENT, | 
|  | 12924 | node, decl->subtypes, "The element content is not valid", NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12925 | #ifdef DEBUG_CONTENT | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12926 | } else { | 
|  | 12927 | xmlGenericError(xmlGenericErrorContext, | 
|  | 12928 | "Element %s content check succeeded\n", | 
|  | 12929 | node->name); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12930 |  | 
|  | 12931 | #endif | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12932 | } | 
|  | 12933 | xmlRegFreeExecCtxt(ctxt->regexp); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12934 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12935 | ctxt->regexp = oldregexp; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12936 | ctxt->node = child; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12937 | ctxt->type = (xmlSchemaTypePtr) decl; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 12938 | return (ctxt->err); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12939 | } | 
|  | 12940 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 12941 | /** | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12942 | * xmlSchemaValidateAnyInternal: | 
|  | 12943 | * @ctxt:  a schema validation context | 
|  | 12944 | * @node:  the top node. | 
|  | 12945 | * | 
|  | 12946 | * Represents the recursive portion of xmlSchemaValidateAny. Not | 
|  | 12947 | * intended to be used by other functions. | 
|  | 12948 | * | 
|  | 12949 | * Returns 0 if the element is valid, a positive error code | 
|  | 12950 | * number otherwise and -1 in case of an internal error. | 
|  | 12951 | */ | 
|  | 12952 | static int | 
|  | 12953 | xmlSchemaValidateAnyInternal(xmlSchemaValidCtxtPtr ctxt, | 
|  | 12954 | xmlSchemaWildcardPtr wild, | 
|  | 12955 | xmlNodePtr node) | 
|  | 12956 | { | 
|  | 12957 | const xmlChar *uri; | 
|  | 12958 | int ret = 0; | 
|  | 12959 | xmlNodePtr child; | 
|  | 12960 |  | 
|  | 12961 | if (wild->processContents != XML_SCHEMAS_ANY_SKIP) { | 
|  | 12962 | xmlSchemaElementPtr decl = NULL; | 
|  | 12963 |  | 
|  | 12964 | if (node->ns != NULL) | 
|  | 12965 | decl = xmlHashLookup3(ctxt->schema->elemDecl, | 
|  | 12966 | node->name, node->ns->href, NULL); | 
|  | 12967 | else | 
|  | 12968 | decl = xmlHashLookup3(ctxt->schema->elemDecl, node->name, NULL, NULL); | 
|  | 12969 | if (decl != NULL) { | 
|  | 12970 | ctxt->node = node; | 
|  | 12971 | ctxt->type = (xmlSchemaTypePtr) decl; | 
|  | 12972 | ret = xmlSchemaValidateElementType(ctxt, node->parent); | 
|  | 12973 | if (ret < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12974 | xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12975 | "Internal error: xmlSchemaValidateAnyInternal, " | 
|  | 12976 | "validating an element in the context of a wildcard.", | 
|  | 12977 | NULL, NULL); | 
|  | 12978 | } else if (ret > 0) | 
|  | 12979 | return (ret); | 
|  | 12980 | } else if (wild->processContents == XML_SCHEMAS_ANY_STRICT) { | 
|  | 12981 | /* TODO: Change to proper error code. */ | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12982 | xmlSchemaVWildcardErr(ctxt, XML_SCHEMAV_CVC_ELT_1, | 
|  | 12983 | node, wild, "Global declaration is absent"); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12984 | return (ctxt->err); | 
|  | 12985 | } | 
|  | 12986 | } | 
|  | 12987 | if (node->children != NULL) { | 
|  | 12988 | child = node->children; | 
|  | 12989 | do { | 
|  | 12990 | if (child->type == XML_ELEMENT_NODE) { | 
|  | 12991 | if (child->ns != NULL) | 
|  | 12992 | uri = child->ns->href; | 
|  | 12993 | else | 
|  | 12994 | uri = NULL; | 
|  | 12995 | if (xmlSchemaMatchesWildcardNs(wild, uri) == 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 12996 | /* TODO: error code. */ | 
|  | 12997 | xmlSchemaVWildcardErr(ctxt, XML_SCHEMAV_ELEMENT_CONTENT, | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 12998 | child, wild, | 
|  | 12999 | "The namespace of the element is not allowed."); | 
|  | 13000 | return (ctxt->err); | 
|  | 13001 | } | 
|  | 13002 | ret = xmlSchemaValidateAnyInternal(ctxt, wild, child); | 
|  | 13003 | if (ret != 0) | 
|  | 13004 | return (ret); | 
|  | 13005 | } | 
|  | 13006 | child = child->next; | 
|  | 13007 | } while  (child != NULL); | 
|  | 13008 | } | 
|  | 13009 | return (0); | 
|  | 13010 | } | 
|  | 13011 |  | 
|  | 13012 | /** | 
|  | 13013 | * xmlSchemaValidateAny: | 
|  | 13014 | * @ctxt:  a schema validation context | 
|  | 13015 | * | 
|  | 13016 | * Returns 0 if the element is valid, a positive error code | 
|  | 13017 | * number otherwise and -1 in case of an internal or API error. | 
|  | 13018 | */ | 
|  | 13019 | static int | 
|  | 13020 | xmlSchemaValidateAny(xmlSchemaValidCtxtPtr ctxt) | 
|  | 13021 | { | 
|  | 13022 | return(xmlSchemaValidateAnyInternal(ctxt, | 
|  | 13023 | ctxt->type->attributeWildcard, ctxt->cur)); | 
|  | 13024 | } | 
|  | 13025 |  | 
|  | 13026 | /** | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 13027 | * xmlSchemaValidateAnyTypeContent: | 
|  | 13028 | * @ctxt:  a schema validation context | 
|  | 13029 | * @node: the current element | 
|  | 13030 | * | 
|  | 13031 | * This one validates the content of an element of the type | 
|  | 13032 | * 'anyType'. The process contents of the wildcard of 'anyType' is "lax", | 
|  | 13033 | * thus elements in the subtree will be validated, if a corresponding | 
|  | 13034 | * declaration in the schema exists. | 
|  | 13035 | * | 
|  | 13036 | * Returns 0 if the element and its subtree is valid, a positive error code | 
|  | 13037 | * otherwise and -1 in case of an internal or API error. | 
|  | 13038 | */ | 
|  | 13039 | static int | 
|  | 13040 | xmlSchemaValidateAnyTypeContent(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node) | 
|  | 13041 | { | 
|  | 13042 | xmlNodePtr top = node; | 
|  | 13043 | xmlSchemaTypePtr decl; | 
|  | 13044 | int skipContent, ret; | 
|  | 13045 |  | 
|  | 13046 | if (node->children == NULL) | 
|  | 13047 | return (0); | 
|  | 13048 | node = node->children; | 
|  | 13049 | while (node != NULL) { | 
|  | 13050 | skipContent = 0; | 
|  | 13051 | if (node->type == XML_ELEMENT_NODE) { | 
|  | 13052 | /* | 
|  | 13053 | * The process contents of the wildcard is "lax", thus | 
|  | 13054 | * we need to validate the element if a declaration | 
|  | 13055 | * exists. | 
|  | 13056 | */ | 
|  | 13057 | if (node->ns != NULL) | 
|  | 13058 | decl = xmlHashLookup3(ctxt->schema->elemDecl, | 
|  | 13059 | node->name, node->ns->href, NULL); | 
|  | 13060 | else | 
|  | 13061 | decl = xmlHashLookup3(ctxt->schema->elemDecl, node->name, NULL, NULL); | 
|  | 13062 |  | 
|  | 13063 | if (decl != NULL) { | 
|  | 13064 | ctxt->node = node; | 
|  | 13065 | ctxt->type = (xmlSchemaTypePtr) decl; | 
|  | 13066 | ret = xmlSchemaValidateElementType(ctxt, node->parent); | 
|  | 13067 | if (ret < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13068 | xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL, | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 13069 | "Internal error: xmlSchemaValidateAnyTypeContent, " | 
|  | 13070 | "validating an element in the context of a wildcard.", | 
|  | 13071 | NULL, NULL); | 
|  | 13072 | return (ret); | 
|  | 13073 | } else if (ret > 0) | 
|  | 13074 | return (ret); | 
|  | 13075 | skipContent = 1; | 
|  | 13076 | } | 
|  | 13077 | } | 
|  | 13078 | /* | 
|  | 13079 | * Browse the full subtree, deep first. | 
|  | 13080 | */ | 
|  | 13081 | if ((skipContent == 0) && (node->children != NULL)) { | 
|  | 13082 | /* deep first */ | 
|  | 13083 | node = node->children; | 
|  | 13084 | } else if ((node != top) && (node->next != NULL)) { | 
|  | 13085 | /* then siblings */ | 
|  | 13086 | node = node->next; | 
|  | 13087 | } else if (node != top) { | 
|  | 13088 | /* go up to parents->next if needed */ | 
|  | 13089 | while (node != top) { | 
|  | 13090 | if (node->parent != NULL) | 
|  | 13091 | node = node->parent; | 
|  | 13092 | if ((node != top) && (node->next != NULL)) { | 
|  | 13093 | node = node->next; | 
|  | 13094 | break; | 
|  | 13095 | } | 
|  | 13096 | if (node->parent == NULL) { | 
|  | 13097 | node = NULL; | 
|  | 13098 | break; | 
|  | 13099 | } | 
|  | 13100 | } | 
|  | 13101 | /* exit condition */ | 
|  | 13102 | if (node == top) | 
|  | 13103 | node = NULL; | 
|  | 13104 | } else | 
|  | 13105 | break; | 
|  | 13106 | } | 
|  | 13107 | return (0); | 
|  | 13108 | } | 
|  | 13109 |  | 
|  | 13110 | /** | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13111 | * xmlSchemaHasElemOrCharContent: | 
|  | 13112 | * @node:  the node | 
|  | 13113 | * | 
|  | 13114 | * Scours the content of the given node for element | 
|  | 13115 | * and character nodes. | 
|  | 13116 | * | 
|  | 13117 | * Returns 1 if an element or character node is found, | 
|  | 13118 | * 0 otherwise. | 
|  | 13119 | */ | 
|  | 13120 | static int | 
|  | 13121 | xmlSchemaHasElemOrCharContent(xmlNodePtr node) | 
|  | 13122 | { | 
|  | 13123 | xmlNodePtr cur; | 
|  | 13124 |  | 
|  | 13125 | if (node == NULL) | 
|  | 13126 | return (0); | 
|  | 13127 | cur = node->children; | 
|  | 13128 | while (cur != NULL) { | 
|  | 13129 | if ((cur->type == XML_ELEMENT_NODE) || | 
|  | 13130 | /* | 
|  | 13131 | * TODO: Ask Daniel if these are all character nodes. | 
|  | 13132 | */ | 
|  | 13133 | (cur->type == XML_TEXT_NODE) || | 
|  | 13134 | (cur->type == XML_CDATA_SECTION_NODE) || | 
|  | 13135 | /* | 
|  | 13136 | * TODO: How XML_ENTITY_NODEs evaluated? | 
|  | 13137 | */ | 
|  | 13138 | (cur->type == XML_ENTITY_REF_NODE) || | 
|  | 13139 | (cur->type == XML_ENTITY_NODE)) { | 
|  | 13140 | return (1); | 
|  | 13141 | } | 
|  | 13142 | cur = cur->next; | 
|  | 13143 | } | 
|  | 13144 | return (0); | 
|  | 13145 | } | 
|  | 13146 |  | 
|  | 13147 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13148 | * xmlSchemaValidateComplexType: | 
|  | 13149 | * @ctxt:  a schema validation context | 
|  | 13150 | * @node:  the top node. | 
|  | 13151 | * | 
|  | 13152 | * Validate the content of an element expected to be a complex type type | 
|  | 13153 | * xmlschema-1.html#cvc-complex-type | 
|  | 13154 | * Validation Rule: Element Locally Valid (Complex Type) | 
|  | 13155 | * | 
|  | 13156 | * Returns 0 if the element is schemas valid, a positive error code | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13157 | * number otherwise and -1 in case of internal or API error. | 
|  | 13158 | * Note on reported errors: Although it might be nice to report | 
|  | 13159 | * the name of the simple/complex type, used to validate the content | 
|  | 13160 | * of a node, it is quite unnecessary: for global defined types | 
|  | 13161 | * the local name of the element is equal to the NCName of the type, | 
|  | 13162 | * for local defined types it makes no sense to output the internal | 
|  | 13163 | * computed name of the type. TODO: Instead, one should attach the | 
|  | 13164 | * struct of the type involved to the error handler - this allows | 
|  | 13165 | * the report of any additional information by the user. | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13166 | */ | 
|  | 13167 | static int | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13168 | xmlSchemaValidateComplexType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node) | 
|  | 13169 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13170 | xmlNodePtr child; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13171 | xmlSchemaTypePtr type; | 
|  | 13172 | int ret = 0; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 13173 | const xmlChar *nsUri; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13174 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13175 | child = ctxt->node; | 
|  | 13176 | type = ctxt->type; | 
| Daniel Veillard | 82bbbd4 | 2003-05-11 20:16:09 +0000 | [diff] [blame] | 13177 | ctxt->cur = node; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13178 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13179 | switch (type->contentType) { | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13180 | case XML_SCHEMA_CONTENT_EMPTY: { | 
|  | 13181 | /* | 
|  | 13182 | * 1 If the {content type} is empty, then the element information | 
|  | 13183 | * item has no character or element information item [children]. | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13184 | */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13185 | /* | 
|  | 13186 | * TODO: Is the entity stuff correct? | 
|  | 13187 | */ | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13188 | if (xmlSchemaHasElemOrCharContent(node) == 1) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 13189 | xmlSchemaVComplexTypeErr(ctxt, | 
|  | 13190 | XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, | 
|  | 13191 | node, type, | 
|  | 13192 | "Character or element content is not allowed, " | 
|  | 13193 | "because the content type is empty"); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13194 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13195 | break; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13196 | } | 
|  | 13197 | case XML_SCHEMA_CONTENT_ELEMENTS: | 
|  | 13198 | case XML_SCHEMA_CONTENT_MIXED: | 
|  | 13199 | while (child != NULL) { | 
|  | 13200 | if (child->type == XML_ELEMENT_NODE) { | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13201 | if (child->ns != NULL) | 
|  | 13202 | nsUri = child->ns->href; | 
|  | 13203 | else | 
|  | 13204 | nsUri = NULL; | 
|  | 13205 | ret = xmlRegExecPushString2(ctxt->regexp, | 
|  | 13206 | child->name, nsUri, child); | 
|  | 13207 | #ifdef DEBUG_AUTOMATA | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13208 | if (ret < 0) | 
|  | 13209 | xmlGenericError(xmlGenericErrorContext, | 
|  | 13210 | "  --> %s Error\n", child->name); | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 13211 | else | 
|  | 13212 | xmlGenericError(xmlGenericErrorContext, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13213 | "  --> %s\n", child->name); | 
|  | 13214 | #endif | 
|  | 13215 | } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) && | 
|  | 13216 | /* | 
|  | 13217 | * TODO: Ask Daniel if this are all character nodes. | 
|  | 13218 | */ | 
|  | 13219 | (((child->type == XML_TEXT_NODE) && (!IS_BLANK_NODE(child))) || | 
|  | 13220 | (child->type == XML_ENTITY_NODE) || | 
|  | 13221 | (child->type == XML_ENTITY_REF_NODE) || | 
|  | 13222 | (child->type == XML_CDATA_SECTION_NODE))) { | 
|  | 13223 | /* | 
|  | 13224 | * 2.3 If the {content type} is element-only, then the | 
|  | 13225 | * element information item has no character information | 
|  | 13226 | * item [children] other than those whose [character | 
|  | 13227 | * code] is defined as a white space in [XML 1.0 (Second | 
|  | 13228 | * Edition)]. | 
|  | 13229 | */ | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 13230 | xmlSchemaVComplexTypeErr(ctxt, | 
|  | 13231 | XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, | 
|  | 13232 | node, type, | 
|  | 13233 | "Character content is not allowed, " | 
|  | 13234 | "because the content type is element-only"); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13235 | break; | 
|  | 13236 | } | 
|  | 13237 | child = child->next; | 
|  | 13238 | } | 
|  | 13239 | break; | 
|  | 13240 | case XML_SCHEMA_CONTENT_SIMPLE: | 
|  | 13241 | case XML_SCHEMA_CONTENT_BASIC:{ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13242 | xmlChar *value = NULL; | 
|  | 13243 | /* | 
|  | 13244 | * We hit a complexType with a simpleContent resolving | 
|  | 13245 | * to a user derived or built-in simple type. | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 13246 | */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13247 | /* | 
|  | 13248 | * 2.2 If the {content type} is a simple type definition, | 
|  | 13249 | * then the element information item has no element | 
|  | 13250 | * information item [children], and the ·normalized value· | 
|  | 13251 | * of the element information item is ·valid· with respect | 
|  | 13252 | * to that simple type definition as defined by String | 
|  | 13253 | * Valid (§3.14.4). | 
|  | 13254 | */ | 
|  | 13255 | child = node->children; | 
|  | 13256 | while (child != NULL) { | 
|  | 13257 | if (child->type == XML_ELEMENT_NODE) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 13258 | xmlSchemaVComplexTypeErr(ctxt, | 
|  | 13259 | XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2, | 
|  | 13260 | node, type, | 
|  | 13261 | "Element content is not allowed, because " | 
|  | 13262 | "the content type is a simple type"); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13263 | ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2; | 
|  | 13264 | break; | 
|  | 13265 | } | 
|  | 13266 | child = child->next; | 
|  | 13267 | } | 
|  | 13268 | if (ret == 0) { | 
|  | 13269 | /* | 
|  | 13270 | * Validate the character content against a simple type. | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13271 | */ | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13272 | if (ctxt->node == NULL) | 
|  | 13273 | value = NULL; | 
|  | 13274 | else | 
|  | 13275 | value = xmlNodeGetContent(node); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13276 | ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 1, 1, 1); | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 13277 | if (ret > 0) { | 
|  | 13278 | /* | 
|  | 13279 | * NOTE: Although an error will be reported by | 
|  | 13280 | * xmlSchemaValidateSimpleTypeValue, the spec wants | 
|  | 13281 | * a specific complex type error to be reported | 
|  | 13282 | * additionally. | 
|  | 13283 | */ | 
|  | 13284 | xmlSchemaVComplexTypeErr(ctxt, | 
|  | 13285 | XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2, | 
|  | 13286 | node, type, | 
|  | 13287 | "The character content is not valid"); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13288 | ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2; | 
|  | 13289 | } else if (ret < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13290 | xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13291 | "Internal error: xmlSchemaValidateComplexType, " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13292 | "Element '%s': Error while validating character " | 
|  | 13293 | "content against complex type '%s'.\n", | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13294 | node->name, type->name); | 
|  | 13295 | return (-1); | 
|  | 13296 | } | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 13297 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13298 | if (ret == 0) { | 
|  | 13299 | /* | 
|  | 13300 | * Apply facets of the complexType. Be sure to pass the | 
|  | 13301 | * built-in type to xmlSchemaValidateFacetsInternal. | 
|  | 13302 | */ | 
|  | 13303 | /* TODO: I don't know yet if the facets of the simple type | 
|  | 13304 | * are used, or if the facets, defined by this complex type, | 
|  | 13305 | * are to be used only. This here applies both facet sets. | 
|  | 13306 | */ | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13307 |  | 
|  | 13308 | ret = xmlSchemaValidateFacetsInternal(ctxt, type, | 
|  | 13309 | value, 0, 1); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13310 | if (ret > 0) { | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 13311 | xmlSchemaVComplexTypeErr(ctxt, | 
|  | 13312 | XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2, | 
|  | 13313 | node, type, | 
|  | 13314 | "The character content is not valid"); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13315 | ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2; | 
|  | 13316 | } else if (ret < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13317 | xmlSchemaVErr(ctxt, ctxt->cur, XML_SCHEMAV_INTERNAL, | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13318 | "Internal error: xmlSchemaValidateComplexType, " | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13319 | "Element '%s': Error while validating character " | 
|  | 13320 | "content against complex type '%s'; failed to " | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13321 | "apply facets.\n", | 
|  | 13322 | type->name, NULL); | 
|  | 13323 | } | 
|  | 13324 | } | 
|  | 13325 | if (value != NULL) | 
|  | 13326 | xmlFree(value); | 
|  | 13327 | /* TODO: facets */ | 
|  | 13328 | break; | 
|  | 13329 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13330 | default: | 
|  | 13331 | TODO xmlGenericError(xmlGenericErrorContext, | 
|  | 13332 | "unimplemented content type %d\n", | 
|  | 13333 | type->contentType); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13334 | } | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13335 | ctxt->cur = node; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13336 | return (ctxt->err); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13337 | } | 
|  | 13338 |  | 
|  | 13339 | /** | 
|  | 13340 | * xmlSchemaValidateContent: | 
|  | 13341 | * @ctxt:  a schema validation context | 
|  | 13342 | * @elem:  an element | 
|  | 13343 | * @type:  the type declaration | 
|  | 13344 | * | 
|  | 13345 | * Validate the content of an element against the type. | 
|  | 13346 | * | 
|  | 13347 | * Returns 0 if the element is schemas valid, a positive error code | 
|  | 13348 | *     number otherwise and -1 in case of internal or API error. | 
|  | 13349 | */ | 
|  | 13350 | static int | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13351 | xmlSchemaValidateContent(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node) | 
|  | 13352 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13353 | xmlSchemaTypePtr type; | 
|  | 13354 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13355 | type = ctxt->type; | 
| Daniel Veillard | 82bbbd4 | 2003-05-11 20:16:09 +0000 | [diff] [blame] | 13356 | ctxt->cur = node; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13357 |  | 
|  | 13358 | switch (type->type) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13359 | case XML_SCHEMA_TYPE_ANY: | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13360 | xmlSchemaValidateAny(ctxt); | 
|  | 13361 | ctxt->type = type; | 
|  | 13362 | break; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13363 | case XML_SCHEMA_TYPE_COMPLEX: | 
|  | 13364 | xmlSchemaValidateComplexType(ctxt, node); | 
|  | 13365 | break; | 
|  | 13366 | case XML_SCHEMA_TYPE_ELEMENT:{ | 
|  | 13367 | xmlSchemaElementPtr decl = (xmlSchemaElementPtr) type; | 
|  | 13368 |  | 
|  | 13369 | /* | 
|  | 13370 | * Handle element reference here | 
|  | 13371 | */ | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 13372 | /* | 
|  | 13373 | * TODO: This should be removed, since checks for | 
|  | 13374 | * consistence should not be done during validation. | 
|  | 13375 | */ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13376 | if (decl->ref != NULL) { | 
|  | 13377 | if (decl->refDecl == NULL) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13378 | xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL, | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 13379 | "Internal error: element reference %s " | 
|  | 13380 | "not resolved\n", decl->ref, NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13381 | return (-1); | 
|  | 13382 | } | 
|  | 13383 | ctxt->type = (xmlSchemaTypePtr) decl->refDecl; | 
|  | 13384 | decl = decl->refDecl; | 
|  | 13385 | } | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 13386 | /* TODO: Should "xmlSchemaValidateElement" be called instead? */ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13387 | xmlSchemaValidateElementType(ctxt, node); | 
|  | 13388 | ctxt->type = type; | 
|  | 13389 | break; | 
|  | 13390 | } | 
|  | 13391 | case XML_SCHEMA_TYPE_BASIC: | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 13392 | if (type->builtInType == XML_SCHEMAS_ANYTYPE) | 
|  | 13393 | xmlSchemaValidateAnyTypeContent(ctxt, node); | 
|  | 13394 | else | 
|  | 13395 | xmlSchemaValidateSimpleTypeElement(ctxt, node); | 
|  | 13396 | break; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13397 | case XML_SCHEMA_TYPE_SIMPLE: | 
|  | 13398 | xmlSchemaValidateSimpleTypeElement(ctxt, node); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13399 | break; | 
|  | 13400 | case XML_SCHEMA_TYPE_FACET: | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13401 | TODO break; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13402 | case XML_SCHEMA_TYPE_SEQUENCE: | 
|  | 13403 | TODO break; | 
|  | 13404 | case XML_SCHEMA_TYPE_CHOICE: | 
|  | 13405 | TODO break; | 
|  | 13406 | case XML_SCHEMA_TYPE_ALL: | 
|  | 13407 | TODO break; | 
|  | 13408 | case XML_SCHEMA_TYPE_SIMPLE_CONTENT: | 
|  | 13409 | TODO break; | 
|  | 13410 | case XML_SCHEMA_TYPE_COMPLEX_CONTENT: | 
|  | 13411 | TODO break; | 
|  | 13412 | case XML_SCHEMA_TYPE_UR: | 
|  | 13413 | TODO break; | 
|  | 13414 | case XML_SCHEMA_TYPE_RESTRICTION: | 
|  | 13415 | /*xmlSchemaValidateRestrictionType(ctxt, node); */ | 
|  | 13416 | TODO break; | 
|  | 13417 | case XML_SCHEMA_TYPE_EXTENSION: | 
|  | 13418 | TODO break; | 
|  | 13419 | case XML_SCHEMA_TYPE_ATTRIBUTE: | 
|  | 13420 | TODO break; | 
|  | 13421 | case XML_SCHEMA_TYPE_GROUP: | 
|  | 13422 | TODO break; | 
|  | 13423 | case XML_SCHEMA_TYPE_NOTATION: | 
|  | 13424 | TODO break; | 
|  | 13425 | case XML_SCHEMA_TYPE_LIST: | 
|  | 13426 | TODO break; | 
|  | 13427 | case XML_SCHEMA_TYPE_UNION: | 
|  | 13428 | TODO break; | 
|  | 13429 | case XML_SCHEMA_FACET_MININCLUSIVE: | 
|  | 13430 | TODO break; | 
|  | 13431 | case XML_SCHEMA_FACET_MINEXCLUSIVE: | 
|  | 13432 | TODO break; | 
|  | 13433 | case XML_SCHEMA_FACET_MAXINCLUSIVE: | 
|  | 13434 | TODO break; | 
|  | 13435 | case XML_SCHEMA_FACET_MAXEXCLUSIVE: | 
|  | 13436 | TODO break; | 
|  | 13437 | case XML_SCHEMA_FACET_TOTALDIGITS: | 
|  | 13438 | TODO break; | 
|  | 13439 | case XML_SCHEMA_FACET_FRACTIONDIGITS: | 
|  | 13440 | TODO break; | 
|  | 13441 | case XML_SCHEMA_FACET_PATTERN: | 
|  | 13442 | TODO break; | 
|  | 13443 | case XML_SCHEMA_FACET_ENUMERATION: | 
|  | 13444 | TODO break; | 
|  | 13445 | case XML_SCHEMA_FACET_WHITESPACE: | 
|  | 13446 | TODO break; | 
|  | 13447 | case XML_SCHEMA_FACET_LENGTH: | 
|  | 13448 | TODO break; | 
|  | 13449 | case XML_SCHEMA_FACET_MAXLENGTH: | 
|  | 13450 | TODO break; | 
|  | 13451 | case XML_SCHEMA_FACET_MINLENGTH: | 
|  | 13452 | TODO break; | 
|  | 13453 | case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: | 
|  | 13454 | TODO break; | 
| William M. Brack | 29aa772 | 2004-05-12 00:27:56 +0000 | [diff] [blame] | 13455 | case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: | 
|  | 13456 | TODO break; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13457 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13458 |  | 
|  | 13459 | if (ctxt->node == NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13460 | return (ctxt->err); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13461 | ctxt->node = ctxt->node->next; | 
|  | 13462 | ctxt->type = type->next; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13463 | return (ctxt->err); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13464 | } | 
|  | 13465 |  | 
|  | 13466 | /** | 
|  | 13467 | * xmlSchemaValidateType: | 
|  | 13468 | * @ctxt:  a schema validation context | 
|  | 13469 | * @elem:  an element | 
|  | 13470 | * @type:  the list of type declarations | 
|  | 13471 | * | 
|  | 13472 | * Validate the content of an element against the types. | 
|  | 13473 | * | 
|  | 13474 | * Returns 0 if the element is schemas valid, a positive error code | 
|  | 13475 | *     number otherwise and -1 in case of internal or API error. | 
|  | 13476 | */ | 
|  | 13477 | static int | 
|  | 13478 | xmlSchemaValidateType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13479 | xmlSchemaElementPtr elemDecl, xmlSchemaTypePtr type) | 
|  | 13480 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13481 | xmlChar *nil; | 
|  | 13482 |  | 
| Daniel Veillard | 2db8c12 | 2003-07-08 12:16:59 +0000 | [diff] [blame] | 13483 | if ((elem == NULL) || (type == NULL) || (elemDecl == NULL)) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13484 | return (0); | 
| Daniel Veillard | 2db8c12 | 2003-07-08 12:16:59 +0000 | [diff] [blame] | 13485 |  | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13486 | /* This one is called by "xmlSchemaValidateElementType" and | 
|  | 13487 | * "xmlSchemaValidateElement". | 
|  | 13488 | */ | 
|  | 13489 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13490 | /* | 
|  | 13491 | * 3.3.4 : 2 | 
|  | 13492 | */ | 
|  | 13493 | if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13494 | xmlSchemaVCustomErr(ctxt, | 
|  | 13495 | XML_SCHEMAV_CVC_ELT_2, | 
|  | 13496 | elem, NULL, | 
|  | 13497 | "The element declaration is abstract", NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13498 | return (ctxt->err); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13499 | } | 
|  | 13500 | /* | 
|  | 13501 | * 3.3.4: 3 | 
|  | 13502 | */ | 
|  | 13503 | nil = xmlGetNsProp(elem, BAD_CAST "nil", xmlSchemaInstanceNs); | 
|  | 13504 | if (elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13505 | /* 3.3.4: 3.2 */ | 
|  | 13506 | if (xmlStrEqual(nil, BAD_CAST "true")) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13507 | if (xmlSchemaHasElemOrCharContent(elem) == 1) { | 
|  | 13508 | xmlSchemaVCustomErr(ctxt, | 
|  | 13509 | XML_SCHEMAV_CVC_ELT_3_2_1, | 
|  | 13510 | /* XML_SCHEMAS_ERR_NOTEMPTY, */ | 
|  | 13511 | elem, NULL, | 
|  | 13512 | "The 'nilled' element must have no character or element " | 
|  | 13513 | "content", NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13514 | return (ctxt->err); | 
|  | 13515 | } | 
|  | 13516 | if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) && | 
|  | 13517 | (elemDecl->value != NULL)) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13518 | xmlSchemaVCustomErr(ctxt, XML_SCHEMAV_CVC_ELT_3_2_2, | 
|  | 13519 | /* XML_SCHEMAS_ERR_HAVEDEFAULT, */ | 
|  | 13520 | elem, NULL, | 
|  | 13521 | "There is a fixed value constraint defined for " | 
|  | 13522 | "the 'nilled' element", NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13523 | return (ctxt->err); | 
|  | 13524 | } | 
|  | 13525 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13526 | } else { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13527 | /* 3.3.4: 3.1 */ | 
|  | 13528 | if (nil != NULL) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13529 | xmlSchemaVCustomErr(ctxt, XML_SCHEMAV_CVC_ELT_3_1, | 
|  | 13530 | /* XML_SCHEMAS_ERR_NOTNILLABLE, */ | 
|  | 13531 | elem, NULL, | 
|  | 13532 | "The element is not 'nillable'", NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13533 | xmlFree(nil); | 
|  | 13534 | return (ctxt->err); | 
|  | 13535 | } | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13536 | } | 
|  | 13537 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13538 | /* TODO 3.3.4: 4 if the element carries xs:type */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13539 |  | 
|  | 13540 | ctxt->type = elemDecl->subtypes; | 
|  | 13541 | ctxt->node = elem->children; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13542 | xmlSchemaValidateContent(ctxt, elem); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13543 | return (ctxt->err); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13544 | } | 
|  | 13545 |  | 
|  | 13546 |  | 
|  | 13547 | /** | 
|  | 13548 | * xmlSchemaValidateAttributes: | 
|  | 13549 | * @ctxt:  a schema validation context | 
|  | 13550 | * @elem:  an element | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13551 | * @type:  the complexType holding the attribute uses | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13552 | * | 
|  | 13553 | * Validate the attributes of an element. | 
|  | 13554 | * | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13555 | * 1. Existent, invalid attributes are reported in the form | 
|  | 13556 | *    "prefix:localName". | 
|  | 13557 | *    Reason: readability - it is easier to find the actual XML | 
|  | 13558 | *    representation of the attributes QName. | 
|  | 13559 | * 2. Missing attributes are reported in the form | 
|  | 13560 | *    {"URI", "localName"}. | 
|  | 13561 | *    This is necessary, since the the prefix need not to be declared | 
|  | 13562 | *    at all, and thus is not computable. | 
|  | 13563 | * | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13564 | * Returns 0 if the element is schemas valid, a positive error code | 
|  | 13565 | *     number otherwise and -1 in case of internal or API error. | 
|  | 13566 | */ | 
|  | 13567 | static int | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13568 | xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem, xmlSchemaTypePtr type) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13569 | { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13570 | int ret; | 
|  | 13571 | xmlAttrPtr attr; /* An attribute on the element. */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13572 | xmlChar *value; | 
| Daniel Veillard | 8acdfbf | 2004-06-03 16:00:59 +0000 | [diff] [blame] | 13573 | const xmlChar *nsURI; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13574 | xmlSchemaAttributeLinkPtr attrUse; | 
|  | 13575 | xmlSchemaAttributePtr attrDecl; | 
| Daniel Veillard | c85d0fe | 2004-04-16 16:46:51 +0000 | [diff] [blame] | 13576 | int found; | 
| William M. Brack | 803812b | 2004-06-03 02:11:24 +0000 | [diff] [blame] | 13577 | xmlSchemaAttrStatePtr curState, reqAttrStates = NULL, reqAttrStatesTop = NULL; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13578 | #ifdef DEBUG_ATTR_VALIDATION | 
|  | 13579 | int redundant = 0; | 
|  | 13580 | #endif | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13581 |  | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13582 | /* | 
|  | 13583 | * NOTE: This one uses attr->subtypes to get the type decl. - regardless | 
|  | 13584 | * if we have an attribute reference or an attribute declaration. | 
|  | 13585 | */ | 
|  | 13586 | /* | 
|  | 13587 | * Allow all attributes if the type is anyType. | 
|  | 13588 | */ | 
|  | 13589 | if (type == xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE)) | 
|  | 13590 | return (0); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13591 | attrUse = type->attributeUses; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13592 | while (attrUse != NULL) { | 
| Daniel Veillard | c85d0fe | 2004-04-16 16:46:51 +0000 | [diff] [blame] | 13593 | found = 0; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13594 | attrDecl = attrUse->attr; | 
|  | 13595 | #ifdef DEBUG_ATTR_VALIDATION | 
|  | 13596 | printf("attr use - name: %s\n", xmlSchemaGetOnymousAttrName(attrDecl)); | 
|  | 13597 | printf("attr use - use: %d\n", attrDecl->occurs); | 
|  | 13598 | #endif | 
|  | 13599 | for (curState = ctxt->attr; curState != NULL; curState = curState->next) { | 
|  | 13600 |  | 
|  | 13601 | if (curState->decl == attrUse->attr) { | 
|  | 13602 | #ifdef DEBUG_ATTR_VALIDATION | 
|  | 13603 | redundant = 1; | 
|  | 13604 | #endif | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13605 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13606 | attr = curState->attr; | 
|  | 13607 | #ifdef DEBUG_ATTR_VALIDATION | 
|  | 13608 | printf("attr - name: %s\n", attr->name); | 
|  | 13609 | if (attr->ns != NULL) | 
|  | 13610 | printf("attr - ns: %s\n", attr->ns->href); | 
|  | 13611 | else | 
|  | 13612 | printf("attr - ns: none\n"); | 
|  | 13613 | #endif | 
|  | 13614 | /* TODO: Can this ever happen? */ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13615 | if (attr == NULL) | 
|  | 13616 | continue; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13617 | if (attrDecl->ref != NULL) { | 
|  | 13618 | if (!xmlStrEqual(attr->name, attrDecl->ref)) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13619 | continue; | 
|  | 13620 | if (attr->ns != NULL) { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13621 | if ((attrDecl->refNs == NULL) || | 
|  | 13622 | (!xmlStrEqual(attr->ns->href, attrDecl->refNs))) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13623 | continue; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13624 | } else if (attrDecl->refNs != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13625 | continue; | 
|  | 13626 | } | 
|  | 13627 | } else { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13628 | if (!xmlStrEqual(attr->name, attrDecl->name)) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13629 | continue; | 
|  | 13630 | /* | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 13631 | * handle the namespaces checks here | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13632 | */ | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 13633 | if (attr->ns == NULL) { | 
|  | 13634 | /* | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 13635 | * accept an unqualified attribute only if the target | 
|  | 13636 | * namespace of the declaration is absent. | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 13637 | */ | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13638 | if (attrDecl->targetNamespace != NULL) | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 13639 | /* | 
|  | 13640 | * This check was removed, since the target namespace | 
|  | 13641 | * was evaluated during parsing and already took | 
|  | 13642 | * "attributeFormDefault" into account. | 
|  | 13643 | */ | 
|  | 13644 | /* ((attributes->flags & XML_SCHEMAS_ATTR_NSDEFAULT) == 0)) */ | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 13645 | continue; | 
|  | 13646 | } else { | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13647 | if (attrDecl->targetNamespace == NULL) | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 13648 | continue; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13649 | if (!xmlStrEqual(attrDecl->targetNamespace, | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 13650 | attr->ns->href)) | 
|  | 13651 | continue; | 
|  | 13652 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13653 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13654 | #ifdef DEBUG_ATTR_VALIDATION | 
|  | 13655 | printf("found\n"); | 
|  | 13656 | #endif | 
| Daniel Veillard | c85d0fe | 2004-04-16 16:46:51 +0000 | [diff] [blame] | 13657 | found = 1; | 
| Daniel Veillard | 50355f0 | 2004-06-08 17:52:16 +0000 | [diff] [blame] | 13658 | ctxt->cur = (xmlNodePtr) attr; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13659 | ctxt->node = attr->children; | 
| Daniel Veillard | c85d0fe | 2004-04-16 16:46:51 +0000 | [diff] [blame] | 13660 |  | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13661 | if (attrDecl->subtypes == NULL) { | 
|  | 13662 | curState->state = XML_SCHEMAS_ATTR_TYPE_NOT_RESOLVED; | 
|  | 13663 | curState->decl = attrDecl; | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13664 | xmlSchemaVErr(ctxt, (xmlNodePtr) attr, XML_SCHEMAV_INTERNAL, | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 13665 | "Internal error: attribute %s type not resolved\n", | 
|  | 13666 | attr->name, NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13667 | continue; | 
|  | 13668 | } | 
|  | 13669 | value = xmlNodeListGetString(elem->doc, attr->children, 1); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13670 | ctxt->type = attrDecl->subtypes; | 
|  | 13671 | ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 1, 1, 1); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13672 | ctxt->type = type; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13673 | if (ret != 0) | 
|  | 13674 | curState->state = XML_SCHEMAS_ATTR_INVALID_VALUE; | 
|  | 13675 | else | 
|  | 13676 | curState->state = XML_SCHEMAS_ATTR_CHECKED; | 
|  | 13677 | curState->decl = attrDecl; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13678 | if (value != NULL) { | 
|  | 13679 | xmlFree(value); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13680 | } | 
|  | 13681 | } | 
|  | 13682 | if ((!found) && (attrDecl->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED)) { | 
|  | 13683 | xmlSchemaAttrStatePtr tmp; | 
|  | 13684 |  | 
|  | 13685 | #ifdef DEBUG_ATTR_VALIDATION | 
|  | 13686 | printf("required attr not found\n"); | 
|  | 13687 | #endif | 
|  | 13688 | /* | 
|  | 13689 | * Add a new dummy attribute state. | 
|  | 13690 | */ | 
|  | 13691 | tmp = (xmlSchemaAttrStatePtr) xmlMalloc(sizeof(xmlSchemaAttrState)); | 
|  | 13692 | if (tmp == NULL) { | 
|  | 13693 | xmlSchemaVErrMemory(ctxt, "registering required attributes", NULL); | 
|  | 13694 | return (-1); | 
|  | 13695 | } | 
|  | 13696 | tmp->attr = NULL; | 
|  | 13697 | tmp->state = XML_SCHEMAS_ATTR_MISSING; | 
|  | 13698 | tmp->decl = attrDecl; | 
|  | 13699 | tmp->next = NULL; | 
|  | 13700 |  | 
|  | 13701 | if (reqAttrStates == NULL) { | 
|  | 13702 | reqAttrStates = tmp; | 
|  | 13703 | reqAttrStatesTop = tmp; | 
|  | 13704 | } else { | 
|  | 13705 | reqAttrStatesTop->next = tmp; | 
|  | 13706 | reqAttrStatesTop = tmp; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13707 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13708 |  | 
|  | 13709 | } | 
|  | 13710 | attrUse = attrUse->next; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13711 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13712 | /* | 
|  | 13713 | * Add required attributes to the attribute states of the context. | 
|  | 13714 | */ | 
|  | 13715 | if (reqAttrStates != NULL) { | 
|  | 13716 | if (ctxt->attr == NULL) { | 
|  | 13717 | ctxt->attr = reqAttrStates; | 
|  | 13718 | } else { | 
|  | 13719 | ctxt->attrTop->next = reqAttrStates; | 
|  | 13720 | } | 
|  | 13721 | ctxt->attrTop = reqAttrStatesTop; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13722 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13723 | /* | 
|  | 13724 | * Process wildcards. | 
|  | 13725 | */ | 
|  | 13726 | if (type->attributeWildcard != NULL) { | 
|  | 13727 | #ifdef DEBUG_ATTR_VALIDATION | 
|  | 13728 | xmlSchemaWildcardNsPtr ns; | 
|  | 13729 | printf("matching wildcard: [%d] of complexType: %s\n", type->attributeWildcard, type->name); | 
| Daniel Veillard | 8acdfbf | 2004-06-03 16:00:59 +0000 | [diff] [blame] | 13730 | if (type->attributeWildcard->processContents == | 
|  | 13731 | XML_SCHEMAS_ANY_LAX) | 
|  | 13732 | printf("processContents: lax\n"); | 
|  | 13733 | else if (type->attributeWildcard->processContents == | 
|  | 13734 | XML_SCHEMAS_ANY_STRICT) | 
|  | 13735 | printf("processContents: strict\n"); | 
|  | 13736 | else | 
|  | 13737 | printf("processContents: skip\n"); | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13738 | if (type->attributeWildcard->any) | 
|  | 13739 | printf("type: any\n"); | 
|  | 13740 | else if (type->attributeWildcard->negNsSet != NULL) { | 
|  | 13741 | printf("type: negated\n"); | 
|  | 13742 | if (type->attributeWildcard->negNsSet->value == NULL) | 
|  | 13743 | printf("ns: (absent)\n"); | 
|  | 13744 | else | 
|  | 13745 | printf("ns: %s\n", type->attributeWildcard->negNsSet->value); | 
|  | 13746 | } else if (type->attributeWildcard->nsSet != NULL) { | 
|  | 13747 | printf("type: set\n"); | 
|  | 13748 | ns = type->attributeWildcard->nsSet; | 
|  | 13749 | while (ns != NULL) { | 
|  | 13750 | if (ns->value == NULL) | 
|  | 13751 | printf("ns: (absent)\n"); | 
|  | 13752 | else | 
|  | 13753 | printf("ns: %s\n", ns->value); | 
|  | 13754 | ns = ns->next; | 
|  | 13755 | } | 
|  | 13756 | } else | 
|  | 13757 | printf("empty\n"); | 
|  | 13758 |  | 
| Daniel Veillard | 8acdfbf | 2004-06-03 16:00:59 +0000 | [diff] [blame] | 13759 |  | 
|  | 13760 | #endif | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13761 | curState = ctxt->attr; | 
|  | 13762 | while (curState != NULL) { | 
| Daniel Veillard | 8acdfbf | 2004-06-03 16:00:59 +0000 | [diff] [blame] | 13763 | if (curState->state == XML_SCHEMAS_ATTR_UNKNOWN) { | 
|  | 13764 | if (curState->attr->ns != NULL) | 
|  | 13765 | nsURI = curState->attr->ns->href; | 
|  | 13766 | else | 
|  | 13767 | nsURI = NULL; | 
|  | 13768 | if (xmlSchemaMatchesWildcardNs(type->attributeWildcard, | 
|  | 13769 | nsURI)) { | 
|  | 13770 | /* | 
|  | 13771 | * Handle processContents. | 
|  | 13772 | */ | 
|  | 13773 | if ((type->attributeWildcard->processContents == | 
|  | 13774 | XML_SCHEMAS_ANY_LAX) || | 
|  | 13775 | (type->attributeWildcard->processContents == | 
|  | 13776 | XML_SCHEMAS_ANY_STRICT)) { | 
|  | 13777 |  | 
|  | 13778 | attr = curState->attr; | 
|  | 13779 | attrDecl = xmlSchemaGetAttribute(ctxt->schema, | 
|  | 13780 | attr->name, nsURI); | 
|  | 13781 | if (attrDecl != NULL) { | 
|  | 13782 | value = xmlNodeListGetString(elem->doc, attr->children, 1); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13783 | ctxt->cur = (xmlNodePtr) attr; | 
|  | 13784 | ctxt->node = attr->children; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13785 | ctxt->type = attrDecl->subtypes; | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13786 | ret = xmlSchemaValidateSimpleTypeValue(ctxt, value, 1, 1, 1); | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13787 | ctxt->type = type; | 
| Daniel Veillard | 8acdfbf | 2004-06-03 16:00:59 +0000 | [diff] [blame] | 13788 | if (ret != 0) | 
|  | 13789 | curState->state = XML_SCHEMAS_ATTR_INVALID_VALUE; | 
|  | 13790 | else | 
|  | 13791 | curState->state = XML_SCHEMAS_ATTR_CHECKED; | 
|  | 13792 | curState->decl = attrDecl; | 
|  | 13793 | if (value != NULL) { | 
|  | 13794 | xmlFree(value); | 
|  | 13795 | } | 
|  | 13796 |  | 
|  | 13797 | } else if (type->attributeWildcard->processContents == | 
|  | 13798 | XML_SCHEMAS_ANY_LAX) { | 
|  | 13799 | curState->state = XML_SCHEMAS_ATTR_CHECKED; | 
|  | 13800 | } | 
|  | 13801 | } else | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13802 | curState->state = XML_SCHEMAS_ATTR_CHECKED; | 
| Daniel Veillard | 8acdfbf | 2004-06-03 16:00:59 +0000 | [diff] [blame] | 13803 | } | 
|  | 13804 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13805 | curState = curState->next; | 
|  | 13806 | } | 
|  | 13807 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13808 | /* | 
|  | 13809 | * Report missing and illegal attributes. | 
|  | 13810 | */ | 
|  | 13811 | if (ctxt->attr != NULL) { | 
|  | 13812 | curState = ctxt->attr; | 
|  | 13813 | while ((curState != NULL) && (curState != ctxt->attrTop->next)) { | 
|  | 13814 | if (curState->state != XML_SCHEMAS_ATTR_CHECKED) { | 
|  | 13815 | attr = curState->attr; | 
|  | 13816 | if (curState->state == XML_SCHEMAS_ATTR_MISSING) | 
|  | 13817 | xmlSchemaVMissingAttrErr(ctxt, elem, curState->decl); | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13818 | else if (curState->state == XML_SCHEMAS_ATTR_UNKNOWN) { | 
|  | 13819 | /* TODO: "prohibited" won't ever be touched here!. | 
|  | 13820 | (curState->state == XML_SCHEMAS_ATTR_PROHIBITED)) | 
|  | 13821 | */ | 
|  | 13822 | if (type->attributeWildcard == NULL) { | 
|  | 13823 | xmlSchemaVIllegalAttrErr(ctxt, | 
|  | 13824 | XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, attr); | 
|  | 13825 | } else { | 
|  | 13826 | xmlSchemaVIllegalAttrErr(ctxt, | 
|  | 13827 | XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, attr); | 
|  | 13828 | } | 
|  | 13829 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13830 | } | 
|  | 13831 | curState = curState->next; | 
|  | 13832 | } | 
|  | 13833 | } | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13834 | #ifdef DEBUG_ATTR_VALIDATION | 
|  | 13835 | if (redundant) | 
|  | 13836 | xmlGenericError(xmlGenericErrorContext, | 
|  | 13837 | "xmlSchemaValidateAttributes: redundant call by type: %s\n", | 
|  | 13838 | type->name); | 
|  | 13839 | #endif | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13840 | return (ctxt->err); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13841 | } | 
|  | 13842 |  | 
|  | 13843 | /** | 
|  | 13844 | * xmlSchemaValidateElement: | 
|  | 13845 | * @ctxt:  a schema validation context | 
|  | 13846 | * @elem:  an element | 
|  | 13847 | * | 
|  | 13848 | * Validate an element in a tree | 
|  | 13849 | * | 
|  | 13850 | * Returns 0 if the element is schemas valid, a positive error code | 
|  | 13851 | *     number otherwise and -1 in case of internal or API error. | 
|  | 13852 | */ | 
|  | 13853 | static int | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13854 | xmlSchemaValidateElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem) | 
|  | 13855 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13856 | xmlSchemaElementPtr elemDecl; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13857 | int ret; | 
|  | 13858 | xmlSchemaAttrStatePtr attrs, attrTop; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13859 |  | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 13860 | if (elem->ns != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13861 | elemDecl = xmlHashLookup3(ctxt->schema->elemDecl, | 
|  | 13862 | elem->name, elem->ns->href, NULL); | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 13863 | } else { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13864 | elemDecl = xmlHashLookup3(ctxt->schema->elemDecl, | 
|  | 13865 | elem->name, NULL, NULL); | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 13866 | } | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13867 | /* | 
|  | 13868 | * This one is called by xmlSchemaValidateDocument and | 
|  | 13869 | * xmlSchemaValidateAnyInernal. | 
|  | 13870 | */ | 
| Daniel Veillard | be9c632 | 2003-11-22 20:37:51 +0000 | [diff] [blame] | 13871 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13872 | /* | 
|  | 13873 | * 3.3.4 : 1 | 
|  | 13874 | */ | 
|  | 13875 | if (elemDecl == NULL) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13876 | xmlSchemaVCustomErr(ctxt, | 
|  | 13877 | XML_SCHEMAV_CVC_ELT_1, | 
|  | 13878 | /* XML_SCHEMAS_ERR_UNDECLAREDELEM, */ | 
|  | 13879 | elem, NULL, | 
|  | 13880 | "Global declaration is absent", NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13881 | return (ctxt->err); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13882 | } | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13883 | /* TODO: This should be already catched at the schema parsing level. */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13884 | if (elemDecl->subtypes == NULL) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13885 | xmlSchemaVCustomErr(ctxt, | 
|  | 13886 | XML_SCHEMAV_INTERNAL, | 
|  | 13887 | /* XML_SCHEMAS_ERR_NOTYPE */ | 
|  | 13888 | elem, NULL, | 
|  | 13889 | "The element declaration has no type assigned", NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13890 | return (ctxt->err); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13891 | } | 
|  | 13892 | /* | 
|  | 13893 | * Verify the attributes | 
|  | 13894 | */ | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13895 | attrs = ctxt->attr; | 
|  | 13896 | attrTop = ctxt->attrTop; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13897 | xmlSchemaRegisterAttributes(ctxt, elem->properties); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13898 | xmlSchemaValidateAttributes(ctxt, elem, elemDecl->subtypes); | 
|  | 13899 | if (ctxt->attr != NULL) | 
|  | 13900 | xmlSchemaFreeAttributeStates(ctxt->attr); | 
|  | 13901 | ctxt->attr = attrs; | 
|  | 13902 | ctxt->attrTop = attrTop; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13903 | /* | 
|  | 13904 | * Verify the element content recursively | 
|  | 13905 | */ | 
|  | 13906 | if (elemDecl->contModel != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13907 | ctxt->regexp = xmlRegNewExecCtxt(elemDecl->contModel, | 
|  | 13908 | (xmlRegExecCallbacks) | 
|  | 13909 | xmlSchemaValidateCallback, ctxt); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13910 | #ifdef DEBUG_AUTOMATA | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13911 | xmlGenericError(xmlGenericErrorContext, "====> %s\n", elem->name); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13912 | #endif | 
|  | 13913 | } | 
|  | 13914 | xmlSchemaValidateType(ctxt, elem, elemDecl, elemDecl->subtypes); | 
| Daniel Veillard | decd64d | 2002-04-18 14:41:51 +0000 | [diff] [blame] | 13915 | if (elemDecl->contModel != NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13916 | ret = xmlRegExecPushString(ctxt->regexp, NULL, NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13917 | #ifdef DEBUG_AUTOMATA | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13918 | xmlGenericError(xmlGenericErrorContext, | 
|  | 13919 | "====> %s : %d\n", elem->name, ret); | 
| Daniel Veillard | decd64d | 2002-04-18 14:41:51 +0000 | [diff] [blame] | 13920 | #endif | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13921 | if (ret == 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13922 | /* TODO: error code. */ | 
|  | 13923 | xmlSchemaVCustomErr(ctxt, XML_SCHEMAV_ELEMENT_CONTENT, | 
|  | 13924 | elem, elemDecl->subtypes, | 
|  | 13925 | "The element content is not valid", NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13926 | } else if (ret < 0) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13927 | xmlSchemaVCustomErr(ctxt, XML_SCHEMAV_ELEMENT_CONTENT, | 
|  | 13928 | elem, elemDecl->subtypes, | 
|  | 13929 | "The element content is not valid", NULL); | 
| Daniel Veillard | decd64d | 2002-04-18 14:41:51 +0000 | [diff] [blame] | 13930 | #ifdef DEBUG_CONTENT | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 13931 | else { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13932 | xmlGenericError(xmlGenericErrorContext, | 
|  | 13933 | "Element %s content check succeeded\n", | 
|  | 13934 | elem->name); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13935 |  | 
|  | 13936 | #endif | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13937 | } | 
|  | 13938 | xmlRegFreeExecCtxt(ctxt->regexp); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13939 | } | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13940 | return (ctxt->err); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13941 | } | 
|  | 13942 |  | 
|  | 13943 | /** | 
|  | 13944 | * xmlSchemaValidateDocument: | 
|  | 13945 | * @ctxt:  a schema validation context | 
|  | 13946 | * @doc:  a parsed document tree | 
|  | 13947 | * | 
|  | 13948 | * Validate a document tree in memory. | 
|  | 13949 | * | 
|  | 13950 | * Returns 0 if the document is schemas valid, a positive error code | 
|  | 13951 | *     number otherwise and -1 in case of internal or API error. | 
|  | 13952 | */ | 
|  | 13953 | static int | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13954 | xmlSchemaValidateDocument(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc) | 
|  | 13955 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13956 | xmlNodePtr root; | 
|  | 13957 | xmlSchemaElementPtr elemDecl; | 
| Daniel Veillard | 01fa615 | 2004-06-29 17:04:39 +0000 | [diff] [blame] | 13958 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13959 | root = xmlDocGetRootElement(doc); | 
|  | 13960 | if (root == NULL) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13961 | xmlSchemaVCustomErr(ctxt, | 
|  | 13962 | XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING, | 
|  | 13963 | (xmlNodePtr) doc, NULL, | 
|  | 13964 | "The document has no document element", NULL); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13965 | return (ctxt->err); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13966 | } | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13967 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13968 | if (root->ns != NULL) | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13969 | elemDecl = xmlSchemaGetElem(ctxt->schema, root->name, root->ns->href); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13970 | else | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13971 | elemDecl = xmlSchemaGetElem(ctxt->schema, root->name, NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13972 | if (elemDecl == NULL) { | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13973 | xmlSchemaVCustomErr(ctxt, | 
|  | 13974 | XML_SCHEMAV_CVC_ELT_1, | 
|  | 13975 | root, NULL, | 
|  | 13976 | /* XML_SCHEMAS_ERR_UNDECLAREDELEM, */ | 
|  | 13977 | "Global declaration is absent", NULL); | 
|  | 13978 | } | 
|  | 13979 | /* | 
|  | 13980 | * Removed, since xmlSchemaGetElem will return global declarations only. | 
|  | 13981 | * | 
|  | 13982 | else if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) { | 
| William M. Brack | e709195 | 2004-05-11 15:09:58 +0000 | [diff] [blame] | 13983 | xmlSchemaVErr(ctxt, root, XML_SCHEMAS_ERR_NOTTOPLEVEL, | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 13984 | "Root element %s not global\n", root->name, NULL); | 
| Kasimier T. Buchcik | bea2354 | 2004-08-25 20:35:45 +0000 | [diff] [blame] | 13985 | } | 
|  | 13986 | */ | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13987 | /* | 
|  | 13988 | * Okay, start the recursive validation | 
|  | 13989 | */ | 
|  | 13990 | xmlSchemaValidateElement(ctxt, root); | 
|  | 13991 |  | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 13992 | return (ctxt->err); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 13993 | } | 
|  | 13994 |  | 
|  | 13995 | /************************************************************************ | 
|  | 13996 | * 									* | 
|  | 13997 | * 			SAX Validation code				* | 
|  | 13998 | * 									* | 
|  | 13999 | ************************************************************************/ | 
|  | 14000 |  | 
|  | 14001 | /************************************************************************ | 
|  | 14002 | * 									* | 
|  | 14003 | * 			Validation interfaces				* | 
|  | 14004 | * 									* | 
|  | 14005 | ************************************************************************/ | 
|  | 14006 |  | 
|  | 14007 | /** | 
|  | 14008 | * xmlSchemaNewValidCtxt: | 
|  | 14009 | * @schema:  a precompiled XML Schemas | 
|  | 14010 | * | 
|  | 14011 | * Create an XML Schemas validation context based on the given schema | 
|  | 14012 | * | 
|  | 14013 | * Returns the validation context or NULL in case of error | 
|  | 14014 | */ | 
|  | 14015 | xmlSchemaValidCtxtPtr | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 14016 | xmlSchemaNewValidCtxt(xmlSchemaPtr schema) | 
|  | 14017 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14018 | xmlSchemaValidCtxtPtr ret; | 
|  | 14019 |  | 
|  | 14020 | ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt)); | 
|  | 14021 | if (ret == NULL) { | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 14022 | xmlSchemaVErrMemory(NULL, "allocating validation context", NULL); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14023 | return (NULL); | 
|  | 14024 | } | 
|  | 14025 | memset(ret, 0, sizeof(xmlSchemaValidCtxt)); | 
| Daniel Veillard | c0826a7 | 2004-08-10 14:17:33 +0000 | [diff] [blame] | 14026 | ret->schema = schema; | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 14027 | ret->attrTop = NULL; | 
|  | 14028 | ret->attr = NULL; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14029 | return (ret); | 
|  | 14030 | } | 
|  | 14031 |  | 
|  | 14032 | /** | 
|  | 14033 | * xmlSchemaFreeValidCtxt: | 
|  | 14034 | * @ctxt:  the schema validation context | 
|  | 14035 | * | 
|  | 14036 | * Free the resources associated to the schema validation context | 
|  | 14037 | */ | 
|  | 14038 | void | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 14039 | xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt) | 
|  | 14040 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14041 | if (ctxt == NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 14042 | return; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14043 | if (ctxt->attr != NULL) | 
| Daniel Veillard | 3646d64 | 2004-06-02 19:19:14 +0000 | [diff] [blame] | 14044 | xmlSchemaFreeAttributeStates(ctxt->attr); | 
| Daniel Veillard | 88c5891 | 2002-04-23 07:12:20 +0000 | [diff] [blame] | 14045 | if (ctxt->value != NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 14046 | xmlSchemaFreeValue(ctxt->value); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14047 | xmlFree(ctxt); | 
|  | 14048 | } | 
|  | 14049 |  | 
|  | 14050 | /** | 
|  | 14051 | * xmlSchemaSetValidErrors: | 
|  | 14052 | * @ctxt:  a schema validation context | 
|  | 14053 | * @err:  the error function | 
|  | 14054 | * @warn: the warning function | 
| Daniel Veillard | a9b66d0 | 2002-12-11 14:23:49 +0000 | [diff] [blame] | 14055 | * @ctx: the functions context | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14056 | * | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 14057 | * Set the error and warning callback informations | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14058 | */ | 
|  | 14059 | void | 
|  | 14060 | xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 14061 | xmlSchemaValidityErrorFunc err, | 
|  | 14062 | xmlSchemaValidityWarningFunc warn, void *ctx) | 
|  | 14063 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14064 | if (ctxt == NULL) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 14065 | return; | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14066 | ctxt->error = err; | 
|  | 14067 | ctxt->warning = warn; | 
|  | 14068 | ctxt->userData = ctx; | 
|  | 14069 | } | 
|  | 14070 |  | 
|  | 14071 | /** | 
| Daniel Veillard | 259f0df | 2004-08-18 09:13:18 +0000 | [diff] [blame] | 14072 | * xmlSchemaGetValidErrors: | 
|  | 14073 | * @ctxt:	a XML-Schema validation context | 
|  | 14074 | * @err: the error function result | 
|  | 14075 | * @warn: the warning function result | 
|  | 14076 | * @ctx: the functions context result | 
|  | 14077 | * | 
|  | 14078 | * Get the error and warning callback informations | 
|  | 14079 | * | 
|  | 14080 | * Returns -1 in case of error and 0 otherwise | 
|  | 14081 | */ | 
|  | 14082 | int | 
|  | 14083 | xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt, | 
|  | 14084 | xmlSchemaValidityErrorFunc * err, | 
|  | 14085 | xmlSchemaValidityWarningFunc * warn, void **ctx) | 
|  | 14086 | { | 
|  | 14087 | if (ctxt == NULL) | 
|  | 14088 | return (-1); | 
|  | 14089 | if (err != NULL) | 
|  | 14090 | *err = ctxt->error; | 
|  | 14091 | if (warn != NULL) | 
|  | 14092 | *warn = ctxt->warning; | 
|  | 14093 | if (ctx != NULL) | 
|  | 14094 | *ctx = ctxt->userData; | 
|  | 14095 | return (0); | 
|  | 14096 | } | 
|  | 14097 |  | 
|  | 14098 | /** | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14099 | * xmlSchemaValidateDoc: | 
|  | 14100 | * @ctxt:  a schema validation context | 
|  | 14101 | * @doc:  a parsed document tree | 
|  | 14102 | * | 
|  | 14103 | * Validate a document tree in memory. | 
|  | 14104 | * | 
|  | 14105 | * Returns 0 if the document is schemas valid, a positive error code | 
|  | 14106 | *     number otherwise and -1 in case of internal or API error. | 
|  | 14107 | */ | 
|  | 14108 | int | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 14109 | xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc) | 
|  | 14110 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14111 | int ret; | 
|  | 14112 |  | 
|  | 14113 | if ((ctxt == NULL) || (doc == NULL)) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 14114 | return (-1); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14115 |  | 
|  | 14116 | ctxt->doc = doc; | 
| William M. Brack | 2f2a663 | 2004-08-20 23:09:47 +0000 | [diff] [blame] | 14117 | ctxt->err = 0; | 
|  | 14118 | ctxt->nberrors = 0; | 
|  | 14119 |  | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14120 | ret = xmlSchemaValidateDocument(ctxt, doc); | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 14121 | return (ret); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14122 | } | 
|  | 14123 |  | 
|  | 14124 | /** | 
|  | 14125 | * xmlSchemaValidateStream: | 
|  | 14126 | * @ctxt:  a schema validation context | 
|  | 14127 | * @input:  the input to use for reading the data | 
|  | 14128 | * @enc:  an optional encoding information | 
|  | 14129 | * @sax:  a SAX handler for the resulting events | 
|  | 14130 | * @user_data:  the context to provide to the SAX handler. | 
|  | 14131 | * | 
|  | 14132 | * Validate a document tree in memory. | 
|  | 14133 | * | 
|  | 14134 | * Returns 0 if the document is schemas valid, a positive error code | 
|  | 14135 | *     number otherwise and -1 in case of internal or API error. | 
|  | 14136 | */ | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 14137 | int | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14138 | xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt, | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 14139 | xmlParserInputBufferPtr input, xmlCharEncoding enc, | 
|  | 14140 | xmlSAXHandlerPtr sax, void *user_data) | 
|  | 14141 | { | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14142 | if ((ctxt == NULL) || (input == NULL)) | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 14143 | return (-1); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14144 | ctxt->input = input; | 
|  | 14145 | ctxt->enc = enc; | 
|  | 14146 | ctxt->sax = sax; | 
|  | 14147 | ctxt->user_data = user_data; | 
| Daniel Veillard | d0c9c32 | 2003-10-10 00:49:42 +0000 | [diff] [blame] | 14148 | TODO return (0); | 
| Daniel Veillard | 4255d50 | 2002-04-16 15:50:10 +0000 | [diff] [blame] | 14149 | } | 
|  | 14150 |  | 
|  | 14151 | #endif /* LIBXML_SCHEMAS_ENABLED */ |