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 (at) redhat.com> 8 */ 9 10 /* 11 * TODO: 12 * - when types are redefined in includes, check that all 13 * types in the redef list are equal 14 * -> need a type equality operation. 15 * - 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. 18 * - Eliminate item creation for: ?? 19 * 20 * URGENT TODO: 21 * - For xsi-driven schema acquisition, augment the IDCs after every 22 * acquisition episode (xmlSchemaAugmentIDC). 23 * 24 * NOTES: 25 * - Elimated item creation for: <restriction>, <extension>, 26 * <simpleContent>, <complexContent>, <list>, <union> 27 * 28 * PROBLEMS: 29 * - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html 30 * IDC XPath expression and chameleon includes: the targetNamespace is changed, so 31 * XPath will have trouble to resolve to this namespace, since not known. 32 * 33 * 34 * CONSTRAINTS: 35 * 36 * Schema Component Constraint: 37 * All Group Limited (cos-all-limited) 38 * Status: complete 39 * (1.2) 40 * In xmlSchemaGroupDefReferenceTermFixup() and 41 * (2) 42 * In xmlSchemaParseModelGroup() 43 * TODO: Actually this should go to component-level checks, 44 * but is done here due to performance. Move it to an other layer 45 * is schema construction via an API is implemented. 46 */ 47 #define IN_LIBXML 48 #include "libxml.h" 49 50 #ifdef LIBXML_SCHEMAS_ENABLED 51 52 #include <string.h> 53 #include <libxml/xmlmemory.h> 54 #include <libxml/parser.h> 55 #include <libxml/parserInternals.h> 56 #include <libxml/hash.h> 57 #include <libxml/uri.h> 58 #include <libxml/xmlschemas.h> 59 #include <libxml/schemasInternals.h> 60 #include <libxml/xmlschemastypes.h> 61 #include <libxml/xmlautomata.h> 62 #include <libxml/xmlregexp.h> 63 #include <libxml/dict.h> 64 #include <libxml/encoding.h> 65 #include <libxml/xmlIO.h> 66 #ifdef LIBXML_PATTERN_ENABLED 67 #include <libxml/pattern.h> 68 #endif 69 #ifdef LIBXML_READER_ENABLED 70 #include <libxml/xmlreader.h> 71 #endif 72 73 /* #define DEBUG 1 */ 74 75 /* #define DEBUG_CONTENT 1 */ 76 77 /* #define DEBUG_TYPE 1 */ 78 79 /* #define DEBUG_CONTENT_REGEXP 1 */ 80 81 /* #define DEBUG_AUTOMATA 1 */ 82 83 /* #define DEBUG_IDC */ 84 85 /* #define DEBUG_IDC_NODE_TABLE */ 86 87 /* #define WXS_ELEM_DECL_CONS_ENABLED */ 88 89 #ifdef DEBUG_IDC 90 #ifndef DEBUG_IDC_NODE_TABLE 91 #define DEBUG_IDC_NODE_TABLE 92 #endif 93 #endif 94 95 /* #define ENABLE_PARTICLE_RESTRICTION 1 */ 96 97 #define ENABLE_REDEFINE 98 99 /* #define ENABLE_NAMED_LOCALS */ 100 101 /* #define ENABLE_IDC_NODE_TABLES_TEST */ 102 103 #define DUMP_CONTENT_MODEL 104 105 #ifdef LIBXML_READER_ENABLED 106 /* #define XML_SCHEMA_READER_ENABLED */ 107 #endif 108 109 #define UNBOUNDED (1 << 30) 110 #define TODO \ 111 xmlGenericError(xmlGenericErrorContext, \ 112 "Unimplemented block at %s:%d\n", \ 113 __FILE__, __LINE__); 114 115 #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##" 116 117 /* 118 * The XML Schemas namespaces 119 */ 120 static const xmlChar *xmlSchemaNs = (const xmlChar *) 121 "http://www.w3.org/2001/XMLSchema"; 122 123 static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *) 124 "http://www.w3.org/2001/XMLSchema-instance"; 125 126 static const xmlChar *xmlNamespaceNs = (const xmlChar *) 127 "http://www.w3.org/2000/xmlns/"; 128 129 /* 130 * Come casting macros. 131 */ 132 #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr) 133 #define PCTXT_CAST (xmlSchemaParserCtxtPtr) 134 #define VCTXT_CAST (xmlSchemaValidCtxtPtr) 135 #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr) 136 #define WXS_TREE_CAST (xmlSchemaTreeItemPtr) 137 #define WXS_PTC_CAST (xmlSchemaParticlePtr) 138 #define WXS_TYPE_CAST (xmlSchemaTypePtr) 139 #define WXS_ELEM_CAST (xmlSchemaElementPtr) 140 #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr) 141 #define WXS_ATTR_CAST (xmlSchemaAttributePtr) 142 #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr) 143 #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr) 144 #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr) 145 #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr) 146 #define WXS_IDC_CAST (xmlSchemaIDCPtr) 147 #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr) 148 #define WXS_LIST_CAST (xmlSchemaItemListPtr) 149 150 /* 151 * Macros to query common properties of components. 152 */ 153 #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i)) 154 155 #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i)) 156 /* 157 * Macros for element declarations. 158 */ 159 #define WXS_ELEM_TYPEDEF(e) (e)->subtypes 160 161 #define WXS_SUBST_HEAD(item) (item)->refDecl 162 /* 163 * Macros for attribute declarations. 164 */ 165 #define WXS_ATTR_TYPEDEF(a) (a)->subtypes 166 /* 167 * Macros for attribute uses. 168 */ 169 #define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl 170 171 #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au)) 172 173 #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name 174 175 #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace 176 /* 177 * Macros for attribute groups. 178 */ 179 #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) 180 #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) 181 /* 182 * Macros for particles. 183 */ 184 #define WXS_PARTICLE(p) WXS_PTC_CAST (p) 185 186 #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children 187 188 #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p)) 189 190 #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children 191 /* 192 * Macros for model groups definitions. 193 */ 194 #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children 195 /* 196 * Macros for model groups. 197 */ 198 #define WXS_IS_MODEL_GROUP(i) \ 199 (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \ 200 ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \ 201 ((i)->type == XML_SCHEMA_TYPE_ALL)) 202 203 #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children 204 /* 205 * Macros for schema buckets. 206 */ 207 #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \ 208 ((t) == XML_SCHEMA_SCHEMA_REDEFINE)) 209 210 #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \ 211 ((t) == XML_SCHEMA_SCHEMA_IMPORT)) 212 213 #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b)) 214 215 #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b)) 216 /* 217 * Macros for complex/simple types. 218 */ 219 #define WXS_IS_ANYTYPE(i) \ 220 (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \ 221 ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE)) 222 223 #define WXS_IS_COMPLEX(i) \ 224 (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \ 225 ((i)->builtInType == XML_SCHEMAS_ANYTYPE)) 226 227 #define WXS_IS_SIMPLE(item) \ 228 ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \ 229 ((item->type == XML_SCHEMA_TYPE_BASIC) && \ 230 (item->builtInType != XML_SCHEMAS_ANYTYPE))) 231 232 #define WXS_IS_ANY_SIMPLE_TYPE(i) \ 233 (((i)->type == XML_SCHEMA_TYPE_BASIC) && \ 234 ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) 235 236 #define WXS_IS_RESTRICTION(t) \ 237 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) 238 239 #define WXS_IS_EXTENSION(t) \ 240 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) 241 242 #define WXS_IS_TYPE_NOT_FIXED(i) \ 243 (((i)->type != XML_SCHEMA_TYPE_BASIC) && \ 244 (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0)) 245 246 #define WXS_IS_TYPE_NOT_FIXED_1(item) \ 247 (((item)->type != XML_SCHEMA_TYPE_BASIC) && \ 248 (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0)) 249 250 #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) 251 252 #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0) 253 /* 254 * Macros for exclusively for complex types. 255 */ 256 #define WXS_HAS_COMPLEX_CONTENT(item) \ 257 ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \ 258 (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \ 259 (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) 260 261 #define WXS_HAS_SIMPLE_CONTENT(item) \ 262 ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \ 263 (item->contentType == XML_SCHEMA_CONTENT_BASIC)) 264 265 #define WXS_HAS_MIXED_CONTENT(item) \ 266 (item->contentType == XML_SCHEMA_CONTENT_MIXED) 267 268 #define WXS_EMPTIABLE(t) \ 269 (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes)) 270 271 #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes 272 273 #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes 274 275 #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t)) 276 /* 277 * Macros for exclusively for simple types. 278 */ 279 #define WXS_LIST_ITEMTYPE(t) (t)->subtypes 280 281 #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) 282 283 #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) 284 285 #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) 286 /* 287 * Misc parser context macros. 288 */ 289 #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor 290 291 #define WXS_HAS_BUCKETS(ctx) \ 292 ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \ 293 (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) ) 294 295 #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups 296 297 #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket 298 299 #define WXS_SCHEMA(ctx) (ctx)->schema 300 301 #define WXS_ADD_LOCAL(ctx, item) \ 302 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item) 303 304 #define WXS_ADD_GLOBAL(ctx, item) \ 305 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item) 306 307 #define WXS_ADD_PENDING(ctx, item) \ 308 xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item) 309 /* 310 * xmlSchemaItemList macros. 311 */ 312 #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0)) 313 /* 314 * Misc macros. 315 */ 316 #define IS_SCHEMA(node, type) \ 317 ((node != NULL) && (node->ns != NULL) && \ 318 (xmlStrEqual(node->name, (const xmlChar *) type)) && \ 319 (xmlStrEqual(node->ns->href, xmlSchemaNs))) 320 321 #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; } 322 323 /* 324 * Since we put the default/fixed values into the dict, we can 325 * use pointer comparison for those values. 326 * REMOVED: (xmlStrEqual((v1), (v2))) 327 */ 328 #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2)) 329 330 #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED) 331 332 #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0)) 333 334 #define HFAILURE if (res == -1) goto exit_failure; 335 336 #define HERROR if (res != 0) goto exit_error; 337 338 #define HSTOP(ctx) if ((ctx)->stop) goto exit; 339 /* 340 * Some flags used for various schema constraints. 341 */ 342 #define SUBSET_RESTRICTION 1<<0 343 #define SUBSET_EXTENSION 1<<1 344 #define SUBSET_SUBSTITUTION 1<<2 345 #define SUBSET_LIST 1<<3 346 #define SUBSET_UNION 1<<4 347 348 typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo; 349 typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr; 350 351 typedef struct _xmlSchemaItemList xmlSchemaItemList; 352 typedef xmlSchemaItemList *xmlSchemaItemListPtr; 353 struct _xmlSchemaItemList { 354 void **items; /* used for dynamic addition of schemata */ 355 int nbItems; /* used for dynamic addition of schemata */ 356 int sizeItems; /* used for dynamic addition of schemata */ 357 }; 358 359 #define XML_SCHEMA_CTXT_PARSER 1 360 #define XML_SCHEMA_CTXT_VALIDATOR 2 361 362 typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt; 363 typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr; 364 struct _xmlSchemaAbstractCtxt { 365 int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */ 366 }; 367 368 typedef struct _xmlSchemaBucket xmlSchemaBucket; 369 typedef xmlSchemaBucket *xmlSchemaBucketPtr; 370 371 #define XML_SCHEMA_SCHEMA_MAIN 0 372 #define XML_SCHEMA_SCHEMA_IMPORT 1 373 #define XML_SCHEMA_SCHEMA_INCLUDE 2 374 #define XML_SCHEMA_SCHEMA_REDEFINE 3 375 376 /** 377 * xmlSchemaSchemaRelation: 378 * 379 * Used to create a graph of schema relationships. 380 */ 381 typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation; 382 typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr; 383 struct _xmlSchemaSchemaRelation { 384 xmlSchemaSchemaRelationPtr next; 385 int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */ 386 const xmlChar *importNamespace; 387 xmlSchemaBucketPtr bucket; 388 }; 389 390 #define XML_SCHEMA_BUCKET_MARKED 1<<0 391 #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1 392 393 struct _xmlSchemaBucket { 394 int type; 395 int flags; 396 const xmlChar *schemaLocation; 397 const xmlChar *origTargetNamespace; 398 const xmlChar *targetNamespace; 399 xmlDocPtr doc; 400 xmlSchemaSchemaRelationPtr relations; 401 int located; 402 int parsed; 403 int imported; 404 int preserveDoc; 405 xmlSchemaItemListPtr globals; /* Global components. */ 406 xmlSchemaItemListPtr locals; /* Local components. */ 407 }; 408 409 /** 410 * xmlSchemaImport: 411 * (extends xmlSchemaBucket) 412 * 413 * Reflects a schema. Holds some information 414 * about the schema and its toplevel components. Duplicate 415 * toplevel components are not checked at this level. 416 */ 417 typedef struct _xmlSchemaImport xmlSchemaImport; 418 typedef xmlSchemaImport *xmlSchemaImportPtr; 419 struct _xmlSchemaImport { 420 int type; /* Main OR import OR include. */ 421 int flags; 422 const xmlChar *schemaLocation; /* The URI of the schema document. */ 423 /* For chameleon includes, @origTargetNamespace will be NULL */ 424 const xmlChar *origTargetNamespace; 425 /* 426 * For chameleon includes, @targetNamespace will be the 427 * targetNamespace of the including schema. 428 */ 429 const xmlChar *targetNamespace; 430 xmlDocPtr doc; /* The schema node-tree. */ 431 /* @relations will hold any included/imported/redefined schemas. */ 432 xmlSchemaSchemaRelationPtr relations; 433 int located; 434 int parsed; 435 int imported; 436 int preserveDoc; 437 xmlSchemaItemListPtr globals; 438 xmlSchemaItemListPtr locals; 439 /* The imported schema. */ 440 xmlSchemaPtr schema; 441 }; 442 443 /* 444 * (extends xmlSchemaBucket) 445 */ 446 typedef struct _xmlSchemaInclude xmlSchemaInclude; 447 typedef xmlSchemaInclude *xmlSchemaIncludePtr; 448 struct _xmlSchemaInclude { 449 int type; 450 int flags; 451 const xmlChar *schemaLocation; 452 const xmlChar *origTargetNamespace; 453 const xmlChar *targetNamespace; 454 xmlDocPtr doc; 455 xmlSchemaSchemaRelationPtr relations; 456 int located; 457 int parsed; 458 int imported; 459 int preserveDoc; 460 xmlSchemaItemListPtr globals; /* Global components. */ 461 xmlSchemaItemListPtr locals; /* Local components. */ 462 463 /* The owning main or import schema bucket. */ 464 xmlSchemaImportPtr ownerImport; 465 }; 466 467 /** 468 * xmlSchemaBasicItem: 469 * 470 * The abstract base type for schema components. 471 */ 472 typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem; 473 typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr; 474 struct _xmlSchemaBasicItem { 475 xmlSchemaTypeType type; 476 }; 477 478 /** 479 * xmlSchemaAnnotItem: 480 * 481 * The abstract base type for annotated schema components. 482 * (Extends xmlSchemaBasicItem) 483 */ 484 typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem; 485 typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr; 486 struct _xmlSchemaAnnotItem { 487 xmlSchemaTypeType type; 488 xmlSchemaAnnotPtr annot; 489 }; 490 491 /** 492 * xmlSchemaTreeItem: 493 * 494 * The abstract base type for tree-like structured schema components. 495 * (Extends xmlSchemaAnnotItem) 496 */ 497 typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem; 498 typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr; 499 struct _xmlSchemaTreeItem { 500 xmlSchemaTypeType type; 501 xmlSchemaAnnotPtr annot; 502 xmlSchemaTreeItemPtr next; 503 xmlSchemaTreeItemPtr children; 504 }; 505 506 507 #define XML_SCHEMA_ATTR_USE_FIXED 1<<0 508 /** 509 * xmlSchemaAttributeUsePtr: 510 * 511 * The abstract base type for tree-like structured schema components. 512 * (Extends xmlSchemaTreeItem) 513 */ 514 typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse; 515 typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr; 516 struct _xmlSchemaAttributeUse { 517 xmlSchemaTypeType type; 518 xmlSchemaAnnotPtr annot; 519 xmlSchemaAttributeUsePtr next; /* The next attr. use. */ 520 /* 521 * The attr. decl. OR a QName-ref. to an attr. decl. OR 522 * a QName-ref. to an attribute group definition. 523 */ 524 xmlSchemaAttributePtr attrDecl; 525 526 int flags; 527 xmlNodePtr node; 528 int occurs; /* required, optional */ 529 const xmlChar * defValue; 530 xmlSchemaValPtr defVal; 531 }; 532 533 /** 534 * xmlSchemaAttributeUseProhibPtr: 535 * 536 * A helper component to reflect attribute prohibitions. 537 * (Extends xmlSchemaBasicItem) 538 */ 539 typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib; 540 typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr; 541 struct _xmlSchemaAttributeUseProhib { 542 xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */ 543 xmlNodePtr node; 544 const xmlChar *name; 545 const xmlChar *targetNamespace; 546 int isRef; 547 }; 548 549 /** 550 * xmlSchemaRedef: 551 */ 552 typedef struct _xmlSchemaRedef xmlSchemaRedef; 553 typedef xmlSchemaRedef *xmlSchemaRedefPtr; 554 struct _xmlSchemaRedef { 555 xmlSchemaRedefPtr next; 556 xmlSchemaBasicItemPtr item; /* The redefining component. */ 557 xmlSchemaBasicItemPtr reference; /* The referencing component. */ 558 xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */ 559 const xmlChar *refName; /* The name of the to-be-redefined component. */ 560 const xmlChar *refTargetNs; /* The target namespace of the 561 to-be-redefined comp. */ 562 xmlSchemaBucketPtr targetBucket; /* The redefined schema. */ 563 }; 564 565 /** 566 * xmlSchemaConstructionCtxt: 567 */ 568 typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt; 569 typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr; 570 struct _xmlSchemaConstructionCtxt { 571 xmlSchemaPtr mainSchema; /* The main schema. */ 572 xmlSchemaBucketPtr mainBucket; /* The main schema bucket */ 573 xmlDictPtr dict; 574 xmlSchemaItemListPtr buckets; /* List of schema buckets. */ 575 /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */ 576 xmlSchemaBucketPtr bucket; /* The current schema bucket */ 577 xmlSchemaItemListPtr pending; /* All Components of all schemas that 578 need to be fixed. */ 579 xmlHashTablePtr substGroups; 580 xmlSchemaRedefPtr redefs; 581 xmlSchemaRedefPtr lastRedef; 582 }; 583 584 #define XML_SCHEMAS_PARSE_ERROR 1 585 #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT 586 587 struct _xmlSchemaParserCtxt { 588 int type; 589 void *errCtxt; /* user specific error context */ 590 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 591 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 592 int err; 593 int nberrors; 594 xmlStructuredErrorFunc serror; 595 596 xmlSchemaConstructionCtxtPtr constructor; 597 int ownsConstructor; /* TODO: Move this to parser *flags*. */ 598 599 /* xmlSchemaPtr topschema; */ 600 /* xmlHashTablePtr namespaces; */ 601 602 xmlSchemaPtr schema; /* The main schema in use */ 603 int counter; 604 605 const xmlChar *URL; 606 xmlDocPtr doc; 607 int preserve; /* Whether the doc should be freed */ 608 609 const char *buffer; 610 int size; 611 612 /* 613 * Used to build complex element content models 614 */ 615 xmlAutomataPtr am; 616 xmlAutomataStatePtr start; 617 xmlAutomataStatePtr end; 618 xmlAutomataStatePtr state; 619 620 xmlDictPtr dict; /* dictionnary for interned string names */ 621 xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */ 622 int options; 623 xmlSchemaValidCtxtPtr vctxt; 624 int isS4S; 625 int isRedefine; 626 int xsiAssemble; 627 int stop; /* If the parser should stop; i.e. a critical error. */ 628 const xmlChar *targetNamespace; 629 xmlSchemaBucketPtr redefined; /* The schema to be redefined. */ 630 631 xmlSchemaRedefPtr redef; /* Used for redefinitions. */ 632 int redefCounter; /* Used for redefinitions. */ 633 xmlSchemaItemListPtr attrProhibs; 634 }; 635 636 /** 637 * xmlSchemaQNameRef: 638 * 639 * A component reference item (not a schema component) 640 * (Extends xmlSchemaBasicItem) 641 */ 642 typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef; 643 typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr; 644 struct _xmlSchemaQNameRef { 645 xmlSchemaTypeType type; 646 xmlSchemaBasicItemPtr item; /* The resolved referenced item. */ 647 xmlSchemaTypeType itemType; 648 const xmlChar *name; 649 const xmlChar *targetNamespace; 650 xmlNodePtr node; 651 }; 652 653 /** 654 * xmlSchemaParticle: 655 * 656 * A particle component. 657 * (Extends xmlSchemaTreeItem) 658 */ 659 typedef struct _xmlSchemaParticle xmlSchemaParticle; 660 typedef xmlSchemaParticle *xmlSchemaParticlePtr; 661 struct _xmlSchemaParticle { 662 xmlSchemaTypeType type; 663 xmlSchemaAnnotPtr annot; 664 xmlSchemaTreeItemPtr next; /* next particle */ 665 xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group, 666 a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference), 667 etc.) */ 668 int minOccurs; 669 int maxOccurs; 670 xmlNodePtr node; 671 }; 672 673 /** 674 * xmlSchemaModelGroup: 675 * 676 * A model group component. 677 * (Extends xmlSchemaTreeItem) 678 */ 679 typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup; 680 typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr; 681 struct _xmlSchemaModelGroup { 682 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */ 683 xmlSchemaAnnotPtr annot; 684 xmlSchemaTreeItemPtr next; /* not used */ 685 xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */ 686 xmlNodePtr node; 687 }; 688 689 #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0 690 #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1 691 /** 692 * xmlSchemaModelGroupDef: 693 * 694 * A model group definition component. 695 * (Extends xmlSchemaTreeItem) 696 */ 697 typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef; 698 typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr; 699 struct _xmlSchemaModelGroupDef { 700 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */ 701 xmlSchemaAnnotPtr annot; 702 xmlSchemaTreeItemPtr next; /* not used */ 703 xmlSchemaTreeItemPtr children; /* the "model group" */ 704 const xmlChar *name; 705 const xmlChar *targetNamespace; 706 xmlNodePtr node; 707 int flags; 708 }; 709 710 typedef struct _xmlSchemaIDC xmlSchemaIDC; 711 typedef xmlSchemaIDC *xmlSchemaIDCPtr; 712 713 /** 714 * xmlSchemaIDCSelect: 715 * 716 * The identity-constraint "field" and "selector" item, holding the 717 * XPath expression. 718 */ 719 typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect; 720 typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr; 721 struct _xmlSchemaIDCSelect { 722 xmlSchemaIDCSelectPtr next; 723 xmlSchemaIDCPtr idc; 724 int index; /* an index position if significant for IDC key-sequences */ 725 const xmlChar *xpath; /* the XPath expression */ 726 void *xpathComp; /* the compiled XPath expression */ 727 }; 728 729 /** 730 * xmlSchemaIDC: 731 * 732 * The identity-constraint definition component. 733 * (Extends xmlSchemaAnnotItem) 734 */ 735 736 struct _xmlSchemaIDC { 737 xmlSchemaTypeType type; 738 xmlSchemaAnnotPtr annot; 739 xmlSchemaIDCPtr next; 740 xmlNodePtr node; 741 const xmlChar *name; 742 const xmlChar *targetNamespace; 743 xmlSchemaIDCSelectPtr selector; 744 xmlSchemaIDCSelectPtr fields; 745 int nbFields; 746 xmlSchemaQNameRefPtr ref; 747 }; 748 749 /** 750 * xmlSchemaIDCAug: 751 * 752 * The augmented IDC information used for validation. 753 */ 754 typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug; 755 typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr; 756 struct _xmlSchemaIDCAug { 757 xmlSchemaIDCAugPtr next; /* next in a list */ 758 xmlSchemaIDCPtr def; /* the IDC definition */ 759 int keyrefDepth; /* the lowest tree level to which IDC 760 tables need to be bubbled upwards */ 761 }; 762 763 /** 764 * xmlSchemaPSVIIDCKeySequence: 765 * 766 * The key sequence of a node table item. 767 */ 768 typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey; 769 typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr; 770 struct _xmlSchemaPSVIIDCKey { 771 xmlSchemaTypePtr type; 772 xmlSchemaValPtr val; 773 }; 774 775 /** 776 * xmlSchemaPSVIIDCNode: 777 * 778 * The node table item of a node table. 779 */ 780 typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode; 781 typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr; 782 struct _xmlSchemaPSVIIDCNode { 783 xmlNodePtr node; 784 xmlSchemaPSVIIDCKeyPtr *keys; 785 int nodeLine; 786 int nodeQNameID; 787 788 }; 789 790 /** 791 * xmlSchemaPSVIIDCBinding: 792 * 793 * The identity-constraint binding item of the [identity-constraint table]. 794 */ 795 typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding; 796 typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr; 797 struct _xmlSchemaPSVIIDCBinding { 798 xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */ 799 xmlSchemaIDCPtr definition; /* the IDC definition */ 800 xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */ 801 int nbNodes; /* number of entries in the node table */ 802 int sizeNodes; /* size of the node table */ 803 xmlSchemaItemListPtr dupls; 804 }; 805 806 807 #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1 808 #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2 809 810 #define XPATH_STATE_OBJ_MATCHES -2 811 #define XPATH_STATE_OBJ_BLOCKED -3 812 813 typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher; 814 typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr; 815 816 /** 817 * xmlSchemaIDCStateObj: 818 * 819 * The state object used to evaluate XPath expressions. 820 */ 821 typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj; 822 typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr; 823 struct _xmlSchemaIDCStateObj { 824 int type; 825 xmlSchemaIDCStateObjPtr next; /* next if in a list */ 826 int depth; /* depth of creation */ 827 int *history; /* list of (depth, state-id) tuples */ 828 int nbHistory; 829 int sizeHistory; 830 xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector 831 matcher */ 832 xmlSchemaIDCSelectPtr sel; 833 void *xpathCtxt; 834 }; 835 836 #define IDC_MATCHER 0 837 838 /** 839 * xmlSchemaIDCMatcher: 840 * 841 * Used to evaluate IDC selectors (and fields). 842 */ 843 struct _xmlSchemaIDCMatcher { 844 int type; 845 int depth; /* the tree depth at creation time */ 846 xmlSchemaIDCMatcherPtr next; /* next in the list */ 847 xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */ 848 xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */ 849 int idcType; 850 xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target 851 elements */ 852 int sizeKeySeqs; 853 xmlSchemaItemListPtr targets; /* list of target-node 854 (xmlSchemaPSVIIDCNodePtr) entries */ 855 }; 856 857 /* 858 * Element info flags. 859 */ 860 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0 861 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1 862 #define XML_SCHEMA_ELEM_INFO_NILLED 1<<2 863 #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3 864 865 #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4 866 #define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5 867 #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6 868 869 #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7 870 #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8 871 #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9 872 #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10 873 874 /** 875 * xmlSchemaNodeInfo: 876 * 877 * Holds information of an element node. 878 */ 879 struct _xmlSchemaNodeInfo { 880 int nodeType; 881 xmlNodePtr node; 882 int nodeLine; 883 const xmlChar *localName; 884 const xmlChar *nsName; 885 const xmlChar *value; 886 xmlSchemaValPtr val; /* the pre-computed value if any */ 887 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 888 889 int flags; /* combination of node info flags */ 890 891 int valNeeded; 892 int normVal; 893 894 xmlSchemaElementPtr decl; /* the element/attribute declaration */ 895 int depth; 896 xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings 897 for the scope element*/ 898 xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope 899 element */ 900 xmlRegExecCtxtPtr regexCtxt; 901 902 const xmlChar **nsBindings; /* Namespace bindings on this element */ 903 int nbNsBindings; 904 int sizeNsBindings; 905 906 int hasKeyrefs; 907 int appliedXPath; /* Indicates that an XPath has been applied. */ 908 }; 909 910 #define XML_SCHEMAS_ATTR_UNKNOWN 1 911 #define XML_SCHEMAS_ATTR_ASSESSED 2 912 #define XML_SCHEMAS_ATTR_PROHIBITED 3 913 #define XML_SCHEMAS_ATTR_ERR_MISSING 4 914 #define XML_SCHEMAS_ATTR_INVALID_VALUE 5 915 #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6 916 #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7 917 #define XML_SCHEMAS_ATTR_DEFAULT 8 918 #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9 919 #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10 920 #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11 921 #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12 922 #define XML_SCHEMAS_ATTR_WILD_SKIP 13 923 #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14 924 #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15 925 #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16 926 #define XML_SCHEMAS_ATTR_META 17 927 /* 928 * @metaType values of xmlSchemaAttrInfo. 929 */ 930 #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1 931 #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2 932 #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3 933 #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4 934 #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5 935 936 typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo; 937 typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr; 938 struct _xmlSchemaAttrInfo { 939 int nodeType; 940 xmlNodePtr node; 941 int nodeLine; 942 const xmlChar *localName; 943 const xmlChar *nsName; 944 const xmlChar *value; 945 xmlSchemaValPtr val; /* the pre-computed value if any */ 946 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 947 int flags; /* combination of node info flags */ 948 949 xmlSchemaAttributePtr decl; /* the attribute declaration */ 950 xmlSchemaAttributeUsePtr use; /* the attribute use */ 951 int state; 952 int metaType; 953 const xmlChar *vcValue; /* the value constraint value */ 954 xmlSchemaNodeInfoPtr parent; 955 }; 956 957 958 #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1 959 /** 960 * xmlSchemaValidCtxt: 961 * 962 * A Schemas validation context 963 */ 964 struct _xmlSchemaValidCtxt { 965 int type; 966 void *errCtxt; /* user specific data block */ 967 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 968 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 969 xmlStructuredErrorFunc serror; 970 971 xmlSchemaPtr schema; /* The schema in use */ 972 xmlDocPtr doc; 973 xmlParserInputBufferPtr input; 974 xmlCharEncoding enc; 975 xmlSAXHandlerPtr sax; 976 xmlParserCtxtPtr parserCtxt; 977 void *user_data; /* TODO: What is this for? */ 978 979 int err; 980 int nberrors; 981 982 xmlNodePtr node; 983 xmlNodePtr cur; 984 /* xmlSchemaTypePtr type; */ 985 986 xmlRegExecCtxtPtr regexp; 987 xmlSchemaValPtr value; 988 989 int valueWS; 990 int options; 991 xmlNodePtr validationRoot; 992 xmlSchemaParserCtxtPtr pctxt; 993 int xsiAssemble; 994 995 int depth; 996 xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */ 997 int sizeElemInfos; 998 xmlSchemaNodeInfoPtr inode; /* the current element information */ 999 1000 xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */ 1001 1002 xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */ 1003 xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */ 1004 xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */ 1005 1006 xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/ 1007 int nbIdcNodes; 1008 int sizeIdcNodes; 1009 1010 xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */ 1011 int nbIdcKeys; 1012 int sizeIdcKeys; 1013 1014 int flags; 1015 1016 xmlDictPtr dict; 1017 1018 #ifdef LIBXML_READER_ENABLED 1019 xmlTextReaderPtr reader; 1020 #endif 1021 1022 xmlSchemaAttrInfoPtr *attrInfos; 1023 int nbAttrInfos; 1024 int sizeAttrInfos; 1025 1026 int skipDepth; 1027 xmlSchemaItemListPtr nodeQNames; 1028 int hasKeyrefs; 1029 int createIDCNodeTables; 1030 int psviExposeIDCNodeTables; 1031 }; 1032 1033 /** 1034 * xmlSchemaSubstGroup: 1035 * 1036 * 1037 */ 1038 typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup; 1039 typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr; 1040 struct _xmlSchemaSubstGroup { 1041 xmlSchemaElementPtr head; 1042 xmlSchemaItemListPtr members; 1043 }; 1044 1045 /************************************************************************ 1046 * * 1047 * Some predeclarations * 1048 * * 1049 ************************************************************************/ 1050 1051 static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, 1052 xmlSchemaPtr schema, 1053 xmlNodePtr node); 1054 static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt, 1055 xmlSchemaPtr schema, 1056 xmlNodePtr node); 1057 static int 1058 xmlSchemaTypeFixup(xmlSchemaTypePtr type, 1059 xmlSchemaAbstractCtxtPtr ctxt); 1060 static const xmlChar * 1061 xmlSchemaFacetTypeToString(xmlSchemaTypeType type); 1062 static int 1063 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1064 xmlNodePtr node); 1065 static int 1066 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 1067 xmlSchemaParserCtxtPtr ctxt); 1068 static void 1069 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt); 1070 static xmlSchemaWhitespaceValueType 1071 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type); 1072 static xmlSchemaTreeItemPtr 1073 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1074 xmlNodePtr node, xmlSchemaTypeType type, 1075 int withParticle); 1076 static const xmlChar * 1077 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item); 1078 static xmlSchemaTypeLinkPtr 1079 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type); 1080 static void 1081 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 1082 const char *funcName, 1083 const char *message); 1084 static int 1085 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt, 1086 xmlSchemaTypePtr type, 1087 xmlSchemaTypePtr baseType, 1088 int subset); 1089 static void 1090 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl, 1091 xmlSchemaParserCtxtPtr ctxt); 1092 static void 1093 xmlSchemaComponentListFree(xmlSchemaItemListPtr list); 1094 static xmlSchemaQNameRefPtr 1095 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 1096 xmlSchemaPtr schema, 1097 xmlNodePtr node); 1098 1099 /************************************************************************ 1100 * * 1101 * Helper functions * 1102 * * 1103 ************************************************************************/ 1104 1105 /** 1106 * xmlSchemaItemTypeToStr: 1107 * @type: the type of the schema item 1108 * 1109 * Returns the component name of a schema item. 1110 */ 1111 static const xmlChar * 1112 xmlSchemaItemTypeToStr(xmlSchemaTypeType type) 1113 { 1114 switch (type) { 1115 case XML_SCHEMA_TYPE_BASIC: 1116 return(BAD_CAST "simple type definition"); 1117 case XML_SCHEMA_TYPE_SIMPLE: 1118 return(BAD_CAST "simple type definition"); 1119 case XML_SCHEMA_TYPE_COMPLEX: 1120 return(BAD_CAST "complex type definition"); 1121 case XML_SCHEMA_TYPE_ELEMENT: 1122 return(BAD_CAST "element declaration"); 1123 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1124 return(BAD_CAST "attribute use"); 1125 case XML_SCHEMA_TYPE_ATTRIBUTE: 1126 return(BAD_CAST "attribute declaration"); 1127 case XML_SCHEMA_TYPE_GROUP: 1128 return(BAD_CAST "model group definition"); 1129 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1130 return(BAD_CAST "attribute group definition"); 1131 case XML_SCHEMA_TYPE_NOTATION: 1132 return(BAD_CAST "notation declaration"); 1133 case XML_SCHEMA_TYPE_SEQUENCE: 1134 return(BAD_CAST "model group (sequence)"); 1135 case XML_SCHEMA_TYPE_CHOICE: 1136 return(BAD_CAST "model group (choice)"); 1137 case XML_SCHEMA_TYPE_ALL: 1138 return(BAD_CAST "model group (all)"); 1139 case XML_SCHEMA_TYPE_PARTICLE: 1140 return(BAD_CAST "particle"); 1141 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1142 return(BAD_CAST "unique identity-constraint"); 1143 /* return(BAD_CAST "IDC (unique)"); */ 1144 case XML_SCHEMA_TYPE_IDC_KEY: 1145 return(BAD_CAST "key identity-constraint"); 1146 /* return(BAD_CAST "IDC (key)"); */ 1147 case XML_SCHEMA_TYPE_IDC_KEYREF: 1148 return(BAD_CAST "keyref identity-constraint"); 1149 /* return(BAD_CAST "IDC (keyref)"); */ 1150 case XML_SCHEMA_TYPE_ANY: 1151 return(BAD_CAST "wildcard (any)"); 1152 case XML_SCHEMA_EXTRA_QNAMEREF: 1153 return(BAD_CAST "[helper component] QName reference"); 1154 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 1155 return(BAD_CAST "[helper component] attribute use prohibition"); 1156 default: 1157 return(BAD_CAST "Not a schema component"); 1158 } 1159 } 1160 1161 /** 1162 * xmlSchemaGetComponentTypeStr: 1163 * @type: the type of the schema item 1164 * 1165 * Returns the component name of a schema item. 1166 */ 1167 static const xmlChar * 1168 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item) 1169 { 1170 switch (item->type) { 1171 case XML_SCHEMA_TYPE_BASIC: 1172 if (WXS_IS_COMPLEX(WXS_TYPE_CAST item)) 1173 return(BAD_CAST "complex type definition"); 1174 else 1175 return(BAD_CAST "simple type definition"); 1176 default: 1177 return(xmlSchemaItemTypeToStr(item->type)); 1178 } 1179 } 1180 1181 /** 1182 * xmlSchemaGetComponentNode: 1183 * @item: a schema component 1184 * 1185 * Returns node associated with the schema component. 1186 * NOTE that such a node need not be available; plus, a component's 1187 * node need not to reflect the component directly, since there is no 1188 * one-to-one relationship between the XML Schema representation and 1189 * the component representation. 1190 */ 1191 static xmlNodePtr 1192 xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item) 1193 { 1194 switch (item->type) { 1195 case XML_SCHEMA_TYPE_ELEMENT: 1196 return (((xmlSchemaElementPtr) item)->node); 1197 case XML_SCHEMA_TYPE_ATTRIBUTE: 1198 return (((xmlSchemaAttributePtr) item)->node); 1199 case XML_SCHEMA_TYPE_COMPLEX: 1200 case XML_SCHEMA_TYPE_SIMPLE: 1201 return (((xmlSchemaTypePtr) item)->node); 1202 case XML_SCHEMA_TYPE_ANY: 1203 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1204 return (((xmlSchemaWildcardPtr) item)->node); 1205 case XML_SCHEMA_TYPE_PARTICLE: 1206 return (((xmlSchemaParticlePtr) item)->node); 1207 case XML_SCHEMA_TYPE_SEQUENCE: 1208 case XML_SCHEMA_TYPE_CHOICE: 1209 case XML_SCHEMA_TYPE_ALL: 1210 return (((xmlSchemaModelGroupPtr) item)->node); 1211 case XML_SCHEMA_TYPE_GROUP: 1212 return (((xmlSchemaModelGroupDefPtr) item)->node); 1213 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1214 return (((xmlSchemaAttributeGroupPtr) item)->node); 1215 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1216 case XML_SCHEMA_TYPE_IDC_KEY: 1217 case XML_SCHEMA_TYPE_IDC_KEYREF: 1218 return (((xmlSchemaIDCPtr) item)->node); 1219 case XML_SCHEMA_EXTRA_QNAMEREF: 1220 return(((xmlSchemaQNameRefPtr) item)->node); 1221 /* TODO: What to do with NOTATIONs? 1222 case XML_SCHEMA_TYPE_NOTATION: 1223 return (((xmlSchemaNotationPtr) item)->node); 1224 */ 1225 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1226 return (((xmlSchemaAttributeUsePtr) item)->node); 1227 default: 1228 return (NULL); 1229 } 1230 } 1231 1232 #if 0 1233 /** 1234 * xmlSchemaGetNextComponent: 1235 * @item: a schema component 1236 * 1237 * Returns the next sibling of the schema component. 1238 */ 1239 static xmlSchemaBasicItemPtr 1240 xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item) 1241 { 1242 switch (item->type) { 1243 case XML_SCHEMA_TYPE_ELEMENT: 1244 return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next); 1245 case XML_SCHEMA_TYPE_ATTRIBUTE: 1246 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next); 1247 case XML_SCHEMA_TYPE_COMPLEX: 1248 case XML_SCHEMA_TYPE_SIMPLE: 1249 return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next); 1250 case XML_SCHEMA_TYPE_ANY: 1251 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1252 return (NULL); 1253 case XML_SCHEMA_TYPE_PARTICLE: 1254 return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next); 1255 case XML_SCHEMA_TYPE_SEQUENCE: 1256 case XML_SCHEMA_TYPE_CHOICE: 1257 case XML_SCHEMA_TYPE_ALL: 1258 return (NULL); 1259 case XML_SCHEMA_TYPE_GROUP: 1260 return (NULL); 1261 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1262 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next); 1263 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1264 case XML_SCHEMA_TYPE_IDC_KEY: 1265 case XML_SCHEMA_TYPE_IDC_KEYREF: 1266 return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next); 1267 default: 1268 return (NULL); 1269 } 1270 } 1271 #endif 1272 1273 1274 /** 1275 * xmlSchemaFormatQName: 1276 * @buf: the string buffer 1277 * @namespaceName: the namespace name 1278 * @localName: the local name 1279 * 1280 * Returns the given QName in the format "{namespaceName}localName" or 1281 * just "localName" if @namespaceName is NULL. 1282 * 1283 * Returns the localName if @namespaceName is NULL, a formatted 1284 * string otherwise. 1285 */ 1286 static const xmlChar* 1287 xmlSchemaFormatQName(xmlChar **buf, 1288 const xmlChar *namespaceName, 1289 const xmlChar *localName) 1290 { 1291 FREE_AND_NULL(*buf) 1292 if (namespaceName != NULL) { 1293 *buf = xmlStrdup(BAD_CAST "{"); 1294 *buf = xmlStrcat(*buf, namespaceName); 1295 *buf = xmlStrcat(*buf, BAD_CAST "}"); 1296 } 1297 if (localName != NULL) { 1298 if (namespaceName == NULL) 1299 return(localName); 1300 *buf = xmlStrcat(*buf, localName); 1301 } else { 1302 *buf = xmlStrcat(*buf, BAD_CAST "(NULL)"); 1303 } 1304 return ((const xmlChar *) *buf); 1305 } 1306 1307 static const xmlChar* 1308 xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName) 1309 { 1310 if (ns != NULL) 1311 return (xmlSchemaFormatQName(buf, ns->href, localName)); 1312 else 1313 return (xmlSchemaFormatQName(buf, NULL, localName)); 1314 } 1315 1316 static const xmlChar * 1317 xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item) 1318 { 1319 switch (item->type) { 1320 case XML_SCHEMA_TYPE_ELEMENT: 1321 return (((xmlSchemaElementPtr) item)->name); 1322 case XML_SCHEMA_TYPE_ATTRIBUTE: 1323 return (((xmlSchemaAttributePtr) item)->name); 1324 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1325 return (((xmlSchemaAttributeGroupPtr) item)->name); 1326 case XML_SCHEMA_TYPE_BASIC: 1327 case XML_SCHEMA_TYPE_SIMPLE: 1328 case XML_SCHEMA_TYPE_COMPLEX: 1329 return (((xmlSchemaTypePtr) item)->name); 1330 case XML_SCHEMA_TYPE_GROUP: 1331 return (((xmlSchemaModelGroupDefPtr) item)->name); 1332 case XML_SCHEMA_TYPE_IDC_KEY: 1333 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1334 case XML_SCHEMA_TYPE_IDC_KEYREF: 1335 return (((xmlSchemaIDCPtr) item)->name); 1336 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1337 if (WXS_ATTRUSE_DECL(item) != NULL) { 1338 return(xmlSchemaGetComponentName( 1339 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1340 } else 1341 return(NULL); 1342 case XML_SCHEMA_EXTRA_QNAMEREF: 1343 return (((xmlSchemaQNameRefPtr) item)->name); 1344 case XML_SCHEMA_TYPE_NOTATION: 1345 return (((xmlSchemaNotationPtr) item)->name); 1346 default: 1347 /* 1348 * Other components cannot have names. 1349 */ 1350 break; 1351 } 1352 return (NULL); 1353 } 1354 1355 #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name 1356 #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace 1357 /* 1358 static const xmlChar * 1359 xmlSchemaGetQNameRefName(void *ref) 1360 { 1361 return(((xmlSchemaQNameRefPtr) ref)->name); 1362 } 1363 1364 static const xmlChar * 1365 xmlSchemaGetQNameRefTargetNs(void *ref) 1366 { 1367 return(((xmlSchemaQNameRefPtr) ref)->targetNamespace); 1368 } 1369 */ 1370 1371 static const xmlChar * 1372 xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item) 1373 { 1374 switch (item->type) { 1375 case XML_SCHEMA_TYPE_ELEMENT: 1376 return (((xmlSchemaElementPtr) item)->targetNamespace); 1377 case XML_SCHEMA_TYPE_ATTRIBUTE: 1378 return (((xmlSchemaAttributePtr) item)->targetNamespace); 1379 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1380 return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace); 1381 case XML_SCHEMA_TYPE_BASIC: 1382 return (BAD_CAST "http://www.w3.org/2001/XMLSchema"); 1383 case XML_SCHEMA_TYPE_SIMPLE: 1384 case XML_SCHEMA_TYPE_COMPLEX: 1385 return (((xmlSchemaTypePtr) item)->targetNamespace); 1386 case XML_SCHEMA_TYPE_GROUP: 1387 return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace); 1388 case XML_SCHEMA_TYPE_IDC_KEY: 1389 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1390 case XML_SCHEMA_TYPE_IDC_KEYREF: 1391 return (((xmlSchemaIDCPtr) item)->targetNamespace); 1392 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1393 if (WXS_ATTRUSE_DECL(item) != NULL) { 1394 return(xmlSchemaGetComponentTargetNs( 1395 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1396 } 1397 /* TODO: Will returning NULL break something? */ 1398 break; 1399 case XML_SCHEMA_EXTRA_QNAMEREF: 1400 return (((xmlSchemaQNameRefPtr) item)->targetNamespace); 1401 case XML_SCHEMA_TYPE_NOTATION: 1402 return (((xmlSchemaNotationPtr) item)->targetNamespace); 1403 default: 1404 /* 1405 * Other components cannot have names. 1406 */ 1407 break; 1408 } 1409 return (NULL); 1410 } 1411 1412 static const xmlChar* 1413 xmlSchemaGetComponentQName(xmlChar **buf, 1414 void *item) 1415 { 1416 return (xmlSchemaFormatQName(buf, 1417 xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item), 1418 xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item))); 1419 } 1420 1421 static const xmlChar* 1422 xmlSchemaGetComponentDesignation(xmlChar **buf, void *item) 1423 { 1424 xmlChar *str = NULL; 1425 1426 *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item)); 1427 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1428 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, 1429 (xmlSchemaBasicItemPtr) item)); 1430 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1431 FREE_AND_NULL(str); 1432 return(*buf); 1433 } 1434 1435 static const xmlChar* 1436 xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc) 1437 { 1438 return(xmlSchemaGetComponentDesignation(buf, idc)); 1439 } 1440 1441 /** 1442 * xmlSchemaWildcardPCToString: 1443 * @pc: the type of processContents 1444 * 1445 * Returns a string representation of the type of 1446 * processContents. 1447 */ 1448 static const xmlChar * 1449 xmlSchemaWildcardPCToString(int pc) 1450 { 1451 switch (pc) { 1452 case XML_SCHEMAS_ANY_SKIP: 1453 return (BAD_CAST "skip"); 1454 case XML_SCHEMAS_ANY_LAX: 1455 return (BAD_CAST "lax"); 1456 case XML_SCHEMAS_ANY_STRICT: 1457 return (BAD_CAST "strict"); 1458 default: 1459 return (BAD_CAST "invalid process contents"); 1460 } 1461 } 1462 1463 /** 1464 * xmlSchemaGetCanonValueWhtspExt: 1465 * @val: the precomputed value 1466 * @retValue: the returned value 1467 * @ws: the whitespace type of the value 1468 * 1469 * Get a the cononical representation of the value. 1470 * The caller has to free the returned retValue. 1471 * 1472 * Returns 0 if the value could be built and -1 in case of 1473 * API errors or if the value type is not supported yet. 1474 */ 1475 static int 1476 xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val, 1477 xmlSchemaWhitespaceValueType ws, 1478 xmlChar **retValue) 1479 { 1480 int list; 1481 xmlSchemaValType valType; 1482 const xmlChar *value, *value2 = NULL; 1483 1484 1485 if ((retValue == NULL) || (val == NULL)) 1486 return (-1); 1487 list = xmlSchemaValueGetNext(val) ? 1 : 0; 1488 *retValue = NULL; 1489 do { 1490 value = NULL; 1491 valType = xmlSchemaGetValType(val); 1492 switch (valType) { 1493 case XML_SCHEMAS_STRING: 1494 case XML_SCHEMAS_NORMSTRING: 1495 case XML_SCHEMAS_ANYSIMPLETYPE: 1496 value = xmlSchemaValueGetAsString(val); 1497 if (value != NULL) { 1498 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE) 1499 value2 = xmlSchemaCollapseString(value); 1500 else if (ws == XML_SCHEMA_WHITESPACE_REPLACE) 1501 value2 = xmlSchemaWhiteSpaceReplace(value); 1502 if (value2 != NULL) 1503 value = value2; 1504 } 1505 break; 1506 default: 1507 if (xmlSchemaGetCanonValue(val, &value2) == -1) { 1508 if (value2 != NULL) 1509 xmlFree((xmlChar *) value2); 1510 goto internal_error; 1511 } 1512 value = value2; 1513 } 1514 if (*retValue == NULL) 1515 if (value == NULL) { 1516 if (! list) 1517 *retValue = xmlStrdup(BAD_CAST ""); 1518 } else 1519 *retValue = xmlStrdup(value); 1520 else if (value != NULL) { 1521 /* List. */ 1522 *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " "); 1523 *retValue = xmlStrcat((xmlChar *) *retValue, value); 1524 } 1525 FREE_AND_NULL(value2) 1526 val = xmlSchemaValueGetNext(val); 1527 } while (val != NULL); 1528 1529 return (0); 1530 internal_error: 1531 if (*retValue != NULL) 1532 xmlFree((xmlChar *) (*retValue)); 1533 if (value2 != NULL) 1534 xmlFree((xmlChar *) value2); 1535 return (-1); 1536 } 1537 1538 /** 1539 * xmlSchemaFormatItemForReport: 1540 * @buf: the string buffer 1541 * @itemDes: the designation of the item 1542 * @itemName: the name of the item 1543 * @item: the item as an object 1544 * @itemNode: the node of the item 1545 * @local: the local name 1546 * @parsing: if the function is used during the parse 1547 * 1548 * Returns a representation of the given item used 1549 * for error reports. 1550 * 1551 * The following order is used to build the resulting 1552 * designation if the arguments are not NULL: 1553 * 1a. If itemDes not NULL -> itemDes 1554 * 1b. If (itemDes not NULL) and (itemName not NULL) 1555 * -> itemDes + itemName 1556 * 2. If the preceding was NULL and (item not NULL) -> item 1557 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode 1558 * 1559 * If the itemNode is an attribute node, the name of the attribute 1560 * will be appended to the result. 1561 * 1562 * Returns the formatted string and sets @buf to the resulting value. 1563 */ 1564 static xmlChar* 1565 xmlSchemaFormatItemForReport(xmlChar **buf, 1566 const xmlChar *itemDes, 1567 xmlSchemaBasicItemPtr item, 1568 xmlNodePtr itemNode) 1569 { 1570 xmlChar *str = NULL; 1571 int named = 1; 1572 1573 if (*buf != NULL) { 1574 xmlFree(*buf); 1575 *buf = NULL; 1576 } 1577 1578 if (itemDes != NULL) { 1579 *buf = xmlStrdup(itemDes); 1580 } else if (item != NULL) { 1581 switch (item->type) { 1582 case XML_SCHEMA_TYPE_BASIC: { 1583 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1584 1585 if (WXS_IS_ATOMIC(type)) 1586 *buf = xmlStrdup(BAD_CAST "atomic type 'xs:"); 1587 else if (WXS_IS_LIST(type)) 1588 *buf = xmlStrdup(BAD_CAST "list type 'xs:"); 1589 else if (WXS_IS_UNION(type)) 1590 *buf = xmlStrdup(BAD_CAST "union type 'xs:"); 1591 else 1592 *buf = xmlStrdup(BAD_CAST "simple type 'xs:"); 1593 *buf = xmlStrcat(*buf, type->name); 1594 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1595 } 1596 break; 1597 case XML_SCHEMA_TYPE_SIMPLE: { 1598 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1599 1600 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1601 *buf = xmlStrdup(BAD_CAST""); 1602 } else { 1603 *buf = xmlStrdup(BAD_CAST "local "); 1604 } 1605 if (WXS_IS_ATOMIC(type)) 1606 *buf = xmlStrcat(*buf, BAD_CAST "atomic type"); 1607 else if (WXS_IS_LIST(type)) 1608 *buf = xmlStrcat(*buf, BAD_CAST "list type"); 1609 else if (WXS_IS_UNION(type)) 1610 *buf = xmlStrcat(*buf, BAD_CAST "union type"); 1611 else 1612 *buf = xmlStrcat(*buf, BAD_CAST "simple type"); 1613 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1614 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1615 *buf = xmlStrcat(*buf, type->name); 1616 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1617 } 1618 } 1619 break; 1620 case XML_SCHEMA_TYPE_COMPLEX: { 1621 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1622 1623 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) 1624 *buf = xmlStrdup(BAD_CAST ""); 1625 else 1626 *buf = xmlStrdup(BAD_CAST "local "); 1627 *buf = xmlStrcat(*buf, BAD_CAST "complex type"); 1628 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1629 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1630 *buf = xmlStrcat(*buf, type->name); 1631 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1632 } 1633 } 1634 break; 1635 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: { 1636 xmlSchemaAttributeUsePtr ause; 1637 1638 ause = WXS_ATTR_USE_CAST item; 1639 *buf = xmlStrdup(BAD_CAST "attribute use "); 1640 if (WXS_ATTRUSE_DECL(ause) != NULL) { 1641 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1642 *buf = xmlStrcat(*buf, 1643 xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause))); 1644 FREE_AND_NULL(str) 1645 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1646 } else { 1647 *buf = xmlStrcat(*buf, BAD_CAST "(unknown)"); 1648 } 1649 } 1650 break; 1651 case XML_SCHEMA_TYPE_ATTRIBUTE: { 1652 xmlSchemaAttributePtr attr; 1653 1654 attr = (xmlSchemaAttributePtr) item; 1655 *buf = xmlStrdup(BAD_CAST "attribute decl."); 1656 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1657 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1658 attr->targetNamespace, attr->name)); 1659 FREE_AND_NULL(str) 1660 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1661 } 1662 break; 1663 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1664 xmlSchemaGetComponentDesignation(buf, item); 1665 break; 1666 case XML_SCHEMA_TYPE_ELEMENT: { 1667 xmlSchemaElementPtr elem; 1668 1669 elem = (xmlSchemaElementPtr) item; 1670 *buf = xmlStrdup(BAD_CAST "element decl."); 1671 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1672 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1673 elem->targetNamespace, elem->name)); 1674 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1675 } 1676 break; 1677 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1678 case XML_SCHEMA_TYPE_IDC_KEY: 1679 case XML_SCHEMA_TYPE_IDC_KEYREF: 1680 if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE) 1681 *buf = xmlStrdup(BAD_CAST "unique '"); 1682 else if (item->type == XML_SCHEMA_TYPE_IDC_KEY) 1683 *buf = xmlStrdup(BAD_CAST "key '"); 1684 else 1685 *buf = xmlStrdup(BAD_CAST "keyRef '"); 1686 *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name); 1687 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1688 break; 1689 case XML_SCHEMA_TYPE_ANY: 1690 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1691 *buf = xmlStrdup(xmlSchemaWildcardPCToString( 1692 ((xmlSchemaWildcardPtr) item)->processContents)); 1693 *buf = xmlStrcat(*buf, BAD_CAST " wildcard"); 1694 break; 1695 case XML_SCHEMA_FACET_MININCLUSIVE: 1696 case XML_SCHEMA_FACET_MINEXCLUSIVE: 1697 case XML_SCHEMA_FACET_MAXINCLUSIVE: 1698 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 1699 case XML_SCHEMA_FACET_TOTALDIGITS: 1700 case XML_SCHEMA_FACET_FRACTIONDIGITS: 1701 case XML_SCHEMA_FACET_PATTERN: 1702 case XML_SCHEMA_FACET_ENUMERATION: 1703 case XML_SCHEMA_FACET_WHITESPACE: 1704 case XML_SCHEMA_FACET_LENGTH: 1705 case XML_SCHEMA_FACET_MAXLENGTH: 1706 case XML_SCHEMA_FACET_MINLENGTH: 1707 *buf = xmlStrdup(BAD_CAST "facet '"); 1708 *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type)); 1709 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1710 break; 1711 case XML_SCHEMA_TYPE_GROUP: { 1712 *buf = xmlStrdup(BAD_CAST "model group def."); 1713 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1714 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1715 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1716 FREE_AND_NULL(str) 1717 } 1718 break; 1719 case XML_SCHEMA_TYPE_SEQUENCE: 1720 case XML_SCHEMA_TYPE_CHOICE: 1721 case XML_SCHEMA_TYPE_ALL: 1722 case XML_SCHEMA_TYPE_PARTICLE: 1723 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1724 break; 1725 case XML_SCHEMA_TYPE_NOTATION: { 1726 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1727 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1728 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1729 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1730 FREE_AND_NULL(str); 1731 } 1732 default: 1733 named = 0; 1734 } 1735 } else 1736 named = 0; 1737 1738 if ((named == 0) && (itemNode != NULL)) { 1739 xmlNodePtr elem; 1740 1741 if (itemNode->type == XML_ATTRIBUTE_NODE) 1742 elem = itemNode->parent; 1743 else 1744 elem = itemNode; 1745 *buf = xmlStrdup(BAD_CAST "Element '"); 1746 if (elem->ns != NULL) { 1747 *buf = xmlStrcat(*buf, 1748 xmlSchemaFormatQName(&str, elem->ns->href, elem->name)); 1749 FREE_AND_NULL(str) 1750 } else 1751 *buf = xmlStrcat(*buf, elem->name); 1752 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1753 1754 } 1755 if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) { 1756 *buf = xmlStrcat(*buf, BAD_CAST ", attribute '"); 1757 if (itemNode->ns != NULL) { 1758 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1759 itemNode->ns->href, itemNode->name)); 1760 FREE_AND_NULL(str) 1761 } else 1762 *buf = xmlStrcat(*buf, itemNode->name); 1763 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1764 } 1765 FREE_AND_NULL(str) 1766 1767 return (*buf); 1768 } 1769 1770 /** 1771 * xmlSchemaFormatFacetEnumSet: 1772 * @buf: the string buffer 1773 * @type: the type holding the enumeration facets 1774 * 1775 * Builds a string consisting of all enumeration elements. 1776 * 1777 * Returns a string of all enumeration elements. 1778 */ 1779 static const xmlChar * 1780 xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt, 1781 xmlChar **buf, xmlSchemaTypePtr type) 1782 { 1783 xmlSchemaFacetPtr facet; 1784 xmlSchemaWhitespaceValueType ws; 1785 xmlChar *value = NULL; 1786 int res, found = 0; 1787 1788 if (*buf != NULL) 1789 xmlFree(*buf); 1790 *buf = NULL; 1791 1792 do { 1793 /* 1794 * Use the whitespace type of the base type. 1795 */ 1796 ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType); 1797 for (facet = type->facets; facet != NULL; facet = facet->next) { 1798 if (facet->type != XML_SCHEMA_FACET_ENUMERATION) 1799 continue; 1800 found = 1; 1801 res = xmlSchemaGetCanonValueWhtspExt(facet->val, 1802 ws, &value); 1803 if (res == -1) { 1804 xmlSchemaInternalErr(actxt, 1805 "xmlSchemaFormatFacetEnumSet", 1806 "compute the canonical lexical representation"); 1807 if (*buf != NULL) 1808 xmlFree(*buf); 1809 *buf = NULL; 1810 return (NULL); 1811 } 1812 if (*buf == NULL) 1813 *buf = xmlStrdup(BAD_CAST "'"); 1814 else 1815 *buf = xmlStrcat(*buf, BAD_CAST ", '"); 1816 *buf = xmlStrcat(*buf, BAD_CAST value); 1817 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1818 if (value != NULL) { 1819 xmlFree((xmlChar *)value); 1820 value = NULL; 1821 } 1822 } 1823 /* 1824 * The enumeration facet of a type restricts the enumeration 1825 * facet of the ancestor type; i.e., such restricted enumerations 1826 * do not belong to the set of the given type. Thus we break 1827 * on the first found enumeration. 1828 */ 1829 if (found) 1830 break; 1831 type = type->baseType; 1832 } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC)); 1833 1834 return ((const xmlChar *) *buf); 1835 } 1836 1837 /************************************************************************ 1838 * * 1839 * Error functions * 1840 * * 1841 ************************************************************************/ 1842 1843 #if 0 1844 static void 1845 xmlSchemaErrMemory(const char *msg) 1846 { 1847 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1848 msg); 1849 } 1850 #endif 1851 1852 static void 1853 xmlSchemaPSimpleErr(const char *msg) 1854 { 1855 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1856 msg); 1857 } 1858 1859 /** 1860 * xmlSchemaPErrMemory: 1861 * @node: a context node 1862 * @extra: extra informations 1863 * 1864 * Handle an out of memory condition 1865 */ 1866 static void 1867 xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt, 1868 const char *extra, xmlNodePtr node) 1869 { 1870 if (ctxt != NULL) 1871 ctxt->nberrors++; 1872 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL, 1873 extra); 1874 } 1875 1876 /** 1877 * xmlSchemaPErr: 1878 * @ctxt: the parsing context 1879 * @node: the context node 1880 * @error: the error code 1881 * @msg: the error message 1882 * @str1: extra data 1883 * @str2: extra data 1884 * 1885 * Handle a parser error 1886 */ 1887 static void 1888 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1889 const char *msg, const xmlChar * str1, const xmlChar * str2) 1890 { 1891 xmlGenericErrorFunc channel = NULL; 1892 xmlStructuredErrorFunc schannel = NULL; 1893 void *data = NULL; 1894 1895 if (ctxt != NULL) { 1896 ctxt->nberrors++; 1897 ctxt->err = error; 1898 channel = ctxt->error; 1899 data = ctxt->errCtxt; 1900 schannel = ctxt->serror; 1901 } 1902 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1903 error, XML_ERR_ERROR, NULL, 0, 1904 (const char *) str1, (const char *) str2, NULL, 0, 0, 1905 msg, str1, str2); 1906 } 1907 1908 /** 1909 * xmlSchemaPErr2: 1910 * @ctxt: the parsing context 1911 * @node: the context node 1912 * @node: the current child 1913 * @error: the error code 1914 * @msg: the error message 1915 * @str1: extra data 1916 * @str2: extra data 1917 * 1918 * Handle a parser error 1919 */ 1920 static void 1921 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 1922 xmlNodePtr child, int error, 1923 const char *msg, const xmlChar * str1, const xmlChar * str2) 1924 { 1925 if (child != NULL) 1926 xmlSchemaPErr(ctxt, child, error, msg, str1, str2); 1927 else 1928 xmlSchemaPErr(ctxt, node, error, msg, str1, str2); 1929 } 1930 1931 1932 /** 1933 * xmlSchemaPErrExt: 1934 * @ctxt: the parsing context 1935 * @node: the context node 1936 * @error: the error code 1937 * @strData1: extra data 1938 * @strData2: extra data 1939 * @strData3: extra data 1940 * @msg: the message 1941 * @str1: extra parameter for the message display 1942 * @str2: extra parameter for the message display 1943 * @str3: extra parameter for the message display 1944 * @str4: extra parameter for the message display 1945 * @str5: extra parameter for the message display 1946 * 1947 * Handle a parser error 1948 */ 1949 static void 1950 xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1951 const xmlChar * strData1, const xmlChar * strData2, 1952 const xmlChar * strData3, const char *msg, const xmlChar * str1, 1953 const xmlChar * str2, const xmlChar * str3, const xmlChar * str4, 1954 const xmlChar * str5) 1955 { 1956 1957 xmlGenericErrorFunc channel = NULL; 1958 xmlStructuredErrorFunc schannel = NULL; 1959 void *data = NULL; 1960 1961 if (ctxt != NULL) { 1962 ctxt->nberrors++; 1963 ctxt->err = error; 1964 channel = ctxt->error; 1965 data = ctxt->errCtxt; 1966 schannel = ctxt->serror; 1967 } 1968 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1969 error, XML_ERR_ERROR, NULL, 0, 1970 (const char *) strData1, (const char *) strData2, 1971 (const char *) strData3, 0, 0, msg, str1, str2, 1972 str3, str4, str5); 1973 } 1974 1975 /************************************************************************ 1976 * * 1977 * Allround error functions * 1978 * * 1979 ************************************************************************/ 1980 1981 /** 1982 * xmlSchemaVTypeErrMemory: 1983 * @node: a context node 1984 * @extra: extra informations 1985 * 1986 * Handle an out of memory condition 1987 */ 1988 static void 1989 xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt, 1990 const char *extra, xmlNodePtr node) 1991 { 1992 if (ctxt != NULL) { 1993 ctxt->nberrors++; 1994 ctxt->err = XML_SCHEMAV_INTERNAL; 1995 } 1996 __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL, 1997 extra); 1998 } 1999 2000 static void 2001 xmlSchemaPSimpleInternalErr(xmlNodePtr node, 2002 const char *msg, const xmlChar *str) 2003 { 2004 __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node, 2005 msg, (const char *) str); 2006 } 2007 2008 #define WXS_ERROR_TYPE_ERROR 1 2009 #define WXS_ERROR_TYPE_WARNING 2 2010 /** 2011 * xmlSchemaErr3: 2012 * @ctxt: the validation context 2013 * @node: the context node 2014 * @error: the error code 2015 * @msg: the error message 2016 * @str1: extra data 2017 * @str2: extra data 2018 * @str3: extra data 2019 * 2020 * Handle a validation error 2021 */ 2022 static void 2023 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt, 2024 xmlErrorLevel errorLevel, 2025 int error, xmlNodePtr node, int line, const char *msg, 2026 const xmlChar *str1, const xmlChar *str2, 2027 const xmlChar *str3, const xmlChar *str4) 2028 { 2029 xmlStructuredErrorFunc schannel = NULL; 2030 xmlGenericErrorFunc channel = NULL; 2031 void *data = NULL; 2032 2033 if (ctxt != NULL) { 2034 if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2035 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt; 2036 const char *file = NULL; 2037 if (errorLevel != XML_ERR_WARNING) { 2038 vctxt->nberrors++; 2039 vctxt->err = error; 2040 channel = vctxt->error; 2041 } else { 2042 channel = vctxt->warning; 2043 } 2044 schannel = vctxt->serror; 2045 data = vctxt->errCtxt; 2046 2047 /* 2048 * Error node. If we specify a line number, then 2049 * do not channel any node to the error function. 2050 */ 2051 if (line == 0) { 2052 if ((node == NULL) && 2053 (vctxt->depth >= 0) && 2054 (vctxt->inode != NULL)) { 2055 node = vctxt->inode->node; 2056 } 2057 /* 2058 * Get filename and line if no node-tree. 2059 */ 2060 if ((node == NULL) && 2061 (vctxt->parserCtxt != NULL) && 2062 (vctxt->parserCtxt->input != NULL)) { 2063 file = vctxt->parserCtxt->input->filename; 2064 line = vctxt->parserCtxt->input->line; 2065 } 2066 } else { 2067 /* 2068 * Override the given node's (if any) position 2069 * and channel only the given line number. 2070 */ 2071 node = NULL; 2072 /* 2073 * Get filename. 2074 */ 2075 if (vctxt->doc != NULL) 2076 file = (const char *) vctxt->doc->URL; 2077 else if ((vctxt->parserCtxt != NULL) && 2078 (vctxt->parserCtxt->input != NULL)) 2079 file = vctxt->parserCtxt->input->filename; 2080 } 2081 __xmlRaiseError(schannel, channel, data, ctxt, 2082 node, XML_FROM_SCHEMASV, 2083 error, errorLevel, file, line, 2084 (const char *) str1, (const char *) str2, 2085 (const char *) str3, 0, 0, msg, str1, str2, str3, str4); 2086 2087 } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) { 2088 xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt; 2089 if (errorLevel != XML_ERR_WARNING) { 2090 pctxt->nberrors++; 2091 pctxt->err = error; 2092 channel = pctxt->error; 2093 } else { 2094 channel = pctxt->warning; 2095 } 2096 schannel = pctxt->serror; 2097 data = pctxt->errCtxt; 2098 __xmlRaiseError(schannel, channel, data, ctxt, 2099 node, XML_FROM_SCHEMASP, error, 2100 errorLevel, NULL, 0, 2101 (const char *) str1, (const char *) str2, 2102 (const char *) str3, 0, 0, msg, str1, str2, str3, str4); 2103 } else { 2104 TODO 2105 } 2106 } 2107 } 2108 2109 /** 2110 * xmlSchemaErr3: 2111 * @ctxt: the validation context 2112 * @node: the context node 2113 * @error: the error code 2114 * @msg: the error message 2115 * @str1: extra data 2116 * @str2: extra data 2117 * @str3: extra data 2118 * 2119 * Handle a validation error 2120 */ 2121 static void 2122 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt, 2123 int error, xmlNodePtr node, const char *msg, 2124 const xmlChar *str1, const xmlChar *str2, const xmlChar *str3) 2125 { 2126 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2127 msg, str1, str2, str3, NULL); 2128 } 2129 2130 static void 2131 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt, 2132 int error, xmlNodePtr node, const char *msg, 2133 const xmlChar *str1, const xmlChar *str2, 2134 const xmlChar *str3, const xmlChar *str4) 2135 { 2136 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2137 msg, str1, str2, str3, str4); 2138 } 2139 2140 static void 2141 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt, 2142 int error, xmlNodePtr node, const char *msg, 2143 const xmlChar *str1, const xmlChar *str2) 2144 { 2145 xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL); 2146 } 2147 2148 static xmlChar * 2149 xmlSchemaFormatNodeForError(xmlChar ** msg, 2150 xmlSchemaAbstractCtxtPtr actxt, 2151 xmlNodePtr node) 2152 { 2153 xmlChar *str = NULL; 2154 2155 *msg = NULL; 2156 if ((node != NULL) && 2157 (node->type != XML_ELEMENT_NODE) && 2158 (node->type != XML_ATTRIBUTE_NODE)) 2159 { 2160 /* 2161 * Don't try to format other nodes than element and 2162 * attribute nodes. 2163 * Play save and return an empty string. 2164 */ 2165 *msg = xmlStrdup(BAD_CAST ""); 2166 return(*msg); 2167 } 2168 if (node != NULL) { 2169 /* 2170 * Work on tree nodes. 2171 */ 2172 if (node->type == XML_ATTRIBUTE_NODE) { 2173 xmlNodePtr elem = node->parent; 2174 2175 *msg = xmlStrdup(BAD_CAST "Element '"); 2176 if (elem->ns != NULL) 2177 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2178 elem->ns->href, elem->name)); 2179 else 2180 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2181 NULL, elem->name)); 2182 FREE_AND_NULL(str); 2183 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2184 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2185 } else { 2186 *msg = xmlStrdup(BAD_CAST "Element '"); 2187 } 2188 if (node->ns != NULL) 2189 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2190 node->ns->href, node->name)); 2191 else 2192 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2193 NULL, node->name)); 2194 FREE_AND_NULL(str); 2195 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2196 } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2197 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt; 2198 /* 2199 * Work on node infos. 2200 */ 2201 if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) { 2202 xmlSchemaNodeInfoPtr ielem = 2203 vctxt->elemInfos[vctxt->depth]; 2204 2205 *msg = xmlStrdup(BAD_CAST "Element '"); 2206 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2207 ielem->nsName, ielem->localName)); 2208 FREE_AND_NULL(str); 2209 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2210 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2211 } else { 2212 *msg = xmlStrdup(BAD_CAST "Element '"); 2213 } 2214 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2215 vctxt->inode->nsName, vctxt->inode->localName)); 2216 FREE_AND_NULL(str); 2217 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2218 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) { 2219 /* 2220 * Hmm, no node while parsing? 2221 * Return an empty string, in case NULL will break something. 2222 */ 2223 *msg = xmlStrdup(BAD_CAST ""); 2224 } else { 2225 TODO 2226 return (NULL); 2227 } 2228 /* 2229 * VAL TODO: The output of the given schema component is currently 2230 * disabled. 2231 */ 2232 #if 0 2233 if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) { 2234 *msg = xmlStrcat(*msg, BAD_CAST " ["); 2235 *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str, 2236 NULL, type, NULL, 0)); 2237 FREE_AND_NULL(str) 2238 *msg = xmlStrcat(*msg, BAD_CAST "]"); 2239 } 2240 #endif 2241 return (*msg); 2242 } 2243 2244 static void 2245 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt, 2246 const char *funcName, 2247 const char *message, 2248 const xmlChar *str1, 2249 const xmlChar *str2) 2250 { 2251 xmlChar *msg = NULL; 2252 2253 if (actxt == NULL) 2254 return; 2255 msg = xmlStrdup(BAD_CAST "Internal error: "); 2256 msg = xmlStrcat(msg, BAD_CAST funcName); 2257 msg = xmlStrcat(msg, BAD_CAST ", "); 2258 msg = xmlStrcat(msg, BAD_CAST message); 2259 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2260 2261 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) 2262 xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL, 2263 (const char *) msg, str1, str2); 2264 2265 else if (actxt->type == XML_SCHEMA_CTXT_PARSER) 2266 xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL, 2267 (const char *) msg, str1, str2); 2268 2269 FREE_AND_NULL(msg) 2270 } 2271 2272 static void 2273 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 2274 const char *funcName, 2275 const char *message) 2276 { 2277 xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL); 2278 } 2279 2280 #if 0 2281 static void 2282 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt, 2283 const char *funcName, 2284 const char *message, 2285 const xmlChar *str1, 2286 const xmlChar *str2) 2287 { 2288 xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message, 2289 str1, str2); 2290 } 2291 #endif 2292 2293 static void 2294 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt, 2295 xmlParserErrors error, 2296 xmlNodePtr node, 2297 xmlSchemaBasicItemPtr item, 2298 const char *message, 2299 const xmlChar *str1, const xmlChar *str2, 2300 const xmlChar *str3, const xmlChar *str4) 2301 { 2302 xmlChar *msg = NULL; 2303 2304 if ((node == NULL) && (item != NULL) && 2305 (actxt->type == XML_SCHEMA_CTXT_PARSER)) { 2306 node = WXS_ITEM_NODE(item); 2307 xmlSchemaFormatItemForReport(&msg, NULL, item, NULL); 2308 msg = xmlStrcat(msg, BAD_CAST ": "); 2309 } else 2310 xmlSchemaFormatNodeForError(&msg, actxt, node); 2311 msg = xmlStrcat(msg, (const xmlChar *) message); 2312 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2313 xmlSchemaErr4(actxt, error, node, 2314 (const char *) msg, str1, str2, str3, str4); 2315 FREE_AND_NULL(msg) 2316 } 2317 2318 static void 2319 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt, 2320 xmlParserErrors error, 2321 xmlNodePtr node, 2322 xmlSchemaBasicItemPtr item, 2323 const char *message, 2324 const xmlChar *str1, 2325 const xmlChar *str2) 2326 { 2327 xmlSchemaCustomErr4(actxt, error, node, item, 2328 message, str1, str2, NULL, NULL); 2329 } 2330 2331 2332 2333 static void 2334 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt, 2335 xmlParserErrors error, 2336 xmlNodePtr node, 2337 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2338 const char *message, 2339 const xmlChar *str1, 2340 const xmlChar *str2, 2341 const xmlChar *str3) 2342 { 2343 xmlChar *msg = NULL; 2344 2345 xmlSchemaFormatNodeForError(&msg, actxt, node); 2346 msg = xmlStrcat(msg, (const xmlChar *) message); 2347 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2348 2349 /* URGENT TODO: Set the error code to something sane. */ 2350 xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0, 2351 (const char *) msg, str1, str2, str3, NULL); 2352 2353 FREE_AND_NULL(msg) 2354 } 2355 2356 2357 2358 static void 2359 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt, 2360 xmlParserErrors error, 2361 xmlSchemaPSVIIDCNodePtr idcNode, 2362 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2363 const char *message, 2364 const xmlChar *str1, 2365 const xmlChar *str2) 2366 { 2367 xmlChar *msg = NULL, *qname = NULL; 2368 2369 msg = xmlStrdup(BAD_CAST "Element '%s': "); 2370 msg = xmlStrcat(msg, (const xmlChar *) message); 2371 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2372 xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR, 2373 error, NULL, idcNode->nodeLine, (const char *) msg, 2374 xmlSchemaFormatQName(&qname, 2375 vctxt->nodeQNames->items[idcNode->nodeQNameID +1], 2376 vctxt->nodeQNames->items[idcNode->nodeQNameID]), 2377 str1, str2, NULL); 2378 FREE_AND_NULL(qname); 2379 FREE_AND_NULL(msg); 2380 } 2381 2382 static int 2383 xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt, 2384 xmlNodePtr node) 2385 { 2386 if (node != NULL) 2387 return (node->type); 2388 if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) && 2389 (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL)) 2390 return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType); 2391 return (-1); 2392 } 2393 2394 static int 2395 xmlSchemaIsGlobalItem(xmlSchemaTypePtr item) 2396 { 2397 switch (item->type) { 2398 case XML_SCHEMA_TYPE_COMPLEX: 2399 case XML_SCHEMA_TYPE_SIMPLE: 2400 if (item->flags & XML_SCHEMAS_TYPE_GLOBAL) 2401 return(1); 2402 break; 2403 case XML_SCHEMA_TYPE_GROUP: 2404 return (1); 2405 case XML_SCHEMA_TYPE_ELEMENT: 2406 if ( ((xmlSchemaElementPtr) item)->flags & 2407 XML_SCHEMAS_ELEM_GLOBAL) 2408 return(1); 2409 break; 2410 case XML_SCHEMA_TYPE_ATTRIBUTE: 2411 if ( ((xmlSchemaAttributePtr) item)->flags & 2412 XML_SCHEMAS_ATTR_GLOBAL) 2413 return(1); 2414 break; 2415 /* Note that attribute groups are always global. */ 2416 default: 2417 return(1); 2418 } 2419 return (0); 2420 } 2421 2422 static void 2423 xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2424 xmlParserErrors error, 2425 xmlNodePtr node, 2426 const xmlChar *value, 2427 xmlSchemaTypePtr type, 2428 int displayValue) 2429 { 2430 xmlChar *msg = NULL; 2431 2432 xmlSchemaFormatNodeForError(&msg, actxt, node); 2433 2434 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2435 XML_ATTRIBUTE_NODE)) 2436 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 2437 else 2438 msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid " 2439 "value of "); 2440 2441 if (! xmlSchemaIsGlobalItem(type)) 2442 msg = xmlStrcat(msg, BAD_CAST "the local "); 2443 else 2444 msg = xmlStrcat(msg, BAD_CAST "the "); 2445 2446 if (WXS_IS_ATOMIC(type)) 2447 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 2448 else if (WXS_IS_LIST(type)) 2449 msg = xmlStrcat(msg, BAD_CAST "list type"); 2450 else if (WXS_IS_UNION(type)) 2451 msg = xmlStrcat(msg, BAD_CAST "union type"); 2452 2453 if (xmlSchemaIsGlobalItem(type)) { 2454 xmlChar *str = NULL; 2455 msg = xmlStrcat(msg, BAD_CAST " '"); 2456 if (type->builtInType != 0) { 2457 msg = xmlStrcat(msg, BAD_CAST "xs:"); 2458 msg = xmlStrcat(msg, type->name); 2459 } else 2460 msg = xmlStrcat(msg, 2461 xmlSchemaFormatQName(&str, 2462 type->targetNamespace, type->name)); 2463 msg = xmlStrcat(msg, BAD_CAST "'"); 2464 FREE_AND_NULL(str); 2465 } 2466 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2467 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2468 XML_ATTRIBUTE_NODE)) 2469 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2470 else 2471 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2472 FREE_AND_NULL(msg) 2473 } 2474 2475 static const xmlChar * 2476 xmlSchemaFormatErrorNodeQName(xmlChar ** str, 2477 xmlSchemaNodeInfoPtr ni, 2478 xmlNodePtr node) 2479 { 2480 if (node != NULL) { 2481 if (node->ns != NULL) 2482 return (xmlSchemaFormatQName(str, node->ns->href, node->name)); 2483 else 2484 return (xmlSchemaFormatQName(str, NULL, node->name)); 2485 } else if (ni != NULL) 2486 return (xmlSchemaFormatQName(str, ni->nsName, ni->localName)); 2487 return (NULL); 2488 } 2489 2490 static void 2491 xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt, 2492 xmlParserErrors error, 2493 xmlSchemaAttrInfoPtr ni, 2494 xmlNodePtr node) 2495 { 2496 xmlChar *msg = NULL, *str = NULL; 2497 2498 xmlSchemaFormatNodeForError(&msg, actxt, node); 2499 msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n"); 2500 xmlSchemaErr(actxt, error, node, (const char *) msg, 2501 xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node), 2502 NULL); 2503 FREE_AND_NULL(str) 2504 FREE_AND_NULL(msg) 2505 } 2506 2507 static void 2508 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2509 xmlParserErrors error, 2510 xmlNodePtr node, 2511 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2512 const char *message, 2513 int nbval, 2514 int nbneg, 2515 xmlChar **values) 2516 { 2517 xmlChar *str = NULL, *msg = NULL; 2518 xmlChar *localName, *nsName; 2519 const xmlChar *cur, *end; 2520 int i; 2521 2522 xmlSchemaFormatNodeForError(&msg, actxt, node); 2523 msg = xmlStrcat(msg, (const xmlChar *) message); 2524 msg = xmlStrcat(msg, BAD_CAST "."); 2525 /* 2526 * Note that is does not make sense to report that we have a 2527 * wildcard here, since the wildcard might be unfolded into 2528 * multiple transitions. 2529 */ 2530 if (nbval + nbneg > 0) { 2531 if (nbval + nbneg > 1) { 2532 str = xmlStrdup(BAD_CAST " Expected is one of ( "); 2533 } else 2534 str = xmlStrdup(BAD_CAST " Expected is ( "); 2535 nsName = NULL; 2536 2537 for (i = 0; i < nbval + nbneg; i++) { 2538 cur = values[i]; 2539 if (cur == NULL) 2540 continue; 2541 if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') && 2542 (cur[3] == ' ')) { 2543 cur += 4; 2544 str = xmlStrcat(str, BAD_CAST "##other"); 2545 } 2546 /* 2547 * Get the local name. 2548 */ 2549 localName = NULL; 2550 2551 end = cur; 2552 if (*end == '*') { 2553 localName = xmlStrdup(BAD_CAST "*"); 2554 end++; 2555 } else { 2556 while ((*end != 0) && (*end != '|')) 2557 end++; 2558 localName = xmlStrncat(localName, BAD_CAST cur, end - cur); 2559 } 2560 if (*end != 0) { 2561 end++; 2562 /* 2563 * Skip "*|*" if they come with negated expressions, since 2564 * they represent the same negated wildcard. 2565 */ 2566 if ((nbneg == 0) || (*end != '*') || (*localName != '*')) { 2567 /* 2568 * Get the namespace name. 2569 */ 2570 cur = end; 2571 if (*end == '*') { 2572 nsName = xmlStrdup(BAD_CAST "{*}"); 2573 } else { 2574 while (*end != 0) 2575 end++; 2576 2577 if (i >= nbval) 2578 nsName = xmlStrdup(BAD_CAST "{##other:"); 2579 else 2580 nsName = xmlStrdup(BAD_CAST "{"); 2581 2582 nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur); 2583 nsName = xmlStrcat(nsName, BAD_CAST "}"); 2584 } 2585 str = xmlStrcat(str, BAD_CAST nsName); 2586 FREE_AND_NULL(nsName) 2587 } else { 2588 FREE_AND_NULL(localName); 2589 continue; 2590 } 2591 } 2592 str = xmlStrcat(str, BAD_CAST localName); 2593 FREE_AND_NULL(localName); 2594 2595 if (i < nbval + nbneg -1) 2596 str = xmlStrcat(str, BAD_CAST ", "); 2597 } 2598 str = xmlStrcat(str, BAD_CAST " ).\n"); 2599 msg = xmlStrcat(msg, BAD_CAST str); 2600 FREE_AND_NULL(str) 2601 } else 2602 msg = xmlStrcat(msg, BAD_CAST "\n"); 2603 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2604 xmlFree(msg); 2605 } 2606 2607 static void 2608 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt, 2609 xmlParserErrors error, 2610 xmlNodePtr node, 2611 const xmlChar *value, 2612 unsigned long length, 2613 xmlSchemaTypePtr type, 2614 xmlSchemaFacetPtr facet, 2615 const char *message, 2616 const xmlChar *str1, 2617 const xmlChar *str2) 2618 { 2619 xmlChar *str = NULL, *msg = NULL; 2620 xmlSchemaTypeType facetType; 2621 int nodeType = xmlSchemaEvalErrorNodeType(actxt, node); 2622 2623 xmlSchemaFormatNodeForError(&msg, actxt, node); 2624 if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) { 2625 facetType = XML_SCHEMA_FACET_ENUMERATION; 2626 /* 2627 * If enumerations are validated, one must not expect the 2628 * facet to be given. 2629 */ 2630 } else 2631 facetType = facet->type; 2632 msg = xmlStrcat(msg, BAD_CAST "["); 2633 msg = xmlStrcat(msg, BAD_CAST "facet '"); 2634 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType)); 2635 msg = xmlStrcat(msg, BAD_CAST "'] "); 2636 if (message == NULL) { 2637 /* 2638 * Use a default message. 2639 */ 2640 if ((facetType == XML_SCHEMA_FACET_LENGTH) || 2641 (facetType == XML_SCHEMA_FACET_MINLENGTH) || 2642 (facetType == XML_SCHEMA_FACET_MAXLENGTH)) { 2643 2644 char len[25], actLen[25]; 2645 2646 /* FIXME, TODO: What is the max expected string length of the 2647 * this value? 2648 */ 2649 if (nodeType == XML_ATTRIBUTE_NODE) 2650 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; "); 2651 else 2652 msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; "); 2653 2654 snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet)); 2655 snprintf(actLen, 24, "%lu", length); 2656 2657 if (facetType == XML_SCHEMA_FACET_LENGTH) 2658 msg = xmlStrcat(msg, 2659 BAD_CAST "this differs from the allowed length of '%s'.\n"); 2660 else if (facetType == XML_SCHEMA_FACET_MAXLENGTH) 2661 msg = xmlStrcat(msg, 2662 BAD_CAST "this exceeds the allowed maximum length of '%s'.\n"); 2663 else if (facetType == XML_SCHEMA_FACET_MINLENGTH) 2664 msg = xmlStrcat(msg, 2665 BAD_CAST "this underruns the allowed minimum length of '%s'.\n"); 2666 2667 if (nodeType == XML_ATTRIBUTE_NODE) 2668 xmlSchemaErr3(actxt, error, node, (const char *) msg, 2669 value, (const xmlChar *) actLen, (const xmlChar *) len); 2670 else 2671 xmlSchemaErr(actxt, error, node, (const char *) msg, 2672 (const xmlChar *) actLen, (const xmlChar *) len); 2673 2674 } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) { 2675 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element " 2676 "of the set {%s}.\n"); 2677 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2678 xmlSchemaFormatFacetEnumSet(actxt, &str, type)); 2679 } else if (facetType == XML_SCHEMA_FACET_PATTERN) { 2680 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted " 2681 "by the pattern '%s'.\n"); 2682 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2683 facet->value); 2684 } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) { 2685 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the " 2686 "minimum value allowed ('%s').\n"); 2687 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2688 facet->value); 2689 } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) { 2690 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the " 2691 "maximum value allowed ('%s').\n"); 2692 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2693 facet->value); 2694 } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) { 2695 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than " 2696 "'%s'.\n"); 2697 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2698 facet->value); 2699 } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) { 2700 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than " 2701 "'%s'.\n"); 2702 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2703 facet->value); 2704 } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) { 2705 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more " 2706 "digits than are allowed ('%s').\n"); 2707 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2708 facet->value); 2709 } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) { 2710 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional " 2711 "digits than are allowed ('%s').\n"); 2712 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2713 facet->value); 2714 } else if (nodeType == XML_ATTRIBUTE_NODE) { 2715 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n"); 2716 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2717 } else { 2718 msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n"); 2719 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2720 } 2721 } else { 2722 msg = xmlStrcat(msg, (const xmlChar *) message); 2723 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2724 xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2); 2725 } 2726 FREE_AND_NULL(str) 2727 xmlFree(msg); 2728 } 2729 2730 #define VERROR(err, type, msg) \ 2731 xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL); 2732 2733 #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg); 2734 2735 #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg); 2736 #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg); 2737 2738 #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg); 2739 2740 2741 /** 2742 * xmlSchemaPMissingAttrErr: 2743 * @ctxt: the schema validation context 2744 * @ownerDes: the designation of the owner 2745 * @ownerName: the name of the owner 2746 * @ownerItem: the owner as a schema object 2747 * @ownerElem: the owner as an element node 2748 * @node: the parent element node of the missing attribute node 2749 * @type: the corresponding type of the attribute node 2750 * 2751 * Reports an illegal attribute. 2752 */ 2753 static void 2754 xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt, 2755 xmlParserErrors error, 2756 xmlSchemaBasicItemPtr ownerItem, 2757 xmlNodePtr ownerElem, 2758 const char *name, 2759 const char *message) 2760 { 2761 xmlChar *des = NULL; 2762 2763 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2764 2765 if (message != NULL) 2766 xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message); 2767 else 2768 xmlSchemaPErr(ctxt, ownerElem, error, 2769 "%s: The attribute '%s' is required but missing.\n", 2770 BAD_CAST des, BAD_CAST name); 2771 FREE_AND_NULL(des); 2772 } 2773 2774 2775 /** 2776 * xmlSchemaPResCompAttrErr: 2777 * @ctxt: the schema validation context 2778 * @error: the error code 2779 * @ownerDes: the designation of the owner 2780 * @ownerItem: the owner as a schema object 2781 * @ownerElem: the owner as an element node 2782 * @name: the name of the attribute holding the QName 2783 * @refName: the referenced local name 2784 * @refURI: the referenced namespace URI 2785 * @message: optional message 2786 * 2787 * Used to report QName attribute values that failed to resolve 2788 * to schema components. 2789 */ 2790 static void 2791 xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt, 2792 xmlParserErrors error, 2793 xmlSchemaBasicItemPtr ownerItem, 2794 xmlNodePtr ownerElem, 2795 const char *name, 2796 const xmlChar *refName, 2797 const xmlChar *refURI, 2798 xmlSchemaTypeType refType, 2799 const char *refTypeStr) 2800 { 2801 xmlChar *des = NULL, *strA = NULL; 2802 2803 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2804 if (refTypeStr == NULL) 2805 refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType); 2806 xmlSchemaPErrExt(ctxt, ownerElem, error, 2807 NULL, NULL, NULL, 2808 "%s, attribute '%s': The QName value '%s' does not resolve to a(n) " 2809 "%s.\n", BAD_CAST des, BAD_CAST name, 2810 xmlSchemaFormatQName(&strA, refURI, refName), 2811 BAD_CAST refTypeStr, NULL); 2812 FREE_AND_NULL(des) 2813 FREE_AND_NULL(strA) 2814 } 2815 2816 /** 2817 * xmlSchemaPCustomAttrErr: 2818 * @ctxt: the schema parser context 2819 * @error: the error code 2820 * @ownerDes: the designation of the owner 2821 * @ownerItem: the owner as a schema object 2822 * @attr: the illegal attribute node 2823 * 2824 * Reports an illegal attribute during the parse. 2825 */ 2826 static void 2827 xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt, 2828 xmlParserErrors error, 2829 xmlChar **ownerDes, 2830 xmlSchemaBasicItemPtr ownerItem, 2831 xmlAttrPtr attr, 2832 const char *msg) 2833 { 2834 xmlChar *des = NULL; 2835 2836 if (ownerDes == NULL) 2837 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent); 2838 else if (*ownerDes == NULL) { 2839 xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent); 2840 des = *ownerDes; 2841 } else 2842 des = *ownerDes; 2843 if (attr == NULL) { 2844 xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL, 2845 "%s, attribute '%s': %s.\n", 2846 BAD_CAST des, (const xmlChar *) "Unknown", 2847 (const xmlChar *) msg, NULL, NULL); 2848 } else { 2849 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 2850 "%s, attribute '%s': %s.\n", 2851 BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL); 2852 } 2853 if (ownerDes == NULL) 2854 FREE_AND_NULL(des); 2855 } 2856 2857 /** 2858 * xmlSchemaPIllegalAttrErr: 2859 * @ctxt: the schema parser context 2860 * @error: the error code 2861 * @ownerDes: the designation of the attribute's owner 2862 * @ownerItem: the attribute's owner item 2863 * @attr: the illegal attribute node 2864 * 2865 * Reports an illegal attribute during the parse. 2866 */ 2867 static void 2868 xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt, 2869 xmlParserErrors error, 2870 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED, 2871 xmlAttrPtr attr) 2872 { 2873 xmlChar *strA = NULL, *strB = NULL; 2874 2875 xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent); 2876 xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr, 2877 "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA, 2878 xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name), 2879 NULL, NULL); 2880 FREE_AND_NULL(strA); 2881 FREE_AND_NULL(strB); 2882 } 2883 2884 /** 2885 * xmlSchemaPCustomErr: 2886 * @ctxt: the schema parser context 2887 * @error: the error code 2888 * @itemDes: the designation of the schema item 2889 * @item: the schema item 2890 * @itemElem: the node of the schema item 2891 * @message: the error message 2892 * @str1: an optional param for the error message 2893 * @str2: an optional param for the error message 2894 * @str3: an optional param for the error message 2895 * 2896 * Reports an error during parsing. 2897 */ 2898 static void 2899 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt, 2900 xmlParserErrors error, 2901 xmlSchemaBasicItemPtr item, 2902 xmlNodePtr itemElem, 2903 const char *message, 2904 const xmlChar *str1, 2905 const xmlChar *str2, 2906 const xmlChar *str3) 2907 { 2908 xmlChar *des = NULL, *msg = NULL; 2909 2910 xmlSchemaFormatItemForReport(&des, NULL, item, itemElem); 2911 msg = xmlStrdup(BAD_CAST "%s: "); 2912 msg = xmlStrcat(msg, (const xmlChar *) message); 2913 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2914 if ((itemElem == NULL) && (item != NULL)) 2915 itemElem = WXS_ITEM_NODE(item); 2916 xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL, 2917 (const char *) msg, BAD_CAST des, str1, str2, str3, NULL); 2918 FREE_AND_NULL(des); 2919 FREE_AND_NULL(msg); 2920 } 2921 2922 /** 2923 * xmlSchemaPCustomErr: 2924 * @ctxt: the schema parser context 2925 * @error: the error code 2926 * @itemDes: the designation of the schema item 2927 * @item: the schema item 2928 * @itemElem: the node of the schema item 2929 * @message: the error message 2930 * @str1: the optional param for the error message 2931 * 2932 * Reports an error during parsing. 2933 */ 2934 static void 2935 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt, 2936 xmlParserErrors error, 2937 xmlSchemaBasicItemPtr item, 2938 xmlNodePtr itemElem, 2939 const char *message, 2940 const xmlChar *str1) 2941 { 2942 xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message, 2943 str1, NULL, NULL); 2944 } 2945 2946 /** 2947 * xmlSchemaPAttrUseErr: 2948 * @ctxt: the schema parser context 2949 * @error: the error code 2950 * @itemDes: the designation of the schema type 2951 * @item: the schema type 2952 * @itemElem: the node of the schema type 2953 * @attr: the invalid schema attribute 2954 * @message: the error message 2955 * @str1: the optional param for the error message 2956 * 2957 * Reports an attribute use error during parsing. 2958 */ 2959 static void 2960 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt, 2961 xmlParserErrors error, 2962 xmlNodePtr node, 2963 xmlSchemaBasicItemPtr ownerItem, 2964 const xmlSchemaAttributeUsePtr attruse, 2965 const char *message, 2966 const xmlChar *str1, const xmlChar *str2, 2967 const xmlChar *str3,const xmlChar *str4) 2968 { 2969 xmlChar *str = NULL, *msg = NULL; 2970 2971 xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL); 2972 msg = xmlStrcat(msg, BAD_CAST ", "); 2973 msg = xmlStrcat(msg, 2974 BAD_CAST xmlSchemaFormatItemForReport(&str, NULL, 2975 WXS_BASIC_CAST attruse, NULL)); 2976 FREE_AND_NULL(str); 2977 msg = xmlStrcat(msg, BAD_CAST ": "); 2978 msg = xmlStrcat(msg, (const xmlChar *) message); 2979 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2980 xmlSchemaErr4(ACTXT_CAST ctxt, error, node, 2981 (const char *) msg, str1, str2, str3, str4); 2982 xmlFree(msg); 2983 } 2984 2985 /** 2986 * xmlSchemaPIllegalFacetAtomicErr: 2987 * @ctxt: the schema parser context 2988 * @error: the error code 2989 * @type: the schema type 2990 * @baseType: the base type of type 2991 * @facet: the illegal facet 2992 * 2993 * Reports an illegal facet for atomic simple types. 2994 */ 2995 static void 2996 xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt, 2997 xmlParserErrors error, 2998 xmlSchemaTypePtr type, 2999 xmlSchemaTypePtr baseType, 3000 xmlSchemaFacetPtr facet) 3001 { 3002 xmlChar *des = NULL, *strT = NULL; 3003 3004 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node); 3005 xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL, 3006 "%s: The facet '%s' is not allowed on types derived from the " 3007 "type %s.\n", 3008 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type), 3009 xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL), 3010 NULL, NULL); 3011 FREE_AND_NULL(des); 3012 FREE_AND_NULL(strT); 3013 } 3014 3015 /** 3016 * xmlSchemaPIllegalFacetListUnionErr: 3017 * @ctxt: the schema parser context 3018 * @error: the error code 3019 * @itemDes: the designation of the schema item involved 3020 * @item: the schema item involved 3021 * @facet: the illegal facet 3022 * 3023 * Reports an illegal facet for <list> and <union>. 3024 */ 3025 static void 3026 xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt, 3027 xmlParserErrors error, 3028 xmlSchemaTypePtr type, 3029 xmlSchemaFacetPtr facet) 3030 { 3031 xmlChar *des = NULL; 3032 3033 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, 3034 type->node); 3035 xmlSchemaPErr(ctxt, type->node, error, 3036 "%s: The facet '%s' is not allowed.\n", 3037 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type)); 3038 FREE_AND_NULL(des); 3039 } 3040 3041 /** 3042 * xmlSchemaPMutualExclAttrErr: 3043 * @ctxt: the schema validation context 3044 * @error: the error code 3045 * @elemDes: the designation of the parent element node 3046 * @attr: the bad attribute node 3047 * @type: the corresponding type of the attribute node 3048 * 3049 * Reports an illegal attribute. 3050 */ 3051 static void 3052 xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt, 3053 xmlParserErrors error, 3054 xmlSchemaBasicItemPtr ownerItem, 3055 xmlAttrPtr attr, 3056 const char *name1, 3057 const char *name2) 3058 { 3059 xmlChar *des = NULL; 3060 3061 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent); 3062 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 3063 "%s: The attributes '%s' and '%s' are mutually exclusive.\n", 3064 BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL); 3065 FREE_AND_NULL(des); 3066 } 3067 3068 /** 3069 * xmlSchemaPSimpleTypeErr: 3070 * @ctxt: the schema validation context 3071 * @error: the error code 3072 * @type: the type specifier 3073 * @ownerDes: the designation of the owner 3074 * @ownerItem: the schema object if existent 3075 * @node: the validated node 3076 * @value: the validated value 3077 * 3078 * Reports a simple type validation error. 3079 * TODO: Should this report the value of an element as well? 3080 */ 3081 static void 3082 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt, 3083 xmlParserErrors error, 3084 xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED, 3085 xmlNodePtr node, 3086 xmlSchemaTypePtr type, 3087 const char *expected, 3088 const xmlChar *value, 3089 const char *message, 3090 const xmlChar *str1, 3091 const xmlChar *str2) 3092 { 3093 xmlChar *msg = NULL; 3094 3095 xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node); 3096 if (message == NULL) { 3097 /* 3098 * Use default messages. 3099 */ 3100 if (type != NULL) { 3101 if (node->type == XML_ATTRIBUTE_NODE) 3102 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 3103 else 3104 msg = xmlStrcat(msg, BAD_CAST "The character content is not a " 3105 "valid value of "); 3106 if (! xmlSchemaIsGlobalItem(type)) 3107 msg = xmlStrcat(msg, BAD_CAST "the local "); 3108 else 3109 msg = xmlStrcat(msg, BAD_CAST "the "); 3110 3111 if (WXS_IS_ATOMIC(type)) 3112 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 3113 else if (WXS_IS_LIST(type)) 3114 msg = xmlStrcat(msg, BAD_CAST "list type"); 3115 else if (WXS_IS_UNION(type)) 3116 msg = xmlStrcat(msg, BAD_CAST "union type"); 3117 3118 if (xmlSchemaIsGlobalItem(type)) { 3119 xmlChar *str = NULL; 3120 msg = xmlStrcat(msg, BAD_CAST " '"); 3121 if (type->builtInType != 0) { 3122 msg = xmlStrcat(msg, BAD_CAST "xs:"); 3123 msg = xmlStrcat(msg, type->name); 3124 } else 3125 msg = xmlStrcat(msg, 3126 xmlSchemaFormatQName(&str, 3127 type->targetNamespace, type->name)); 3128 msg = xmlStrcat(msg, BAD_CAST "'."); 3129 FREE_AND_NULL(str); 3130 } 3131 } else { 3132 if (node->type == XML_ATTRIBUTE_NODE) 3133 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid."); 3134 else 3135 msg = xmlStrcat(msg, BAD_CAST "The character content is not " 3136 "valid."); 3137 } 3138 if (expected) { 3139 msg = xmlStrcat(msg, BAD_CAST " Expected is '"); 3140 msg = xmlStrcat(msg, BAD_CAST expected); 3141 msg = xmlStrcat(msg, BAD_CAST "'.\n"); 3142 } else 3143 msg = xmlStrcat(msg, BAD_CAST "\n"); 3144 if (node->type == XML_ATTRIBUTE_NODE) 3145 xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL); 3146 else 3147 xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL); 3148 } else { 3149 msg = xmlStrcat(msg, BAD_CAST message); 3150 msg = xmlStrcat(msg, BAD_CAST ".\n"); 3151 xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL, 3152 (const char*) msg, str1, str2, NULL, NULL, NULL); 3153 } 3154 /* Cleanup. */ 3155 FREE_AND_NULL(msg) 3156 } 3157 3158 /** 3159 * xmlSchemaPContentErr: 3160 * @ctxt: the schema parser context 3161 * @error: the error code 3162 * @onwerDes: the designation of the holder of the content 3163 * @ownerItem: the owner item of the holder of the content 3164 * @ownerElem: the node of the holder of the content 3165 * @child: the invalid child node 3166 * @message: the optional error message 3167 * @content: the optional string describing the correct content 3168 * 3169 * Reports an error concerning the content of a schema element. 3170 */ 3171 static void 3172 xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt, 3173 xmlParserErrors error, 3174 xmlSchemaBasicItemPtr ownerItem, 3175 xmlNodePtr ownerElem, 3176 xmlNodePtr child, 3177 const char *message, 3178 const char *content) 3179 { 3180 xmlChar *des = NULL; 3181 3182 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 3183 if (message != NULL) 3184 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3185 "%s: %s.\n", 3186 BAD_CAST des, BAD_CAST message); 3187 else { 3188 if (content != NULL) { 3189 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3190 "%s: The content is not valid. Expected is %s.\n", 3191 BAD_CAST des, BAD_CAST content); 3192 } else { 3193 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3194 "%s: The content is not valid.\n", 3195 BAD_CAST des, NULL); 3196 } 3197 } 3198 FREE_AND_NULL(des) 3199 } 3200 3201 /************************************************************************ 3202 * * 3203 * Streamable error functions * 3204 * * 3205 ************************************************************************/ 3206 3207 3208 3209 3210 /************************************************************************ 3211 * * 3212 * Validation helper functions * 3213 * * 3214 ************************************************************************/ 3215 3216 3217 /************************************************************************ 3218 * * 3219 * Allocation functions * 3220 * * 3221 ************************************************************************/ 3222 3223 /** 3224 * xmlSchemaNewSchemaForParserCtxt: 3225 * @ctxt: a schema validation context 3226 * 3227 * Allocate a new Schema structure. 3228 * 3229 * Returns the newly allocated structure or NULL in case or error 3230 */ 3231 static xmlSchemaPtr 3232 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt) 3233 { 3234 xmlSchemaPtr ret; 3235 3236 ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema)); 3237 if (ret == NULL) { 3238 xmlSchemaPErrMemory(ctxt, "allocating schema", NULL); 3239 return (NULL); 3240 } 3241 memset(ret, 0, sizeof(xmlSchema)); 3242 ret->dict = ctxt->dict; 3243 xmlDictReference(ret->dict); 3244 3245 return (ret); 3246 } 3247 3248 /** 3249 * xmlSchemaNewFacet: 3250 * 3251 * Allocate a new Facet structure. 3252 * 3253 * Returns the newly allocated structure or NULL in case or error 3254 */ 3255 xmlSchemaFacetPtr 3256 xmlSchemaNewFacet(void) 3257 { 3258 xmlSchemaFacetPtr ret; 3259 3260 ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet)); 3261 if (ret == NULL) { 3262 return (NULL); 3263 } 3264 memset(ret, 0, sizeof(xmlSchemaFacet)); 3265 3266 return (ret); 3267 } 3268 3269 /** 3270 * xmlSchemaNewAnnot: 3271 * @ctxt: a schema validation context 3272 * @node: a node 3273 * 3274 * Allocate a new annotation structure. 3275 * 3276 * Returns the newly allocated structure or NULL in case or error 3277 */ 3278 static xmlSchemaAnnotPtr 3279 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 3280 { 3281 xmlSchemaAnnotPtr ret; 3282 3283 ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot)); 3284 if (ret == NULL) { 3285 xmlSchemaPErrMemory(ctxt, "allocating annotation", node); 3286 return (NULL); 3287 } 3288 memset(ret, 0, sizeof(xmlSchemaAnnot)); 3289 ret->content = node; 3290 return (ret); 3291 } 3292 3293 static xmlSchemaItemListPtr 3294 xmlSchemaItemListCreate(void) 3295 { 3296 xmlSchemaItemListPtr ret; 3297 3298 ret = xmlMalloc(sizeof(xmlSchemaItemList)); 3299 if (ret == NULL) { 3300 xmlSchemaPErrMemory(NULL, 3301 "allocating an item list structure", NULL); 3302 return (NULL); 3303 } 3304 memset(ret, 0, sizeof(xmlSchemaItemList)); 3305 return (ret); 3306 } 3307 3308 static void 3309 xmlSchemaItemListClear(xmlSchemaItemListPtr list) 3310 { 3311 if (list->items != NULL) { 3312 xmlFree(list->items); 3313 list->items = NULL; 3314 } 3315 list->nbItems = 0; 3316 list->sizeItems = 0; 3317 } 3318 3319 static int 3320 xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item) 3321 { 3322 if (list->items == NULL) { 3323 list->items = (void **) xmlMalloc( 3324 20 * sizeof(void *)); 3325 if (list->items == NULL) { 3326 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3327 return(-1); 3328 } 3329 list->sizeItems = 20; 3330 } else if (list->sizeItems <= list->nbItems) { 3331 list->sizeItems *= 2; 3332 list->items = (void **) xmlRealloc(list->items, 3333 list->sizeItems * sizeof(void *)); 3334 if (list->items == NULL) { 3335 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3336 list->sizeItems = 0; 3337 return(-1); 3338 } 3339 } 3340 list->items[list->nbItems++] = item; 3341 return(0); 3342 } 3343 3344 static int 3345 xmlSchemaItemListAddSize(xmlSchemaItemListPtr list, 3346 int initialSize, 3347 void *item) 3348 { 3349 if (list->items == NULL) { 3350 if (initialSize <= 0) 3351 initialSize = 1; 3352 list->items = (void **) xmlMalloc( 3353 initialSize * sizeof(void *)); 3354 if (list->items == NULL) { 3355 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3356 return(-1); 3357 } 3358 list->sizeItems = initialSize; 3359 } else if (list->sizeItems <= list->nbItems) { 3360 list->sizeItems *= 2; 3361 list->items = (void **) xmlRealloc(list->items, 3362 list->sizeItems * sizeof(void *)); 3363 if (list->items == NULL) { 3364 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3365 list->sizeItems = 0; 3366 return(-1); 3367 } 3368 } 3369 list->items[list->nbItems++] = item; 3370 return(0); 3371 } 3372 3373 static int 3374 xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx) 3375 { 3376 if (list->items == NULL) { 3377 list->items = (void **) xmlMalloc( 3378 20 * sizeof(void *)); 3379 if (list->items == NULL) { 3380 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3381 return(-1); 3382 } 3383 list->sizeItems = 20; 3384 } else if (list->sizeItems <= list->nbItems) { 3385 list->sizeItems *= 2; 3386 list->items = (void **) xmlRealloc(list->items, 3387 list->sizeItems * sizeof(void *)); 3388 if (list->items == NULL) { 3389 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3390 list->sizeItems = 0; 3391 return(-1); 3392 } 3393 } 3394 /* 3395 * Just append if the index is greater/equal than the item count. 3396 */ 3397 if (idx >= list->nbItems) { 3398 list->items[list->nbItems++] = item; 3399 } else { 3400 int i; 3401 for (i = list->nbItems; i > idx; i--) 3402 list->items[i] = list->items[i-1]; 3403 list->items[idx] = item; 3404 list->nbItems++; 3405 } 3406 return(0); 3407 } 3408 3409 #if 0 /* enable if ever needed */ 3410 static int 3411 xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list, 3412 int initialSize, 3413 void *item, 3414 int idx) 3415 { 3416 if (list->items == NULL) { 3417 if (initialSize <= 0) 3418 initialSize = 1; 3419 list->items = (void **) xmlMalloc( 3420 initialSize * sizeof(void *)); 3421 if (list->items == NULL) { 3422 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3423 return(-1); 3424 } 3425 list->sizeItems = initialSize; 3426 } else if (list->sizeItems <= list->nbItems) { 3427 list->sizeItems *= 2; 3428 list->items = (void **) xmlRealloc(list->items, 3429 list->sizeItems * sizeof(void *)); 3430 if (list->items == NULL) { 3431 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3432 list->sizeItems = 0; 3433 return(-1); 3434 } 3435 } 3436 /* 3437 * Just append if the index is greater/equal than the item count. 3438 */ 3439 if (idx >= list->nbItems) { 3440 list->items[list->nbItems++] = item; 3441 } else { 3442 int i; 3443 for (i = list->nbItems; i > idx; i--) 3444 list->items[i] = list->items[i-1]; 3445 list->items[idx] = item; 3446 list->nbItems++; 3447 } 3448 return(0); 3449 } 3450 #endif 3451 3452 static int 3453 xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx) 3454 { 3455 int i; 3456 if ((list->items == NULL) || (idx >= list->nbItems)) { 3457 xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, " 3458 "index error.\n"); 3459 return(-1); 3460 } 3461 3462 if (list->nbItems == 1) { 3463 /* TODO: Really free the list? */ 3464 xmlFree(list->items); 3465 list->items = NULL; 3466 list->nbItems = 0; 3467 list->sizeItems = 0; 3468 } else if (list->nbItems -1 == idx) { 3469 list->nbItems--; 3470 } else { 3471 for (i = idx; i < list->nbItems -1; i++) 3472 list->items[i] = list->items[i+1]; 3473 list->nbItems--; 3474 } 3475 return(0); 3476 } 3477 3478 /** 3479 * xmlSchemaItemListFree: 3480 * @annot: a schema type structure 3481 * 3482 * Deallocate a annotation structure 3483 */ 3484 static void 3485 xmlSchemaItemListFree(xmlSchemaItemListPtr list) 3486 { 3487 if (list == NULL) 3488 return; 3489 if (list->items != NULL) 3490 xmlFree(list->items); 3491 xmlFree(list); 3492 } 3493 3494 static void 3495 xmlSchemaBucketFree(xmlSchemaBucketPtr bucket) 3496 { 3497 if (bucket == NULL) 3498 return; 3499 if (bucket->globals != NULL) { 3500 xmlSchemaComponentListFree(bucket->globals); 3501 xmlSchemaItemListFree(bucket->globals); 3502 } 3503 if (bucket->locals != NULL) { 3504 xmlSchemaComponentListFree(bucket->locals); 3505 xmlSchemaItemListFree(bucket->locals); 3506 } 3507 if (bucket->relations != NULL) { 3508 xmlSchemaSchemaRelationPtr prev, cur = bucket->relations; 3509 do { 3510 prev = cur; 3511 cur = cur->next; 3512 xmlFree(prev); 3513 } while (cur != NULL); 3514 } 3515 if ((! bucket->preserveDoc) && (bucket->doc != NULL)) { 3516 xmlFreeDoc(bucket->doc); 3517 } 3518 if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) { 3519 if (WXS_IMPBUCKET(bucket)->schema != NULL) 3520 xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema); 3521 } 3522 xmlFree(bucket); 3523 } 3524 3525 static xmlSchemaBucketPtr 3526 xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt, 3527 int type, const xmlChar *targetNamespace) 3528 { 3529 xmlSchemaBucketPtr ret; 3530 int size; 3531 xmlSchemaPtr mainSchema; 3532 3533 if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) { 3534 PERROR_INT("xmlSchemaBucketCreate", 3535 "no main schema on constructor"); 3536 return(NULL); 3537 } 3538 mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema; 3539 /* Create the schema bucket. */ 3540 if (WXS_IS_BUCKET_INCREDEF(type)) 3541 size = sizeof(xmlSchemaInclude); 3542 else 3543 size = sizeof(xmlSchemaImport); 3544 ret = (xmlSchemaBucketPtr) xmlMalloc(size); 3545 if (ret == NULL) { 3546 xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL); 3547 return(NULL); 3548 } 3549 memset(ret, 0, size); 3550 ret->targetNamespace = targetNamespace; 3551 ret->type = type; 3552 ret->globals = xmlSchemaItemListCreate(); 3553 if (ret->globals == NULL) { 3554 xmlFree(ret); 3555 return(NULL); 3556 } 3557 ret->locals = xmlSchemaItemListCreate(); 3558 if (ret->locals == NULL) { 3559 xmlFree(ret); 3560 return(NULL); 3561 } 3562 /* 3563 * The following will assure that only the first bucket is marked as 3564 * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema. 3565 * For each following import buckets an xmlSchema will be created. 3566 * An xmlSchema will be created for every distinct targetNamespace. 3567 * We assign the targetNamespace to the schemata here. 3568 */ 3569 if (! WXS_HAS_BUCKETS(pctxt)) { 3570 if (WXS_IS_BUCKET_INCREDEF(type)) { 3571 PERROR_INT("xmlSchemaBucketCreate", 3572 "first bucket but it's an include or redefine"); 3573 xmlSchemaBucketFree(ret); 3574 return(NULL); 3575 } 3576 /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */ 3577 ret->type = XML_SCHEMA_SCHEMA_MAIN; 3578 /* Point to the *main* schema. */ 3579 WXS_CONSTRUCTOR(pctxt)->mainBucket = ret; 3580 WXS_IMPBUCKET(ret)->schema = mainSchema; 3581 /* 3582 * Ensure that the main schema gets a targetNamespace. 3583 */ 3584 mainSchema->targetNamespace = targetNamespace; 3585 } else { 3586 if (type == XML_SCHEMA_SCHEMA_MAIN) { 3587 PERROR_INT("xmlSchemaBucketCreate", 3588 "main bucket but it's not the first one"); 3589 xmlSchemaBucketFree(ret); 3590 return(NULL); 3591 } else if (type == XML_SCHEMA_SCHEMA_IMPORT) { 3592 /* 3593 * Create a schema for imports and assign the 3594 * targetNamespace. 3595 */ 3596 WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt); 3597 if (WXS_IMPBUCKET(ret)->schema == NULL) { 3598 xmlSchemaBucketFree(ret); 3599 return(NULL); 3600 } 3601 WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace; 3602 } 3603 } 3604 if (WXS_IS_BUCKET_IMPMAIN(type)) { 3605 int res; 3606 /* 3607 * Imports go into the "schemasImports" slot of the main *schema*. 3608 * Note that we create an import entry for the main schema as well; i.e., 3609 * even if there's only one schema, we'll get an import. 3610 */ 3611 if (mainSchema->schemasImports == NULL) { 3612 mainSchema->schemasImports = xmlHashCreateDict(5, 3613 WXS_CONSTRUCTOR(pctxt)->dict); 3614 if (mainSchema->schemasImports == NULL) { 3615 xmlSchemaBucketFree(ret); 3616 return(NULL); 3617 } 3618 } 3619 if (targetNamespace == NULL) 3620 res = xmlHashAddEntry(mainSchema->schemasImports, 3621 XML_SCHEMAS_NO_NAMESPACE, ret); 3622 else 3623 res = xmlHashAddEntry(mainSchema->schemasImports, 3624 targetNamespace, ret); 3625 if (res != 0) { 3626 PERROR_INT("xmlSchemaBucketCreate", 3627 "failed to add the schema bucket to the hash"); 3628 xmlSchemaBucketFree(ret); 3629 return(NULL); 3630 } 3631 } else { 3632 /* Set the @ownerImport of an include bucket. */ 3633 if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type)) 3634 WXS_INCBUCKET(ret)->ownerImport = 3635 WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket); 3636 else 3637 WXS_INCBUCKET(ret)->ownerImport = 3638 WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport; 3639 3640 /* Includes got into the "includes" slot of the *main* schema. */ 3641 if (mainSchema->includes == NULL) { 3642 mainSchema->includes = xmlSchemaItemListCreate(); 3643 if (mainSchema->includes == NULL) { 3644 xmlSchemaBucketFree(ret); 3645 return(NULL); 3646 } 3647 } 3648 xmlSchemaItemListAdd(mainSchema->includes, ret); 3649 } 3650 /* 3651 * Add to list of all buckets; this is used for lookup 3652 * during schema construction time only. 3653 */ 3654 if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1) 3655 return(NULL); 3656 return(ret); 3657 } 3658 3659 static int 3660 xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item) 3661 { 3662 if (*list == NULL) { 3663 *list = xmlSchemaItemListCreate(); 3664 if (*list == NULL) 3665 return(-1); 3666 } 3667 xmlSchemaItemListAddSize(*list, initialSize, item); 3668 return(0); 3669 } 3670 3671 /** 3672 * xmlSchemaFreeAnnot: 3673 * @annot: a schema type structure 3674 * 3675 * Deallocate a annotation structure 3676 */ 3677 static void 3678 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot) 3679 { 3680 if (annot == NULL) 3681 return; 3682 if (annot->next == NULL) { 3683 xmlFree(annot); 3684 } else { 3685 xmlSchemaAnnotPtr prev; 3686 3687 do { 3688 prev = annot; 3689 annot = annot->next; 3690 xmlFree(prev); 3691 } while (annot != NULL); 3692 } 3693 } 3694 3695 /** 3696 * xmlSchemaFreeNotation: 3697 * @schema: a schema notation structure 3698 * 3699 * Deallocate a Schema Notation structure. 3700 */ 3701 static void 3702 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota) 3703 { 3704 if (nota == NULL) 3705 return; 3706 xmlFree(nota); 3707 } 3708 3709 /** 3710 * xmlSchemaFreeAttribute: 3711 * @attr: an attribute declaration 3712 * 3713 * Deallocates an attribute declaration structure. 3714 */ 3715 static void 3716 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr) 3717 { 3718 if (attr == NULL) 3719 return; 3720 if (attr->annot != NULL) 3721 xmlSchemaFreeAnnot(attr->annot); 3722 if (attr->defVal != NULL) 3723 xmlSchemaFreeValue(attr->defVal); 3724 xmlFree(attr); 3725 } 3726 3727 /** 3728 * xmlSchemaFreeAttributeUse: 3729 * @use: an attribute use 3730 * 3731 * Deallocates an attribute use structure. 3732 */ 3733 static void 3734 xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use) 3735 { 3736 if (use == NULL) 3737 return; 3738 if (use->annot != NULL) 3739 xmlSchemaFreeAnnot(use->annot); 3740 if (use->defVal != NULL) 3741 xmlSchemaFreeValue(use->defVal); 3742 xmlFree(use); 3743 } 3744 3745 /** 3746 * xmlSchemaFreeAttributeUseProhib: 3747 * @prohib: an attribute use prohibition 3748 * 3749 * Deallocates an attribute use structure. 3750 */ 3751 static void 3752 xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib) 3753 { 3754 if (prohib == NULL) 3755 return; 3756 xmlFree(prohib); 3757 } 3758 3759 /** 3760 * xmlSchemaFreeWildcardNsSet: 3761 * set: a schema wildcard namespace 3762 * 3763 * Deallocates a list of wildcard constraint structures. 3764 */ 3765 static void 3766 xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set) 3767 { 3768 xmlSchemaWildcardNsPtr next; 3769 3770 while (set != NULL) { 3771 next = set->next; 3772 xmlFree(set); 3773 set = next; 3774 } 3775 } 3776 3777 /** 3778 * xmlSchemaFreeWildcard: 3779 * @wildcard: a wildcard structure 3780 * 3781 * Deallocates a wildcard structure. 3782 */ 3783 void 3784 xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard) 3785 { 3786 if (wildcard == NULL) 3787 return; 3788 if (wildcard->annot != NULL) 3789 xmlSchemaFreeAnnot(wildcard->annot); 3790 if (wildcard->nsSet != NULL) 3791 xmlSchemaFreeWildcardNsSet(wildcard->nsSet); 3792 if (wildcard->negNsSet != NULL) 3793 xmlFree(wildcard->negNsSet); 3794 xmlFree(wildcard); 3795 } 3796 3797 /** 3798 * xmlSchemaFreeAttributeGroup: 3799 * @schema: a schema attribute group structure 3800 * 3801 * Deallocate a Schema Attribute Group structure. 3802 */ 3803 static void 3804 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr) 3805 { 3806 if (attrGr == NULL) 3807 return; 3808 if (attrGr->annot != NULL) 3809 xmlSchemaFreeAnnot(attrGr->annot); 3810 if (attrGr->attrUses != NULL) 3811 xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses); 3812 xmlFree(attrGr); 3813 } 3814 3815 /** 3816 * xmlSchemaFreeQNameRef: 3817 * @item: a QName reference structure 3818 * 3819 * Deallocatea a QName reference structure. 3820 */ 3821 static void 3822 xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item) 3823 { 3824 xmlFree(item); 3825 } 3826 3827 /** 3828 * xmlSchemaFreeTypeLinkList: 3829 * @alink: a type link 3830 * 3831 * Deallocate a list of types. 3832 */ 3833 static void 3834 xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link) 3835 { 3836 xmlSchemaTypeLinkPtr next; 3837 3838 while (link != NULL) { 3839 next = link->next; 3840 xmlFree(link); 3841 link = next; 3842 } 3843 } 3844 3845 static void 3846 xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto) 3847 { 3848 xmlSchemaIDCStateObjPtr next; 3849 while (sto != NULL) { 3850 next = sto->next; 3851 if (sto->history != NULL) 3852 xmlFree(sto->history); 3853 if (sto->xpathCtxt != NULL) 3854 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt); 3855 xmlFree(sto); 3856 sto = next; 3857 } 3858 } 3859 3860 /** 3861 * xmlSchemaFreeIDC: 3862 * @idc: a identity-constraint definition 3863 * 3864 * Deallocates an identity-constraint definition. 3865 */ 3866 static void 3867 xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef) 3868 { 3869 xmlSchemaIDCSelectPtr cur, prev; 3870 3871 if (idcDef == NULL) 3872 return; 3873 if (idcDef->annot != NULL) 3874 xmlSchemaFreeAnnot(idcDef->annot); 3875 /* Selector */ 3876 if (idcDef->selector != NULL) { 3877 if (idcDef->selector->xpathComp != NULL) 3878 xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp); 3879 xmlFree(idcDef->selector); 3880 } 3881 /* Fields */ 3882 if (idcDef->fields != NULL) { 3883 cur = idcDef->fields; 3884 do { 3885 prev = cur; 3886 cur = cur->next; 3887 if (prev->xpathComp != NULL) 3888 xmlFreePattern((xmlPatternPtr) prev->xpathComp); 3889 xmlFree(prev); 3890 } while (cur != NULL); 3891 } 3892 xmlFree(idcDef); 3893 } 3894 3895 /** 3896 * xmlSchemaFreeElement: 3897 * @schema: a schema element structure 3898 * 3899 * Deallocate a Schema Element structure. 3900 */ 3901 static void 3902 xmlSchemaFreeElement(xmlSchemaElementPtr elem) 3903 { 3904 if (elem == NULL) 3905 return; 3906 if (elem->annot != NULL) 3907 xmlSchemaFreeAnnot(elem->annot); 3908 if (elem->contModel != NULL) 3909 xmlRegFreeRegexp(elem->contModel); 3910 if (elem->defVal != NULL) 3911 xmlSchemaFreeValue(elem->defVal); 3912 xmlFree(elem); 3913 } 3914 3915 /** 3916 * xmlSchemaFreeFacet: 3917 * @facet: a schema facet structure 3918 * 3919 * Deallocate a Schema Facet structure. 3920 */ 3921 void 3922 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet) 3923 { 3924 if (facet == NULL) 3925 return; 3926 if (facet->val != NULL) 3927 xmlSchemaFreeValue(facet->val); 3928 if (facet->regexp != NULL) 3929 xmlRegFreeRegexp(facet->regexp); 3930 if (facet->annot != NULL) 3931 xmlSchemaFreeAnnot(facet->annot); 3932 xmlFree(facet); 3933 } 3934 3935 /** 3936 * xmlSchemaFreeType: 3937 * @type: a schema type structure 3938 * 3939 * Deallocate a Schema Type structure. 3940 */ 3941 void 3942 xmlSchemaFreeType(xmlSchemaTypePtr type) 3943 { 3944 if (type == NULL) 3945 return; 3946 if (type->annot != NULL) 3947 xmlSchemaFreeAnnot(type->annot); 3948 if (type->facets != NULL) { 3949 xmlSchemaFacetPtr facet, next; 3950 3951 facet = type->facets; 3952 while (facet != NULL) { 3953 next = facet->next; 3954 xmlSchemaFreeFacet(facet); 3955 facet = next; 3956 } 3957 } 3958 if (type->attrUses != NULL) 3959 xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses); 3960 if (type->memberTypes != NULL) 3961 xmlSchemaFreeTypeLinkList(type->memberTypes); 3962 if (type->facetSet != NULL) { 3963 xmlSchemaFacetLinkPtr next, link; 3964 3965 link = type->facetSet; 3966 do { 3967 next = link->next; 3968 xmlFree(link); 3969 link = next; 3970 } while (link != NULL); 3971 } 3972 if (type->contModel != NULL) 3973 xmlRegFreeRegexp(type->contModel); 3974 xmlFree(type); 3975 } 3976 3977 /** 3978 * xmlSchemaFreeModelGroupDef: 3979 * @item: a schema model group definition 3980 * 3981 * Deallocates a schema model group definition. 3982 */ 3983 static void 3984 xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item) 3985 { 3986 if (item->annot != NULL) 3987 xmlSchemaFreeAnnot(item->annot); 3988 xmlFree(item); 3989 } 3990 3991 /** 3992 * xmlSchemaFreeModelGroup: 3993 * @item: a schema model group 3994 * 3995 * Deallocates a schema model group structure. 3996 */ 3997 static void 3998 xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item) 3999 { 4000 if (item->annot != NULL) 4001 xmlSchemaFreeAnnot(item->annot); 4002 xmlFree(item); 4003 } 4004 4005 static void 4006 xmlSchemaComponentListFree(xmlSchemaItemListPtr list) 4007 { 4008 if ((list == NULL) || (list->nbItems == 0)) 4009 return; 4010 { 4011 xmlSchemaTreeItemPtr item; 4012 xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items; 4013 int i; 4014 4015 for (i = 0; i < list->nbItems; i++) { 4016 item = items[i]; 4017 if (item == NULL) 4018 continue; 4019 switch (item->type) { 4020 case XML_SCHEMA_TYPE_SIMPLE: 4021 case XML_SCHEMA_TYPE_COMPLEX: 4022 xmlSchemaFreeType((xmlSchemaTypePtr) item); 4023 break; 4024 case XML_SCHEMA_TYPE_ATTRIBUTE: 4025 xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item); 4026 break; 4027 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 4028 xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item); 4029 break; 4030 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 4031 xmlSchemaFreeAttributeUseProhib( 4032 (xmlSchemaAttributeUseProhibPtr) item); 4033 break; 4034 case XML_SCHEMA_TYPE_ELEMENT: 4035 xmlSchemaFreeElement((xmlSchemaElementPtr) item); 4036 break; 4037 case XML_SCHEMA_TYPE_PARTICLE: 4038 if (item->annot != NULL) 4039 xmlSchemaFreeAnnot(item->annot); 4040 xmlFree(item); 4041 break; 4042 case XML_SCHEMA_TYPE_SEQUENCE: 4043 case XML_SCHEMA_TYPE_CHOICE: 4044 case XML_SCHEMA_TYPE_ALL: 4045 xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item); 4046 break; 4047 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 4048 xmlSchemaFreeAttributeGroup( 4049 (xmlSchemaAttributeGroupPtr) item); 4050 break; 4051 case XML_SCHEMA_TYPE_GROUP: 4052 xmlSchemaFreeModelGroupDef( 4053 (xmlSchemaModelGroupDefPtr) item); 4054 break; 4055 case XML_SCHEMA_TYPE_ANY: 4056 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 4057 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item); 4058 break; 4059 case XML_SCHEMA_TYPE_IDC_KEY: 4060 case XML_SCHEMA_TYPE_IDC_UNIQUE: 4061 case XML_SCHEMA_TYPE_IDC_KEYREF: 4062 xmlSchemaFreeIDC((xmlSchemaIDCPtr) item); 4063 break; 4064 case XML_SCHEMA_TYPE_NOTATION: 4065 xmlSchemaFreeNotation((xmlSchemaNotationPtr) item); 4066 break; 4067 case XML_SCHEMA_EXTRA_QNAMEREF: 4068 xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item); 4069 break; 4070 default: { 4071 /* TODO: This should never be hit. */ 4072 xmlSchemaPSimpleInternalErr(NULL, 4073 "Internal error: xmlSchemaComponentListFree, " 4074 "unexpected component type '%s'\n", 4075 (const xmlChar *) WXS_ITEM_TYPE_NAME(item)); 4076 } 4077 break; 4078 } 4079 } 4080 list->nbItems = 0; 4081 } 4082 } 4083 4084 /** 4085 * xmlSchemaFree: 4086 * @schema: a schema structure 4087 * 4088 * Deallocate a Schema structure. 4089 */ 4090 void 4091 xmlSchemaFree(xmlSchemaPtr schema) 4092 { 4093 if (schema == NULL) 4094 return; 4095 /* @volatiles is not used anymore :-/ */ 4096 if (schema->volatiles != NULL) 4097 TODO 4098 /* 4099 * Note that those slots are not responsible for freeing 4100 * schema components anymore; this will now be done by 4101 * the schema buckets. 4102 */ 4103 if (schema->notaDecl != NULL) 4104 xmlHashFree(schema->notaDecl, NULL); 4105 if (schema->attrDecl != NULL) 4106 xmlHashFree(schema->attrDecl, NULL); 4107 if (schema->attrgrpDecl != NULL) 4108 xmlHashFree(schema->attrgrpDecl, NULL); 4109 if (schema->elemDecl != NULL) 4110 xmlHashFree(schema->elemDecl, NULL); 4111 if (schema->typeDecl != NULL) 4112 xmlHashFree(schema->typeDecl, NULL); 4113 if (schema->groupDecl != NULL) 4114 xmlHashFree(schema->groupDecl, NULL); 4115 if (schema->idcDef != NULL) 4116 xmlHashFree(schema->idcDef, NULL); 4117 4118 if (schema->schemasImports != NULL) 4119 xmlHashFree(schema->schemasImports, 4120 (xmlHashDeallocator) xmlSchemaBucketFree); 4121 if (schema->includes != NULL) { 4122 xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes; 4123 int i; 4124 for (i = 0; i < list->nbItems; i++) { 4125 xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]); 4126 } 4127 xmlSchemaItemListFree(list); 4128 } 4129 if (schema->annot != NULL) 4130 xmlSchemaFreeAnnot(schema->annot); 4131 /* Never free the doc here, since this will be done by the buckets. */ 4132 4133 xmlDictFree(schema->dict); 4134 xmlFree(schema); 4135 } 4136 4137 /************************************************************************ 4138 * * 4139 * Debug functions * 4140 * * 4141 ************************************************************************/ 4142 4143 #ifdef LIBXML_OUTPUT_ENABLED 4144 4145 static void 4146 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */ 4147 4148 /** 4149 * xmlSchemaElementDump: 4150 * @elem: an element 4151 * @output: the file output 4152 * 4153 * Dump the element 4154 */ 4155 static void 4156 xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output, 4157 const xmlChar * name ATTRIBUTE_UNUSED, 4158 const xmlChar * namespace ATTRIBUTE_UNUSED, 4159 const xmlChar * context ATTRIBUTE_UNUSED) 4160 { 4161 if (elem == NULL) 4162 return; 4163 4164 4165 fprintf(output, "Element"); 4166 if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL) 4167 fprintf(output, " (global)"); 4168 fprintf(output, ": '%s' ", elem->name); 4169 if (namespace != NULL) 4170 fprintf(output, "ns '%s'", namespace); 4171 fprintf(output, "\n"); 4172 #if 0 4173 if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) { 4174 fprintf(output, " min %d ", elem->minOccurs); 4175 if (elem->maxOccurs >= UNBOUNDED) 4176 fprintf(output, "max: unbounded\n"); 4177 else if (elem->maxOccurs != 1) 4178 fprintf(output, "max: %d\n", elem->maxOccurs); 4179 else 4180 fprintf(output, "\n"); 4181 } 4182 #endif 4183 /* 4184 * Misc other properties. 4185 */ 4186 if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) || 4187 (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) || 4188 (elem->flags & XML_SCHEMAS_ELEM_FIXED) || 4189 (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) { 4190 fprintf(output, " props: "); 4191 if (elem->flags & XML_SCHEMAS_ELEM_FIXED) 4192 fprintf(output, "[fixed] "); 4193 if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT) 4194 fprintf(output, "[default] "); 4195 if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) 4196 fprintf(output, "[abstract] "); 4197 if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE) 4198 fprintf(output, "[nillable] "); 4199 fprintf(output, "\n"); 4200 } 4201 /* 4202 * Default/fixed value. 4203 */ 4204 if (elem->value != NULL) 4205 fprintf(output, " value: '%s'\n", elem->value); 4206 /* 4207 * Type. 4208 */ 4209 if (elem->namedType != NULL) { 4210 fprintf(output, " type: '%s' ", elem->namedType); 4211 if (elem->namedTypeNs != NULL) 4212 fprintf(output, "ns '%s'\n", elem->namedTypeNs); 4213 else 4214 fprintf(output, "\n"); 4215 } else if (elem->subtypes != NULL) { 4216 /* 4217 * Dump local types. 4218 */ 4219 xmlSchemaTypeDump(elem->subtypes, output); 4220 } 4221 /* 4222 * Substitution group. 4223 */ 4224 if (elem->substGroup != NULL) { 4225 fprintf(output, " substitutionGroup: '%s' ", elem->substGroup); 4226 if (elem->substGroupNs != NULL) 4227 fprintf(output, "ns '%s'\n", elem->substGroupNs); 4228 else 4229 fprintf(output, "\n"); 4230 } 4231 } 4232 4233 /** 4234 * xmlSchemaAnnotDump: 4235 * @output: the file output 4236 * @annot: a annotation 4237 * 4238 * Dump the annotation 4239 */ 4240 static void 4241 xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot) 4242 { 4243 xmlChar *content; 4244 4245 if (annot == NULL) 4246 return; 4247 4248 content = xmlNodeGetContent(annot->content); 4249 if (content != NULL) { 4250 fprintf(output, " Annot: %s\n", content); 4251 xmlFree(content); 4252 } else 4253 fprintf(output, " Annot: empty\n"); 4254 } 4255 4256 /** 4257 * xmlSchemaContentModelDump: 4258 * @particle: the schema particle 4259 * @output: the file output 4260 * @depth: the depth used for intentation 4261 * 4262 * Dump a SchemaType structure 4263 */ 4264 static void 4265 xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth) 4266 { 4267 xmlChar *str = NULL; 4268 xmlSchemaTreeItemPtr term; 4269 char shift[100]; 4270 int i; 4271 4272 if (particle == NULL) 4273 return; 4274 for (i = 0;((i < depth) && (i < 25));i++) 4275 shift[2 * i] = shift[2 * i + 1] = ' '; 4276 shift[2 * i] = shift[2 * i + 1] = 0; 4277 fprintf(output, "%s", shift); 4278 if (particle->children == NULL) { 4279 fprintf(output, "MISSING particle term\n"); 4280 return; 4281 } 4282 term = particle->children; 4283 if (term == NULL) { 4284 fprintf(output, "(NULL)"); 4285 } else { 4286 switch (term->type) { 4287 case XML_SCHEMA_TYPE_ELEMENT: 4288 fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str, 4289 ((xmlSchemaElementPtr)term)->targetNamespace, 4290 ((xmlSchemaElementPtr)term)->name)); 4291 FREE_AND_NULL(str); 4292 break; 4293 case XML_SCHEMA_TYPE_SEQUENCE: 4294 fprintf(output, "SEQUENCE"); 4295 break; 4296 case XML_SCHEMA_TYPE_CHOICE: 4297 fprintf(output, "CHOICE"); 4298 break; 4299 case XML_SCHEMA_TYPE_ALL: 4300 fprintf(output, "ALL"); 4301 break; 4302 case XML_SCHEMA_TYPE_ANY: 4303 fprintf(output, "ANY"); 4304 break; 4305 default: 4306 fprintf(output, "UNKNOWN\n"); 4307 return; 4308 } 4309 } 4310 if (particle->minOccurs != 1) 4311 fprintf(output, " min: %d", particle->minOccurs); 4312 if (particle->maxOccurs >= UNBOUNDED) 4313 fprintf(output, " max: unbounded"); 4314 else if (particle->maxOccurs != 1) 4315 fprintf(output, " max: %d", particle->maxOccurs); 4316 fprintf(output, "\n"); 4317 if (term && 4318 ((term->type == XML_SCHEMA_TYPE_SEQUENCE) || 4319 (term->type == XML_SCHEMA_TYPE_CHOICE) || 4320 (term->type == XML_SCHEMA_TYPE_ALL)) && 4321 (term->children != NULL)) { 4322 xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children, 4323 output, depth +1); 4324 } 4325 if (particle->next != NULL) 4326 xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next, 4327 output, depth); 4328 } 4329 4330 /** 4331 * xmlSchemaAttrUsesDump: 4332 * @uses: attribute uses list 4333 * @output: the file output 4334 * 4335 * Dumps a list of attribute use components. 4336 */ 4337 static void 4338 xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output) 4339 { 4340 xmlSchemaAttributeUsePtr use; 4341 xmlSchemaAttributeUseProhibPtr prohib; 4342 xmlSchemaQNameRefPtr ref; 4343 const xmlChar *name, *tns; 4344 xmlChar *str = NULL; 4345 int i; 4346 4347 if ((uses == NULL) || (uses->nbItems == 0)) 4348 return; 4349 4350 fprintf(output, " attributes:\n"); 4351 for (i = 0; i < uses->nbItems; i++) { 4352 use = uses->items[i]; 4353 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 4354 fprintf(output, " [prohibition] "); 4355 prohib = (xmlSchemaAttributeUseProhibPtr) use; 4356 name = prohib->name; 4357 tns = prohib->targetNamespace; 4358 } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) { 4359 fprintf(output, " [reference] "); 4360 ref = (xmlSchemaQNameRefPtr) use; 4361 name = ref->name; 4362 tns = ref->targetNamespace; 4363 } else { 4364 fprintf(output, " [use] "); 4365 name = WXS_ATTRUSE_DECL_NAME(use); 4366 tns = WXS_ATTRUSE_DECL_TNS(use); 4367 } 4368 fprintf(output, "'%s'\n", 4369 (const char *) xmlSchemaFormatQName(&str, tns, name)); 4370 FREE_AND_NULL(str); 4371 } 4372 } 4373 4374 /** 4375 * xmlSchemaTypeDump: 4376 * @output: the file output 4377 * @type: a type structure 4378 * 4379 * Dump a SchemaType structure 4380 */ 4381 static void 4382 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output) 4383 { 4384 if (type == NULL) { 4385 fprintf(output, "Type: NULL\n"); 4386 return; 4387 } 4388 fprintf(output, "Type: "); 4389 if (type->name != NULL) 4390 fprintf(output, "'%s' ", type->name); 4391 else 4392 fprintf(output, "(no name) "); 4393 if (type->targetNamespace != NULL) 4394 fprintf(output, "ns '%s' ", type->targetNamespace); 4395 switch (type->type) { 4396 case XML_SCHEMA_TYPE_BASIC: 4397 fprintf(output, "[basic] "); 4398 break; 4399 case XML_SCHEMA_TYPE_SIMPLE: 4400 fprintf(output, "[simple] "); 4401 break; 4402 case XML_SCHEMA_TYPE_COMPLEX: 4403 fprintf(output, "[complex] "); 4404 break; 4405 case XML_SCHEMA_TYPE_SEQUENCE: 4406 fprintf(output, "[sequence] "); 4407 break; 4408 case XML_SCHEMA_TYPE_CHOICE: 4409 fprintf(output, "[choice] "); 4410 break; 4411 case XML_SCHEMA_TYPE_ALL: 4412 fprintf(output, "[all] "); 4413 break; 4414 case XML_SCHEMA_TYPE_UR: 4415 fprintf(output, "[ur] "); 4416 break; 4417 case XML_SCHEMA_TYPE_RESTRICTION: 4418 fprintf(output, "[restriction] "); 4419 break; 4420 case XML_SCHEMA_TYPE_EXTENSION: 4421 fprintf(output, "[extension] "); 4422 break; 4423 default: 4424 fprintf(output, "[unknown type %d] ", type->type); 4425 break; 4426 } 4427 fprintf(output, "content: "); 4428 switch (type->contentType) { 4429 case XML_SCHEMA_CONTENT_UNKNOWN: 4430 fprintf(output, "[unknown] "); 4431 break; 4432 case XML_SCHEMA_CONTENT_EMPTY: 4433 fprintf(output, "[empty] "); 4434 break; 4435 case XML_SCHEMA_CONTENT_ELEMENTS: 4436 fprintf(output, "[element] "); 4437 break; 4438 case XML_SCHEMA_CONTENT_MIXED: 4439 fprintf(output, "[mixed] "); 4440 break; 4441 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 4442 /* not used. */ 4443 break; 4444 case XML_SCHEMA_CONTENT_BASIC: 4445 fprintf(output, "[basic] "); 4446 break; 4447 case XML_SCHEMA_CONTENT_SIMPLE: 4448 fprintf(output, "[simple] "); 4449 break; 4450 case XML_SCHEMA_CONTENT_ANY: 4451 fprintf(output, "[any] "); 4452 break; 4453 } 4454 fprintf(output, "\n"); 4455 if (type->base != NULL) { 4456 fprintf(output, " base type: '%s'", type->base); 4457 if (type->baseNs != NULL) 4458 fprintf(output, " ns '%s'\n", type->baseNs); 4459 else 4460 fprintf(output, "\n"); 4461 } 4462 if (type->attrUses != NULL) 4463 xmlSchemaAttrUsesDump(type->attrUses, output); 4464 if (type->annot != NULL) 4465 xmlSchemaAnnotDump(output, type->annot); 4466 #ifdef DUMP_CONTENT_MODEL 4467 if ((type->type == XML_SCHEMA_TYPE_COMPLEX) && 4468 (type->subtypes != NULL)) { 4469 xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes, 4470 output, 1); 4471 } 4472 #endif 4473 } 4474 4475 /** 4476 * xmlSchemaDump: 4477 * @output: the file output 4478 * @schema: a schema structure 4479 * 4480 * Dump a Schema structure. 4481 */ 4482 void 4483 xmlSchemaDump(FILE * output, xmlSchemaPtr schema) 4484 { 4485 if (output == NULL) 4486 return; 4487 if (schema == NULL) { 4488 fprintf(output, "Schemas: NULL\n"); 4489 return; 4490 } 4491 fprintf(output, "Schemas: "); 4492 if (schema->name != NULL) 4493 fprintf(output, "%s, ", schema->name); 4494 else 4495 fprintf(output, "no name, "); 4496 if (schema->targetNamespace != NULL) 4497 fprintf(output, "%s", (const char *) schema->targetNamespace); 4498 else 4499 fprintf(output, "no target namespace"); 4500 fprintf(output, "\n"); 4501 if (schema->annot != NULL) 4502 xmlSchemaAnnotDump(output, schema->annot); 4503 xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump, 4504 output); 4505 xmlHashScanFull(schema->elemDecl, 4506 (xmlHashScannerFull) xmlSchemaElementDump, output); 4507 } 4508 4509 #ifdef DEBUG_IDC_NODE_TABLE 4510 /** 4511 * xmlSchemaDebugDumpIDCTable: 4512 * @vctxt: the WXS validation context 4513 * 4514 * Displays the current IDC table for debug purposes. 4515 */ 4516 static void 4517 xmlSchemaDebugDumpIDCTable(FILE * output, 4518 const xmlChar *namespaceName, 4519 const xmlChar *localName, 4520 xmlSchemaPSVIIDCBindingPtr bind) 4521 { 4522 xmlChar *str = NULL; 4523 const xmlChar *value; 4524 xmlSchemaPSVIIDCNodePtr tab; 4525 xmlSchemaPSVIIDCKeyPtr key; 4526 int i, j, res; 4527 4528 fprintf(output, "IDC: TABLES on '%s'\n", 4529 xmlSchemaFormatQName(&str, namespaceName, localName)); 4530 FREE_AND_NULL(str) 4531 4532 if (bind == NULL) 4533 return; 4534 do { 4535 fprintf(output, "IDC: BINDING '%s' (%d)\n", 4536 xmlSchemaGetComponentQName(&str, 4537 bind->definition), bind->nbNodes); 4538 FREE_AND_NULL(str) 4539 for (i = 0; i < bind->nbNodes; i++) { 4540 tab = bind->nodeTable[i]; 4541 fprintf(output, " ( "); 4542 for (j = 0; j < bind->definition->nbFields; j++) { 4543 key = tab->keys[j]; 4544 if ((key != NULL) && (key->val != NULL)) { 4545 res = xmlSchemaGetCanonValue(key->val, &value); 4546 if (res >= 0) 4547 fprintf(output, "'%s' ", value); 4548 else 4549 fprintf(output, "CANON-VALUE-FAILED "); 4550 if (res == 0) 4551 FREE_AND_NULL(value) 4552 } else if (key != NULL) 4553 fprintf(output, "(no val), "); 4554 else 4555 fprintf(output, "(key missing), "); 4556 } 4557 fprintf(output, ")\n"); 4558 } 4559 if (bind->dupls && bind->dupls->nbItems) { 4560 fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems); 4561 for (i = 0; i < bind->dupls->nbItems; i++) { 4562 tab = bind->dupls->items[i]; 4563 fprintf(output, " ( "); 4564 for (j = 0; j < bind->definition->nbFields; j++) { 4565 key = tab->keys[j]; 4566 if ((key != NULL) && (key->val != NULL)) { 4567 res = xmlSchemaGetCanonValue(key->val, &value); 4568 if (res >= 0) 4569 fprintf(output, "'%s' ", value); 4570 else 4571 fprintf(output, "CANON-VALUE-FAILED "); 4572 if (res == 0) 4573 FREE_AND_NULL(value) 4574 } else if (key != NULL) 4575 fprintf(output, "(no val), "); 4576 else 4577 fprintf(output, "(key missing), "); 4578 } 4579 fprintf(output, ")\n"); 4580 } 4581 } 4582 bind = bind->next; 4583 } while (bind != NULL); 4584 } 4585 #endif /* DEBUG_IDC */ 4586 #endif /* LIBXML_OUTPUT_ENABLED */ 4587 4588 /************************************************************************ 4589 * * 4590 * Utilities * 4591 * * 4592 ************************************************************************/ 4593 4594 /** 4595 * xmlSchemaGetPropNode: 4596 * @node: the element node 4597 * @name: the name of the attribute 4598 * 4599 * Seeks an attribute with a name of @name in 4600 * no namespace. 4601 * 4602 * Returns the attribute or NULL if not present. 4603 */ 4604 static xmlAttrPtr 4605 xmlSchemaGetPropNode(xmlNodePtr node, const char *name) 4606 { 4607 xmlAttrPtr prop; 4608 4609 if ((node == NULL) || (name == NULL)) 4610 return(NULL); 4611 prop = node->properties; 4612 while (prop != NULL) { 4613 if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name)) 4614 return(prop); 4615 prop = prop->next; 4616 } 4617 return (NULL); 4618 } 4619 4620 /** 4621 * xmlSchemaGetPropNodeNs: 4622 * @node: the element node 4623 * @uri: the uri 4624 * @name: the name of the attribute 4625 * 4626 * Seeks an attribute with a local name of @name and 4627 * a namespace URI of @uri. 4628 * 4629 * Returns the attribute or NULL if not present. 4630 */ 4631 static xmlAttrPtr 4632 xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name) 4633 { 4634 xmlAttrPtr prop; 4635 4636 if ((node == NULL) || (name == NULL)) 4637 return(NULL); 4638 prop = node->properties; 4639 while (prop != NULL) { 4640 if ((prop->ns != NULL) && 4641 xmlStrEqual(prop->name, BAD_CAST name) && 4642 xmlStrEqual(prop->ns->href, BAD_CAST uri)) 4643 return(prop); 4644 prop = prop->next; 4645 } 4646 return (NULL); 4647 } 4648 4649 static const xmlChar * 4650 xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 4651 { 4652 xmlChar *val; 4653 const xmlChar *ret; 4654 4655 val = xmlNodeGetContent(node); 4656 if (val == NULL) 4657 val = xmlStrdup((xmlChar *)""); 4658 ret = xmlDictLookup(ctxt->dict, val, -1); 4659 xmlFree(val); 4660 return(ret); 4661 } 4662 4663 static const xmlChar * 4664 xmlSchemaGetNodeContentNoDict(xmlNodePtr node) 4665 { 4666 return((const xmlChar*) xmlNodeGetContent(node)); 4667 } 4668 4669 /** 4670 * xmlSchemaGetProp: 4671 * @ctxt: the parser context 4672 * @node: the node 4673 * @name: the property name 4674 * 4675 * Read a attribute value and internalize the string 4676 * 4677 * Returns the string or NULL if not present. 4678 */ 4679 static const xmlChar * 4680 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 4681 const char *name) 4682 { 4683 xmlChar *val; 4684 const xmlChar *ret; 4685 4686 val = xmlGetNoNsProp(node, BAD_CAST name); 4687 if (val == NULL) 4688 return(NULL); 4689 ret = xmlDictLookup(ctxt->dict, val, -1); 4690 xmlFree(val); 4691 return(ret); 4692 } 4693 4694 /************************************************************************ 4695 * * 4696 * Parsing functions * 4697 * * 4698 ************************************************************************/ 4699 4700 #define WXS_FIND_GLOBAL_ITEM(slot) \ 4701 if (xmlStrEqual(nsName, schema->targetNamespace)) { \ 4702 ret = xmlHashLookup(schema->slot, name); \ 4703 if (ret != NULL) goto exit; \ 4704 } \ 4705 if (xmlHashSize(schema->schemasImports) > 1) { \ 4706 xmlSchemaImportPtr import; \ 4707 if (nsName == NULL) \ 4708 import = xmlHashLookup(schema->schemasImports, \ 4709 XML_SCHEMAS_NO_NAMESPACE); \ 4710 else \ 4711 import = xmlHashLookup(schema->schemasImports, nsName); \ 4712 if (import == NULL) \ 4713 goto exit; \ 4714 ret = xmlHashLookup(import->schema->slot, name); \ 4715 } 4716 4717 /** 4718 * xmlSchemaGetElem: 4719 * @schema: the schema context 4720 * @name: the element name 4721 * @ns: the element namespace 4722 * 4723 * Lookup a global element declaration in the schema. 4724 * 4725 * Returns the element declaration or NULL if not found. 4726 */ 4727 static xmlSchemaElementPtr 4728 xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name, 4729 const xmlChar * nsName) 4730 { 4731 xmlSchemaElementPtr ret = NULL; 4732 4733 if ((name == NULL) || (schema == NULL)) 4734 return(NULL); 4735 if (schema != NULL) { 4736 WXS_FIND_GLOBAL_ITEM(elemDecl) 4737 } 4738 exit: 4739 #ifdef DEBUG 4740 if (ret == NULL) { 4741 if (nsName == NULL) 4742 fprintf(stderr, "Unable to lookup element decl. %s", name); 4743 else 4744 fprintf(stderr, "Unable to lookup element decl. %s:%s", name, 4745 nsName); 4746 } 4747 #endif 4748 return (ret); 4749 } 4750 4751 /** 4752 * xmlSchemaGetType: 4753 * @schema: the main schema 4754 * @name: the type's name 4755 * nsName: the type's namespace 4756 * 4757 * Lookup a type in the schemas or the predefined types 4758 * 4759 * Returns the group definition or NULL if not found. 4760 */ 4761 static xmlSchemaTypePtr 4762 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name, 4763 const xmlChar * nsName) 4764 { 4765 xmlSchemaTypePtr ret = NULL; 4766 4767 if (name == NULL) 4768 return (NULL); 4769 /* First try the built-in types. */ 4770 if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) { 4771 ret = xmlSchemaGetPredefinedType(name, nsName); 4772 if (ret != NULL) 4773 goto exit; 4774 /* 4775 * Note that we try the parsed schemas as well here 4776 * since one might have parsed the S4S, which contain more 4777 * than the built-in types. 4778 * TODO: Can we optimize this? 4779 */ 4780 } 4781 if (schema != NULL) { 4782 WXS_FIND_GLOBAL_ITEM(typeDecl) 4783 } 4784 exit: 4785 4786 #ifdef DEBUG 4787 if (ret == NULL) { 4788 if (nsName == NULL) 4789 fprintf(stderr, "Unable to lookup type %s", name); 4790 else 4791 fprintf(stderr, "Unable to lookup type %s:%s", name, 4792 nsName); 4793 } 4794 #endif 4795 return (ret); 4796 } 4797 4798 /** 4799 * xmlSchemaGetAttributeDecl: 4800 * @schema: the context of the schema 4801 * @name: the name of the attribute 4802 * @ns: the target namespace of the attribute 4803 * 4804 * Lookup a an attribute in the schema or imported schemas 4805 * 4806 * Returns the attribute declaration or NULL if not found. 4807 */ 4808 static xmlSchemaAttributePtr 4809 xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name, 4810 const xmlChar * nsName) 4811 { 4812 xmlSchemaAttributePtr ret = NULL; 4813 4814 if ((name == NULL) || (schema == NULL)) 4815 return (NULL); 4816 if (schema != NULL) { 4817 WXS_FIND_GLOBAL_ITEM(attrDecl) 4818 } 4819 exit: 4820 #ifdef DEBUG 4821 if (ret == NULL) { 4822 if (nsName == NULL) 4823 fprintf(stderr, "Unable to lookup attribute %s", name); 4824 else 4825 fprintf(stderr, "Unable to lookup attribute %s:%s", name, 4826 nsName); 4827 } 4828 #endif 4829 return (ret); 4830 } 4831 4832 /** 4833 * xmlSchemaGetAttributeGroup: 4834 * @schema: the context of the schema 4835 * @name: the name of the attribute group 4836 * @ns: the target namespace of the attribute group 4837 * 4838 * Lookup a an attribute group in the schema or imported schemas 4839 * 4840 * Returns the attribute group definition or NULL if not found. 4841 */ 4842 static xmlSchemaAttributeGroupPtr 4843 xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name, 4844 const xmlChar * nsName) 4845 { 4846 xmlSchemaAttributeGroupPtr ret = NULL; 4847 4848 if ((name == NULL) || (schema == NULL)) 4849 return (NULL); 4850 if (schema != NULL) { 4851 WXS_FIND_GLOBAL_ITEM(attrgrpDecl) 4852 } 4853 exit: 4854 /* TODO: 4855 if ((ret != NULL) && (ret->redef != NULL)) { 4856 * Return the last redefinition. * 4857 ret = ret->redef; 4858 } 4859 */ 4860 #ifdef DEBUG 4861 if (ret == NULL) { 4862 if (nsName == NULL) 4863 fprintf(stderr, "Unable to lookup attribute group %s", name); 4864 else 4865 fprintf(stderr, "Unable to lookup attribute group %s:%s", name, 4866 nsName); 4867 } 4868 #endif 4869 return (ret); 4870 } 4871 4872 /** 4873 * xmlSchemaGetGroup: 4874 * @schema: the context of the schema 4875 * @name: the name of the group 4876 * @ns: the target namespace of the group 4877 * 4878 * Lookup a group in the schema or imported schemas 4879 * 4880 * Returns the group definition or NULL if not found. 4881 */ 4882 static xmlSchemaModelGroupDefPtr 4883 xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name, 4884 const xmlChar * nsName) 4885 { 4886 xmlSchemaModelGroupDefPtr ret = NULL; 4887 4888 if ((name == NULL) || (schema == NULL)) 4889 return (NULL); 4890 if (schema != NULL) { 4891 WXS_FIND_GLOBAL_ITEM(groupDecl) 4892 } 4893 exit: 4894 4895 #ifdef DEBUG 4896 if (ret == NULL) { 4897 if (nsName == NULL) 4898 fprintf(stderr, "Unable to lookup group %s", name); 4899 else 4900 fprintf(stderr, "Unable to lookup group %s:%s", name, 4901 nsName); 4902 } 4903 #endif 4904 return (ret); 4905 } 4906 4907 static xmlSchemaNotationPtr 4908 xmlSchemaGetNotation(xmlSchemaPtr schema, 4909 const xmlChar *name, 4910 const xmlChar *nsName) 4911 { 4912 xmlSchemaNotationPtr ret = NULL; 4913 4914 if ((name == NULL) || (schema == NULL)) 4915 return (NULL); 4916 if (schema != NULL) { 4917 WXS_FIND_GLOBAL_ITEM(notaDecl) 4918 } 4919 exit: 4920 return (ret); 4921 } 4922 4923 static xmlSchemaIDCPtr 4924 xmlSchemaGetIDC(xmlSchemaPtr schema, 4925 const xmlChar *name, 4926 const xmlChar *nsName) 4927 { 4928 xmlSchemaIDCPtr ret = NULL; 4929 4930 if ((name == NULL) || (schema == NULL)) 4931 return (NULL); 4932 if (schema != NULL) { 4933 WXS_FIND_GLOBAL_ITEM(idcDef) 4934 } 4935 exit: 4936 return (ret); 4937 } 4938 4939 /** 4940 * xmlSchemaGetNamedComponent: 4941 * @schema: the schema 4942 * @name: the name of the group 4943 * @ns: the target namespace of the group 4944 * 4945 * Lookup a group in the schema or imported schemas 4946 * 4947 * Returns the group definition or NULL if not found. 4948 */ 4949 static xmlSchemaBasicItemPtr 4950 xmlSchemaGetNamedComponent(xmlSchemaPtr schema, 4951 xmlSchemaTypeType itemType, 4952 const xmlChar *name, 4953 const xmlChar *targetNs) 4954 { 4955 switch (itemType) { 4956 case XML_SCHEMA_TYPE_GROUP: 4957 return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema, 4958 name, targetNs)); 4959 case XML_SCHEMA_TYPE_ELEMENT: 4960 return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema, 4961 name, targetNs)); 4962 default: 4963 TODO 4964 return (NULL); 4965 } 4966 } 4967 4968 /************************************************************************ 4969 * * 4970 * Parsing functions * 4971 * * 4972 ************************************************************************/ 4973 4974 #define IS_BLANK_NODE(n) \ 4975 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1))) 4976 4977 /** 4978 * xmlSchemaIsBlank: 4979 * @str: a string 4980 * @len: the length of the string or -1 4981 * 4982 * Check if a string is ignorable 4983 * 4984 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise 4985 */ 4986 static int 4987 xmlSchemaIsBlank(xmlChar * str, int len) 4988 { 4989 if (str == NULL) 4990 return (1); 4991 if (len < 0) { 4992 while (*str != 0) { 4993 if (!(IS_BLANK_CH(*str))) 4994 return (0); 4995 str++; 4996 } 4997 } else while ((*str != 0) && (len != 0)) { 4998 if (!(IS_BLANK_CH(*str))) 4999 return (0); 5000 str++; 5001 len--; 5002 } 5003 5004 return (1); 5005 } 5006 5007 #define WXS_COMP_NAME(c, t) ((t) (c))->name 5008 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace 5009 /* 5010 * xmlSchemaFindRedefCompInGraph: 5011 * ATTENTION TODO: This uses pointer comp. for strings. 5012 */ 5013 static xmlSchemaBasicItemPtr 5014 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket, 5015 xmlSchemaTypeType type, 5016 const xmlChar *name, 5017 const xmlChar *nsName) 5018 { 5019 xmlSchemaBasicItemPtr ret; 5020 int i; 5021 5022 if ((bucket == NULL) || (name == NULL)) 5023 return(NULL); 5024 if ((bucket->globals == NULL) || 5025 (bucket->globals->nbItems == 0)) 5026 goto subschemas; 5027 /* 5028 * Search in global components. 5029 */ 5030 for (i = 0; i < bucket->globals->nbItems; i++) { 5031 ret = bucket->globals->items[i]; 5032 if (ret->type == type) { 5033 switch (type) { 5034 case XML_SCHEMA_TYPE_COMPLEX: 5035 case XML_SCHEMA_TYPE_SIMPLE: 5036 if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) && 5037 (WXS_COMP_TNS(ret, xmlSchemaTypePtr) == 5038 nsName)) 5039 { 5040 return(ret); 5041 } 5042 break; 5043 case XML_SCHEMA_TYPE_GROUP: 5044 if ((WXS_COMP_NAME(ret, 5045 xmlSchemaModelGroupDefPtr) == name) && 5046 (WXS_COMP_TNS(ret, 5047 xmlSchemaModelGroupDefPtr) == nsName)) 5048 { 5049 return(ret); 5050 } 5051 break; 5052 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 5053 if ((WXS_COMP_NAME(ret, 5054 xmlSchemaAttributeGroupPtr) == name) && 5055 (WXS_COMP_TNS(ret, 5056 xmlSchemaAttributeGroupPtr) == nsName)) 5057 { 5058 return(ret); 5059 } 5060 break; 5061 default: 5062 /* Should not be hit. */ 5063 return(NULL); 5064 } 5065 } 5066 } 5067 subschemas: 5068 /* 5069 * Process imported/included schemas. 5070 */ 5071 if (bucket->relations != NULL) { 5072 xmlSchemaSchemaRelationPtr rel = bucket->relations; 5073 5074 /* 5075 * TODO: Marking the bucket will not avoid multiple searches 5076 * in the same schema, but avoids at least circularity. 5077 */ 5078 bucket->flags |= XML_SCHEMA_BUCKET_MARKED; 5079 do { 5080 if ((rel->bucket != NULL) && 5081 ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) { 5082 ret = xmlSchemaFindRedefCompInGraph(rel->bucket, 5083 type, name, nsName); 5084 if (ret != NULL) 5085 return(ret); 5086 } 5087 rel = rel->next; 5088 } while (rel != NULL); 5089 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED; 5090 } 5091 return(NULL); 5092 } 5093 5094 /** 5095 * xmlSchemaAddNotation: 5096 * @ctxt: a schema parser context 5097 * @schema: the schema being built 5098 * @name: the item name 5099 * 5100 * Add an XML schema annotation declaration 5101 * *WARNING* this interface is highly subject to change 5102 * 5103 * Returns the new struture or NULL in case of error 5104 */ 5105 static xmlSchemaNotationPtr 5106 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5107 const xmlChar *name, const xmlChar *nsName, 5108 xmlNodePtr node ATTRIBUTE_UNUSED) 5109 { 5110 xmlSchemaNotationPtr ret = NULL; 5111 5112 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5113 return (NULL); 5114 5115 ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation)); 5116 if (ret == NULL) { 5117 xmlSchemaPErrMemory(ctxt, "add annotation", NULL); 5118 return (NULL); 5119 } 5120 memset(ret, 0, sizeof(xmlSchemaNotation)); 5121 ret->type = XML_SCHEMA_TYPE_NOTATION; 5122 ret->name = name; 5123 ret->targetNamespace = nsName; 5124 /* TODO: do we need the node to be set? 5125 * ret->node = node;*/ 5126 WXS_ADD_GLOBAL(ctxt, ret); 5127 return (ret); 5128 } 5129 5130 /** 5131 * xmlSchemaAddAttribute: 5132 * @ctxt: a schema parser context 5133 * @schema: the schema being built 5134 * @name: the item name 5135 * @namespace: the namespace 5136 * 5137 * Add an XML schema Attrribute declaration 5138 * *WARNING* this interface is highly subject to change 5139 * 5140 * Returns the new struture or NULL in case of error 5141 */ 5142 static xmlSchemaAttributePtr 5143 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5144 const xmlChar * name, const xmlChar * nsName, 5145 xmlNodePtr node, int topLevel) 5146 { 5147 xmlSchemaAttributePtr ret = NULL; 5148 5149 if ((ctxt == NULL) || (schema == NULL)) 5150 return (NULL); 5151 5152 ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute)); 5153 if (ret == NULL) { 5154 xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL); 5155 return (NULL); 5156 } 5157 memset(ret, 0, sizeof(xmlSchemaAttribute)); 5158 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE; 5159 ret->node = node; 5160 ret->name = name; 5161 ret->targetNamespace = nsName; 5162 5163 if (topLevel) 5164 WXS_ADD_GLOBAL(ctxt, ret); 5165 else 5166 WXS_ADD_LOCAL(ctxt, ret); 5167 WXS_ADD_PENDING(ctxt, ret); 5168 return (ret); 5169 } 5170 5171 /** 5172 * xmlSchemaAddAttributeUse: 5173 * @ctxt: a schema parser context 5174 * @schema: the schema being built 5175 * @name: the item name 5176 * @namespace: the namespace 5177 * 5178 * Add an XML schema Attrribute declaration 5179 * *WARNING* this interface is highly subject to change 5180 * 5181 * Returns the new struture or NULL in case of error 5182 */ 5183 static xmlSchemaAttributeUsePtr 5184 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt, 5185 xmlNodePtr node) 5186 { 5187 xmlSchemaAttributeUsePtr ret = NULL; 5188 5189 if (pctxt == NULL) 5190 return (NULL); 5191 5192 ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse)); 5193 if (ret == NULL) { 5194 xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL); 5195 return (NULL); 5196 } 5197 memset(ret, 0, sizeof(xmlSchemaAttributeUse)); 5198 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE; 5199 ret->node = node; 5200 5201 WXS_ADD_LOCAL(pctxt, ret); 5202 return (ret); 5203 } 5204 5205 /* 5206 * xmlSchemaAddRedef: 5207 * 5208 * Adds a redefinition information. This is used at a later stage to: 5209 * resolve references to the redefined components and to check constraints. 5210 */ 5211 static xmlSchemaRedefPtr 5212 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt, 5213 xmlSchemaBucketPtr targetBucket, 5214 void *item, 5215 const xmlChar *refName, 5216 const xmlChar *refTargetNs) 5217 { 5218 xmlSchemaRedefPtr ret; 5219 5220 ret = (xmlSchemaRedefPtr) 5221 xmlMalloc(sizeof(xmlSchemaRedef)); 5222 if (ret == NULL) { 5223 xmlSchemaPErrMemory(pctxt, 5224 "allocating redefinition info", NULL); 5225 return (NULL); 5226 } 5227 memset(ret, 0, sizeof(xmlSchemaRedef)); 5228 ret->item = item; 5229 ret->targetBucket = targetBucket; 5230 ret->refName = refName; 5231 ret->refTargetNs = refTargetNs; 5232 if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL) 5233 WXS_CONSTRUCTOR(pctxt)->redefs = ret; 5234 else 5235 WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret; 5236 WXS_CONSTRUCTOR(pctxt)->lastRedef = ret; 5237 5238 return (ret); 5239 } 5240 5241 /** 5242 * xmlSchemaAddAttributeGroupDefinition: 5243 * @ctxt: a schema parser context 5244 * @schema: the schema being built 5245 * @name: the item name 5246 * @nsName: the target namespace 5247 * @node: the corresponding node 5248 * 5249 * Add an XML schema Attrribute Group definition. 5250 * 5251 * Returns the new struture or NULL in case of error 5252 */ 5253 static xmlSchemaAttributeGroupPtr 5254 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 5255 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 5256 const xmlChar *name, 5257 const xmlChar *nsName, 5258 xmlNodePtr node) 5259 { 5260 xmlSchemaAttributeGroupPtr ret = NULL; 5261 5262 if ((pctxt == NULL) || (name == NULL)) 5263 return (NULL); 5264 5265 ret = (xmlSchemaAttributeGroupPtr) 5266 xmlMalloc(sizeof(xmlSchemaAttributeGroup)); 5267 if (ret == NULL) { 5268 xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL); 5269 return (NULL); 5270 } 5271 memset(ret, 0, sizeof(xmlSchemaAttributeGroup)); 5272 ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP; 5273 ret->name = name; 5274 ret->targetNamespace = nsName; 5275 ret->node = node; 5276 5277 /* TODO: Remove the flag. */ 5278 ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL; 5279 if (pctxt->isRedefine) { 5280 pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined, 5281 ret, name, nsName); 5282 if (pctxt->redef == NULL) { 5283 xmlFree(ret); 5284 return(NULL); 5285 } 5286 pctxt->redefCounter = 0; 5287 } 5288 WXS_ADD_GLOBAL(pctxt, ret); 5289 WXS_ADD_PENDING(pctxt, ret); 5290 return (ret); 5291 } 5292 5293 /** 5294 * xmlSchemaAddElement: 5295 * @ctxt: a schema parser context 5296 * @schema: the schema being built 5297 * @name: the type name 5298 * @namespace: the type namespace 5299 * 5300 * Add an XML schema Element declaration 5301 * *WARNING* this interface is highly subject to change 5302 * 5303 * Returns the new struture or NULL in case of error 5304 */ 5305 static xmlSchemaElementPtr 5306 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, 5307 const xmlChar * name, const xmlChar * nsName, 5308 xmlNodePtr node, int topLevel) 5309 { 5310 xmlSchemaElementPtr ret = NULL; 5311 5312 if ((ctxt == NULL) || (name == NULL)) 5313 return (NULL); 5314 5315 ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement)); 5316 if (ret == NULL) { 5317 xmlSchemaPErrMemory(ctxt, "allocating element", NULL); 5318 return (NULL); 5319 } 5320 memset(ret, 0, sizeof(xmlSchemaElement)); 5321 ret->type = XML_SCHEMA_TYPE_ELEMENT; 5322 ret->name = name; 5323 ret->targetNamespace = nsName; 5324 ret->node = node; 5325 5326 if (topLevel) 5327 WXS_ADD_GLOBAL(ctxt, ret); 5328 else 5329 WXS_ADD_LOCAL(ctxt, ret); 5330 WXS_ADD_PENDING(ctxt, ret); 5331 return (ret); 5332 } 5333 5334 /** 5335 * xmlSchemaAddType: 5336 * @ctxt: a schema parser context 5337 * @schema: the schema being built 5338 * @name: the item name 5339 * @namespace: the namespace 5340 * 5341 * Add an XML schema item 5342 * *WARNING* this interface is highly subject to change 5343 * 5344 * Returns the new struture or NULL in case of error 5345 */ 5346 static xmlSchemaTypePtr 5347 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5348 xmlSchemaTypeType type, 5349 const xmlChar * name, const xmlChar * nsName, 5350 xmlNodePtr node, int topLevel) 5351 { 5352 xmlSchemaTypePtr ret = NULL; 5353 5354 if ((ctxt == NULL) || (schema == NULL)) 5355 return (NULL); 5356 5357 ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType)); 5358 if (ret == NULL) { 5359 xmlSchemaPErrMemory(ctxt, "allocating type", NULL); 5360 return (NULL); 5361 } 5362 memset(ret, 0, sizeof(xmlSchemaType)); 5363 ret->type = type; 5364 ret->name = name; 5365 ret->targetNamespace = nsName; 5366 ret->node = node; 5367 if (topLevel) { 5368 if (ctxt->isRedefine) { 5369 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5370 ret, name, nsName); 5371 if (ctxt->redef == NULL) { 5372 xmlFree(ret); 5373 return(NULL); 5374 } 5375 ctxt->redefCounter = 0; 5376 } 5377 WXS_ADD_GLOBAL(ctxt, ret); 5378 } else 5379 WXS_ADD_LOCAL(ctxt, ret); 5380 WXS_ADD_PENDING(ctxt, ret); 5381 return (ret); 5382 } 5383 5384 static xmlSchemaQNameRefPtr 5385 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt, 5386 xmlSchemaTypeType refType, 5387 const xmlChar *refName, 5388 const xmlChar *refNs) 5389 { 5390 xmlSchemaQNameRefPtr ret; 5391 5392 ret = (xmlSchemaQNameRefPtr) 5393 xmlMalloc(sizeof(xmlSchemaQNameRef)); 5394 if (ret == NULL) { 5395 xmlSchemaPErrMemory(pctxt, 5396 "allocating QName reference item", NULL); 5397 return (NULL); 5398 } 5399 ret->node = NULL; 5400 ret->type = XML_SCHEMA_EXTRA_QNAMEREF; 5401 ret->name = refName; 5402 ret->targetNamespace = refNs; 5403 ret->item = NULL; 5404 ret->itemType = refType; 5405 /* 5406 * Store the reference item in the schema. 5407 */ 5408 WXS_ADD_LOCAL(pctxt, ret); 5409 return (ret); 5410 } 5411 5412 static xmlSchemaAttributeUseProhibPtr 5413 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt) 5414 { 5415 xmlSchemaAttributeUseProhibPtr ret; 5416 5417 ret = (xmlSchemaAttributeUseProhibPtr) 5418 xmlMalloc(sizeof(xmlSchemaAttributeUseProhib)); 5419 if (ret == NULL) { 5420 xmlSchemaPErrMemory(pctxt, 5421 "allocating attribute use prohibition", NULL); 5422 return (NULL); 5423 } 5424 memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib)); 5425 ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB; 5426 WXS_ADD_LOCAL(pctxt, ret); 5427 return (ret); 5428 } 5429 5430 5431 /** 5432 * xmlSchemaAddModelGroup: 5433 * @ctxt: a schema parser context 5434 * @schema: the schema being built 5435 * @type: the "compositor" type of the model group 5436 * @node: the node in the schema doc 5437 * 5438 * Adds a schema model group 5439 * *WARNING* this interface is highly subject to change 5440 * 5441 * Returns the new struture or NULL in case of error 5442 */ 5443 static xmlSchemaModelGroupPtr 5444 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt, 5445 xmlSchemaPtr schema, 5446 xmlSchemaTypeType type, 5447 xmlNodePtr node) 5448 { 5449 xmlSchemaModelGroupPtr ret = NULL; 5450 5451 if ((ctxt == NULL) || (schema == NULL)) 5452 return (NULL); 5453 5454 ret = (xmlSchemaModelGroupPtr) 5455 xmlMalloc(sizeof(xmlSchemaModelGroup)); 5456 if (ret == NULL) { 5457 xmlSchemaPErrMemory(ctxt, "allocating model group component", 5458 NULL); 5459 return (NULL); 5460 } 5461 memset(ret, 0, sizeof(xmlSchemaModelGroup)); 5462 ret->type = type; 5463 ret->node = node; 5464 WXS_ADD_LOCAL(ctxt, ret); 5465 if ((type == XML_SCHEMA_TYPE_SEQUENCE) || 5466 (type == XML_SCHEMA_TYPE_CHOICE)) 5467 WXS_ADD_PENDING(ctxt, ret); 5468 return (ret); 5469 } 5470 5471 5472 /** 5473 * xmlSchemaAddParticle: 5474 * @ctxt: a schema parser context 5475 * @schema: the schema being built 5476 * @node: the corresponding node in the schema doc 5477 * @min: the minOccurs 5478 * @max: the maxOccurs 5479 * 5480 * Adds an XML schema particle component. 5481 * *WARNING* this interface is highly subject to change 5482 * 5483 * Returns the new struture or NULL in case of error 5484 */ 5485 static xmlSchemaParticlePtr 5486 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt, 5487 xmlNodePtr node, int min, int max) 5488 { 5489 xmlSchemaParticlePtr ret = NULL; 5490 if (ctxt == NULL) 5491 return (NULL); 5492 5493 #ifdef DEBUG 5494 fprintf(stderr, "Adding particle component\n"); 5495 #endif 5496 ret = (xmlSchemaParticlePtr) 5497 xmlMalloc(sizeof(xmlSchemaParticle)); 5498 if (ret == NULL) { 5499 xmlSchemaPErrMemory(ctxt, "allocating particle component", 5500 NULL); 5501 return (NULL); 5502 } 5503 ret->type = XML_SCHEMA_TYPE_PARTICLE; 5504 ret->annot = NULL; 5505 ret->node = node; 5506 ret->minOccurs = min; 5507 ret->maxOccurs = max; 5508 ret->next = NULL; 5509 ret->children = NULL; 5510 5511 WXS_ADD_LOCAL(ctxt, ret); 5512 /* 5513 * Note that addition to pending components will be done locally 5514 * to the specific parsing function, since the most particles 5515 * need not to be fixed up (i.e. the reference to be resolved). 5516 * REMOVED: WXS_ADD_PENDING(ctxt, ret); 5517 */ 5518 return (ret); 5519 } 5520 5521 /** 5522 * xmlSchemaAddModelGroupDefinition: 5523 * @ctxt: a schema validation context 5524 * @schema: the schema being built 5525 * @name: the group name 5526 * 5527 * Add an XML schema Group definition 5528 * 5529 * Returns the new struture or NULL in case of error 5530 */ 5531 static xmlSchemaModelGroupDefPtr 5532 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 5533 xmlSchemaPtr schema, 5534 const xmlChar *name, 5535 const xmlChar *nsName, 5536 xmlNodePtr node) 5537 { 5538 xmlSchemaModelGroupDefPtr ret = NULL; 5539 5540 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5541 return (NULL); 5542 5543 ret = (xmlSchemaModelGroupDefPtr) 5544 xmlMalloc(sizeof(xmlSchemaModelGroupDef)); 5545 if (ret == NULL) { 5546 xmlSchemaPErrMemory(ctxt, "adding group", NULL); 5547 return (NULL); 5548 } 5549 memset(ret, 0, sizeof(xmlSchemaModelGroupDef)); 5550 ret->name = name; 5551 ret->type = XML_SCHEMA_TYPE_GROUP; 5552 ret->node = node; 5553 ret->targetNamespace = nsName; 5554 5555 if (ctxt->isRedefine) { 5556 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5557 ret, name, nsName); 5558 if (ctxt->redef == NULL) { 5559 xmlFree(ret); 5560 return(NULL); 5561 } 5562 ctxt->redefCounter = 0; 5563 } 5564 WXS_ADD_GLOBAL(ctxt, ret); 5565 WXS_ADD_PENDING(ctxt, ret); 5566 return (ret); 5567 } 5568 5569 /** 5570 * xmlSchemaNewWildcardNs: 5571 * @ctxt: a schema validation context 5572 * 5573 * Creates a new wildcard namespace constraint. 5574 * 5575 * Returns the new struture or NULL in case of error 5576 */ 5577 static xmlSchemaWildcardNsPtr 5578 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt) 5579 { 5580 xmlSchemaWildcardNsPtr ret; 5581 5582 ret = (xmlSchemaWildcardNsPtr) 5583 xmlMalloc(sizeof(xmlSchemaWildcardNs)); 5584 if (ret == NULL) { 5585 xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL); 5586 return (NULL); 5587 } 5588 ret->value = NULL; 5589 ret->next = NULL; 5590 return (ret); 5591 } 5592 5593 static xmlSchemaIDCPtr 5594 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5595 const xmlChar *name, const xmlChar *nsName, 5596 int category, xmlNodePtr node) 5597 { 5598 xmlSchemaIDCPtr ret = NULL; 5599 5600 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5601 return (NULL); 5602 5603 ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC)); 5604 if (ret == NULL) { 5605 xmlSchemaPErrMemory(ctxt, 5606 "allocating an identity-constraint definition", NULL); 5607 return (NULL); 5608 } 5609 memset(ret, 0, sizeof(xmlSchemaIDC)); 5610 /* The target namespace of the parent element declaration. */ 5611 ret->targetNamespace = nsName; 5612 ret->name = name; 5613 ret->type = category; 5614 ret->node = node; 5615 5616 WXS_ADD_GLOBAL(ctxt, ret); 5617 /* 5618 * Only keyrefs need to be fixup up. 5619 */ 5620 if (category == XML_SCHEMA_TYPE_IDC_KEYREF) 5621 WXS_ADD_PENDING(ctxt, ret); 5622 return (ret); 5623 } 5624 5625 /** 5626 * xmlSchemaAddWildcard: 5627 * @ctxt: a schema validation context 5628 * @schema: a schema 5629 * 5630 * Adds a wildcard. 5631 * It corresponds to a xsd:anyAttribute and xsd:any. 5632 * 5633 * Returns the new struture or NULL in case of error 5634 */ 5635 static xmlSchemaWildcardPtr 5636 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5637 xmlSchemaTypeType type, xmlNodePtr node) 5638 { 5639 xmlSchemaWildcardPtr ret = NULL; 5640 5641 if ((ctxt == NULL) || (schema == NULL)) 5642 return (NULL); 5643 5644 ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard)); 5645 if (ret == NULL) { 5646 xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL); 5647 return (NULL); 5648 } 5649 memset(ret, 0, sizeof(xmlSchemaWildcard)); 5650 ret->type = type; 5651 ret->node = node; 5652 WXS_ADD_LOCAL(ctxt, ret); 5653 return (ret); 5654 } 5655 5656 static void 5657 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group) 5658 { 5659 if (group == NULL) 5660 return; 5661 if (group->members != NULL) 5662 xmlSchemaItemListFree(group->members); 5663 xmlFree(group); 5664 } 5665 5666 static xmlSchemaSubstGroupPtr 5667 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt, 5668 xmlSchemaElementPtr head) 5669 { 5670 xmlSchemaSubstGroupPtr ret; 5671 5672 /* Init subst group hash. */ 5673 if (WXS_SUBST_GROUPS(pctxt) == NULL) { 5674 WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict); 5675 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5676 return(NULL); 5677 } 5678 /* Create a new substitution group. */ 5679 ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup)); 5680 if (ret == NULL) { 5681 xmlSchemaPErrMemory(NULL, 5682 "allocating a substitution group container", NULL); 5683 return(NULL); 5684 } 5685 memset(ret, 0, sizeof(xmlSchemaSubstGroup)); 5686 ret->head = head; 5687 /* Create list of members. */ 5688 ret->members = xmlSchemaItemListCreate(); 5689 if (ret->members == NULL) { 5690 xmlSchemaSubstGroupFree(ret); 5691 return(NULL); 5692 } 5693 /* Add subst group to hash. */ 5694 if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt), 5695 head->name, head->targetNamespace, ret) != 0) { 5696 PERROR_INT("xmlSchemaSubstGroupAdd", 5697 "failed to add a new substitution container"); 5698 xmlSchemaSubstGroupFree(ret); 5699 return(NULL); 5700 } 5701 return(ret); 5702 } 5703 5704 static xmlSchemaSubstGroupPtr 5705 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt, 5706 xmlSchemaElementPtr head) 5707 { 5708 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5709 return(NULL); 5710 return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt), 5711 head->name, head->targetNamespace)); 5712 5713 } 5714 5715 /** 5716 * xmlSchemaAddElementSubstitutionMember: 5717 * @pctxt: a schema parser context 5718 * @head: the head of the substitution group 5719 * @member: the new member of the substitution group 5720 * 5721 * Allocate a new annotation structure. 5722 * 5723 * Returns the newly allocated structure or NULL in case or error 5724 */ 5725 static int 5726 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt, 5727 xmlSchemaElementPtr head, 5728 xmlSchemaElementPtr member) 5729 { 5730 xmlSchemaSubstGroupPtr substGroup = NULL; 5731 5732 if ((pctxt == NULL) || (head == NULL) || (member == NULL)) 5733 return (-1); 5734 5735 substGroup = xmlSchemaSubstGroupGet(pctxt, head); 5736 if (substGroup == NULL) 5737 substGroup = xmlSchemaSubstGroupAdd(pctxt, head); 5738 if (substGroup == NULL) 5739 return(-1); 5740 if (xmlSchemaItemListAdd(substGroup->members, member) == -1) 5741 return(-1); 5742 return(0); 5743 } 5744 5745 /************************************************************************ 5746 * * 5747 * Utilities for parsing * 5748 * * 5749 ************************************************************************/ 5750 5751 /** 5752 * xmlSchemaPValAttrNodeQNameValue: 5753 * @ctxt: a schema parser context 5754 * @schema: the schema context 5755 * @ownerDes: the designation of the parent element 5756 * @ownerItem: the parent as a schema object 5757 * @value: the QName value 5758 * @local: the resulting local part if found, the attribute value otherwise 5759 * @uri: the resulting namespace URI if found 5760 * 5761 * Extracts the local name and the URI of a QName value and validates it. 5762 * This one is intended to be used on attribute values that 5763 * should resolve to schema components. 5764 * 5765 * Returns 0, in case the QName is valid, a positive error code 5766 * if not valid and -1 if an internal error occurs. 5767 */ 5768 static int 5769 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt, 5770 xmlSchemaPtr schema, 5771 xmlSchemaBasicItemPtr ownerItem, 5772 xmlAttrPtr attr, 5773 const xmlChar *value, 5774 const xmlChar **uri, 5775 const xmlChar **local) 5776 { 5777 const xmlChar *pref; 5778 xmlNsPtr ns; 5779 int len, ret; 5780 5781 *uri = NULL; 5782 *local = NULL; 5783 ret = xmlValidateQName(value, 1); 5784 if (ret > 0) { 5785 xmlSchemaPSimpleTypeErr(ctxt, 5786 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5787 ownerItem, (xmlNodePtr) attr, 5788 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 5789 NULL, value, NULL, NULL, NULL); 5790 *local = value; 5791 return (ctxt->err); 5792 } else if (ret < 0) 5793 return (-1); 5794 5795 if (!strchr((char *) value, ':')) { 5796 ns = xmlSearchNs(attr->doc, attr->parent, NULL); 5797 if (ns) 5798 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5799 else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) { 5800 /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the 5801 * parser context. */ 5802 /* 5803 * This one takes care of included schemas with no 5804 * target namespace. 5805 */ 5806 *uri = ctxt->targetNamespace; 5807 } 5808 *local = xmlDictLookup(ctxt->dict, value, -1); 5809 return (0); 5810 } 5811 /* 5812 * At this point xmlSplitQName3 has to return a local name. 5813 */ 5814 *local = xmlSplitQName3(value, &len); 5815 *local = xmlDictLookup(ctxt->dict, *local, -1); 5816 pref = xmlDictLookup(ctxt->dict, value, len); 5817 ns = xmlSearchNs(attr->doc, attr->parent, pref); 5818 if (ns == NULL) { 5819 xmlSchemaPSimpleTypeErr(ctxt, 5820 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5821 ownerItem, (xmlNodePtr) attr, 5822 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value, 5823 "The value '%s' of simple type 'xs:QName' has no " 5824 "corresponding namespace declaration in scope", value, NULL); 5825 return (ctxt->err); 5826 } else { 5827 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5828 } 5829 return (0); 5830 } 5831 5832 /** 5833 * xmlSchemaPValAttrNodeQName: 5834 * @ctxt: a schema parser context 5835 * @schema: the schema context 5836 * @ownerDes: the designation of the owner element 5837 * @ownerItem: the owner as a schema object 5838 * @attr: the attribute node 5839 * @local: the resulting local part if found, the attribute value otherwise 5840 * @uri: the resulting namespace URI if found 5841 * 5842 * Extracts and validates the QName of an attribute value. 5843 * This one is intended to be used on attribute values that 5844 * should resolve to schema components. 5845 * 5846 * Returns 0, in case the QName is valid, a positive error code 5847 * if not valid and -1 if an internal error occurs. 5848 */ 5849 static int 5850 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt, 5851 xmlSchemaPtr schema, 5852 xmlSchemaBasicItemPtr ownerItem, 5853 xmlAttrPtr attr, 5854 const xmlChar **uri, 5855 const xmlChar **local) 5856 { 5857 const xmlChar *value; 5858 5859 value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 5860 return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 5861 ownerItem, attr, value, uri, local)); 5862 } 5863 5864 /** 5865 * xmlSchemaPValAttrQName: 5866 * @ctxt: a schema parser context 5867 * @schema: the schema context 5868 * @ownerDes: the designation of the parent element 5869 * @ownerItem: the owner as a schema object 5870 * @ownerElem: the parent node of the attribute 5871 * @name: the name of the attribute 5872 * @local: the resulting local part if found, the attribute value otherwise 5873 * @uri: the resulting namespace URI if found 5874 * 5875 * Extracts and validates the QName of an attribute value. 5876 * 5877 * Returns 0, in case the QName is valid, a positive error code 5878 * if not valid and -1 if an internal error occurs. 5879 */ 5880 static int 5881 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt, 5882 xmlSchemaPtr schema, 5883 xmlSchemaBasicItemPtr ownerItem, 5884 xmlNodePtr ownerElem, 5885 const char *name, 5886 const xmlChar **uri, 5887 const xmlChar **local) 5888 { 5889 xmlAttrPtr attr; 5890 5891 attr = xmlSchemaGetPropNode(ownerElem, name); 5892 if (attr == NULL) { 5893 *local = NULL; 5894 *uri = NULL; 5895 return (0); 5896 } 5897 return (xmlSchemaPValAttrNodeQName(ctxt, schema, 5898 ownerItem, attr, uri, local)); 5899 } 5900 5901 /** 5902 * xmlSchemaPValAttrID: 5903 * @ctxt: a schema parser context 5904 * @schema: the schema context 5905 * @ownerDes: the designation of the parent element 5906 * @ownerItem: the owner as a schema object 5907 * @ownerElem: the parent node of the attribute 5908 * @name: the name of the attribute 5909 * 5910 * Extracts and validates the ID of an attribute value. 5911 * 5912 * Returns 0, in case the ID is valid, a positive error code 5913 * if not valid and -1 if an internal error occurs. 5914 */ 5915 static int 5916 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr) 5917 { 5918 int ret; 5919 const xmlChar *value; 5920 5921 if (attr == NULL) 5922 return(0); 5923 value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr); 5924 ret = xmlValidateNCName(value, 1); 5925 if (ret == 0) { 5926 /* 5927 * NOTE: the IDness might have already be declared in the DTD 5928 */ 5929 if (attr->atype != XML_ATTRIBUTE_ID) { 5930 xmlIDPtr res; 5931 xmlChar *strip; 5932 5933 /* 5934 * TODO: Use xmlSchemaStrip here; it's not exported at this 5935 * moment. 5936 */ 5937 strip = xmlSchemaCollapseString(value); 5938 if (strip != NULL) { 5939 xmlFree((xmlChar *) value); 5940 value = strip; 5941 } 5942 res = xmlAddID(NULL, attr->doc, value, attr); 5943 if (res == NULL) { 5944 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 5945 xmlSchemaPSimpleTypeErr(ctxt, 5946 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5947 NULL, (xmlNodePtr) attr, 5948 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 5949 NULL, NULL, "Duplicate value '%s' of simple " 5950 "type 'xs:ID'", value, NULL); 5951 } else 5952 attr->atype = XML_ATTRIBUTE_ID; 5953 } 5954 } else if (ret > 0) { 5955 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 5956 xmlSchemaPSimpleTypeErr(ctxt, 5957 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5958 NULL, (xmlNodePtr) attr, 5959 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 5960 NULL, NULL, "The value '%s' of simple type 'xs:ID' is " 5961 "not a valid 'xs:NCName'", 5962 value, NULL); 5963 } 5964 if (value != NULL) 5965 xmlFree((xmlChar *)value); 5966 5967 return (ret); 5968 } 5969 5970 static int 5971 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt, 5972 xmlNodePtr ownerElem, 5973 const xmlChar *name) 5974 { 5975 xmlAttrPtr attr; 5976 5977 attr = xmlSchemaGetPropNode(ownerElem, (const char *) name); 5978 if (attr == NULL) 5979 return(0); 5980 return(xmlSchemaPValAttrNodeID(ctxt, attr)); 5981 5982 } 5983 5984 /** 5985 * xmlGetMaxOccurs: 5986 * @ctxt: a schema validation context 5987 * @node: a subtree containing XML Schema informations 5988 * 5989 * Get the maxOccurs property 5990 * 5991 * Returns the default if not found, or the value 5992 */ 5993 static int 5994 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 5995 int min, int max, int def, const char *expected) 5996 { 5997 const xmlChar *val, *cur; 5998 int ret = 0; 5999 xmlAttrPtr attr; 6000 6001 attr = xmlSchemaGetPropNode(node, "maxOccurs"); 6002 if (attr == NULL) 6003 return (def); 6004 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6005 6006 if (xmlStrEqual(val, (const xmlChar *) "unbounded")) { 6007 if (max != UNBOUNDED) { 6008 xmlSchemaPSimpleTypeErr(ctxt, 6009 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6010 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6011 NULL, (xmlNodePtr) attr, NULL, expected, 6012 val, NULL, NULL, NULL); 6013 return (def); 6014 } else 6015 return (UNBOUNDED); /* encoding it with -1 might be another option */ 6016 } 6017 6018 cur = val; 6019 while (IS_BLANK_CH(*cur)) 6020 cur++; 6021 if (*cur == 0) { 6022 xmlSchemaPSimpleTypeErr(ctxt, 6023 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6024 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6025 NULL, (xmlNodePtr) attr, NULL, expected, 6026 val, NULL, NULL, NULL); 6027 return (def); 6028 } 6029 while ((*cur >= '0') && (*cur <= '9')) { 6030 ret = ret * 10 + (*cur - '0'); 6031 cur++; 6032 } 6033 while (IS_BLANK_CH(*cur)) 6034 cur++; 6035 /* 6036 * TODO: Restrict the maximal value to Integer. 6037 */ 6038 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6039 xmlSchemaPSimpleTypeErr(ctxt, 6040 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6041 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6042 NULL, (xmlNodePtr) attr, NULL, expected, 6043 val, NULL, NULL, NULL); 6044 return (def); 6045 } 6046 return (ret); 6047 } 6048 6049 /** 6050 * xmlGetMinOccurs: 6051 * @ctxt: a schema validation context 6052 * @node: a subtree containing XML Schema informations 6053 * 6054 * Get the minOccurs property 6055 * 6056 * Returns the default if not found, or the value 6057 */ 6058 static int 6059 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 6060 int min, int max, int def, const char *expected) 6061 { 6062 const xmlChar *val, *cur; 6063 int ret = 0; 6064 xmlAttrPtr attr; 6065 6066 attr = xmlSchemaGetPropNode(node, "minOccurs"); 6067 if (attr == NULL) 6068 return (def); 6069 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6070 cur = val; 6071 while (IS_BLANK_CH(*cur)) 6072 cur++; 6073 if (*cur == 0) { 6074 xmlSchemaPSimpleTypeErr(ctxt, 6075 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6076 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6077 NULL, (xmlNodePtr) attr, NULL, expected, 6078 val, NULL, NULL, NULL); 6079 return (def); 6080 } 6081 while ((*cur >= '0') && (*cur <= '9')) { 6082 ret = ret * 10 + (*cur - '0'); 6083 cur++; 6084 } 6085 while (IS_BLANK_CH(*cur)) 6086 cur++; 6087 /* 6088 * TODO: Restrict the maximal value to Integer. 6089 */ 6090 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6091 xmlSchemaPSimpleTypeErr(ctxt, 6092 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6093 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6094 NULL, (xmlNodePtr) attr, NULL, expected, 6095 val, NULL, NULL, NULL); 6096 return (def); 6097 } 6098 return (ret); 6099 } 6100 6101 /** 6102 * xmlSchemaPGetBoolNodeValue: 6103 * @ctxt: a schema validation context 6104 * @ownerDes: owner designation 6105 * @ownerItem: the owner as a schema item 6106 * @node: the node holding the value 6107 * 6108 * Converts a boolean string value into 1 or 0. 6109 * 6110 * Returns 0 or 1. 6111 */ 6112 static int 6113 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt, 6114 xmlSchemaBasicItemPtr ownerItem, 6115 xmlNodePtr node) 6116 { 6117 xmlChar *value = NULL; 6118 int res = 0; 6119 6120 value = xmlNodeGetContent(node); 6121 /* 6122 * 3.2.2.1 Lexical representation 6123 * An instance of a datatype that is defined as boolean 6124 * can have the following legal literals {true, false, 1, 0}. 6125 */ 6126 if (xmlStrEqual(BAD_CAST value, BAD_CAST "true")) 6127 res = 1; 6128 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false")) 6129 res = 0; 6130 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1")) 6131 res = 1; 6132 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0")) 6133 res = 0; 6134 else { 6135 xmlSchemaPSimpleTypeErr(ctxt, 6136 XML_SCHEMAP_INVALID_BOOLEAN, 6137 ownerItem, node, 6138 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6139 NULL, BAD_CAST value, 6140 NULL, NULL, NULL); 6141 } 6142 if (value != NULL) 6143 xmlFree(value); 6144 return (res); 6145 } 6146 6147 /** 6148 * xmlGetBooleanProp: 6149 * @ctxt: a schema validation context 6150 * @node: a subtree containing XML Schema informations 6151 * @name: the attribute name 6152 * @def: the default value 6153 * 6154 * Evaluate if a boolean property is set 6155 * 6156 * Returns the default if not found, 0 if found to be false, 6157 * 1 if found to be true 6158 */ 6159 static int 6160 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, 6161 xmlNodePtr node, 6162 const char *name, int def) 6163 { 6164 const xmlChar *val; 6165 6166 val = xmlSchemaGetProp(ctxt, node, name); 6167 if (val == NULL) 6168 return (def); 6169 /* 6170 * 3.2.2.1 Lexical representation 6171 * An instance of a datatype that is defined as boolean 6172 * can have the following legal literals {true, false, 1, 0}. 6173 */ 6174 if (xmlStrEqual(val, BAD_CAST "true")) 6175 def = 1; 6176 else if (xmlStrEqual(val, BAD_CAST "false")) 6177 def = 0; 6178 else if (xmlStrEqual(val, BAD_CAST "1")) 6179 def = 1; 6180 else if (xmlStrEqual(val, BAD_CAST "0")) 6181 def = 0; 6182 else { 6183 xmlSchemaPSimpleTypeErr(ctxt, 6184 XML_SCHEMAP_INVALID_BOOLEAN, 6185 NULL, 6186 (xmlNodePtr) xmlSchemaGetPropNode(node, name), 6187 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6188 NULL, val, NULL, NULL, NULL); 6189 } 6190 return (def); 6191 } 6192 6193 /************************************************************************ 6194 * * 6195 * Shema extraction from an Infoset * 6196 * * 6197 ************************************************************************/ 6198 static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr 6199 ctxt, xmlSchemaPtr schema, 6200 xmlNodePtr node, 6201 int topLevel); 6202 static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr 6203 ctxt, 6204 xmlSchemaPtr schema, 6205 xmlNodePtr node, 6206 int topLevel); 6207 static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr 6208 ctxt, 6209 xmlSchemaPtr schema, 6210 xmlNodePtr node, 6211 xmlSchemaTypeType parentType); 6212 static xmlSchemaBasicItemPtr 6213 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 6214 xmlSchemaPtr schema, 6215 xmlNodePtr node, 6216 xmlSchemaItemListPtr uses, 6217 int parentType); 6218 static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, 6219 xmlSchemaPtr schema, 6220 xmlNodePtr node); 6221 static xmlSchemaWildcardPtr 6222 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 6223 xmlSchemaPtr schema, xmlNodePtr node); 6224 6225 /** 6226 * xmlSchemaPValAttrNodeValue: 6227 * 6228 * @ctxt: a schema parser context 6229 * @ownerDes: the designation of the parent element 6230 * @ownerItem: the schema object owner if existent 6231 * @attr: the schema attribute node being validated 6232 * @value: the value 6233 * @type: the built-in type to be validated against 6234 * 6235 * Validates a value against the given built-in type. 6236 * This one is intended to be used internally for validation 6237 * of schema attribute values during parsing of the schema. 6238 * 6239 * Returns 0 if the value is valid, a positive error code 6240 * number otherwise and -1 in case of an internal or API error. 6241 */ 6242 static int 6243 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt, 6244 xmlSchemaBasicItemPtr ownerItem, 6245 xmlAttrPtr attr, 6246 const xmlChar *value, 6247 xmlSchemaTypePtr type) 6248 { 6249 6250 int ret = 0; 6251 6252 /* 6253 * NOTE: Should we move this to xmlschematypes.c? Hmm, but this 6254 * one is really meant to be used internally, so better not. 6255 */ 6256 if ((pctxt == NULL) || (type == NULL) || (attr == NULL)) 6257 return (-1); 6258 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6259 PERROR_INT("xmlSchemaPValAttrNodeValue", 6260 "the given type is not a built-in type"); 6261 return (-1); 6262 } 6263 switch (type->builtInType) { 6264 case XML_SCHEMAS_NCNAME: 6265 case XML_SCHEMAS_QNAME: 6266 case XML_SCHEMAS_ANYURI: 6267 case XML_SCHEMAS_TOKEN: 6268 case XML_SCHEMAS_LANGUAGE: 6269 ret = xmlSchemaValPredefTypeNode(type, value, NULL, 6270 (xmlNodePtr) attr); 6271 break; 6272 default: { 6273 PERROR_INT("xmlSchemaPValAttrNodeValue", 6274 "validation using the given type is not supported while " 6275 "parsing a schema"); 6276 return (-1); 6277 } 6278 } 6279 /* 6280 * TODO: Should we use the S4S error codes instead? 6281 */ 6282 if (ret < 0) { 6283 PERROR_INT("xmlSchemaPValAttrNodeValue", 6284 "failed to validate a schema attribute value"); 6285 return (-1); 6286 } else if (ret > 0) { 6287 if (WXS_IS_LIST(type)) 6288 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 6289 else 6290 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 6291 xmlSchemaPSimpleTypeErr(pctxt, 6292 ret, ownerItem, (xmlNodePtr) attr, 6293 type, NULL, value, NULL, NULL, NULL); 6294 } 6295 return (ret); 6296 } 6297 6298 /** 6299 * xmlSchemaPValAttrNode: 6300 * 6301 * @ctxt: a schema parser context 6302 * @ownerDes: the designation of the parent element 6303 * @ownerItem: the schema object owner if existent 6304 * @attr: the schema attribute node being validated 6305 * @type: the built-in type to be validated against 6306 * @value: the resulting value if any 6307 * 6308 * Extracts and validates a value against the given built-in type. 6309 * This one is intended to be used internally for validation 6310 * of schema attribute values during parsing of the schema. 6311 * 6312 * Returns 0 if the value is valid, a positive error code 6313 * number otherwise and -1 in case of an internal or API error. 6314 */ 6315 static int 6316 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt, 6317 xmlSchemaBasicItemPtr ownerItem, 6318 xmlAttrPtr attr, 6319 xmlSchemaTypePtr type, 6320 const xmlChar **value) 6321 { 6322 const xmlChar *val; 6323 6324 if ((ctxt == NULL) || (type == NULL) || (attr == NULL)) 6325 return (-1); 6326 6327 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6328 if (value != NULL) 6329 *value = val; 6330 6331 return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr, 6332 val, type)); 6333 } 6334 6335 /** 6336 * xmlSchemaPValAttr: 6337 * 6338 * @ctxt: a schema parser context 6339 * @node: the element node of the attribute 6340 * @ownerDes: the designation of the parent element 6341 * @ownerItem: the schema object owner if existent 6342 * @ownerElem: the owner element node 6343 * @name: the name of the schema attribute node 6344 * @type: the built-in type to be validated against 6345 * @value: the resulting value if any 6346 * 6347 * Extracts and validates a value against the given built-in type. 6348 * This one is intended to be used internally for validation 6349 * of schema attribute values during parsing of the schema. 6350 * 6351 * Returns 0 if the value is valid, a positive error code 6352 * number otherwise and -1 in case of an internal or API error. 6353 */ 6354 static int 6355 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt, 6356 xmlSchemaBasicItemPtr ownerItem, 6357 xmlNodePtr ownerElem, 6358 const char *name, 6359 xmlSchemaTypePtr type, 6360 const xmlChar **value) 6361 { 6362 xmlAttrPtr attr; 6363 6364 if ((ctxt == NULL) || (type == NULL)) { 6365 if (value != NULL) 6366 *value = NULL; 6367 return (-1); 6368 } 6369 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6370 if (value != NULL) 6371 *value = NULL; 6372 xmlSchemaPErr(ctxt, ownerElem, 6373 XML_SCHEMAP_INTERNAL, 6374 "Internal error: xmlSchemaPValAttr, the given " 6375 "type '%s' is not a built-in type.\n", 6376 type->name, NULL); 6377 return (-1); 6378 } 6379 attr = xmlSchemaGetPropNode(ownerElem, name); 6380 if (attr == NULL) { 6381 if (value != NULL) 6382 *value = NULL; 6383 return (0); 6384 } 6385 return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr, 6386 type, value)); 6387 } 6388 6389 static int 6390 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt, 6391 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6392 xmlNodePtr node, 6393 xmlAttrPtr attr, 6394 const xmlChar *namespaceName) 6395 { 6396 /* TODO: Pointer comparison instead? */ 6397 if (xmlStrEqual(pctxt->targetNamespace, namespaceName)) 6398 return (0); 6399 if (xmlStrEqual(xmlSchemaNs, namespaceName)) 6400 return (0); 6401 /* 6402 * Check if the referenced namespace was <import>ed. 6403 */ 6404 if (WXS_BUCKET(pctxt)->relations != NULL) { 6405 xmlSchemaSchemaRelationPtr rel; 6406 6407 rel = WXS_BUCKET(pctxt)->relations; 6408 do { 6409 if (WXS_IS_BUCKET_IMPMAIN(rel->type) && 6410 xmlStrEqual(namespaceName, rel->importNamespace)) 6411 return (0); 6412 rel = rel->next; 6413 } while (rel != NULL); 6414 } 6415 /* 6416 * No matching <import>ed namespace found. 6417 */ 6418 { 6419 xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node; 6420 6421 if (namespaceName == NULL) 6422 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6423 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6424 "References from this schema to components in no " 6425 "namespace are not allowed, since not indicated by an " 6426 "import statement", NULL, NULL); 6427 else 6428 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6429 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6430 "References from this schema to components in the " 6431 "namespace '%s' are not allowed, since not indicated by an " 6432 "import statement", namespaceName, NULL); 6433 } 6434 return (XML_SCHEMAP_SRC_RESOLVE); 6435 } 6436 6437 /** 6438 * xmlSchemaParseLocalAttributes: 6439 * @ctxt: a schema validation context 6440 * @schema: the schema being built 6441 * @node: a subtree containing XML Schema informations 6442 * @type: the hosting type where the attributes will be anchored 6443 * 6444 * Parses attribute uses and attribute declarations and 6445 * attribute group references. 6446 */ 6447 static int 6448 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6449 xmlNodePtr *child, xmlSchemaItemListPtr *list, 6450 int parentType, int *hasRefs) 6451 { 6452 void *item; 6453 6454 while ((IS_SCHEMA((*child), "attribute")) || 6455 (IS_SCHEMA((*child), "attributeGroup"))) { 6456 if (IS_SCHEMA((*child), "attribute")) { 6457 item = xmlSchemaParseLocalAttribute(ctxt, schema, *child, 6458 *list, parentType); 6459 } else { 6460 item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child); 6461 if ((item != NULL) && (hasRefs != NULL)) 6462 *hasRefs = 1; 6463 } 6464 if (item != NULL) { 6465 if (*list == NULL) { 6466 /* TODO: Customize grow factor. */ 6467 *list = xmlSchemaItemListCreate(); 6468 if (*list == NULL) 6469 return(-1); 6470 } 6471 if (xmlSchemaItemListAddSize(*list, 2, item) == -1) 6472 return(-1); 6473 } 6474 *child = (*child)->next; 6475 } 6476 return (0); 6477 } 6478 6479 /** 6480 * xmlSchemaParseAnnotation: 6481 * @ctxt: a schema validation context 6482 * @schema: the schema being built 6483 * @node: a subtree containing XML Schema informations 6484 * 6485 * parse a XML schema Attrribute declaration 6486 * *WARNING* this interface is highly subject to change 6487 * 6488 * Returns -1 in case of error, 0 if the declaration is improper and 6489 * 1 in case of success. 6490 */ 6491 static xmlSchemaAnnotPtr 6492 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed) 6493 { 6494 xmlSchemaAnnotPtr ret; 6495 xmlNodePtr child = NULL; 6496 xmlAttrPtr attr; 6497 int barked = 0; 6498 6499 /* 6500 * INFO: S4S completed. 6501 */ 6502 /* 6503 * id = ID 6504 * {any attributes with non-schema namespace . . .}> 6505 * Content: (appinfo | documentation)* 6506 */ 6507 if ((ctxt == NULL) || (node == NULL)) 6508 return (NULL); 6509 if (needed) 6510 ret = xmlSchemaNewAnnot(ctxt, node); 6511 else 6512 ret = NULL; 6513 attr = node->properties; 6514 while (attr != NULL) { 6515 if (((attr->ns == NULL) && 6516 (!xmlStrEqual(attr->name, BAD_CAST "id"))) || 6517 ((attr->ns != NULL) && 6518 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6519 6520 xmlSchemaPIllegalAttrErr(ctxt, 6521 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6522 } 6523 attr = attr->next; 6524 } 6525 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6526 /* 6527 * And now for the children... 6528 */ 6529 child = node->children; 6530 while (child != NULL) { 6531 if (IS_SCHEMA(child, "appinfo")) { 6532 /* TODO: make available the content of "appinfo". */ 6533 /* 6534 * source = anyURI 6535 * {any attributes with non-schema namespace . . .}> 6536 * Content: ({any})* 6537 */ 6538 attr = child->properties; 6539 while (attr != NULL) { 6540 if (((attr->ns == NULL) && 6541 (!xmlStrEqual(attr->name, BAD_CAST "source"))) || 6542 ((attr->ns != NULL) && 6543 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6544 6545 xmlSchemaPIllegalAttrErr(ctxt, 6546 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6547 } 6548 attr = attr->next; 6549 } 6550 xmlSchemaPValAttr(ctxt, NULL, child, "source", 6551 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 6552 child = child->next; 6553 } else if (IS_SCHEMA(child, "documentation")) { 6554 /* TODO: make available the content of "documentation". */ 6555 /* 6556 * source = anyURI 6557 * {any attributes with non-schema namespace . . .}> 6558 * Content: ({any})* 6559 */ 6560 attr = child->properties; 6561 while (attr != NULL) { 6562 if (attr->ns == NULL) { 6563 if (!xmlStrEqual(attr->name, BAD_CAST "source")) { 6564 xmlSchemaPIllegalAttrErr(ctxt, 6565 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6566 } 6567 } else { 6568 if (xmlStrEqual(attr->ns->href, xmlSchemaNs) || 6569 (xmlStrEqual(attr->name, BAD_CAST "lang") && 6570 (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) { 6571 6572 xmlSchemaPIllegalAttrErr(ctxt, 6573 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6574 } 6575 } 6576 attr = attr->next; 6577 } 6578 /* 6579 * Attribute "xml:lang". 6580 */ 6581 attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang"); 6582 if (attr != NULL) 6583 xmlSchemaPValAttrNode(ctxt, NULL, attr, 6584 xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL); 6585 child = child->next; 6586 } else { 6587 if (!barked) 6588 xmlSchemaPContentErr(ctxt, 6589 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6590 NULL, node, child, NULL, "(appinfo | documentation)*"); 6591 barked = 1; 6592 child = child->next; 6593 } 6594 } 6595 6596 return (ret); 6597 } 6598 6599 /** 6600 * xmlSchemaParseFacet: 6601 * @ctxt: a schema validation context 6602 * @schema: the schema being built 6603 * @node: a subtree containing XML Schema informations 6604 * 6605 * parse a XML schema Facet declaration 6606 * *WARNING* this interface is highly subject to change 6607 * 6608 * Returns the new type structure or NULL in case of error 6609 */ 6610 static xmlSchemaFacetPtr 6611 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6612 xmlNodePtr node) 6613 { 6614 xmlSchemaFacetPtr facet; 6615 xmlNodePtr child = NULL; 6616 const xmlChar *value; 6617 6618 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6619 return (NULL); 6620 6621 facet = xmlSchemaNewFacet(); 6622 if (facet == NULL) { 6623 xmlSchemaPErrMemory(ctxt, "allocating facet", node); 6624 return (NULL); 6625 } 6626 facet->node = node; 6627 value = xmlSchemaGetProp(ctxt, node, "value"); 6628 if (value == NULL) { 6629 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE, 6630 "Facet %s has no value\n", node->name, NULL); 6631 xmlSchemaFreeFacet(facet); 6632 return (NULL); 6633 } 6634 if (IS_SCHEMA(node, "minInclusive")) { 6635 facet->type = XML_SCHEMA_FACET_MININCLUSIVE; 6636 } else if (IS_SCHEMA(node, "minExclusive")) { 6637 facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE; 6638 } else if (IS_SCHEMA(node, "maxInclusive")) { 6639 facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE; 6640 } else if (IS_SCHEMA(node, "maxExclusive")) { 6641 facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE; 6642 } else if (IS_SCHEMA(node, "totalDigits")) { 6643 facet->type = XML_SCHEMA_FACET_TOTALDIGITS; 6644 } else if (IS_SCHEMA(node, "fractionDigits")) { 6645 facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS; 6646 } else if (IS_SCHEMA(node, "pattern")) { 6647 facet->type = XML_SCHEMA_FACET_PATTERN; 6648 } else if (IS_SCHEMA(node, "enumeration")) { 6649 facet->type = XML_SCHEMA_FACET_ENUMERATION; 6650 } else if (IS_SCHEMA(node, "whiteSpace")) { 6651 facet->type = XML_SCHEMA_FACET_WHITESPACE; 6652 } else if (IS_SCHEMA(node, "length")) { 6653 facet->type = XML_SCHEMA_FACET_LENGTH; 6654 } else if (IS_SCHEMA(node, "maxLength")) { 6655 facet->type = XML_SCHEMA_FACET_MAXLENGTH; 6656 } else if (IS_SCHEMA(node, "minLength")) { 6657 facet->type = XML_SCHEMA_FACET_MINLENGTH; 6658 } else { 6659 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE, 6660 "Unknown facet type %s\n", node->name, NULL); 6661 xmlSchemaFreeFacet(facet); 6662 return (NULL); 6663 } 6664 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6665 facet->value = value; 6666 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 6667 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 6668 const xmlChar *fixed; 6669 6670 fixed = xmlSchemaGetProp(ctxt, node, "fixed"); 6671 if (fixed != NULL) { 6672 if (xmlStrEqual(fixed, BAD_CAST "true")) 6673 facet->fixed = 1; 6674 } 6675 } 6676 child = node->children; 6677 6678 if (IS_SCHEMA(child, "annotation")) { 6679 facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6680 child = child->next; 6681 } 6682 if (child != NULL) { 6683 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD, 6684 "Facet %s has unexpected child content\n", 6685 node->name, NULL); 6686 } 6687 return (facet); 6688 } 6689 6690 /** 6691 * xmlSchemaParseWildcardNs: 6692 * @ctxt: a schema parser context 6693 * @wildc: the wildcard, already created 6694 * @node: a subtree containing XML Schema informations 6695 * 6696 * Parses the attribute "processContents" and "namespace" 6697 * of a xsd:anyAttribute and xsd:any. 6698 * *WARNING* this interface is highly subject to change 6699 * 6700 * Returns 0 if everything goes fine, a positive error code 6701 * if something is not valid and -1 if an internal error occurs. 6702 */ 6703 static int 6704 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt, 6705 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6706 xmlSchemaWildcardPtr wildc, 6707 xmlNodePtr node) 6708 { 6709 const xmlChar *pc, *ns, *dictnsItem; 6710 int ret = 0; 6711 xmlChar *nsItem; 6712 xmlSchemaWildcardNsPtr tmp, lastNs = NULL; 6713 xmlAttrPtr attr; 6714 6715 pc = xmlSchemaGetProp(ctxt, node, "processContents"); 6716 if ((pc == NULL) 6717 || (xmlStrEqual(pc, (const xmlChar *) "strict"))) { 6718 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6719 } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) { 6720 wildc->processContents = XML_SCHEMAS_ANY_SKIP; 6721 } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) { 6722 wildc->processContents = XML_SCHEMAS_ANY_LAX; 6723 } else { 6724 xmlSchemaPSimpleTypeErr(ctxt, 6725 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6726 NULL, node, 6727 NULL, "(strict | skip | lax)", pc, 6728 NULL, NULL, NULL); 6729 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6730 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 6731 } 6732 /* 6733 * Build the namespace constraints. 6734 */ 6735 attr = xmlSchemaGetPropNode(node, "namespace"); 6736 ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6737 if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any"))) 6738 wildc->any = 1; 6739 else if (xmlStrEqual(ns, BAD_CAST "##other")) { 6740 wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 6741 if (wildc->negNsSet == NULL) { 6742 return (-1); 6743 } 6744 wildc->negNsSet->value = ctxt->targetNamespace; 6745 } else { 6746 const xmlChar *end, *cur; 6747 6748 cur = ns; 6749 do { 6750 while (IS_BLANK_CH(*cur)) 6751 cur++; 6752 end = cur; 6753 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 6754 end++; 6755 if (end == cur) 6756 break; 6757 nsItem = xmlStrndup(cur, end - cur); 6758 if ((xmlStrEqual(nsItem, BAD_CAST "##other")) || 6759 (xmlStrEqual(nsItem, BAD_CAST "##any"))) { 6760 xmlSchemaPSimpleTypeErr(ctxt, 6761 XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER, 6762 NULL, (xmlNodePtr) attr, 6763 NULL, 6764 "((##any | ##other) | List of (xs:anyURI | " 6765 "(##targetNamespace | ##local)))", 6766 nsItem, NULL, NULL, NULL); 6767 ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER; 6768 } else { 6769 if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) { 6770 dictnsItem = ctxt->targetNamespace; 6771 } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) { 6772 dictnsItem = NULL; 6773 } else { 6774 /* 6775 * Validate the item (anyURI). 6776 */ 6777 xmlSchemaPValAttrNodeValue(ctxt, NULL, attr, 6778 nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI)); 6779 dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1); 6780 } 6781 /* 6782 * Avoid dublicate namespaces. 6783 */ 6784 tmp = wildc->nsSet; 6785 while (tmp != NULL) { 6786 if (dictnsItem == tmp->value) 6787 break; 6788 tmp = tmp->next; 6789 } 6790 if (tmp == NULL) { 6791 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 6792 if (tmp == NULL) { 6793 xmlFree(nsItem); 6794 return (-1); 6795 } 6796 tmp->value = dictnsItem; 6797 tmp->next = NULL; 6798 if (wildc->nsSet == NULL) 6799 wildc->nsSet = tmp; 6800 else 6801 lastNs->next = tmp; 6802 lastNs = tmp; 6803 } 6804 6805 } 6806 xmlFree(nsItem); 6807 cur = end; 6808 } while (*cur != 0); 6809 } 6810 return (ret); 6811 } 6812 6813 static int 6814 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt, 6815 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED, 6816 xmlNodePtr node, 6817 int minOccurs, 6818 int maxOccurs) { 6819 6820 if ((maxOccurs == 0) && ( minOccurs == 0)) 6821 return (0); 6822 if (maxOccurs != UNBOUNDED) { 6823 /* 6824 * TODO: Maybe we should better not create the particle, 6825 * if min/max is invalid, since it could confuse the build of the 6826 * content model. 6827 */ 6828 /* 6829 * 3.9.6 Schema Component Constraint: Particle Correct 6830 * 6831 */ 6832 if (maxOccurs < 1) { 6833 /* 6834 * 2.2 {max occurs} must be greater than or equal to 1. 6835 */ 6836 xmlSchemaPCustomAttrErr(ctxt, 6837 XML_SCHEMAP_P_PROPS_CORRECT_2_2, 6838 NULL, NULL, 6839 xmlSchemaGetPropNode(node, "maxOccurs"), 6840 "The value must be greater than or equal to 1"); 6841 return (XML_SCHEMAP_P_PROPS_CORRECT_2_2); 6842 } else if (minOccurs > maxOccurs) { 6843 /* 6844 * 2.1 {min occurs} must not be greater than {max occurs}. 6845 */ 6846 xmlSchemaPCustomAttrErr(ctxt, 6847 XML_SCHEMAP_P_PROPS_CORRECT_2_1, 6848 NULL, NULL, 6849 xmlSchemaGetPropNode(node, "minOccurs"), 6850 "The value must not be greater than the value of 'maxOccurs'"); 6851 return (XML_SCHEMAP_P_PROPS_CORRECT_2_1); 6852 } 6853 } 6854 return (0); 6855 } 6856 6857 /** 6858 * xmlSchemaParseAny: 6859 * @ctxt: a schema validation context 6860 * @schema: the schema being built 6861 * @node: a subtree containing XML Schema informations 6862 * 6863 * Parsea a XML schema <any> element. A particle and wildcard 6864 * will be created (except if minOccurs==maxOccurs==0, in this case 6865 * nothing will be created). 6866 * *WARNING* this interface is highly subject to change 6867 * 6868 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0 6869 */ 6870 static xmlSchemaParticlePtr 6871 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6872 xmlNodePtr node) 6873 { 6874 xmlSchemaParticlePtr particle; 6875 xmlNodePtr child = NULL; 6876 xmlSchemaWildcardPtr wild; 6877 int min, max; 6878 xmlAttrPtr attr; 6879 xmlSchemaAnnotPtr annot = NULL; 6880 6881 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6882 return (NULL); 6883 /* 6884 * Check for illegal attributes. 6885 */ 6886 attr = node->properties; 6887 while (attr != NULL) { 6888 if (attr->ns == NULL) { 6889 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 6890 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 6891 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 6892 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 6893 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 6894 xmlSchemaPIllegalAttrErr(ctxt, 6895 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6896 } 6897 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 6898 xmlSchemaPIllegalAttrErr(ctxt, 6899 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6900 } 6901 attr = attr->next; 6902 } 6903 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6904 /* 6905 * minOccurs/maxOccurs. 6906 */ 6907 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 6908 "(xs:nonNegativeInteger | unbounded)"); 6909 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, 6910 "xs:nonNegativeInteger"); 6911 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 6912 /* 6913 * Create & parse the wildcard. 6914 */ 6915 wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node); 6916 if (wild == NULL) 6917 return (NULL); 6918 xmlSchemaParseWildcardNs(ctxt, schema, wild, node); 6919 /* 6920 * And now for the children... 6921 */ 6922 child = node->children; 6923 if (IS_SCHEMA(child, "annotation")) { 6924 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6925 child = child->next; 6926 } 6927 if (child != NULL) { 6928 xmlSchemaPContentErr(ctxt, 6929 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6930 NULL, node, child, 6931 NULL, "(annotation?)"); 6932 } 6933 /* 6934 * No component if minOccurs==maxOccurs==0. 6935 */ 6936 if ((min == 0) && (max == 0)) { 6937 /* Don't free the wildcard, since it's already on the list. */ 6938 return (NULL); 6939 } 6940 /* 6941 * Create the particle. 6942 */ 6943 particle = xmlSchemaAddParticle(ctxt, node, min, max); 6944 if (particle == NULL) 6945 return (NULL); 6946 particle->annot = annot; 6947 particle->children = (xmlSchemaTreeItemPtr) wild; 6948 6949 return (particle); 6950 } 6951 6952 /** 6953 * xmlSchemaParseNotation: 6954 * @ctxt: a schema validation context 6955 * @schema: the schema being built 6956 * @node: a subtree containing XML Schema informations 6957 * 6958 * parse a XML schema Notation declaration 6959 * 6960 * Returns the new structure or NULL in case of error 6961 */ 6962 static xmlSchemaNotationPtr 6963 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6964 xmlNodePtr node) 6965 { 6966 const xmlChar *name; 6967 xmlSchemaNotationPtr ret; 6968 xmlNodePtr child = NULL; 6969 6970 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6971 return (NULL); 6972 name = xmlSchemaGetProp(ctxt, node, "name"); 6973 if (name == NULL) { 6974 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME, 6975 "Notation has no name\n", NULL, NULL); 6976 return (NULL); 6977 } 6978 ret = xmlSchemaAddNotation(ctxt, schema, name, 6979 ctxt->targetNamespace, node); 6980 if (ret == NULL) 6981 return (NULL); 6982 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6983 6984 child = node->children; 6985 if (IS_SCHEMA(child, "annotation")) { 6986 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6987 child = child->next; 6988 } 6989 if (child != NULL) { 6990 xmlSchemaPContentErr(ctxt, 6991 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6992 NULL, node, child, 6993 NULL, "(annotation?)"); 6994 } 6995 6996 return (ret); 6997 } 6998 6999 /** 7000 * xmlSchemaParseAnyAttribute: 7001 * @ctxt: a schema validation context 7002 * @schema: the schema being built 7003 * @node: a subtree containing XML Schema informations 7004 * 7005 * parse a XML schema AnyAttrribute declaration 7006 * *WARNING* this interface is highly subject to change 7007 * 7008 * Returns a wildcard or NULL. 7009 */ 7010 static xmlSchemaWildcardPtr 7011 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 7012 xmlSchemaPtr schema, xmlNodePtr node) 7013 { 7014 xmlSchemaWildcardPtr ret; 7015 xmlNodePtr child = NULL; 7016 xmlAttrPtr attr; 7017 7018 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 7019 return (NULL); 7020 7021 ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 7022 node); 7023 if (ret == NULL) { 7024 return (NULL); 7025 } 7026 /* 7027 * Check for illegal attributes. 7028 */ 7029 attr = node->properties; 7030 while (attr != NULL) { 7031 if (attr->ns == NULL) { 7032 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7033 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 7034 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 7035 xmlSchemaPIllegalAttrErr(ctxt, 7036 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7037 } 7038 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7039 xmlSchemaPIllegalAttrErr(ctxt, 7040 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7041 } 7042 attr = attr->next; 7043 } 7044 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 7045 /* 7046 * Parse the namespace list. 7047 */ 7048 if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0) 7049 return (NULL); 7050 /* 7051 * And now for the children... 7052 */ 7053 child = node->children; 7054 if (IS_SCHEMA(child, "annotation")) { 7055 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 7056 child = child->next; 7057 } 7058 if (child != NULL) { 7059 xmlSchemaPContentErr(ctxt, 7060 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7061 NULL, node, child, 7062 NULL, "(annotation?)"); 7063 } 7064 7065 return (ret); 7066 } 7067 7068 7069 /** 7070 * xmlSchemaParseAttribute: 7071 * @ctxt: a schema validation context 7072 * @schema: the schema being built 7073 * @node: a subtree containing XML Schema informations 7074 * 7075 * parse a XML schema Attrribute declaration 7076 * *WARNING* this interface is highly subject to change 7077 * 7078 * Returns the attribute declaration. 7079 */ 7080 static xmlSchemaBasicItemPtr 7081 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 7082 xmlSchemaPtr schema, 7083 xmlNodePtr node, 7084 xmlSchemaItemListPtr uses, 7085 int parentType) 7086 { 7087 const xmlChar *attrValue, *name = NULL, *ns = NULL; 7088 xmlSchemaAttributeUsePtr use = NULL; 7089 xmlNodePtr child = NULL; 7090 xmlAttrPtr attr; 7091 const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL; 7092 int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7093 int nberrors, hasForm = 0, defValueType = 0; 7094 7095 #define WXS_ATTR_DEF_VAL_DEFAULT 1 7096 #define WXS_ATTR_DEF_VAL_FIXED 2 7097 7098 /* 7099 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7100 */ 7101 7102 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7103 return (NULL); 7104 attr = xmlSchemaGetPropNode(node, "ref"); 7105 if (attr != NULL) { 7106 if (xmlSchemaPValAttrNodeQName(pctxt, schema, 7107 NULL, attr, &tmpNs, &tmpName) != 0) { 7108 return (NULL); 7109 } 7110 if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0) 7111 return(NULL); 7112 isRef = 1; 7113 } 7114 nberrors = pctxt->nberrors; 7115 /* 7116 * Check for illegal attributes. 7117 */ 7118 attr = node->properties; 7119 while (attr != NULL) { 7120 if (attr->ns == NULL) { 7121 if (isRef) { 7122 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7123 xmlSchemaPValAttrNodeID(pctxt, attr); 7124 goto attr_next; 7125 } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) { 7126 goto attr_next; 7127 } 7128 } else { 7129 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 7130 goto attr_next; 7131 } else if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7132 xmlSchemaPValAttrNodeID(pctxt, attr); 7133 goto attr_next; 7134 } else if (xmlStrEqual(attr->name, BAD_CAST "type")) { 7135 xmlSchemaPValAttrNodeQName(pctxt, schema, NULL, 7136 attr, &tmpNs, &tmpName); 7137 goto attr_next; 7138 } else if (xmlStrEqual(attr->name, BAD_CAST "form")) { 7139 /* 7140 * Evaluate the target namespace 7141 */ 7142 hasForm = 1; 7143 attrValue = xmlSchemaGetNodeContent(pctxt, 7144 (xmlNodePtr) attr); 7145 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 7146 ns = pctxt->targetNamespace; 7147 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) 7148 { 7149 xmlSchemaPSimpleTypeErr(pctxt, 7150 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 7151 NULL, (xmlNodePtr) attr, 7152 NULL, "(qualified | unqualified)", 7153 attrValue, NULL, NULL, NULL); 7154 } 7155 goto attr_next; 7156 } 7157 } 7158 if (xmlStrEqual(attr->name, BAD_CAST "use")) { 7159 7160 attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7161 /* TODO: Maybe we need to normalize the value beforehand. */ 7162 if (xmlStrEqual(attrValue, BAD_CAST "optional")) 7163 occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7164 else if (xmlStrEqual(attrValue, BAD_CAST "prohibited")) 7165 occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED; 7166 else if (xmlStrEqual(attrValue, BAD_CAST "required")) 7167 occurs = XML_SCHEMAS_ATTR_USE_REQUIRED; 7168 else { 7169 xmlSchemaPSimpleTypeErr(pctxt, 7170 XML_SCHEMAP_INVALID_ATTR_USE, 7171 NULL, (xmlNodePtr) attr, 7172 NULL, "(optional | prohibited | required)", 7173 attrValue, NULL, NULL, NULL); 7174 } 7175 goto attr_next; 7176 } else if (xmlStrEqual(attr->name, BAD_CAST "default")) { 7177 /* 7178 * 3.2.3 : 1 7179 * default and fixed must not both be present. 7180 */ 7181 if (defValue) { 7182 xmlSchemaPMutualExclAttrErr(pctxt, 7183 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7184 NULL, attr, "default", "fixed"); 7185 } else { 7186 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7187 defValueType = WXS_ATTR_DEF_VAL_DEFAULT; 7188 } 7189 goto attr_next; 7190 } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) { 7191 /* 7192 * 3.2.3 : 1 7193 * default and fixed must not both be present. 7194 */ 7195 if (defValue) { 7196 xmlSchemaPMutualExclAttrErr(pctxt, 7197 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7198 NULL, attr, "default", "fixed"); 7199 } else { 7200 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7201 defValueType = WXS_ATTR_DEF_VAL_FIXED; 7202 } 7203 goto attr_next; 7204 } 7205 } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs)) 7206 goto attr_next; 7207 7208 xmlSchemaPIllegalAttrErr(pctxt, 7209 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7210 7211 attr_next: 7212 attr = attr->next; 7213 } 7214 /* 7215 * 3.2.3 : 2 7216 * If default and use are both present, use must have 7217 * the actual value optional. 7218 */ 7219 if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) && 7220 (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) { 7221 xmlSchemaPSimpleTypeErr(pctxt, 7222 XML_SCHEMAP_SRC_ATTRIBUTE_2, 7223 NULL, node, NULL, 7224 "(optional | prohibited | required)", NULL, 7225 "The value of the attribute 'use' must be 'optional' " 7226 "if the attribute 'default' is present", 7227 NULL, NULL); 7228 } 7229 /* 7230 * We want correct attributes. 7231 */ 7232 if (nberrors != pctxt->nberrors) 7233 return(NULL); 7234 if (! isRef) { 7235 xmlSchemaAttributePtr attrDecl; 7236 7237 /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */ 7238 if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR)) 7239 ns = pctxt->targetNamespace; 7240 /* 7241 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7242 * TODO: Move this to the component layer. 7243 */ 7244 if (xmlStrEqual(ns, xmlSchemaInstanceNs)) { 7245 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7246 XML_SCHEMAP_NO_XSI, 7247 node, NULL, 7248 "The target namespace must not match '%s'", 7249 xmlSchemaInstanceNs, NULL); 7250 } 7251 attr = xmlSchemaGetPropNode(node, "name"); 7252 if (attr == NULL) { 7253 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7254 NULL, node, "name", NULL); 7255 return (NULL); 7256 } 7257 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7258 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7259 return (NULL); 7260 } 7261 /* 7262 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7263 * TODO: Move this to the component layer. 7264 */ 7265 if (xmlStrEqual(name, BAD_CAST "xmlns")) { 7266 xmlSchemaPSimpleTypeErr(pctxt, 7267 XML_SCHEMAP_NO_XMLNS, 7268 NULL, (xmlNodePtr) attr, 7269 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7270 "The value of the attribute must not match 'xmlns'", 7271 NULL, NULL); 7272 return (NULL); 7273 } 7274 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) 7275 goto check_children; 7276 /* 7277 * Create the attribute use component. 7278 */ 7279 use = xmlSchemaAddAttributeUse(pctxt, node); 7280 if (use == NULL) 7281 return(NULL); 7282 use->occurs = occurs; 7283 /* 7284 * Create the attribute declaration. 7285 */ 7286 attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0); 7287 if (attrDecl == NULL) 7288 return (NULL); 7289 if (tmpName != NULL) { 7290 attrDecl->typeName = tmpName; 7291 attrDecl->typeNs = tmpNs; 7292 } 7293 use->attrDecl = attrDecl; 7294 /* 7295 * Value constraint. 7296 */ 7297 if (defValue != NULL) { 7298 attrDecl->defValue = defValue; 7299 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7300 attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED; 7301 } 7302 } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7303 xmlSchemaQNameRefPtr ref; 7304 7305 /* 7306 * Create the attribute use component. 7307 */ 7308 use = xmlSchemaAddAttributeUse(pctxt, node); 7309 if (use == NULL) 7310 return(NULL); 7311 /* 7312 * We need to resolve the reference at later stage. 7313 */ 7314 WXS_ADD_PENDING(pctxt, use); 7315 use->occurs = occurs; 7316 /* 7317 * Create a QName reference to the attribute declaration. 7318 */ 7319 ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE, 7320 tmpName, tmpNs); 7321 if (ref == NULL) 7322 return(NULL); 7323 /* 7324 * Assign the reference. This will be substituted for the 7325 * referenced attribute declaration when the QName is resolved. 7326 */ 7327 use->attrDecl = WXS_ATTR_CAST ref; 7328 /* 7329 * Value constraint. 7330 */ 7331 if (defValue != NULL) 7332 use->defValue = defValue; 7333 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7334 use->flags |= XML_SCHEMA_ATTR_USE_FIXED; 7335 } 7336 7337 check_children: 7338 /* 7339 * And now for the children... 7340 */ 7341 child = node->children; 7342 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7343 xmlSchemaAttributeUseProhibPtr prohib; 7344 7345 if (IS_SCHEMA(child, "annotation")) { 7346 xmlSchemaParseAnnotation(pctxt, child, 0); 7347 child = child->next; 7348 } 7349 if (child != NULL) { 7350 xmlSchemaPContentErr(pctxt, 7351 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7352 NULL, node, child, NULL, 7353 "(annotation?)"); 7354 } 7355 /* 7356 * Check for pointlessness of attribute prohibitions. 7357 */ 7358 if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) { 7359 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7360 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7361 node, NULL, 7362 "Skipping attribute use prohibition, since it is " 7363 "pointless inside an <attributeGroup>", 7364 NULL, NULL, NULL); 7365 return(NULL); 7366 } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) { 7367 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7368 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7369 node, NULL, 7370 "Skipping attribute use prohibition, since it is " 7371 "pointless when extending a type", 7372 NULL, NULL, NULL); 7373 return(NULL); 7374 } 7375 if (! isRef) { 7376 tmpName = name; 7377 tmpNs = ns; 7378 } 7379 /* 7380 * Check for duplicate attribute prohibitions. 7381 */ 7382 if (uses) { 7383 int i; 7384 7385 for (i = 0; i < uses->nbItems; i++) { 7386 use = uses->items[i]; 7387 if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) && 7388 (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) && 7389 (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace)) 7390 { 7391 xmlChar *str = NULL; 7392 7393 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7394 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7395 node, NULL, 7396 "Skipping duplicate attribute use prohibition '%s'", 7397 xmlSchemaFormatQName(&str, tmpNs, tmpName), 7398 NULL, NULL); 7399 FREE_AND_NULL(str) 7400 return(NULL); 7401 } 7402 } 7403 } 7404 /* 7405 * Create the attribute prohibition helper component. 7406 */ 7407 prohib = xmlSchemaAddAttributeUseProhib(pctxt); 7408 if (prohib == NULL) 7409 return(NULL); 7410 prohib->node = node; 7411 prohib->name = tmpName; 7412 prohib->targetNamespace = tmpNs; 7413 if (isRef) { 7414 /* 7415 * We need at least to resolve to the attribute declaration. 7416 */ 7417 WXS_ADD_PENDING(pctxt, prohib); 7418 } 7419 return(WXS_BASIC_CAST prohib); 7420 } else { 7421 if (IS_SCHEMA(child, "annotation")) { 7422 /* 7423 * TODO: Should this go into the attr decl? 7424 */ 7425 use->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7426 child = child->next; 7427 } 7428 if (isRef) { 7429 if (child != NULL) { 7430 if (IS_SCHEMA(child, "simpleType")) 7431 /* 7432 * 3.2.3 : 3.2 7433 * If ref is present, then all of <simpleType>, 7434 * form and type must be absent. 7435 */ 7436 xmlSchemaPContentErr(pctxt, 7437 XML_SCHEMAP_SRC_ATTRIBUTE_3_2, 7438 NULL, node, child, NULL, 7439 "(annotation?)"); 7440 else 7441 xmlSchemaPContentErr(pctxt, 7442 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7443 NULL, node, child, NULL, 7444 "(annotation?)"); 7445 } 7446 } else { 7447 if (IS_SCHEMA(child, "simpleType")) { 7448 if (WXS_ATTRUSE_DECL(use)->typeName != NULL) { 7449 /* 7450 * 3.2.3 : 4 7451 * type and <simpleType> must not both be present. 7452 */ 7453 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7454 NULL, node, child, 7455 "The attribute 'type' and the <simpleType> child " 7456 "are mutually exclusive", NULL); 7457 } else 7458 WXS_ATTRUSE_TYPEDEF(use) = 7459 xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7460 child = child->next; 7461 } 7462 if (child != NULL) 7463 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7464 NULL, node, child, NULL, 7465 "(annotation?, simpleType?)"); 7466 } 7467 } 7468 return (WXS_BASIC_CAST use); 7469 } 7470 7471 7472 static xmlSchemaAttributePtr 7473 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt, 7474 xmlSchemaPtr schema, 7475 xmlNodePtr node) 7476 { 7477 const xmlChar *attrValue; 7478 xmlSchemaAttributePtr ret; 7479 xmlNodePtr child = NULL; 7480 xmlAttrPtr attr; 7481 7482 /* 7483 * Note that the w3c spec assumes the schema to be validated with schema 7484 * for schemas beforehand. 7485 * 7486 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7487 */ 7488 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7489 return (NULL); 7490 /* 7491 * 3.2.3 : 3.1 7492 * One of ref or name must be present, but not both 7493 */ 7494 attr = xmlSchemaGetPropNode(node, "name"); 7495 if (attr == NULL) { 7496 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7497 NULL, node, "name", NULL); 7498 return (NULL); 7499 } 7500 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7501 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) { 7502 return (NULL); 7503 } 7504 /* 7505 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7506 * TODO: Move this to the component layer. 7507 */ 7508 if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) { 7509 xmlSchemaPSimpleTypeErr(pctxt, 7510 XML_SCHEMAP_NO_XMLNS, 7511 NULL, (xmlNodePtr) attr, 7512 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7513 "The value of the attribute must not match 'xmlns'", 7514 NULL, NULL); 7515 return (NULL); 7516 } 7517 /* 7518 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7519 * TODO: Move this to the component layer. 7520 * Or better leave it here and add it to the component layer 7521 * if we have a schema construction API. 7522 */ 7523 if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) { 7524 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7525 XML_SCHEMAP_NO_XSI, node, NULL, 7526 "The target namespace must not match '%s'", 7527 xmlSchemaInstanceNs, NULL); 7528 } 7529 7530 ret = xmlSchemaAddAttribute(pctxt, schema, attrValue, 7531 pctxt->targetNamespace, node, 1); 7532 if (ret == NULL) 7533 return (NULL); 7534 ret->flags |= XML_SCHEMAS_ATTR_GLOBAL; 7535 7536 /* 7537 * Check for illegal attributes. 7538 */ 7539 attr = node->properties; 7540 while (attr != NULL) { 7541 if (attr->ns == NULL) { 7542 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7543 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 7544 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 7545 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 7546 (!xmlStrEqual(attr->name, BAD_CAST "type"))) 7547 { 7548 xmlSchemaPIllegalAttrErr(pctxt, 7549 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7550 } 7551 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7552 xmlSchemaPIllegalAttrErr(pctxt, 7553 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7554 } 7555 attr = attr->next; 7556 } 7557 xmlSchemaPValAttrQName(pctxt, schema, NULL, 7558 node, "type", &ret->typeNs, &ret->typeName); 7559 7560 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7561 /* 7562 * Attribute "fixed". 7563 */ 7564 ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed"); 7565 if (ret->defValue != NULL) 7566 ret->flags |= XML_SCHEMAS_ATTR_FIXED; 7567 /* 7568 * Attribute "default". 7569 */ 7570 attr = xmlSchemaGetPropNode(node, "default"); 7571 if (attr != NULL) { 7572 /* 7573 * 3.2.3 : 1 7574 * default and fixed must not both be present. 7575 */ 7576 if (ret->flags & XML_SCHEMAS_ATTR_FIXED) { 7577 xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1, 7578 WXS_BASIC_CAST ret, attr, "default", "fixed"); 7579 } else 7580 ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7581 } 7582 /* 7583 * And now for the children... 7584 */ 7585 child = node->children; 7586 if (IS_SCHEMA(child, "annotation")) { 7587 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7588 child = child->next; 7589 } 7590 if (IS_SCHEMA(child, "simpleType")) { 7591 if (ret->typeName != NULL) { 7592 /* 7593 * 3.2.3 : 4 7594 * type and <simpleType> must not both be present. 7595 */ 7596 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7597 NULL, node, child, 7598 "The attribute 'type' and the <simpleType> child " 7599 "are mutually exclusive", NULL); 7600 } else 7601 ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7602 child = child->next; 7603 } 7604 if (child != NULL) 7605 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7606 NULL, node, child, NULL, 7607 "(annotation?, simpleType?)"); 7608 7609 return (ret); 7610 } 7611 7612 /** 7613 * xmlSchemaParseAttributeGroupRef: 7614 * @ctxt: a schema validation context 7615 * @schema: the schema being built 7616 * @node: a subtree containing XML Schema informations 7617 * 7618 * Parse an attribute group definition reference. 7619 * Note that a reference to an attribute group does not 7620 * correspond to any component at all. 7621 * *WARNING* this interface is highly subject to change 7622 * 7623 * Returns the attribute group or NULL in case of error. 7624 */ 7625 static xmlSchemaQNameRefPtr 7626 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 7627 xmlSchemaPtr schema, 7628 xmlNodePtr node) 7629 { 7630 xmlSchemaQNameRefPtr ret; 7631 xmlNodePtr child = NULL; 7632 xmlAttrPtr attr; 7633 const xmlChar *refNs = NULL, *ref = NULL; 7634 7635 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7636 return (NULL); 7637 7638 attr = xmlSchemaGetPropNode(node, "ref"); 7639 if (attr == NULL) { 7640 xmlSchemaPMissingAttrErr(pctxt, 7641 XML_SCHEMAP_S4S_ATTR_MISSING, 7642 NULL, node, "ref", NULL); 7643 return (NULL); 7644 } 7645 xmlSchemaPValAttrNodeQName(pctxt, schema, 7646 NULL, attr, &refNs, &ref); 7647 if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0) 7648 return(NULL); 7649 7650 /* 7651 * Check for illegal attributes. 7652 */ 7653 attr = node->properties; 7654 while (attr != NULL) { 7655 if (attr->ns == NULL) { 7656 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 7657 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7658 { 7659 xmlSchemaPIllegalAttrErr(pctxt, 7660 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7661 } 7662 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7663 xmlSchemaPIllegalAttrErr(pctxt, 7664 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7665 } 7666 attr = attr->next; 7667 } 7668 /* Attribute ID */ 7669 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7670 7671 /* 7672 * And now for the children... 7673 */ 7674 child = node->children; 7675 if (IS_SCHEMA(child, "annotation")) { 7676 /* 7677 * TODO: We do not have a place to store the annotation, do we? 7678 */ 7679 xmlSchemaParseAnnotation(pctxt, child, 0); 7680 child = child->next; 7681 } 7682 if (child != NULL) { 7683 xmlSchemaPContentErr(pctxt, 7684 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7685 NULL, node, child, NULL, 7686 "(annotation?)"); 7687 } 7688 7689 /* 7690 * Handle attribute group redefinitions. 7691 */ 7692 if (pctxt->isRedefine && pctxt->redef && 7693 (pctxt->redef->item->type == 7694 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 7695 (ref == pctxt->redef->refName) && 7696 (refNs == pctxt->redef->refTargetNs)) 7697 { 7698 /* 7699 * SPEC src-redefine: 7700 * (7.1) "If it has an <attributeGroup> among its contents 7701 * the actual value of whose ref [attribute] is the same 7702 * as the actual value of its own name attribute plus 7703 * target namespace, then it must have exactly one such group." 7704 */ 7705 if (pctxt->redefCounter != 0) { 7706 xmlChar *str = NULL; 7707 7708 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7709 XML_SCHEMAP_SRC_REDEFINE, node, NULL, 7710 "The redefining attribute group definition " 7711 "'%s' must not contain more than one " 7712 "reference to the redefined definition", 7713 xmlSchemaFormatQName(&str, refNs, ref), NULL); 7714 FREE_AND_NULL(str); 7715 return(NULL); 7716 } 7717 pctxt->redefCounter++; 7718 /* 7719 * URGENT TODO: How to ensure that the reference will not be 7720 * handled by the normal component resolution mechanism? 7721 */ 7722 ret = xmlSchemaNewQNameRef(pctxt, 7723 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7724 if (ret == NULL) 7725 return(NULL); 7726 ret->node = node; 7727 pctxt->redef->reference = WXS_BASIC_CAST ret; 7728 } else { 7729 /* 7730 * Create a QName-reference helper component. We will substitute this 7731 * component for the attribute uses of the referenced attribute group 7732 * definition. 7733 */ 7734 ret = xmlSchemaNewQNameRef(pctxt, 7735 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7736 if (ret == NULL) 7737 return(NULL); 7738 ret->node = node; 7739 /* Add to pending items, to be able to resolve the reference. */ 7740 WXS_ADD_PENDING(pctxt, ret); 7741 } 7742 return (ret); 7743 } 7744 7745 /** 7746 * xmlSchemaParseAttributeGroupDefinition: 7747 * @pctxt: a schema validation context 7748 * @schema: the schema being built 7749 * @node: a subtree containing XML Schema informations 7750 * 7751 * parse a XML schema Attribute Group declaration 7752 * *WARNING* this interface is highly subject to change 7753 * 7754 * Returns the attribute group definition or NULL in case of error. 7755 */ 7756 static xmlSchemaAttributeGroupPtr 7757 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 7758 xmlSchemaPtr schema, 7759 xmlNodePtr node) 7760 { 7761 const xmlChar *name; 7762 xmlSchemaAttributeGroupPtr ret; 7763 xmlNodePtr child = NULL; 7764 xmlAttrPtr attr; 7765 int hasRefs = 0; 7766 7767 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7768 return (NULL); 7769 7770 attr = xmlSchemaGetPropNode(node, "name"); 7771 if (attr == NULL) { 7772 xmlSchemaPMissingAttrErr(pctxt, 7773 XML_SCHEMAP_S4S_ATTR_MISSING, 7774 NULL, node, "name", NULL); 7775 return (NULL); 7776 } 7777 /* 7778 * The name is crucial, exit if invalid. 7779 */ 7780 if (xmlSchemaPValAttrNode(pctxt, 7781 NULL, attr, 7782 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7783 return (NULL); 7784 } 7785 ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema, 7786 name, pctxt->targetNamespace, node); 7787 if (ret == NULL) 7788 return (NULL); 7789 /* 7790 * Check for illegal attributes. 7791 */ 7792 attr = node->properties; 7793 while (attr != NULL) { 7794 if (attr->ns == NULL) { 7795 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 7796 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7797 { 7798 xmlSchemaPIllegalAttrErr(pctxt, 7799 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7800 } 7801 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7802 xmlSchemaPIllegalAttrErr(pctxt, 7803 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7804 } 7805 attr = attr->next; 7806 } 7807 /* Attribute ID */ 7808 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7809 /* 7810 * And now for the children... 7811 */ 7812 child = node->children; 7813 if (IS_SCHEMA(child, "annotation")) { 7814 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7815 child = child->next; 7816 } 7817 /* 7818 * Parse contained attribute decls/refs. 7819 */ 7820 if (xmlSchemaParseLocalAttributes(pctxt, schema, &child, 7821 (xmlSchemaItemListPtr *) &(ret->attrUses), 7822 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1) 7823 return(NULL); 7824 if (hasRefs) 7825 ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS; 7826 /* 7827 * Parse the attribute wildcard. 7828 */ 7829 if (IS_SCHEMA(child, "anyAttribute")) { 7830 ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt, 7831 schema, child); 7832 child = child->next; 7833 } 7834 if (child != NULL) { 7835 xmlSchemaPContentErr(pctxt, 7836 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7837 NULL, node, child, NULL, 7838 "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))"); 7839 } 7840 return (ret); 7841 } 7842 7843 /** 7844 * xmlSchemaPValAttrFormDefault: 7845 * @value: the value 7846 * @flags: the flags to be modified 7847 * @flagQualified: the specific flag for "qualified" 7848 * 7849 * Returns 0 if the value is valid, 1 otherwise. 7850 */ 7851 static int 7852 xmlSchemaPValAttrFormDefault(const xmlChar *value, 7853 int *flags, 7854 int flagQualified) 7855 { 7856 if (xmlStrEqual(value, BAD_CAST "qualified")) { 7857 if ((*flags & flagQualified) == 0) 7858 *flags |= flagQualified; 7859 } else if (!xmlStrEqual(value, BAD_CAST "unqualified")) 7860 return (1); 7861 7862 return (0); 7863 } 7864 7865 /** 7866 * xmlSchemaPValAttrBlockFinal: 7867 * @value: the value 7868 * @flags: the flags to be modified 7869 * @flagAll: the specific flag for "#all" 7870 * @flagExtension: the specific flag for "extension" 7871 * @flagRestriction: the specific flag for "restriction" 7872 * @flagSubstitution: the specific flag for "substitution" 7873 * @flagList: the specific flag for "list" 7874 * @flagUnion: the specific flag for "union" 7875 * 7876 * Validates the value of the attribute "final" and "block". The value 7877 * is converted into the specified flag values and returned in @flags. 7878 * 7879 * Returns 0 if the value is valid, 1 otherwise. 7880 */ 7881 7882 static int 7883 xmlSchemaPValAttrBlockFinal(const xmlChar *value, 7884 int *flags, 7885 int flagAll, 7886 int flagExtension, 7887 int flagRestriction, 7888 int flagSubstitution, 7889 int flagList, 7890 int flagUnion) 7891 { 7892 int ret = 0; 7893 7894 /* 7895 * TODO: This does not check for dublicate entries. 7896 */ 7897 if ((flags == NULL) || (value == NULL)) 7898 return (-1); 7899 if (value[0] == 0) 7900 return (0); 7901 if (xmlStrEqual(value, BAD_CAST "#all")) { 7902 if (flagAll != -1) 7903 *flags |= flagAll; 7904 else { 7905 if (flagExtension != -1) 7906 *flags |= flagExtension; 7907 if (flagRestriction != -1) 7908 *flags |= flagRestriction; 7909 if (flagSubstitution != -1) 7910 *flags |= flagSubstitution; 7911 if (flagList != -1) 7912 *flags |= flagList; 7913 if (flagUnion != -1) 7914 *flags |= flagUnion; 7915 } 7916 } else { 7917 const xmlChar *end, *cur = value; 7918 xmlChar *item; 7919 7920 do { 7921 while (IS_BLANK_CH(*cur)) 7922 cur++; 7923 end = cur; 7924 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 7925 end++; 7926 if (end == cur) 7927 break; 7928 item = xmlStrndup(cur, end - cur); 7929 if (xmlStrEqual(item, BAD_CAST "extension")) { 7930 if (flagExtension != -1) { 7931 if ((*flags & flagExtension) == 0) 7932 *flags |= flagExtension; 7933 } else 7934 ret = 1; 7935 } else if (xmlStrEqual(item, BAD_CAST "restriction")) { 7936 if (flagRestriction != -1) { 7937 if ((*flags & flagRestriction) == 0) 7938 *flags |= flagRestriction; 7939 } else 7940 ret = 1; 7941 } else if (xmlStrEqual(item, BAD_CAST "substitution")) { 7942 if (flagSubstitution != -1) { 7943 if ((*flags & flagSubstitution) == 0) 7944 *flags |= flagSubstitution; 7945 } else 7946 ret = 1; 7947 } else if (xmlStrEqual(item, BAD_CAST "list")) { 7948 if (flagList != -1) { 7949 if ((*flags & flagList) == 0) 7950 *flags |= flagList; 7951 } else 7952 ret = 1; 7953 } else if (xmlStrEqual(item, BAD_CAST "union")) { 7954 if (flagUnion != -1) { 7955 if ((*flags & flagUnion) == 0) 7956 *flags |= flagUnion; 7957 } else 7958 ret = 1; 7959 } else 7960 ret = 1; 7961 if (item != NULL) 7962 xmlFree(item); 7963 cur = end; 7964 } while ((ret == 0) && (*cur != 0)); 7965 } 7966 7967 return (ret); 7968 } 7969 7970 static int 7971 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt, 7972 xmlSchemaIDCPtr idc, 7973 xmlSchemaIDCSelectPtr selector, 7974 xmlAttrPtr attr, 7975 int isField) 7976 { 7977 xmlNodePtr node; 7978 7979 /* 7980 * c-selector-xpath: 7981 * Schema Component Constraint: Selector Value OK 7982 * 7983 * TODO: 1 The {selector} must be a valid XPath expression, as defined 7984 * in [XPath]. 7985 */ 7986 if (selector == NULL) { 7987 xmlSchemaPErr(ctxt, idc->node, 7988 XML_SCHEMAP_INTERNAL, 7989 "Internal error: xmlSchemaCheckCSelectorXPath, " 7990 "the selector is not specified.\n", NULL, NULL); 7991 return (-1); 7992 } 7993 if (attr == NULL) 7994 node = idc->node; 7995 else 7996 node = (xmlNodePtr) attr; 7997 if (selector->xpath == NULL) { 7998 xmlSchemaPCustomErr(ctxt, 7999 /* TODO: Adjust error code. */ 8000 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8001 NULL, node, 8002 "The XPath expression of the selector is not valid", NULL); 8003 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8004 } else { 8005 const xmlChar **nsArray = NULL; 8006 xmlNsPtr *nsList = NULL; 8007 /* 8008 * Compile the XPath expression. 8009 */ 8010 /* 8011 * TODO: We need the array of in-scope namespaces for compilation. 8012 * TODO: Call xmlPatterncompile with different options for selector/ 8013 * field. 8014 */ 8015 if (attr == NULL) 8016 nsList = NULL; 8017 else 8018 nsList = xmlGetNsList(attr->doc, attr->parent); 8019 /* 8020 * Build an array of prefixes and namespaces. 8021 */ 8022 if (nsList != NULL) { 8023 int i, count = 0; 8024 8025 for (i = 0; nsList[i] != NULL; i++) 8026 count++; 8027 8028 nsArray = (const xmlChar **) xmlMalloc( 8029 (count * 2 + 1) * sizeof(const xmlChar *)); 8030 if (nsArray == NULL) { 8031 xmlSchemaPErrMemory(ctxt, "allocating a namespace array", 8032 NULL); 8033 xmlFree(nsList); 8034 return (-1); 8035 } 8036 for (i = 0; i < count; i++) { 8037 nsArray[2 * i] = nsList[i]->href; 8038 nsArray[2 * i + 1] = nsList[i]->prefix; 8039 } 8040 nsArray[count * 2] = NULL; 8041 xmlFree(nsList); 8042 } 8043 /* 8044 * TODO: Differentiate between "selector" and "field". 8045 */ 8046 if (isField) 8047 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8048 NULL, XML_PATTERN_XSFIELD, nsArray); 8049 else 8050 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8051 NULL, XML_PATTERN_XSSEL, nsArray); 8052 if (nsArray != NULL) 8053 xmlFree((xmlChar **) nsArray); 8054 8055 if (selector->xpathComp == NULL) { 8056 xmlSchemaPCustomErr(ctxt, 8057 /* TODO: Adjust error code? */ 8058 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8059 NULL, node, 8060 "The XPath expression '%s' could not be " 8061 "compiled", selector->xpath); 8062 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8063 } 8064 } 8065 return (0); 8066 } 8067 8068 #define ADD_ANNOTATION(annot) \ 8069 xmlSchemaAnnotPtr cur = item->annot; \ 8070 if (item->annot == NULL) { \ 8071 item->annot = annot; \ 8072 return (annot); \ 8073 } \ 8074 cur = item->annot; \ 8075 if (cur->next != NULL) { \ 8076 cur = cur->next; \ 8077 } \ 8078 cur->next = annot; 8079 8080 /** 8081 * xmlSchemaAssignAnnotation: 8082 * @item: the schema component 8083 * @annot: the annotation 8084 * 8085 * Adds the annotation to the given schema component. 8086 * 8087 * Returns the given annotaion. 8088 */ 8089 static xmlSchemaAnnotPtr 8090 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem, 8091 xmlSchemaAnnotPtr annot) 8092 { 8093 if ((annItem == NULL) || (annot == NULL)) 8094 return (NULL); 8095 switch (annItem->type) { 8096 case XML_SCHEMA_TYPE_ELEMENT: { 8097 xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem; 8098 ADD_ANNOTATION(annot) 8099 } 8100 break; 8101 case XML_SCHEMA_TYPE_ATTRIBUTE: { 8102 xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem; 8103 ADD_ANNOTATION(annot) 8104 } 8105 break; 8106 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 8107 case XML_SCHEMA_TYPE_ANY: { 8108 xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem; 8109 ADD_ANNOTATION(annot) 8110 } 8111 break; 8112 case XML_SCHEMA_TYPE_PARTICLE: 8113 case XML_SCHEMA_TYPE_IDC_KEY: 8114 case XML_SCHEMA_TYPE_IDC_KEYREF: 8115 case XML_SCHEMA_TYPE_IDC_UNIQUE: { 8116 xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem; 8117 ADD_ANNOTATION(annot) 8118 } 8119 break; 8120 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: { 8121 xmlSchemaAttributeGroupPtr item = 8122 (xmlSchemaAttributeGroupPtr) annItem; 8123 ADD_ANNOTATION(annot) 8124 } 8125 break; 8126 case XML_SCHEMA_TYPE_NOTATION: { 8127 xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem; 8128 ADD_ANNOTATION(annot) 8129 } 8130 break; 8131 case XML_SCHEMA_FACET_MININCLUSIVE: 8132 case XML_SCHEMA_FACET_MINEXCLUSIVE: 8133 case XML_SCHEMA_FACET_MAXINCLUSIVE: 8134 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 8135 case XML_SCHEMA_FACET_TOTALDIGITS: 8136 case XML_SCHEMA_FACET_FRACTIONDIGITS: 8137 case XML_SCHEMA_FACET_PATTERN: 8138 case XML_SCHEMA_FACET_ENUMERATION: 8139 case XML_SCHEMA_FACET_WHITESPACE: 8140 case XML_SCHEMA_FACET_LENGTH: 8141 case XML_SCHEMA_FACET_MAXLENGTH: 8142 case XML_SCHEMA_FACET_MINLENGTH: { 8143 xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem; 8144 ADD_ANNOTATION(annot) 8145 } 8146 break; 8147 case XML_SCHEMA_TYPE_SIMPLE: 8148 case XML_SCHEMA_TYPE_COMPLEX: { 8149 xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem; 8150 ADD_ANNOTATION(annot) 8151 } 8152 break; 8153 case XML_SCHEMA_TYPE_GROUP: { 8154 xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem; 8155 ADD_ANNOTATION(annot) 8156 } 8157 break; 8158 case XML_SCHEMA_TYPE_SEQUENCE: 8159 case XML_SCHEMA_TYPE_CHOICE: 8160 case XML_SCHEMA_TYPE_ALL: { 8161 xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem; 8162 ADD_ANNOTATION(annot) 8163 } 8164 break; 8165 default: 8166 xmlSchemaPCustomErr(NULL, 8167 XML_SCHEMAP_INTERNAL, 8168 NULL, NULL, 8169 "Internal error: xmlSchemaAddAnnotation, " 8170 "The item is not a annotated schema component", NULL); 8171 break; 8172 } 8173 return (annot); 8174 } 8175 8176 /** 8177 * xmlSchemaParseIDCSelectorAndField: 8178 * @ctxt: a schema validation context 8179 * @schema: the schema being built 8180 * @node: a subtree containing XML Schema informations 8181 * 8182 * Parses a XML Schema identity-contraint definition's 8183 * <selector> and <field> elements. 8184 * 8185 * Returns the parsed identity-constraint definition. 8186 */ 8187 static xmlSchemaIDCSelectPtr 8188 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt, 8189 xmlSchemaIDCPtr idc, 8190 xmlNodePtr node, 8191 int isField) 8192 { 8193 xmlSchemaIDCSelectPtr item; 8194 xmlNodePtr child = NULL; 8195 xmlAttrPtr attr; 8196 8197 /* 8198 * Check for illegal attributes. 8199 */ 8200 attr = node->properties; 8201 while (attr != NULL) { 8202 if (attr->ns == NULL) { 8203 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8204 (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) { 8205 xmlSchemaPIllegalAttrErr(ctxt, 8206 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8207 } 8208 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8209 xmlSchemaPIllegalAttrErr(ctxt, 8210 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8211 } 8212 attr = attr->next; 8213 } 8214 /* 8215 * Create the item. 8216 */ 8217 item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect)); 8218 if (item == NULL) { 8219 xmlSchemaPErrMemory(ctxt, 8220 "allocating a 'selector' of an identity-constraint definition", 8221 NULL); 8222 return (NULL); 8223 } 8224 memset(item, 0, sizeof(xmlSchemaIDCSelect)); 8225 /* 8226 * Attribute "xpath" (mandatory). 8227 */ 8228 attr = xmlSchemaGetPropNode(node, "xpath"); 8229 if (attr == NULL) { 8230 xmlSchemaPMissingAttrErr(ctxt, 8231 XML_SCHEMAP_S4S_ATTR_MISSING, 8232 NULL, node, 8233 "name", NULL); 8234 } else { 8235 item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8236 /* 8237 * URGENT TODO: "field"s have an other syntax than "selector"s. 8238 */ 8239 8240 if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr, 8241 isField) == -1) { 8242 xmlSchemaPErr(ctxt, 8243 (xmlNodePtr) attr, 8244 XML_SCHEMAP_INTERNAL, 8245 "Internal error: xmlSchemaParseIDCSelectorAndField, " 8246 "validating the XPath expression of a IDC selector.\n", 8247 NULL, NULL); 8248 } 8249 8250 } 8251 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8252 /* 8253 * And now for the children... 8254 */ 8255 child = node->children; 8256 if (IS_SCHEMA(child, "annotation")) { 8257 /* 8258 * Add the annotation to the parent IDC. 8259 */ 8260 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc, 8261 xmlSchemaParseAnnotation(ctxt, child, 1)); 8262 child = child->next; 8263 } 8264 if (child != NULL) { 8265 xmlSchemaPContentErr(ctxt, 8266 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8267 NULL, node, child, 8268 NULL, "(annotation?)"); 8269 } 8270 8271 return (item); 8272 } 8273 8274 /** 8275 * xmlSchemaParseIDC: 8276 * @ctxt: a schema validation context 8277 * @schema: the schema being built 8278 * @node: a subtree containing XML Schema informations 8279 * 8280 * Parses a XML Schema identity-contraint definition. 8281 * 8282 * Returns the parsed identity-constraint definition. 8283 */ 8284 static xmlSchemaIDCPtr 8285 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt, 8286 xmlSchemaPtr schema, 8287 xmlNodePtr node, 8288 xmlSchemaTypeType idcCategory, 8289 const xmlChar *targetNamespace) 8290 { 8291 xmlSchemaIDCPtr item = NULL; 8292 xmlNodePtr child = NULL; 8293 xmlAttrPtr attr; 8294 const xmlChar *name = NULL; 8295 xmlSchemaIDCSelectPtr field = NULL, lastField = NULL; 8296 8297 /* 8298 * Check for illegal attributes. 8299 */ 8300 attr = node->properties; 8301 while (attr != NULL) { 8302 if (attr->ns == NULL) { 8303 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8304 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 8305 ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) || 8306 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) { 8307 xmlSchemaPIllegalAttrErr(ctxt, 8308 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8309 } 8310 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8311 xmlSchemaPIllegalAttrErr(ctxt, 8312 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8313 } 8314 attr = attr->next; 8315 } 8316 /* 8317 * Attribute "name" (mandatory). 8318 */ 8319 attr = xmlSchemaGetPropNode(node, "name"); 8320 if (attr == NULL) { 8321 xmlSchemaPMissingAttrErr(ctxt, 8322 XML_SCHEMAP_S4S_ATTR_MISSING, 8323 NULL, node, 8324 "name", NULL); 8325 return (NULL); 8326 } else if (xmlSchemaPValAttrNode(ctxt, 8327 NULL, attr, 8328 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 8329 return (NULL); 8330 } 8331 /* Create the component. */ 8332 item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace, 8333 idcCategory, node); 8334 if (item == NULL) 8335 return(NULL); 8336 8337 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8338 if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) { 8339 /* 8340 * Attribute "refer" (mandatory). 8341 */ 8342 attr = xmlSchemaGetPropNode(node, "refer"); 8343 if (attr == NULL) { 8344 xmlSchemaPMissingAttrErr(ctxt, 8345 XML_SCHEMAP_S4S_ATTR_MISSING, 8346 NULL, node, 8347 "refer", NULL); 8348 } else { 8349 /* 8350 * Create a reference item. 8351 */ 8352 item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY, 8353 NULL, NULL); 8354 if (item->ref == NULL) 8355 return (NULL); 8356 xmlSchemaPValAttrNodeQName(ctxt, schema, 8357 NULL, attr, 8358 &(item->ref->targetNamespace), 8359 &(item->ref->name)); 8360 xmlSchemaCheckReference(ctxt, schema, node, attr, 8361 item->ref->targetNamespace); 8362 } 8363 } 8364 /* 8365 * And now for the children... 8366 */ 8367 child = node->children; 8368 if (IS_SCHEMA(child, "annotation")) { 8369 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8370 child = child->next; 8371 } 8372 if (child == NULL) { 8373 xmlSchemaPContentErr(ctxt, 8374 XML_SCHEMAP_S4S_ELEM_MISSING, 8375 NULL, node, child, 8376 "A child element is missing", 8377 "(annotation?, (selector, field+))"); 8378 } 8379 /* 8380 * Child element <selector>. 8381 */ 8382 if (IS_SCHEMA(child, "selector")) { 8383 item->selector = xmlSchemaParseIDCSelectorAndField(ctxt, 8384 item, child, 0); 8385 child = child->next; 8386 /* 8387 * Child elements <field>. 8388 */ 8389 if (IS_SCHEMA(child, "field")) { 8390 do { 8391 field = xmlSchemaParseIDCSelectorAndField(ctxt, 8392 item, child, 1); 8393 if (field != NULL) { 8394 field->index = item->nbFields; 8395 item->nbFields++; 8396 if (lastField != NULL) 8397 lastField->next = field; 8398 else 8399 item->fields = field; 8400 lastField = field; 8401 } 8402 child = child->next; 8403 } while (IS_SCHEMA(child, "field")); 8404 } else { 8405 xmlSchemaPContentErr(ctxt, 8406 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8407 NULL, node, child, 8408 NULL, "(annotation?, (selector, field+))"); 8409 } 8410 } 8411 if (child != NULL) { 8412 xmlSchemaPContentErr(ctxt, 8413 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8414 NULL, node, child, 8415 NULL, "(annotation?, (selector, field+))"); 8416 } 8417 8418 return (item); 8419 } 8420 8421 /** 8422 * xmlSchemaParseElement: 8423 * @ctxt: a schema validation context 8424 * @schema: the schema being built 8425 * @node: a subtree containing XML Schema informations 8426 * @topLevel: indicates if this is global declaration 8427 * 8428 * Parses a XML schema element declaration. 8429 * *WARNING* this interface is highly subject to change 8430 * 8431 * Returns the element declaration or a particle; NULL in case 8432 * of an error or if the particle has minOccurs==maxOccurs==0. 8433 */ 8434 static xmlSchemaBasicItemPtr 8435 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8436 xmlNodePtr node, int *isElemRef, int topLevel) 8437 { 8438 xmlSchemaElementPtr decl = NULL; 8439 xmlSchemaParticlePtr particle = NULL; 8440 xmlSchemaAnnotPtr annot = NULL; 8441 xmlNodePtr child = NULL; 8442 xmlAttrPtr attr, nameAttr; 8443 int min, max, isRef = 0; 8444 xmlChar *des = NULL; 8445 8446 /* 3.3.3 Constraints on XML Representations of Element Declarations */ 8447 /* TODO: Complete implementation of 3.3.6 */ 8448 8449 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8450 return (NULL); 8451 8452 if (isElemRef != NULL) 8453 *isElemRef = 0; 8454 /* 8455 * If we get a "ref" attribute on a local <element> we will assume it's 8456 * a reference - even if there's a "name" attribute; this seems to be more 8457 * robust. 8458 */ 8459 nameAttr = xmlSchemaGetPropNode(node, "name"); 8460 attr = xmlSchemaGetPropNode(node, "ref"); 8461 if ((topLevel) || (attr == NULL)) { 8462 if (nameAttr == NULL) { 8463 xmlSchemaPMissingAttrErr(ctxt, 8464 XML_SCHEMAP_S4S_ATTR_MISSING, 8465 NULL, node, "name", NULL); 8466 return (NULL); 8467 } 8468 } else 8469 isRef = 1; 8470 8471 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8472 child = node->children; 8473 if (IS_SCHEMA(child, "annotation")) { 8474 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8475 child = child->next; 8476 } 8477 /* 8478 * Skip particle part if a global declaration. 8479 */ 8480 if (topLevel) 8481 goto declaration_part; 8482 /* 8483 * The particle part ================================================== 8484 */ 8485 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 8486 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)"); 8487 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 8488 particle = xmlSchemaAddParticle(ctxt, node, min, max); 8489 if (particle == NULL) 8490 goto return_null; 8491 8492 /* ret->flags |= XML_SCHEMAS_ELEM_REF; */ 8493 8494 if (isRef) { 8495 const xmlChar *refNs = NULL, *ref = NULL; 8496 xmlSchemaQNameRefPtr refer = NULL; 8497 /* 8498 * The reference part ============================================= 8499 */ 8500 if (isElemRef != NULL) 8501 *isElemRef = 1; 8502 8503 xmlSchemaPValAttrNodeQName(ctxt, schema, 8504 NULL, attr, &refNs, &ref); 8505 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 8506 /* 8507 * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both" 8508 */ 8509 if (nameAttr != NULL) { 8510 xmlSchemaPMutualExclAttrErr(ctxt, 8511 XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name"); 8512 } 8513 /* 8514 * Check for illegal attributes. 8515 */ 8516 attr = node->properties; 8517 while (attr != NULL) { 8518 if (attr->ns == NULL) { 8519 if (xmlStrEqual(attr->name, BAD_CAST "ref") || 8520 xmlStrEqual(attr->name, BAD_CAST "name") || 8521 xmlStrEqual(attr->name, BAD_CAST "id") || 8522 xmlStrEqual(attr->name, BAD_CAST "maxOccurs") || 8523 xmlStrEqual(attr->name, BAD_CAST "minOccurs")) 8524 { 8525 attr = attr->next; 8526 continue; 8527 } else { 8528 /* SPEC (3.3.3 : 2.2) */ 8529 xmlSchemaPCustomAttrErr(ctxt, 8530 XML_SCHEMAP_SRC_ELEMENT_2_2, 8531 NULL, NULL, attr, 8532 "Only the attributes 'minOccurs', 'maxOccurs' and " 8533 "'id' are allowed in addition to 'ref'"); 8534 break; 8535 } 8536 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8537 xmlSchemaPIllegalAttrErr(ctxt, 8538 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8539 } 8540 attr = attr->next; 8541 } 8542 /* 8543 * No children except <annotation> expected. 8544 */ 8545 if (child != NULL) { 8546 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8547 NULL, node, child, NULL, "(annotation?)"); 8548 } 8549 if ((min == 0) && (max == 0)) 8550 goto return_null; 8551 /* 8552 * Create the reference item and attach it to the particle. 8553 */ 8554 refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT, 8555 ref, refNs); 8556 if (refer == NULL) 8557 goto return_null; 8558 particle->children = (xmlSchemaTreeItemPtr) refer; 8559 particle->annot = annot; 8560 /* 8561 * Add the particle to pending components, since the reference 8562 * need to be resolved. 8563 */ 8564 WXS_ADD_PENDING(ctxt, particle); 8565 return ((xmlSchemaBasicItemPtr) particle); 8566 } 8567 /* 8568 * The declaration part =============================================== 8569 */ 8570 declaration_part: 8571 { 8572 const xmlChar *ns = NULL, *fixed, *name, *attrValue; 8573 xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL; 8574 8575 if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr, 8576 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) 8577 goto return_null; 8578 /* 8579 * Evaluate the target namespace. 8580 */ 8581 if (topLevel) { 8582 ns = ctxt->targetNamespace; 8583 } else { 8584 attr = xmlSchemaGetPropNode(node, "form"); 8585 if (attr != NULL) { 8586 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8587 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 8588 ns = ctxt->targetNamespace; 8589 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) { 8590 xmlSchemaPSimpleTypeErr(ctxt, 8591 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8592 NULL, (xmlNodePtr) attr, 8593 NULL, "(qualified | unqualified)", 8594 attrValue, NULL, NULL, NULL); 8595 } 8596 } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 8597 ns = ctxt->targetNamespace; 8598 } 8599 decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel); 8600 if (decl == NULL) { 8601 goto return_null; 8602 } 8603 /* 8604 * Check for illegal attributes. 8605 */ 8606 attr = node->properties; 8607 while (attr != NULL) { 8608 if (attr->ns == NULL) { 8609 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 8610 (!xmlStrEqual(attr->name, BAD_CAST "type")) && 8611 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 8612 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 8613 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 8614 (!xmlStrEqual(attr->name, BAD_CAST "block")) && 8615 (!xmlStrEqual(attr->name, BAD_CAST "nillable"))) 8616 { 8617 if (topLevel == 0) { 8618 if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 8619 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 8620 (!xmlStrEqual(attr->name, BAD_CAST "form"))) 8621 { 8622 xmlSchemaPIllegalAttrErr(ctxt, 8623 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8624 } 8625 } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) && 8626 (!xmlStrEqual(attr->name, BAD_CAST "abstract")) && 8627 (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) { 8628 8629 xmlSchemaPIllegalAttrErr(ctxt, 8630 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8631 } 8632 } 8633 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8634 8635 xmlSchemaPIllegalAttrErr(ctxt, 8636 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8637 } 8638 attr = attr->next; 8639 } 8640 /* 8641 * Extract/validate attributes. 8642 */ 8643 if (topLevel) { 8644 /* 8645 * Process top attributes of global element declarations here. 8646 */ 8647 decl->flags |= XML_SCHEMAS_ELEM_GLOBAL; 8648 decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL; 8649 xmlSchemaPValAttrQName(ctxt, schema, 8650 NULL, node, "substitutionGroup", 8651 &(decl->substGroupNs), &(decl->substGroup)); 8652 if (xmlGetBooleanProp(ctxt, node, "abstract", 0)) 8653 decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT; 8654 /* 8655 * Attribute "final". 8656 */ 8657 attr = xmlSchemaGetPropNode(node, "final"); 8658 if (attr == NULL) { 8659 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 8660 decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION; 8661 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 8662 decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION; 8663 } else { 8664 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8665 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8666 -1, 8667 XML_SCHEMAS_ELEM_FINAL_EXTENSION, 8668 XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) { 8669 xmlSchemaPSimpleTypeErr(ctxt, 8670 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8671 NULL, (xmlNodePtr) attr, 8672 NULL, "(#all | List of (extension | restriction))", 8673 attrValue, NULL, NULL, NULL); 8674 } 8675 } 8676 } 8677 /* 8678 * Attribute "block". 8679 */ 8680 attr = xmlSchemaGetPropNode(node, "block"); 8681 if (attr == NULL) { 8682 /* 8683 * Apply default "block" values. 8684 */ 8685 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 8686 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION; 8687 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 8688 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION; 8689 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 8690 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION; 8691 } else { 8692 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8693 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8694 -1, 8695 XML_SCHEMAS_ELEM_BLOCK_EXTENSION, 8696 XML_SCHEMAS_ELEM_BLOCK_RESTRICTION, 8697 XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) { 8698 xmlSchemaPSimpleTypeErr(ctxt, 8699 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8700 NULL, (xmlNodePtr) attr, 8701 NULL, "(#all | List of (extension | " 8702 "restriction | substitution))", attrValue, 8703 NULL, NULL, NULL); 8704 } 8705 } 8706 if (xmlGetBooleanProp(ctxt, node, "nillable", 0)) 8707 decl->flags |= XML_SCHEMAS_ELEM_NILLABLE; 8708 8709 attr = xmlSchemaGetPropNode(node, "type"); 8710 if (attr != NULL) { 8711 xmlSchemaPValAttrNodeQName(ctxt, schema, 8712 NULL, attr, 8713 &(decl->namedTypeNs), &(decl->namedType)); 8714 xmlSchemaCheckReference(ctxt, schema, node, 8715 attr, decl->namedTypeNs); 8716 } 8717 decl->value = xmlSchemaGetProp(ctxt, node, "default"); 8718 attr = xmlSchemaGetPropNode(node, "fixed"); 8719 if (attr != NULL) { 8720 fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8721 if (decl->value != NULL) { 8722 /* 8723 * 3.3.3 : 1 8724 * default and fixed must not both be present. 8725 */ 8726 xmlSchemaPMutualExclAttrErr(ctxt, 8727 XML_SCHEMAP_SRC_ELEMENT_1, 8728 NULL, attr, "default", "fixed"); 8729 } else { 8730 decl->flags |= XML_SCHEMAS_ELEM_FIXED; 8731 decl->value = fixed; 8732 } 8733 } 8734 /* 8735 * And now for the children... 8736 */ 8737 if (IS_SCHEMA(child, "complexType")) { 8738 /* 8739 * 3.3.3 : 3 8740 * "type" and either <simpleType> or <complexType> are mutually 8741 * exclusive 8742 */ 8743 if (decl->namedType != NULL) { 8744 xmlSchemaPContentErr(ctxt, 8745 XML_SCHEMAP_SRC_ELEMENT_3, 8746 NULL, node, child, 8747 "The attribute 'type' and the <complexType> child are " 8748 "mutually exclusive", NULL); 8749 } else 8750 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0); 8751 child = child->next; 8752 } else if (IS_SCHEMA(child, "simpleType")) { 8753 /* 8754 * 3.3.3 : 3 8755 * "type" and either <simpleType> or <complexType> are 8756 * mutually exclusive 8757 */ 8758 if (decl->namedType != NULL) { 8759 xmlSchemaPContentErr(ctxt, 8760 XML_SCHEMAP_SRC_ELEMENT_3, 8761 NULL, node, child, 8762 "The attribute 'type' and the <simpleType> child are " 8763 "mutually exclusive", NULL); 8764 } else 8765 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 8766 child = child->next; 8767 } 8768 while ((IS_SCHEMA(child, "unique")) || 8769 (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) { 8770 if (IS_SCHEMA(child, "unique")) { 8771 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8772 XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace); 8773 } else if (IS_SCHEMA(child, "key")) { 8774 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8775 XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace); 8776 } else if (IS_SCHEMA(child, "keyref")) { 8777 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8778 XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace); 8779 } 8780 if (lastIDC != NULL) 8781 lastIDC->next = curIDC; 8782 else 8783 decl->idcs = (void *) curIDC; 8784 lastIDC = curIDC; 8785 child = child->next; 8786 } 8787 if (child != NULL) { 8788 xmlSchemaPContentErr(ctxt, 8789 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8790 NULL, node, child, 8791 NULL, "(annotation?, ((simpleType | complexType)?, " 8792 "(unique | key | keyref)*))"); 8793 } 8794 decl->annot = annot; 8795 } 8796 /* 8797 * NOTE: Element Declaration Representation OK 4. will be checked at a 8798 * different layer. 8799 */ 8800 FREE_AND_NULL(des) 8801 if (topLevel) 8802 return ((xmlSchemaBasicItemPtr) decl); 8803 else { 8804 particle->children = (xmlSchemaTreeItemPtr) decl; 8805 return ((xmlSchemaBasicItemPtr) particle); 8806 } 8807 8808 return_null: 8809 FREE_AND_NULL(des); 8810 if (annot != NULL) { 8811 if (particle != NULL) 8812 particle->annot = NULL; 8813 if (decl != NULL) 8814 decl->annot = NULL; 8815 xmlSchemaFreeAnnot(annot); 8816 } 8817 return (NULL); 8818 } 8819 8820 /** 8821 * xmlSchemaParseUnion: 8822 * @ctxt: a schema validation context 8823 * @schema: the schema being built 8824 * @node: a subtree containing XML Schema informations 8825 * 8826 * parse a XML schema Union definition 8827 * *WARNING* this interface is highly subject to change 8828 * 8829 * Returns -1 in case of internal error, 0 in case of success and a positive 8830 * error code otherwise. 8831 */ 8832 static int 8833 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8834 xmlNodePtr node) 8835 { 8836 xmlSchemaTypePtr type; 8837 xmlNodePtr child = NULL; 8838 xmlAttrPtr attr; 8839 const xmlChar *cur = NULL; 8840 8841 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8842 return (-1); 8843 /* Not a component, don't create it. */ 8844 type = ctxt->ctxtType; 8845 /* 8846 * Mark the simple type as being of variety "union". 8847 */ 8848 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 8849 /* 8850 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 8851 * then the simple ur-type definition." 8852 */ 8853 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 8854 /* 8855 * Check for illegal attributes. 8856 */ 8857 attr = node->properties; 8858 while (attr != NULL) { 8859 if (attr->ns == NULL) { 8860 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8861 (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) { 8862 xmlSchemaPIllegalAttrErr(ctxt, 8863 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8864 } 8865 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8866 xmlSchemaPIllegalAttrErr(ctxt, 8867 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8868 } 8869 attr = attr->next; 8870 } 8871 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8872 /* 8873 * Attribute "memberTypes". This is a list of QNames. 8874 * TODO: Check the value to contain anything. 8875 */ 8876 attr = xmlSchemaGetPropNode(node, "memberTypes"); 8877 if (attr != NULL) { 8878 const xmlChar *end; 8879 xmlChar *tmp; 8880 const xmlChar *localName, *nsName; 8881 xmlSchemaTypeLinkPtr link, lastLink = NULL; 8882 xmlSchemaQNameRefPtr ref; 8883 8884 cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8885 type->base = cur; 8886 do { 8887 while (IS_BLANK_CH(*cur)) 8888 cur++; 8889 end = cur; 8890 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 8891 end++; 8892 if (end == cur) 8893 break; 8894 tmp = xmlStrndup(cur, end - cur); 8895 if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 8896 NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) { 8897 /* 8898 * Create the member type link. 8899 */ 8900 link = (xmlSchemaTypeLinkPtr) 8901 xmlMalloc(sizeof(xmlSchemaTypeLink)); 8902 if (link == NULL) { 8903 xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, " 8904 "allocating a type link", NULL); 8905 return (-1); 8906 } 8907 link->type = NULL; 8908 link->next = NULL; 8909 if (lastLink == NULL) 8910 type->memberTypes = link; 8911 else 8912 lastLink->next = link; 8913 lastLink = link; 8914 /* 8915 * Create a reference item. 8916 */ 8917 ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE, 8918 localName, nsName); 8919 if (ref == NULL) { 8920 FREE_AND_NULL(tmp) 8921 return (-1); 8922 } 8923 /* 8924 * Assign the reference to the link, it will be resolved 8925 * later during fixup of the union simple type. 8926 */ 8927 link->type = (xmlSchemaTypePtr) ref; 8928 } 8929 FREE_AND_NULL(tmp) 8930 cur = end; 8931 } while (*cur != 0); 8932 8933 } 8934 /* 8935 * And now for the children... 8936 */ 8937 child = node->children; 8938 if (IS_SCHEMA(child, "annotation")) { 8939 /* 8940 * Add the annotation to the simple type ancestor. 8941 */ 8942 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 8943 xmlSchemaParseAnnotation(ctxt, child, 1)); 8944 child = child->next; 8945 } 8946 if (IS_SCHEMA(child, "simpleType")) { 8947 xmlSchemaTypePtr subtype, last = NULL; 8948 8949 /* 8950 * Anchor the member types in the "subtypes" field of the 8951 * simple type. 8952 */ 8953 while (IS_SCHEMA(child, "simpleType")) { 8954 subtype = (xmlSchemaTypePtr) 8955 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 8956 if (subtype != NULL) { 8957 if (last == NULL) { 8958 type->subtypes = subtype; 8959 last = subtype; 8960 } else { 8961 last->next = subtype; 8962 last = subtype; 8963 } 8964 last->next = NULL; 8965 } 8966 child = child->next; 8967 } 8968 } 8969 if (child != NULL) { 8970 xmlSchemaPContentErr(ctxt, 8971 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8972 NULL, node, child, NULL, "(annotation?, simpleType*)"); 8973 } 8974 if ((attr == NULL) && (type->subtypes == NULL)) { 8975 /* 8976 * src-union-memberTypes-or-simpleTypes 8977 * Either the memberTypes [attribute] of the <union> element must 8978 * be non-empty or there must be at least one simpleType [child]. 8979 */ 8980 xmlSchemaPCustomErr(ctxt, 8981 XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES, 8982 NULL, node, 8983 "Either the attribute 'memberTypes' or " 8984 "at least one <simpleType> child must be present", NULL); 8985 } 8986 return (0); 8987 } 8988 8989 /** 8990 * xmlSchemaParseList: 8991 * @ctxt: a schema validation context 8992 * @schema: the schema being built 8993 * @node: a subtree containing XML Schema informations 8994 * 8995 * parse a XML schema List definition 8996 * *WARNING* this interface is highly subject to change 8997 * 8998 * Returns -1 in case of error, 0 if the declaration is improper and 8999 * 1 in case of success. 9000 */ 9001 static xmlSchemaTypePtr 9002 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9003 xmlNodePtr node) 9004 { 9005 xmlSchemaTypePtr type; 9006 xmlNodePtr child = NULL; 9007 xmlAttrPtr attr; 9008 9009 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9010 return (NULL); 9011 /* Not a component, don't create it. */ 9012 type = ctxt->ctxtType; 9013 /* 9014 * Mark the type as being of variety "list". 9015 */ 9016 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 9017 /* 9018 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 9019 * then the simple ur-type definition." 9020 */ 9021 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 9022 /* 9023 * Check for illegal attributes. 9024 */ 9025 attr = node->properties; 9026 while (attr != NULL) { 9027 if (attr->ns == NULL) { 9028 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9029 (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) { 9030 xmlSchemaPIllegalAttrErr(ctxt, 9031 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9032 } 9033 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9034 xmlSchemaPIllegalAttrErr(ctxt, 9035 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9036 } 9037 attr = attr->next; 9038 } 9039 9040 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9041 9042 /* 9043 * Attribute "itemType". NOTE that we will use the "ref" and "refNs" 9044 * fields for holding the reference to the itemType. 9045 * 9046 * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove 9047 * the "ref" fields. 9048 */ 9049 xmlSchemaPValAttrQName(ctxt, schema, NULL, 9050 node, "itemType", &(type->baseNs), &(type->base)); 9051 /* 9052 * And now for the children... 9053 */ 9054 child = node->children; 9055 if (IS_SCHEMA(child, "annotation")) { 9056 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 9057 xmlSchemaParseAnnotation(ctxt, child, 1)); 9058 child = child->next; 9059 } 9060 if (IS_SCHEMA(child, "simpleType")) { 9061 /* 9062 * src-list-itemType-or-simpleType 9063 * Either the itemType [attribute] or the <simpleType> [child] of 9064 * the <list> element must be present, but not both. 9065 */ 9066 if (type->base != NULL) { 9067 xmlSchemaPCustomErr(ctxt, 9068 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9069 NULL, node, 9070 "The attribute 'itemType' and the <simpleType> child " 9071 "are mutually exclusive", NULL); 9072 } else { 9073 type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 9074 } 9075 child = child->next; 9076 } else if (type->base == NULL) { 9077 xmlSchemaPCustomErr(ctxt, 9078 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9079 NULL, node, 9080 "Either the attribute 'itemType' or the <simpleType> child " 9081 "must be present", NULL); 9082 } 9083 if (child != NULL) { 9084 xmlSchemaPContentErr(ctxt, 9085 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9086 NULL, node, child, NULL, "(annotation?, simpleType?)"); 9087 } 9088 if ((type->base == NULL) && 9089 (type->subtypes == NULL) && 9090 (xmlSchemaGetPropNode(node, "itemType") == NULL)) { 9091 xmlSchemaPCustomErr(ctxt, 9092 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9093 NULL, node, 9094 "Either the attribute 'itemType' or the <simpleType> child " 9095 "must be present", NULL); 9096 } 9097 return (NULL); 9098 } 9099 9100 /** 9101 * xmlSchemaParseSimpleType: 9102 * @ctxt: a schema validation context 9103 * @schema: the schema being built 9104 * @node: a subtree containing XML Schema informations 9105 * 9106 * parse a XML schema Simple Type definition 9107 * *WARNING* this interface is highly subject to change 9108 * 9109 * Returns -1 in case of error, 0 if the declaration is improper and 9110 * 1 in case of success. 9111 */ 9112 static xmlSchemaTypePtr 9113 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9114 xmlNodePtr node, int topLevel) 9115 { 9116 xmlSchemaTypePtr type, oldCtxtType; 9117 xmlNodePtr child = NULL; 9118 const xmlChar *attrValue = NULL; 9119 xmlAttrPtr attr; 9120 int hasRestriction = 0; 9121 9122 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9123 return (NULL); 9124 9125 if (topLevel) { 9126 attr = xmlSchemaGetPropNode(node, "name"); 9127 if (attr == NULL) { 9128 xmlSchemaPMissingAttrErr(ctxt, 9129 XML_SCHEMAP_S4S_ATTR_MISSING, 9130 NULL, node, 9131 "name", NULL); 9132 return (NULL); 9133 } else { 9134 if (xmlSchemaPValAttrNode(ctxt, 9135 NULL, attr, 9136 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) 9137 return (NULL); 9138 /* 9139 * Skip built-in types. 9140 */ 9141 if (ctxt->isS4S) { 9142 xmlSchemaTypePtr biType; 9143 9144 if (ctxt->isRedefine) { 9145 /* 9146 * REDEFINE: Disallow redefinition of built-in-types. 9147 * TODO: It seems that the spec does not say anything 9148 * about this case. 9149 */ 9150 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9151 NULL, node, 9152 "Redefinition of built-in simple types is not " 9153 "supported", NULL); 9154 return(NULL); 9155 } 9156 biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs); 9157 if (biType != NULL) 9158 return (biType); 9159 } 9160 } 9161 } 9162 /* 9163 * TargetNamespace: 9164 * SPEC "The actual value of the targetNamespace [attribute] 9165 * of the <schema> ancestor element information item if present, 9166 * otherwise absent. 9167 */ 9168 if (topLevel == 0) { 9169 #ifdef ENABLE_NAMED_LOCALS 9170 char buf[40]; 9171 #endif 9172 /* 9173 * Parse as local simple type definition. 9174 */ 9175 #ifdef ENABLE_NAMED_LOCALS 9176 snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1); 9177 type = xmlSchemaAddType(ctxt, schema, 9178 XML_SCHEMA_TYPE_SIMPLE, 9179 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 9180 ctxt->targetNamespace, node, 0); 9181 #else 9182 type = xmlSchemaAddType(ctxt, schema, 9183 XML_SCHEMA_TYPE_SIMPLE, 9184 NULL, ctxt->targetNamespace, node, 0); 9185 #endif 9186 if (type == NULL) 9187 return (NULL); 9188 type->type = XML_SCHEMA_TYPE_SIMPLE; 9189 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9190 /* 9191 * Check for illegal attributes. 9192 */ 9193 attr = node->properties; 9194 while (attr != NULL) { 9195 if (attr->ns == NULL) { 9196 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 9197 xmlSchemaPIllegalAttrErr(ctxt, 9198 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9199 } 9200 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9201 xmlSchemaPIllegalAttrErr(ctxt, 9202 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9203 } 9204 attr = attr->next; 9205 } 9206 } else { 9207 /* 9208 * Parse as global simple type definition. 9209 * 9210 * Note that attrValue is the value of the attribute "name" here. 9211 */ 9212 type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE, 9213 attrValue, ctxt->targetNamespace, node, 1); 9214 if (type == NULL) 9215 return (NULL); 9216 type->type = XML_SCHEMA_TYPE_SIMPLE; 9217 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9218 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 9219 /* 9220 * Check for illegal attributes. 9221 */ 9222 attr = node->properties; 9223 while (attr != NULL) { 9224 if (attr->ns == NULL) { 9225 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9226 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 9227 (!xmlStrEqual(attr->name, BAD_CAST "final"))) { 9228 xmlSchemaPIllegalAttrErr(ctxt, 9229 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9230 } 9231 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9232 xmlSchemaPIllegalAttrErr(ctxt, 9233 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9234 } 9235 attr = attr->next; 9236 } 9237 /* 9238 * Attribute "final". 9239 */ 9240 attr = xmlSchemaGetPropNode(node, "final"); 9241 if (attr == NULL) { 9242 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9243 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 9244 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9245 type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST; 9246 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9247 type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION; 9248 } else { 9249 attrValue = xmlSchemaGetProp(ctxt, node, "final"); 9250 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 9251 -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1, 9252 XML_SCHEMAS_TYPE_FINAL_LIST, 9253 XML_SCHEMAS_TYPE_FINAL_UNION) != 0) { 9254 9255 xmlSchemaPSimpleTypeErr(ctxt, 9256 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9257 WXS_BASIC_CAST type, (xmlNodePtr) attr, 9258 NULL, "(#all | List of (list | union | restriction)", 9259 attrValue, NULL, NULL, NULL); 9260 } 9261 } 9262 } 9263 type->targetNamespace = ctxt->targetNamespace; 9264 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9265 /* 9266 * And now for the children... 9267 */ 9268 oldCtxtType = ctxt->ctxtType; 9269 9270 ctxt->ctxtType = type; 9271 9272 child = node->children; 9273 if (IS_SCHEMA(child, "annotation")) { 9274 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9275 child = child->next; 9276 } 9277 if (child == NULL) { 9278 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING, 9279 NULL, node, child, NULL, 9280 "(annotation?, (restriction | list | union))"); 9281 } else if (IS_SCHEMA(child, "restriction")) { 9282 xmlSchemaParseRestriction(ctxt, schema, child, 9283 XML_SCHEMA_TYPE_SIMPLE); 9284 hasRestriction = 1; 9285 child = child->next; 9286 } else if (IS_SCHEMA(child, "list")) { 9287 xmlSchemaParseList(ctxt, schema, child); 9288 child = child->next; 9289 } else if (IS_SCHEMA(child, "union")) { 9290 xmlSchemaParseUnion(ctxt, schema, child); 9291 child = child->next; 9292 } 9293 if (child != NULL) { 9294 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9295 NULL, node, child, NULL, 9296 "(annotation?, (restriction | list | union))"); 9297 } 9298 /* 9299 * REDEFINE: SPEC src-redefine (5) 9300 * "Within the [children], each <simpleType> must have a 9301 * <restriction> among its [children] ... the actual value of whose 9302 * base [attribute] must be the same as the actual value of its own 9303 * name attribute plus target namespace;" 9304 */ 9305 if (topLevel && ctxt->isRedefine && (! hasRestriction)) { 9306 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9307 NULL, node, "This is a redefinition, thus the " 9308 "<simpleType> must have a <restriction> child", NULL); 9309 } 9310 9311 ctxt->ctxtType = oldCtxtType; 9312 return (type); 9313 } 9314 9315 /** 9316 * xmlSchemaParseModelGroupDefRef: 9317 * @ctxt: the parser context 9318 * @schema: the schema being built 9319 * @node: the node 9320 * 9321 * Parses a reference to a model group definition. 9322 * 9323 * We will return a particle component with a qname-component or 9324 * NULL in case of an error. 9325 */ 9326 static xmlSchemaTreeItemPtr 9327 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt, 9328 xmlSchemaPtr schema, 9329 xmlNodePtr node) 9330 { 9331 xmlSchemaParticlePtr item; 9332 xmlNodePtr child = NULL; 9333 xmlAttrPtr attr; 9334 const xmlChar *ref = NULL, *refNs = NULL; 9335 int min, max; 9336 9337 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9338 return (NULL); 9339 9340 attr = xmlSchemaGetPropNode(node, "ref"); 9341 if (attr == NULL) { 9342 xmlSchemaPMissingAttrErr(ctxt, 9343 XML_SCHEMAP_S4S_ATTR_MISSING, 9344 NULL, node, "ref", NULL); 9345 return (NULL); 9346 } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL, 9347 attr, &refNs, &ref) != 0) { 9348 return (NULL); 9349 } 9350 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 9351 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 9352 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 9353 "(xs:nonNegativeInteger | unbounded)"); 9354 /* 9355 * Check for illegal attributes. 9356 */ 9357 attr = node->properties; 9358 while (attr != NULL) { 9359 if (attr->ns == NULL) { 9360 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 9361 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 9362 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 9363 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) { 9364 xmlSchemaPIllegalAttrErr(ctxt, 9365 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9366 } 9367 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9368 xmlSchemaPIllegalAttrErr(ctxt, 9369 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9370 } 9371 attr = attr->next; 9372 } 9373 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9374 item = xmlSchemaAddParticle(ctxt, node, min, max); 9375 if (item == NULL) 9376 return (NULL); 9377 /* 9378 * Create a qname-reference and set as the term; it will be substituted 9379 * for the model group after the reference has been resolved. 9380 */ 9381 item->children = (xmlSchemaTreeItemPtr) 9382 xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs); 9383 xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max); 9384 /* 9385 * And now for the children... 9386 */ 9387 child = node->children; 9388 /* TODO: Is annotation even allowed for a model group reference? */ 9389 if (IS_SCHEMA(child, "annotation")) { 9390 /* 9391 * TODO: What to do exactly with the annotation? 9392 */ 9393 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9394 child = child->next; 9395 } 9396 if (child != NULL) { 9397 xmlSchemaPContentErr(ctxt, 9398 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9399 NULL, node, child, NULL, 9400 "(annotation?)"); 9401 } 9402 /* 9403 * Corresponds to no component at all if minOccurs==maxOccurs==0. 9404 */ 9405 if ((min == 0) && (max == 0)) 9406 return (NULL); 9407 9408 return ((xmlSchemaTreeItemPtr) item); 9409 } 9410 9411 /** 9412 * xmlSchemaParseModelGroupDefinition: 9413 * @ctxt: a schema validation context 9414 * @schema: the schema being built 9415 * @node: a subtree containing XML Schema informations 9416 * 9417 * Parses a XML schema model group definition. 9418 * 9419 * Note that the contraint src-redefine (6.2) can't be applied until 9420 * references have been resolved. So we will do this at the 9421 * component fixup level. 9422 * 9423 * *WARNING* this interface is highly subject to change 9424 * 9425 * Returns -1 in case of error, 0 if the declaration is improper and 9426 * 1 in case of success. 9427 */ 9428 static xmlSchemaModelGroupDefPtr 9429 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 9430 xmlSchemaPtr schema, 9431 xmlNodePtr node) 9432 { 9433 xmlSchemaModelGroupDefPtr item; 9434 xmlNodePtr child = NULL; 9435 xmlAttrPtr attr; 9436 const xmlChar *name; 9437 9438 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9439 return (NULL); 9440 9441 attr = xmlSchemaGetPropNode(node, "name"); 9442 if (attr == NULL) { 9443 xmlSchemaPMissingAttrErr(ctxt, 9444 XML_SCHEMAP_S4S_ATTR_MISSING, 9445 NULL, node, 9446 "name", NULL); 9447 return (NULL); 9448 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 9449 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 9450 return (NULL); 9451 } 9452 item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name, 9453 ctxt->targetNamespace, node); 9454 if (item == NULL) 9455 return (NULL); 9456 /* 9457 * Check for illegal attributes. 9458 */ 9459 attr = node->properties; 9460 while (attr != NULL) { 9461 if (attr->ns == NULL) { 9462 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 9463 (!xmlStrEqual(attr->name, BAD_CAST "id"))) { 9464 xmlSchemaPIllegalAttrErr(ctxt, 9465 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9466 } 9467 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9468 xmlSchemaPIllegalAttrErr(ctxt, 9469 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9470 } 9471 attr = attr->next; 9472 } 9473 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9474 /* 9475 * And now for the children... 9476 */ 9477 child = node->children; 9478 if (IS_SCHEMA(child, "annotation")) { 9479 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9480 child = child->next; 9481 } 9482 if (IS_SCHEMA(child, "all")) { 9483 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9484 XML_SCHEMA_TYPE_ALL, 0); 9485 child = child->next; 9486 } else if (IS_SCHEMA(child, "choice")) { 9487 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9488 XML_SCHEMA_TYPE_CHOICE, 0); 9489 child = child->next; 9490 } else if (IS_SCHEMA(child, "sequence")) { 9491 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9492 XML_SCHEMA_TYPE_SEQUENCE, 0); 9493 child = child->next; 9494 } 9495 9496 9497 9498 if (child != NULL) { 9499 xmlSchemaPContentErr(ctxt, 9500 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9501 NULL, node, child, NULL, 9502 "(annotation?, (all | choice | sequence)?)"); 9503 } 9504 return (item); 9505 } 9506 9507 /** 9508 * xmlSchemaCleanupDoc: 9509 * @ctxt: a schema validation context 9510 * @node: the root of the document. 9511 * 9512 * removes unwanted nodes in a schemas document tree 9513 */ 9514 static void 9515 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root) 9516 { 9517 xmlNodePtr delete, cur; 9518 9519 if ((ctxt == NULL) || (root == NULL)) return; 9520 9521 /* 9522 * Remove all the blank text nodes 9523 */ 9524 delete = NULL; 9525 cur = root; 9526 while (cur != NULL) { 9527 if (delete != NULL) { 9528 xmlUnlinkNode(delete); 9529 xmlFreeNode(delete); 9530 delete = NULL; 9531 } 9532 if (cur->type == XML_TEXT_NODE) { 9533 if (IS_BLANK_NODE(cur)) { 9534 if (xmlNodeGetSpacePreserve(cur) != 1) { 9535 delete = cur; 9536 } 9537 } 9538 } else if ((cur->type != XML_ELEMENT_NODE) && 9539 (cur->type != XML_CDATA_SECTION_NODE)) { 9540 delete = cur; 9541 goto skip_children; 9542 } 9543 9544 /* 9545 * Skip to next node 9546 */ 9547 if (cur->children != NULL) { 9548 if ((cur->children->type != XML_ENTITY_DECL) && 9549 (cur->children->type != XML_ENTITY_REF_NODE) && 9550 (cur->children->type != XML_ENTITY_NODE)) { 9551 cur = cur->children; 9552 continue; 9553 } 9554 } 9555 skip_children: 9556 if (cur->next != NULL) { 9557 cur = cur->next; 9558 continue; 9559 } 9560 9561 do { 9562 cur = cur->parent; 9563 if (cur == NULL) 9564 break; 9565 if (cur == root) { 9566 cur = NULL; 9567 break; 9568 } 9569 if (cur->next != NULL) { 9570 cur = cur->next; 9571 break; 9572 } 9573 } while (cur != NULL); 9574 } 9575 if (delete != NULL) { 9576 xmlUnlinkNode(delete); 9577 xmlFreeNode(delete); 9578 delete = NULL; 9579 } 9580 } 9581 9582 9583 static void 9584 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema) 9585 { 9586 if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 9587 schema->flags ^= XML_SCHEMAS_QUALIF_ELEM; 9588 9589 if (schema->flags & XML_SCHEMAS_QUALIF_ATTR) 9590 schema->flags ^= XML_SCHEMAS_QUALIF_ATTR; 9591 9592 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 9593 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION; 9594 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9595 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION; 9596 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9597 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST; 9598 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9599 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION; 9600 9601 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 9602 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION; 9603 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 9604 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION; 9605 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 9606 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION; 9607 } 9608 9609 static int 9610 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt, 9611 xmlSchemaPtr schema, 9612 xmlNodePtr node) 9613 { 9614 xmlAttrPtr attr; 9615 const xmlChar *val; 9616 int res = 0, oldErrs = ctxt->nberrors; 9617 9618 /* 9619 * Those flags should be moved to the parser context flags, 9620 * since they are not visible at the component level. I.e. 9621 * they are used if processing schema *documents* only. 9622 */ 9623 res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9624 HFAILURE; 9625 9626 /* 9627 * Since the version is of type xs:token, we won't bother to 9628 * check it. 9629 */ 9630 /* REMOVED: 9631 attr = xmlSchemaGetPropNode(node, "version"); 9632 if (attr != NULL) { 9633 res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr, 9634 xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val); 9635 HFAILURE; 9636 } 9637 */ 9638 attr = xmlSchemaGetPropNode(node, "targetNamespace"); 9639 if (attr != NULL) { 9640 res = xmlSchemaPValAttrNode(ctxt, NULL, attr, 9641 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 9642 HFAILURE; 9643 if (res != 0) { 9644 ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 9645 goto exit; 9646 } 9647 } 9648 attr = xmlSchemaGetPropNode(node, "elementFormDefault"); 9649 if (attr != NULL) { 9650 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9651 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9652 XML_SCHEMAS_QUALIF_ELEM); 9653 HFAILURE; 9654 if (res != 0) { 9655 xmlSchemaPSimpleTypeErr(ctxt, 9656 XML_SCHEMAP_ELEMFORMDEFAULT_VALUE, 9657 NULL, (xmlNodePtr) attr, NULL, 9658 "(qualified | unqualified)", val, NULL, NULL, NULL); 9659 } 9660 } 9661 attr = xmlSchemaGetPropNode(node, "attributeFormDefault"); 9662 if (attr != NULL) { 9663 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9664 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9665 XML_SCHEMAS_QUALIF_ATTR); 9666 HFAILURE; 9667 if (res != 0) { 9668 xmlSchemaPSimpleTypeErr(ctxt, 9669 XML_SCHEMAP_ATTRFORMDEFAULT_VALUE, 9670 NULL, (xmlNodePtr) attr, NULL, 9671 "(qualified | unqualified)", val, NULL, NULL, NULL); 9672 } 9673 } 9674 attr = xmlSchemaGetPropNode(node, "finalDefault"); 9675 if (attr != NULL) { 9676 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9677 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9678 XML_SCHEMAS_FINAL_DEFAULT_EXTENSION, 9679 XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION, 9680 -1, 9681 XML_SCHEMAS_FINAL_DEFAULT_LIST, 9682 XML_SCHEMAS_FINAL_DEFAULT_UNION); 9683 HFAILURE; 9684 if (res != 0) { 9685 xmlSchemaPSimpleTypeErr(ctxt, 9686 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9687 NULL, (xmlNodePtr) attr, NULL, 9688 "(#all | List of (extension | restriction | list | union))", 9689 val, NULL, NULL, NULL); 9690 } 9691 } 9692 attr = xmlSchemaGetPropNode(node, "blockDefault"); 9693 if (attr != NULL) { 9694 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9695 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9696 XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION, 9697 XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION, 9698 XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1); 9699 HFAILURE; 9700 if (res != 0) { 9701 xmlSchemaPSimpleTypeErr(ctxt, 9702 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9703 NULL, (xmlNodePtr) attr, NULL, 9704 "(#all | List of (extension | restriction | substitution))", 9705 val, NULL, NULL, NULL); 9706 } 9707 } 9708 9709 exit: 9710 if (oldErrs != ctxt->nberrors) 9711 res = ctxt->err; 9712 return(res); 9713 exit_failure: 9714 return(-1); 9715 } 9716 9717 /** 9718 * xmlSchemaParseSchemaTopLevel: 9719 * @ctxt: a schema validation context 9720 * @schema: the schemas 9721 * @nodes: the list of top level nodes 9722 * 9723 * Returns the internal XML Schema structure built from the resource or 9724 * NULL in case of error 9725 */ 9726 static int 9727 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt, 9728 xmlSchemaPtr schema, xmlNodePtr nodes) 9729 { 9730 xmlNodePtr child; 9731 xmlSchemaAnnotPtr annot; 9732 int res = 0, oldErrs, tmpOldErrs; 9733 9734 if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL)) 9735 return(-1); 9736 9737 oldErrs = ctxt->nberrors; 9738 child = nodes; 9739 while ((IS_SCHEMA(child, "include")) || 9740 (IS_SCHEMA(child, "import")) || 9741 (IS_SCHEMA(child, "redefine")) || 9742 (IS_SCHEMA(child, "annotation"))) { 9743 if (IS_SCHEMA(child, "annotation")) { 9744 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9745 if (schema->annot == NULL) 9746 schema->annot = annot; 9747 else 9748 xmlSchemaFreeAnnot(annot); 9749 } else if (IS_SCHEMA(child, "import")) { 9750 tmpOldErrs = ctxt->nberrors; 9751 res = xmlSchemaParseImport(ctxt, schema, child); 9752 HFAILURE; 9753 HSTOP(ctxt); 9754 if (tmpOldErrs != ctxt->nberrors) 9755 goto exit; 9756 } else if (IS_SCHEMA(child, "include")) { 9757 tmpOldErrs = ctxt->nberrors; 9758 res = xmlSchemaParseInclude(ctxt, schema, child); 9759 HFAILURE; 9760 HSTOP(ctxt); 9761 if (tmpOldErrs != ctxt->nberrors) 9762 goto exit; 9763 } else if (IS_SCHEMA(child, "redefine")) { 9764 tmpOldErrs = ctxt->nberrors; 9765 res = xmlSchemaParseRedefine(ctxt, schema, child); 9766 HFAILURE; 9767 HSTOP(ctxt); 9768 if (tmpOldErrs != ctxt->nberrors) 9769 goto exit; 9770 } 9771 child = child->next; 9772 } 9773 /* 9774 * URGENT TODO: Change the functions to return int results. 9775 * We need especially to catch internal errors. 9776 */ 9777 while (child != NULL) { 9778 if (IS_SCHEMA(child, "complexType")) { 9779 xmlSchemaParseComplexType(ctxt, schema, child, 1); 9780 child = child->next; 9781 } else if (IS_SCHEMA(child, "simpleType")) { 9782 xmlSchemaParseSimpleType(ctxt, schema, child, 1); 9783 child = child->next; 9784 } else if (IS_SCHEMA(child, "element")) { 9785 xmlSchemaParseElement(ctxt, schema, child, NULL, 1); 9786 child = child->next; 9787 } else if (IS_SCHEMA(child, "attribute")) { 9788 xmlSchemaParseGlobalAttribute(ctxt, schema, child); 9789 child = child->next; 9790 } else if (IS_SCHEMA(child, "attributeGroup")) { 9791 xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child); 9792 child = child->next; 9793 } else if (IS_SCHEMA(child, "group")) { 9794 xmlSchemaParseModelGroupDefinition(ctxt, schema, child); 9795 child = child->next; 9796 } else if (IS_SCHEMA(child, "notation")) { 9797 xmlSchemaParseNotation(ctxt, schema, child); 9798 child = child->next; 9799 } else { 9800 xmlSchemaPContentErr(ctxt, 9801 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9802 NULL, child->parent, child, 9803 NULL, "((include | import | redefine | annotation)*, " 9804 "(((simpleType | complexType | group | attributeGroup) " 9805 "| element | attribute | notation), annotation*)*)"); 9806 child = child->next; 9807 } 9808 while (IS_SCHEMA(child, "annotation")) { 9809 /* 9810 * TODO: We should add all annotations. 9811 */ 9812 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9813 if (schema->annot == NULL) 9814 schema->annot = annot; 9815 else 9816 xmlSchemaFreeAnnot(annot); 9817 child = child->next; 9818 } 9819 } 9820 exit: 9821 ctxt->ctxtType = NULL; 9822 if (oldErrs != ctxt->nberrors) 9823 res = ctxt->err; 9824 return(res); 9825 exit_failure: 9826 return(-1); 9827 } 9828 9829 static xmlSchemaSchemaRelationPtr 9830 xmlSchemaSchemaRelationCreate(void) 9831 { 9832 xmlSchemaSchemaRelationPtr ret; 9833 9834 ret = (xmlSchemaSchemaRelationPtr) 9835 xmlMalloc(sizeof(xmlSchemaSchemaRelation)); 9836 if (ret == NULL) { 9837 xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL); 9838 return(NULL); 9839 } 9840 memset(ret, 0, sizeof(xmlSchemaSchemaRelation)); 9841 return(ret); 9842 } 9843 9844 #if 0 9845 static void 9846 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel) 9847 { 9848 xmlFree(rel); 9849 } 9850 #endif 9851 9852 static void 9853 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef) 9854 { 9855 xmlSchemaRedefPtr prev; 9856 9857 while (redef != NULL) { 9858 prev = redef; 9859 redef = redef->next; 9860 xmlFree(prev); 9861 } 9862 } 9863 9864 static void 9865 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con) 9866 { 9867 /* 9868 * After the construction context has been freed, there will be 9869 * no schema graph available any more. Only the schema buckets 9870 * will stay alive, which are put into the "schemasImports" and 9871 * "includes" slots of the xmlSchema. 9872 */ 9873 if (con->buckets != NULL) 9874 xmlSchemaItemListFree(con->buckets); 9875 if (con->pending != NULL) 9876 xmlSchemaItemListFree(con->pending); 9877 if (con->substGroups != NULL) 9878 xmlHashFree(con->substGroups, 9879 (xmlHashDeallocator) xmlSchemaSubstGroupFree); 9880 if (con->redefs != NULL) 9881 xmlSchemaRedefListFree(con->redefs); 9882 if (con->dict != NULL) 9883 xmlDictFree(con->dict); 9884 xmlFree(con); 9885 } 9886 9887 static xmlSchemaConstructionCtxtPtr 9888 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict) 9889 { 9890 xmlSchemaConstructionCtxtPtr ret; 9891 9892 ret = (xmlSchemaConstructionCtxtPtr) 9893 xmlMalloc(sizeof(xmlSchemaConstructionCtxt)); 9894 if (ret == NULL) { 9895 xmlSchemaPErrMemory(NULL, 9896 "allocating schema construction context", NULL); 9897 return (NULL); 9898 } 9899 memset(ret, 0, sizeof(xmlSchemaConstructionCtxt)); 9900 9901 ret->buckets = xmlSchemaItemListCreate(); 9902 if (ret->buckets == NULL) { 9903 xmlSchemaPErrMemory(NULL, 9904 "allocating list of schema buckets", NULL); 9905 xmlFree(ret); 9906 return (NULL); 9907 } 9908 ret->pending = xmlSchemaItemListCreate(); 9909 if (ret->pending == NULL) { 9910 xmlSchemaPErrMemory(NULL, 9911 "allocating list of pending global components", NULL); 9912 xmlSchemaConstructionCtxtFree(ret); 9913 return (NULL); 9914 } 9915 ret->dict = dict; 9916 xmlDictReference(dict); 9917 return(ret); 9918 } 9919 9920 static xmlSchemaParserCtxtPtr 9921 xmlSchemaParserCtxtCreate(void) 9922 { 9923 xmlSchemaParserCtxtPtr ret; 9924 9925 ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt)); 9926 if (ret == NULL) { 9927 xmlSchemaPErrMemory(NULL, "allocating schema parser context", 9928 NULL); 9929 return (NULL); 9930 } 9931 memset(ret, 0, sizeof(xmlSchemaParserCtxt)); 9932 ret->type = XML_SCHEMA_CTXT_PARSER; 9933 ret->attrProhibs = xmlSchemaItemListCreate(); 9934 if (ret->attrProhibs == NULL) { 9935 xmlFree(ret); 9936 return(NULL); 9937 } 9938 return(ret); 9939 } 9940 9941 /** 9942 * xmlSchemaNewParserCtxtUseDict: 9943 * @URL: the location of the schema 9944 * @dict: the dictionary to be used 9945 * 9946 * Create an XML Schemas parse context for that file/resource expected 9947 * to contain an XML Schemas file. 9948 * 9949 * Returns the parser context or NULL in case of error 9950 */ 9951 static xmlSchemaParserCtxtPtr 9952 xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict) 9953 { 9954 xmlSchemaParserCtxtPtr ret; 9955 9956 ret = xmlSchemaParserCtxtCreate(); 9957 if (ret == NULL) 9958 return (NULL); 9959 ret->dict = dict; 9960 xmlDictReference(dict); 9961 if (URL != NULL) 9962 ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1); 9963 return (ret); 9964 } 9965 9966 static int 9967 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt) 9968 { 9969 if (vctxt->pctxt == NULL) { 9970 if (vctxt->schema != NULL) 9971 vctxt->pctxt = 9972 xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict); 9973 else 9974 vctxt->pctxt = xmlSchemaNewParserCtxt("*"); 9975 if (vctxt->pctxt == NULL) { 9976 VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt", 9977 "failed to create a temp. parser context"); 9978 return (-1); 9979 } 9980 /* TODO: Pass user data. */ 9981 xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error, 9982 vctxt->warning, vctxt->errCtxt); 9983 xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror, 9984 vctxt->errCtxt); 9985 } 9986 return (0); 9987 } 9988 9989 /** 9990 * xmlSchemaGetSchemaBucket: 9991 * @pctxt: the schema parser context 9992 * @schemaLocation: the URI of the schema document 9993 * 9994 * Returns a schema bucket if it was already parsed. 9995 * 9996 * Returns a schema bucket if it was already parsed from 9997 * @schemaLocation, NULL otherwise. 9998 */ 9999 static xmlSchemaBucketPtr 10000 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10001 const xmlChar *schemaLocation) 10002 { 10003 xmlSchemaBucketPtr cur; 10004 xmlSchemaItemListPtr list; 10005 10006 list = pctxt->constructor->buckets; 10007 if (list->nbItems == 0) 10008 return(NULL); 10009 else { 10010 int i; 10011 for (i = 0; i < list->nbItems; i++) { 10012 cur = (xmlSchemaBucketPtr) list->items[i]; 10013 /* Pointer comparison! */ 10014 if (cur->schemaLocation == schemaLocation) 10015 return(cur); 10016 } 10017 } 10018 return(NULL); 10019 } 10020 10021 static xmlSchemaBucketPtr 10022 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10023 const xmlChar *schemaLocation, 10024 const xmlChar *targetNamespace) 10025 { 10026 xmlSchemaBucketPtr cur; 10027 xmlSchemaItemListPtr list; 10028 10029 list = pctxt->constructor->buckets; 10030 if (list->nbItems == 0) 10031 return(NULL); 10032 else { 10033 int i; 10034 for (i = 0; i < list->nbItems; i++) { 10035 cur = (xmlSchemaBucketPtr) list->items[i]; 10036 /* Pointer comparison! */ 10037 if ((cur->origTargetNamespace == NULL) && 10038 (cur->schemaLocation == schemaLocation) && 10039 (cur->targetNamespace == targetNamespace)) 10040 return(cur); 10041 } 10042 } 10043 return(NULL); 10044 } 10045 10046 10047 #define IS_BAD_SCHEMA_DOC(b) \ 10048 (((b)->doc == NULL) && ((b)->schemaLocation != NULL)) 10049 10050 static xmlSchemaBucketPtr 10051 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt, 10052 const xmlChar *targetNamespace, 10053 int imported) 10054 { 10055 xmlSchemaBucketPtr cur; 10056 xmlSchemaItemListPtr list; 10057 10058 list = pctxt->constructor->buckets; 10059 if (list->nbItems == 0) 10060 return(NULL); 10061 else { 10062 int i; 10063 for (i = 0; i < list->nbItems; i++) { 10064 cur = (xmlSchemaBucketPtr) list->items[i]; 10065 if ((! IS_BAD_SCHEMA_DOC(cur)) && 10066 (cur->origTargetNamespace == targetNamespace) && 10067 ((imported && cur->imported) || 10068 ((!imported) && (!cur->imported)))) 10069 return(cur); 10070 } 10071 } 10072 return(NULL); 10073 } 10074 10075 static int 10076 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt, 10077 xmlSchemaPtr schema, 10078 xmlSchemaBucketPtr bucket) 10079 { 10080 int oldFlags; 10081 xmlDocPtr oldDoc; 10082 xmlNodePtr node; 10083 int ret, oldErrs; 10084 xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket; 10085 10086 /* 10087 * Save old values; reset the *main* schema. 10088 * URGENT TODO: This is not good; move the per-document information 10089 * to the parser. Get rid of passing the main schema to the 10090 * parsing functions. 10091 */ 10092 oldFlags = schema->flags; 10093 oldDoc = schema->doc; 10094 if (schema->flags != 0) 10095 xmlSchemaClearSchemaDefaults(schema); 10096 schema->doc = bucket->doc; 10097 pctxt->schema = schema; 10098 /* 10099 * Keep the current target namespace on the parser *not* on the 10100 * main schema. 10101 */ 10102 pctxt->targetNamespace = bucket->targetNamespace; 10103 WXS_CONSTRUCTOR(pctxt)->bucket = bucket; 10104 10105 if ((bucket->targetNamespace != NULL) && 10106 xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) { 10107 /* 10108 * We are parsing the schema for schemas! 10109 */ 10110 pctxt->isS4S = 1; 10111 } 10112 /* Mark it as parsed, even if parsing fails. */ 10113 bucket->parsed++; 10114 /* Compile the schema doc. */ 10115 node = xmlDocGetRootElement(bucket->doc); 10116 ret = xmlSchemaParseSchemaElement(pctxt, schema, node); 10117 if (ret != 0) 10118 goto exit; 10119 /* An empty schema; just get out. */ 10120 if (node->children == NULL) 10121 goto exit; 10122 oldErrs = pctxt->nberrors; 10123 ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children); 10124 if (ret != 0) 10125 goto exit; 10126 /* 10127 * TODO: Not nice, but I'm not 100% sure we will get always an error 10128 * as a result of the obove functions; so better rely on pctxt->err 10129 * as well. 10130 */ 10131 if ((ret == 0) && (oldErrs != pctxt->nberrors)) { 10132 ret = pctxt->err; 10133 goto exit; 10134 } 10135 10136 exit: 10137 WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket; 10138 /* Restore schema values. */ 10139 schema->doc = oldDoc; 10140 schema->flags = oldFlags; 10141 return(ret); 10142 } 10143 10144 static int 10145 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt, 10146 xmlSchemaPtr schema, 10147 xmlSchemaBucketPtr bucket) 10148 { 10149 xmlSchemaParserCtxtPtr newpctxt; 10150 int res = 0; 10151 10152 if (bucket == NULL) 10153 return(0); 10154 if (bucket->parsed) { 10155 PERROR_INT("xmlSchemaParseNewDoc", 10156 "reparsing a schema doc"); 10157 return(-1); 10158 } 10159 if (bucket->doc == NULL) { 10160 PERROR_INT("xmlSchemaParseNewDoc", 10161 "parsing a schema doc, but there's no doc"); 10162 return(-1); 10163 } 10164 if (pctxt->constructor == NULL) { 10165 PERROR_INT("xmlSchemaParseNewDoc", 10166 "no constructor"); 10167 return(-1); 10168 } 10169 /* Create and init the temporary parser context. */ 10170 newpctxt = xmlSchemaNewParserCtxtUseDict( 10171 (const char *) bucket->schemaLocation, pctxt->dict); 10172 if (newpctxt == NULL) 10173 return(-1); 10174 newpctxt->constructor = pctxt->constructor; 10175 /* 10176 * TODO: Can we avoid that the parser knows about the main schema? 10177 * It would be better if he knows about the current schema bucket 10178 * only. 10179 */ 10180 newpctxt->schema = schema; 10181 xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning, 10182 pctxt->errCtxt); 10183 xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror, 10184 pctxt->errCtxt); 10185 newpctxt->counter = pctxt->counter; 10186 10187 10188 res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket); 10189 10190 /* Channel back errors and cleanup the temporary parser context. */ 10191 if (res != 0) 10192 pctxt->err = res; 10193 pctxt->nberrors += newpctxt->nberrors; 10194 pctxt->counter = newpctxt->counter; 10195 newpctxt->constructor = NULL; 10196 /* Free the parser context. */ 10197 xmlSchemaFreeParserCtxt(newpctxt); 10198 return(res); 10199 } 10200 10201 static void 10202 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket, 10203 xmlSchemaSchemaRelationPtr rel) 10204 { 10205 xmlSchemaSchemaRelationPtr cur = bucket->relations; 10206 10207 if (cur == NULL) { 10208 bucket->relations = rel; 10209 return; 10210 } 10211 while (cur->next != NULL) 10212 cur = cur->next; 10213 cur->next = rel; 10214 } 10215 10216 10217 static const xmlChar * 10218 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location, 10219 xmlNodePtr ctxtNode) 10220 { 10221 /* 10222 * Build an absolue location URI. 10223 */ 10224 if (location != NULL) { 10225 if (ctxtNode == NULL) 10226 return(location); 10227 else { 10228 xmlChar *base, *URI; 10229 const xmlChar *ret = NULL; 10230 10231 base = xmlNodeGetBase(ctxtNode->doc, ctxtNode); 10232 if (base == NULL) { 10233 URI = xmlBuildURI(location, ctxtNode->doc->URL); 10234 } else { 10235 URI = xmlBuildURI(location, base); 10236 xmlFree(base); 10237 } 10238 if (URI != NULL) { 10239 ret = xmlDictLookup(dict, URI, -1); 10240 xmlFree(URI); 10241 return(ret); 10242 } 10243 } 10244 } 10245 return(NULL); 10246 } 10247 10248 10249 10250 /** 10251 * xmlSchemaAddSchemaDoc: 10252 * @pctxt: a schema validation context 10253 * @schema: the schema being built 10254 * @node: a subtree containing XML Schema informations 10255 * 10256 * Parse an included (and to-be-redefined) XML schema document. 10257 * 10258 * Returns 0 on success, a positive error code on errors and 10259 * -1 in case of an internal or API error. 10260 */ 10261 10262 static int 10263 xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt, 10264 int type, /* import or include or redefine */ 10265 const xmlChar *schemaLocation, 10266 xmlDocPtr schemaDoc, 10267 const char *schemaBuffer, 10268 int schemaBufferLen, 10269 xmlNodePtr invokingNode, 10270 const xmlChar *sourceTargetNamespace, 10271 const xmlChar *importNamespace, 10272 xmlSchemaBucketPtr *bucket) 10273 { 10274 const xmlChar *targetNamespace = NULL; 10275 xmlSchemaSchemaRelationPtr relation = NULL; 10276 xmlDocPtr doc = NULL; 10277 int res = 0, err = 0, located = 0, preserveDoc = 0; 10278 xmlSchemaBucketPtr bkt = NULL; 10279 10280 if (bucket != NULL) 10281 *bucket = NULL; 10282 10283 switch (type) { 10284 case XML_SCHEMA_SCHEMA_IMPORT: 10285 case XML_SCHEMA_SCHEMA_MAIN: 10286 err = XML_SCHEMAP_SRC_IMPORT; 10287 break; 10288 case XML_SCHEMA_SCHEMA_INCLUDE: 10289 err = XML_SCHEMAP_SRC_INCLUDE; 10290 break; 10291 case XML_SCHEMA_SCHEMA_REDEFINE: 10292 err = XML_SCHEMAP_SRC_REDEFINE; 10293 break; 10294 } 10295 10296 10297 /* Special handling for the main schema: 10298 * skip the location and relation logic and just parse the doc. 10299 * We need just a bucket to be returned in this case. 10300 */ 10301 if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt))) 10302 goto doc_load; 10303 10304 /* Note that we expect the location to be an absulute URI. */ 10305 if (schemaLocation != NULL) { 10306 bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation); 10307 if ((bkt != NULL) && 10308 (pctxt->constructor->bucket == bkt)) { 10309 /* Report self-imports/inclusions/redefinitions. */ 10310 10311 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10312 invokingNode, NULL, 10313 "The schema must not import/include/redefine itself", 10314 NULL, NULL); 10315 goto exit; 10316 } 10317 } 10318 /* 10319 * Create a relation for the graph of schemas. 10320 */ 10321 relation = xmlSchemaSchemaRelationCreate(); 10322 if (relation == NULL) 10323 return(-1); 10324 xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket, 10325 relation); 10326 relation->type = type; 10327 10328 /* 10329 * Save the namespace import information. 10330 */ 10331 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10332 relation->importNamespace = importNamespace; 10333 if (schemaLocation == NULL) { 10334 /* 10335 * No location; this is just an import of the namespace. 10336 * Note that we don't assign a bucket to the relation 10337 * in this case. 10338 */ 10339 goto exit; 10340 } 10341 targetNamespace = importNamespace; 10342 } 10343 10344 /* Did we already fetch the doc? */ 10345 if (bkt != NULL) { 10346 /* TODO: The following nasty cases will produce an error. */ 10347 if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) { 10348 /* We included/redefined and then try to import a schema. */ 10349 if (schemaLocation == NULL) 10350 schemaLocation = BAD_CAST "in_memory_buffer"; 10351 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10352 invokingNode, NULL, 10353 "The schema document '%s' cannot be imported, since " 10354 "it was already included or redefined", 10355 schemaLocation, NULL); 10356 goto exit; 10357 } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) { 10358 /* We imported and then try to include/redefine a schema. */ 10359 if (schemaLocation == NULL) 10360 schemaLocation = BAD_CAST "in_memory_buffer"; 10361 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10362 invokingNode, NULL, 10363 "The schema document '%s' cannot be included or " 10364 "redefined, since it was already imported", 10365 schemaLocation, NULL); 10366 goto exit; 10367 } 10368 } 10369 10370 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10371 /* 10372 * Given that the schemaLocation [attribute] is only a hint, it is open 10373 * to applications to ignore all but the first <import> for a given 10374 * namespace, regardless of the actual value of schemaLocation, but 10375 * such a strategy risks missing useful information when new 10376 * schemaLocations are offered. 10377 * 10378 * We will use the first <import> that comes with a location. 10379 * Further <import>s *with* a location, will result in an error. 10380 * TODO: Better would be to just report a warning here, but 10381 * we'll try it this way until someone complains. 10382 * 10383 * Schema Document Location Strategy: 10384 * 3 Based on the namespace name, identify an existing schema document, 10385 * either as a resource which is an XML document or a <schema> element 10386 * information item, in some local schema repository; 10387 * 5 Attempt to resolve the namespace name to locate such a resource. 10388 * 10389 * NOTE: (3) and (5) are not supported. 10390 */ 10391 if (bkt != NULL) { 10392 relation->bucket = bkt; 10393 goto exit; 10394 } 10395 bkt = xmlSchemaGetSchemaBucketByTNS(pctxt, 10396 importNamespace, 1); 10397 10398 if (bkt != NULL) { 10399 relation->bucket = bkt; 10400 if (bkt->schemaLocation == NULL) { 10401 /* First given location of the schema; load the doc. */ 10402 bkt->schemaLocation = schemaLocation; 10403 } else { 10404 if (!xmlStrEqual(schemaLocation, 10405 bkt->schemaLocation)) { 10406 /* 10407 * Additional location given; just skip it. 10408 * URGENT TODO: We should report a warning here. 10409 * res = XML_SCHEMAP_SRC_IMPORT; 10410 */ 10411 if (schemaLocation == NULL) 10412 schemaLocation = BAD_CAST "in_memory_buffer"; 10413 10414 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10415 XML_SCHEMAP_WARN_SKIP_SCHEMA, 10416 invokingNode, NULL, 10417 "Skipping import of schema located at '%s' for the " 10418 "namespace '%s', since this namespace was already " 10419 "imported with the schema located at '%s'", 10420 schemaLocation, importNamespace, bkt->schemaLocation); 10421 } 10422 goto exit; 10423 } 10424 } 10425 /* 10426 * No bucket + first location: load the doc and create a 10427 * bucket. 10428 */ 10429 } else { 10430 /* <include> and <redefine> */ 10431 if (bkt != NULL) { 10432 10433 if ((bkt->origTargetNamespace == NULL) && 10434 (bkt->targetNamespace != sourceTargetNamespace)) { 10435 xmlSchemaBucketPtr chamel; 10436 10437 /* 10438 * Chameleon include/redefine: skip loading only if it was 10439 * aleady build for the targetNamespace of the including 10440 * schema. 10441 */ 10442 /* 10443 * URGENT TODO: If the schema is a chameleon-include then copy 10444 * the components into the including schema and modify the 10445 * targetNamespace of those components, do nothing otherwise. 10446 * NOTE: This is currently worked-around by compiling the 10447 * chameleon for every destinct including targetNamespace; thus 10448 * not performant at the moment. 10449 * TODO: Check when the namespace in wildcards for chameleons 10450 * needs to be converted: before we built wildcard intersections 10451 * or after. 10452 * Answer: after! 10453 */ 10454 chamel = xmlSchemaGetChameleonSchemaBucket(pctxt, 10455 schemaLocation, sourceTargetNamespace); 10456 if (chamel != NULL) { 10457 /* A fitting chameleon was already parsed; NOP. */ 10458 relation->bucket = chamel; 10459 goto exit; 10460 } 10461 /* 10462 * We need to parse the chameleon again for a different 10463 * targetNamespace. 10464 * CHAMELEON TODO: Optimize this by only parsing the 10465 * chameleon once, and then copying the components to 10466 * the new targetNamespace. 10467 */ 10468 bkt = NULL; 10469 } else { 10470 relation->bucket = bkt; 10471 goto exit; 10472 } 10473 } 10474 } 10475 if ((bkt != NULL) && (bkt->doc != NULL)) { 10476 PERROR_INT("xmlSchemaAddSchemaDoc", 10477 "trying to load a schema doc, but a doc is already " 10478 "assigned to the schema bucket"); 10479 goto exit_failure; 10480 } 10481 10482 doc_load: 10483 /* 10484 * Load the document. 10485 */ 10486 if (schemaDoc != NULL) { 10487 doc = schemaDoc; 10488 /* Don' free this one, since it was provided by the caller. */ 10489 preserveDoc = 1; 10490 /* TODO: Does the context or the doc hold the location? */ 10491 if (schemaDoc->URL != NULL) 10492 schemaLocation = xmlDictLookup(pctxt->dict, 10493 schemaDoc->URL, -1); 10494 else 10495 schemaLocation = BAD_CAST "in_memory_buffer"; 10496 } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) { 10497 xmlParserCtxtPtr parserCtxt; 10498 10499 parserCtxt = xmlNewParserCtxt(); 10500 if (parserCtxt == NULL) { 10501 xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, " 10502 "allocating a parser context", NULL); 10503 goto exit_failure; 10504 } 10505 if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) { 10506 /* 10507 * TODO: Do we have to burden the schema parser dict with all 10508 * the content of the schema doc? 10509 */ 10510 xmlDictFree(parserCtxt->dict); 10511 parserCtxt->dict = pctxt->dict; 10512 xmlDictReference(parserCtxt->dict); 10513 } 10514 if (schemaLocation != NULL) { 10515 /* Parse from file. */ 10516 doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation, 10517 NULL, SCHEMAS_PARSE_OPTIONS); 10518 } else if (schemaBuffer != NULL) { 10519 /* Parse from memory buffer. */ 10520 doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen, 10521 NULL, NULL, SCHEMAS_PARSE_OPTIONS); 10522 schemaLocation = xmlStrdup(BAD_CAST "in_memory_buffer"); 10523 if (doc != NULL) 10524 doc->URL = schemaLocation; 10525 } 10526 /* 10527 * For <import>: 10528 * 2.1 The referent is (a fragment of) a resource which is an 10529 * XML document (see clause 1.1), which in turn corresponds to 10530 * a <schema> element information item in a well-formed information 10531 * set, which in turn corresponds to a valid schema. 10532 * TODO: (2.1) fragments of XML documents are not supported. 10533 * 10534 * 2.2 The referent is a <schema> element information item in 10535 * a well-formed information set, which in turn corresponds 10536 * to a valid schema. 10537 * TODO: (2.2) is not supported. 10538 */ 10539 if (doc == NULL) { 10540 xmlErrorPtr lerr; 10541 lerr = xmlGetLastError(); 10542 /* 10543 * Check if this a parser error, or if the document could 10544 * just not be located. 10545 * TODO: Try to find specific error codes to react only on 10546 * localisation failures. 10547 */ 10548 if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) { 10549 /* 10550 * We assume a parser error here. 10551 */ 10552 located = 1; 10553 /* TODO: Error code ?? */ 10554 res = XML_SCHEMAP_SRC_IMPORT_2_1; 10555 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10556 invokingNode, NULL, 10557 "Failed to parse the XML resource '%s'", 10558 schemaLocation, NULL); 10559 } 10560 } 10561 xmlFreeParserCtxt(parserCtxt); 10562 if ((doc == NULL) && located) 10563 goto exit_error; 10564 } else { 10565 xmlSchemaPErr(pctxt, NULL, 10566 XML_SCHEMAP_NOTHING_TO_PARSE, 10567 "No information for parsing was provided with the " 10568 "given schema parser context.\n", 10569 NULL, NULL); 10570 goto exit_failure; 10571 } 10572 /* 10573 * Preprocess the document. 10574 */ 10575 if (doc != NULL) { 10576 xmlNodePtr docElem = NULL; 10577 10578 located = 1; 10579 docElem = xmlDocGetRootElement(doc); 10580 if (docElem == NULL) { 10581 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT, 10582 invokingNode, NULL, 10583 "The document '%s' has no document element", 10584 schemaLocation, NULL); 10585 goto exit_error; 10586 } 10587 /* 10588 * Remove all the blank text nodes. 10589 */ 10590 xmlSchemaCleanupDoc(pctxt, docElem); 10591 /* 10592 * Check the schema's top level element. 10593 */ 10594 if (!IS_SCHEMA(docElem, "schema")) { 10595 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA, 10596 invokingNode, NULL, 10597 "The XML document '%s' is not a schema document", 10598 schemaLocation, NULL); 10599 goto exit_error; 10600 } 10601 /* 10602 * Note that we don't apply a type check for the 10603 * targetNamespace value here. 10604 */ 10605 targetNamespace = xmlSchemaGetProp(pctxt, docElem, 10606 "targetNamespace"); 10607 } 10608 10609 /* after_doc_loading: */ 10610 if ((bkt == NULL) && located) { 10611 /* Only create a bucket if the schema was located. */ 10612 bkt = xmlSchemaBucketCreate(pctxt, type, 10613 targetNamespace); 10614 if (bkt == NULL) 10615 goto exit_failure; 10616 } 10617 if (bkt != NULL) { 10618 bkt->schemaLocation = schemaLocation; 10619 bkt->located = located; 10620 if (doc != NULL) { 10621 bkt->doc = doc; 10622 bkt->targetNamespace = targetNamespace; 10623 bkt->origTargetNamespace = targetNamespace; 10624 if (preserveDoc) 10625 bkt->preserveDoc = 1; 10626 } 10627 if (WXS_IS_BUCKET_IMPMAIN(type)) 10628 bkt->imported++; 10629 /* 10630 * Add it to the graph of schemas. 10631 */ 10632 if (relation != NULL) 10633 relation->bucket = bkt; 10634 } 10635 10636 exit: 10637 /* 10638 * Return the bucket explicitely; this is needed for the 10639 * main schema. 10640 */ 10641 if (bucket != NULL) 10642 *bucket = bkt; 10643 return (0); 10644 10645 exit_error: 10646 if ((doc != NULL) && (! preserveDoc)) { 10647 xmlFreeDoc(doc); 10648 if (bkt != NULL) 10649 bkt->doc = NULL; 10650 } 10651 return(pctxt->err); 10652 10653 exit_failure: 10654 if ((doc != NULL) && (! preserveDoc)) { 10655 xmlFreeDoc(doc); 10656 if (bkt != NULL) 10657 bkt->doc = NULL; 10658 } 10659 return (-1); 10660 } 10661 10662 /** 10663 * xmlSchemaParseImport: 10664 * @ctxt: a schema validation context 10665 * @schema: the schema being built 10666 * @node: a subtree containing XML Schema informations 10667 * 10668 * parse a XML schema Import definition 10669 * *WARNING* this interface is highly subject to change 10670 * 10671 * Returns 0 in case of success, a positive error code if 10672 * not valid and -1 in case of an internal error. 10673 */ 10674 static int 10675 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 10676 xmlNodePtr node) 10677 { 10678 xmlNodePtr child; 10679 const xmlChar *namespaceName = NULL, *schemaLocation = NULL; 10680 const xmlChar *thisTargetNamespace; 10681 xmlAttrPtr attr; 10682 int ret = 0; 10683 xmlSchemaBucketPtr bucket = NULL; 10684 10685 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10686 return (-1); 10687 10688 /* 10689 * Check for illegal attributes. 10690 */ 10691 attr = node->properties; 10692 while (attr != NULL) { 10693 if (attr->ns == NULL) { 10694 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10695 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 10696 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10697 xmlSchemaPIllegalAttrErr(pctxt, 10698 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10699 } 10700 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10701 xmlSchemaPIllegalAttrErr(pctxt, 10702 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10703 } 10704 attr = attr->next; 10705 } 10706 /* 10707 * Extract and validate attributes. 10708 */ 10709 if (xmlSchemaPValAttr(pctxt, NULL, node, 10710 "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10711 &namespaceName) != 0) { 10712 xmlSchemaPSimpleTypeErr(pctxt, 10713 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10714 NULL, node, 10715 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10716 NULL, namespaceName, NULL, NULL, NULL); 10717 return (pctxt->err); 10718 } 10719 10720 if (xmlSchemaPValAttr(pctxt, NULL, node, 10721 "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10722 &schemaLocation) != 0) { 10723 xmlSchemaPSimpleTypeErr(pctxt, 10724 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10725 NULL, node, 10726 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10727 NULL, namespaceName, NULL, NULL, NULL); 10728 return (pctxt->err); 10729 } 10730 /* 10731 * And now for the children... 10732 */ 10733 child = node->children; 10734 if (IS_SCHEMA(child, "annotation")) { 10735 /* 10736 * the annotation here is simply discarded ... 10737 * TODO: really? 10738 */ 10739 child = child->next; 10740 } 10741 if (child != NULL) { 10742 xmlSchemaPContentErr(pctxt, 10743 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 10744 NULL, node, child, NULL, 10745 "(annotation?)"); 10746 } 10747 /* 10748 * Apply additional constraints. 10749 * 10750 * Note that it is important to use the original @targetNamespace 10751 * (or none at all), to rule out imports of schemas _with_ a 10752 * @targetNamespace if the importing schema is a chameleon schema 10753 * (with no @targetNamespace). 10754 */ 10755 thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace; 10756 if (namespaceName != NULL) { 10757 /* 10758 * 1.1 If the namespace [attribute] is present, then its actual value 10759 * must not match the actual value of the enclosing <schema>'s 10760 * targetNamespace [attribute]. 10761 */ 10762 if (xmlStrEqual(thisTargetNamespace, namespaceName)) { 10763 xmlSchemaPCustomErr(pctxt, 10764 XML_SCHEMAP_SRC_IMPORT_1_1, 10765 NULL, node, 10766 "The value of the attribute 'namespace' must not match " 10767 "the target namespace '%s' of the importing schema", 10768 thisTargetNamespace); 10769 return (pctxt->err); 10770 } 10771 } else { 10772 /* 10773 * 1.2 If the namespace [attribute] is not present, then the enclosing 10774 * <schema> must have a targetNamespace [attribute]. 10775 */ 10776 if (thisTargetNamespace == NULL) { 10777 xmlSchemaPCustomErr(pctxt, 10778 XML_SCHEMAP_SRC_IMPORT_1_2, 10779 NULL, node, 10780 "The attribute 'namespace' must be existent if " 10781 "the importing schema has no target namespace", 10782 NULL); 10783 return (pctxt->err); 10784 } 10785 } 10786 /* 10787 * Locate and acquire the schema document. 10788 */ 10789 if (schemaLocation != NULL) 10790 schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict, 10791 schemaLocation, node); 10792 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT, 10793 schemaLocation, NULL, NULL, 0, node, thisTargetNamespace, 10794 namespaceName, &bucket); 10795 10796 if (ret != 0) 10797 return(ret); 10798 10799 /* 10800 * For <import>: "It is *not* an error for the application 10801 * schema reference strategy to fail." 10802 * So just don't parse if no schema document was found. 10803 * Note that we will get no bucket if the schema could not be 10804 * located or if there was no schemaLocation. 10805 */ 10806 if ((bucket == NULL) && (schemaLocation != NULL)) { 10807 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10808 XML_SCHEMAP_WARN_UNLOCATED_SCHEMA, 10809 node, NULL, 10810 "Failed to locate a schema at location '%s'. " 10811 "Skipping the import", schemaLocation, NULL, NULL); 10812 } 10813 10814 if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) { 10815 ret = xmlSchemaParseNewDoc(pctxt, schema, bucket); 10816 } 10817 10818 return (ret); 10819 } 10820 10821 static int 10822 xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt, 10823 xmlSchemaPtr schema, 10824 xmlNodePtr node, 10825 xmlChar **schemaLocation, 10826 int type) 10827 { 10828 xmlAttrPtr attr; 10829 10830 if ((pctxt == NULL) || (schema == NULL) || (node == NULL) || 10831 (schemaLocation == NULL)) 10832 return (-1); 10833 10834 *schemaLocation = NULL; 10835 /* 10836 * Check for illegal attributes. 10837 * Applies for both <include> and <redefine>. 10838 */ 10839 attr = node->properties; 10840 while (attr != NULL) { 10841 if (attr->ns == NULL) { 10842 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10843 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10844 xmlSchemaPIllegalAttrErr(pctxt, 10845 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10846 } 10847 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10848 xmlSchemaPIllegalAttrErr(pctxt, 10849 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10850 } 10851 attr = attr->next; 10852 } 10853 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 10854 /* 10855 * Preliminary step, extract the URI-Reference and make an URI 10856 * from the base. 10857 */ 10858 /* 10859 * Attribute "schemaLocation" is mandatory. 10860 */ 10861 attr = xmlSchemaGetPropNode(node, "schemaLocation"); 10862 if (attr != NULL) { 10863 xmlChar *base = NULL; 10864 xmlChar *uri = NULL; 10865 10866 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 10867 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10868 (const xmlChar **) schemaLocation) != 0) 10869 goto exit_error; 10870 base = xmlNodeGetBase(node->doc, node); 10871 if (base == NULL) { 10872 uri = xmlBuildURI(*schemaLocation, node->doc->URL); 10873 } else { 10874 uri = xmlBuildURI(*schemaLocation, base); 10875 xmlFree(base); 10876 } 10877 if (uri == NULL) { 10878 PERROR_INT("xmlSchemaParseIncludeOrRedefine", 10879 "could not build an URI from the schemaLocation") 10880 goto exit_failure; 10881 } 10882 (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1); 10883 xmlFree(uri); 10884 } else { 10885 xmlSchemaPMissingAttrErr(pctxt, 10886 XML_SCHEMAP_S4S_ATTR_MISSING, 10887 NULL, node, "schemaLocation", NULL); 10888 goto exit_error; 10889 } 10890 /* 10891 * Report self-inclusion and self-redefinition. 10892 */ 10893 if (xmlStrEqual(*schemaLocation, pctxt->URL)) { 10894 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 10895 xmlSchemaPCustomErr(pctxt, 10896 XML_SCHEMAP_SRC_REDEFINE, 10897 NULL, node, 10898 "The schema document '%s' cannot redefine itself.", 10899 *schemaLocation); 10900 } else { 10901 xmlSchemaPCustomErr(pctxt, 10902 XML_SCHEMAP_SRC_INCLUDE, 10903 NULL, node, 10904 "The schema document '%s' cannot include itself.", 10905 *schemaLocation); 10906 } 10907 goto exit_error; 10908 } 10909 10910 return(0); 10911 exit_error: 10912 return(pctxt->err); 10913 exit_failure: 10914 return(-1); 10915 } 10916 10917 static int 10918 xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt, 10919 xmlSchemaPtr schema, 10920 xmlNodePtr node, 10921 int type) 10922 { 10923 xmlNodePtr child = NULL; 10924 const xmlChar *schemaLocation = NULL; 10925 int res = 0; /* hasRedefinitions = 0 */ 10926 int isChameleon = 0, wasChameleon = 0; 10927 xmlSchemaBucketPtr bucket = NULL; 10928 10929 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10930 return (-1); 10931 10932 /* 10933 * Parse attributes. Note that the returned schemaLocation will 10934 * be already converted to an absolute URI. 10935 */ 10936 res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema, 10937 node, (xmlChar **) (&schemaLocation), type); 10938 if (res != 0) 10939 return(res); 10940 /* 10941 * Load and add the schema document. 10942 */ 10943 res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL, 10944 NULL, 0, node, pctxt->targetNamespace, NULL, &bucket); 10945 if (res != 0) 10946 return(res); 10947 /* 10948 * If we get no schema bucket back, then this means that the schema 10949 * document could not be located or was broken XML or was not 10950 * a schema document. 10951 */ 10952 if ((bucket == NULL) || (bucket->doc == NULL)) { 10953 if (type == XML_SCHEMA_SCHEMA_INCLUDE) { 10954 /* 10955 * WARNING for <include>: 10956 * We will raise an error if the schema cannot be located 10957 * for inclusions, since the that was the feedback from the 10958 * schema people. I.e. the following spec piece will *not* be 10959 * satisfied: 10960 * SPEC src-include: "It is not an error for the actual value of the 10961 * schemaLocation [attribute] to fail to resolve it all, in which 10962 * case no corresponding inclusion is performed. 10963 * So do we need a warning report here?" 10964 */ 10965 res = XML_SCHEMAP_SRC_INCLUDE; 10966 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10967 node, NULL, 10968 "Failed to load the document '%s' for inclusion", 10969 schemaLocation, NULL); 10970 } else { 10971 /* 10972 * NOTE: This was changed to raise an error even if no redefinitions 10973 * are specified. 10974 * 10975 * SPEC src-redefine (1) 10976 * "If there are any element information items among the [children] 10977 * other than <annotation> then the actual value of the 10978 * schemaLocation [attribute] must successfully resolve." 10979 * TODO: Ask the WG if a the location has always to resolve 10980 * here as well! 10981 */ 10982 res = XML_SCHEMAP_SRC_REDEFINE; 10983 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10984 node, NULL, 10985 "Failed to load the document '%s' for redefinition", 10986 schemaLocation, NULL); 10987 } 10988 } else { 10989 /* 10990 * Check targetNamespace sanity before parsing the new schema. 10991 * TODO: Note that we won't check further content if the 10992 * targetNamespace was bad. 10993 */ 10994 if (bucket->origTargetNamespace != NULL) { 10995 /* 10996 * SPEC src-include (2.1) 10997 * "SII has a targetNamespace [attribute], and its actual 10998 * value is identical to the actual value of the targetNamespace 10999 * [attribute] of SII (which must have such an [attribute])." 11000 */ 11001 if (pctxt->targetNamespace == NULL) { 11002 xmlSchemaCustomErr(ACTXT_CAST pctxt, 11003 XML_SCHEMAP_SRC_INCLUDE, 11004 node, NULL, 11005 "The target namespace of the included/redefined schema " 11006 "'%s' has to be absent, since the including/redefining " 11007 "schema has no target namespace", 11008 schemaLocation, NULL); 11009 goto exit_error; 11010 } else if (!xmlStrEqual(bucket->origTargetNamespace, 11011 pctxt->targetNamespace)) { 11012 /* TODO: Change error function. */ 11013 xmlSchemaPCustomErrExt(pctxt, 11014 XML_SCHEMAP_SRC_INCLUDE, 11015 NULL, node, 11016 "The target namespace '%s' of the included/redefined " 11017 "schema '%s' differs from '%s' of the " 11018 "including/redefining schema", 11019 bucket->origTargetNamespace, schemaLocation, 11020 pctxt->targetNamespace); 11021 goto exit_error; 11022 } 11023 } else if (pctxt->targetNamespace != NULL) { 11024 /* 11025 * Chameleons: the original target namespace will 11026 * differ from the resulting namespace. 11027 */ 11028 isChameleon = 1; 11029 if (bucket->parsed && 11030 (bucket->targetNamespace != pctxt->targetNamespace)) { 11031 /* 11032 * This is a sanity check, I dunno yet if this can happen. 11033 */ 11034 PERROR_INT("xmlSchemaParseIncludeOrRedefine", 11035 "trying to use an already parsed schema for a " 11036 "different targetNamespace"); 11037 return(-1); 11038 } 11039 bucket->targetNamespace = pctxt->targetNamespace; 11040 } 11041 } 11042 /* 11043 * Parse the schema. 11044 */ 11045 if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) { 11046 if (isChameleon) { 11047 /* TODO: Get rid of this flag on the schema itself. */ 11048 if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) { 11049 schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11050 } else 11051 wasChameleon = 1; 11052 } 11053 xmlSchemaParseNewDoc(pctxt, schema, bucket); 11054 /* Restore chameleon flag. */ 11055 if (isChameleon && (!wasChameleon)) 11056 schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11057 } 11058 /* 11059 * And now for the children... 11060 */ 11061 child = node->children; 11062 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11063 /* 11064 * Parse (simpleType | complexType | group | attributeGroup))* 11065 */ 11066 pctxt->redefined = bucket; 11067 /* 11068 * How to proceed if the redefined schema was not located? 11069 */ 11070 pctxt->isRedefine = 1; 11071 while (IS_SCHEMA(child, "annotation") || 11072 IS_SCHEMA(child, "simpleType") || 11073 IS_SCHEMA(child, "complexType") || 11074 IS_SCHEMA(child, "group") || 11075 IS_SCHEMA(child, "attributeGroup")) { 11076 if (IS_SCHEMA(child, "annotation")) { 11077 /* 11078 * TODO: discard or not? 11079 */ 11080 } else if (IS_SCHEMA(child, "simpleType")) { 11081 xmlSchemaParseSimpleType(pctxt, schema, child, 1); 11082 } else if (IS_SCHEMA(child, "complexType")) { 11083 xmlSchemaParseComplexType(pctxt, schema, child, 1); 11084 /* hasRedefinitions = 1; */ 11085 } else if (IS_SCHEMA(child, "group")) { 11086 /* hasRedefinitions = 1; */ 11087 xmlSchemaParseModelGroupDefinition(pctxt, 11088 schema, child); 11089 } else if (IS_SCHEMA(child, "attributeGroup")) { 11090 /* hasRedefinitions = 1; */ 11091 xmlSchemaParseAttributeGroupDefinition(pctxt, schema, 11092 child); 11093 } 11094 child = child->next; 11095 } 11096 pctxt->redefined = NULL; 11097 pctxt->isRedefine = 0; 11098 } else { 11099 if (IS_SCHEMA(child, "annotation")) { 11100 /* 11101 * TODO: discard or not? 11102 */ 11103 child = child->next; 11104 } 11105 } 11106 if (child != NULL) { 11107 res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED; 11108 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11109 xmlSchemaPContentErr(pctxt, res, 11110 NULL, node, child, NULL, 11111 "(annotation | (simpleType | complexType | group | attributeGroup))*"); 11112 } else { 11113 xmlSchemaPContentErr(pctxt, res, 11114 NULL, node, child, NULL, 11115 "(annotation?)"); 11116 } 11117 } 11118 return(res); 11119 11120 exit_error: 11121 return(pctxt->err); 11122 } 11123 11124 static int 11125 xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11126 xmlNodePtr node) 11127 { 11128 int res; 11129 #ifndef ENABLE_REDEFINE 11130 TODO 11131 return(0); 11132 #endif 11133 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11134 XML_SCHEMA_SCHEMA_REDEFINE); 11135 if (res != 0) 11136 return(res); 11137 return(0); 11138 } 11139 11140 static int 11141 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11142 xmlNodePtr node) 11143 { 11144 int res; 11145 11146 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11147 XML_SCHEMA_SCHEMA_INCLUDE); 11148 if (res != 0) 11149 return(res); 11150 return(0); 11151 } 11152 11153 /** 11154 * xmlSchemaParseModelGroup: 11155 * @ctxt: a schema validation context 11156 * @schema: the schema being built 11157 * @node: a subtree containing XML Schema informations 11158 * @type: the "compositor" type 11159 * @particleNeeded: if a a model group with a particle 11160 * 11161 * parse a XML schema Sequence definition. 11162 * Applies parts of: 11163 * Schema Representation Constraint: 11164 * Redefinition Constraints and Semantics (src-redefine) 11165 * (6.1), (6.1.1), (6.1.2) 11166 * 11167 * Schema Component Constraint: 11168 * All Group Limited (cos-all-limited) (2) 11169 * TODO: Actually this should go to component-level checks, 11170 * but is done here due to performance. Move it to an other layer 11171 * is schema construction via an API is implemented. 11172 * 11173 * *WARNING* this interface is highly subject to change 11174 * 11175 * Returns -1 in case of error, 0 if the declaration is improper and 11176 * 1 in case of success. 11177 */ 11178 static xmlSchemaTreeItemPtr 11179 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11180 xmlNodePtr node, xmlSchemaTypeType type, 11181 int withParticle) 11182 { 11183 xmlSchemaModelGroupPtr item; 11184 xmlSchemaParticlePtr particle = NULL; 11185 xmlNodePtr child = NULL; 11186 xmlAttrPtr attr; 11187 int min = 1, max = 1, isElemRef, hasRefs = 0; 11188 11189 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11190 return (NULL); 11191 /* 11192 * Create a model group with the given compositor. 11193 */ 11194 item = xmlSchemaAddModelGroup(ctxt, schema, type, node); 11195 if (item == NULL) 11196 return (NULL); 11197 11198 if (withParticle) { 11199 if (type == XML_SCHEMA_TYPE_ALL) { 11200 min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)"); 11201 max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1"); 11202 } else { 11203 /* choice + sequence */ 11204 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 11205 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 11206 "(xs:nonNegativeInteger | unbounded)"); 11207 } 11208 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 11209 /* 11210 * Create a particle 11211 */ 11212 particle = xmlSchemaAddParticle(ctxt, node, min, max); 11213 if (particle == NULL) 11214 return (NULL); 11215 particle->children = (xmlSchemaTreeItemPtr) item; 11216 /* 11217 * Check for illegal attributes. 11218 */ 11219 attr = node->properties; 11220 while (attr != NULL) { 11221 if (attr->ns == NULL) { 11222 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11223 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 11224 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) { 11225 xmlSchemaPIllegalAttrErr(ctxt, 11226 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11227 } 11228 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11229 xmlSchemaPIllegalAttrErr(ctxt, 11230 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11231 } 11232 attr = attr->next; 11233 } 11234 } else { 11235 /* 11236 * Check for illegal attributes. 11237 */ 11238 attr = node->properties; 11239 while (attr != NULL) { 11240 if (attr->ns == NULL) { 11241 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 11242 xmlSchemaPIllegalAttrErr(ctxt, 11243 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11244 } 11245 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11246 xmlSchemaPIllegalAttrErr(ctxt, 11247 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11248 } 11249 attr = attr->next; 11250 } 11251 } 11252 11253 /* 11254 * Extract and validate attributes. 11255 */ 11256 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11257 /* 11258 * And now for the children... 11259 */ 11260 child = node->children; 11261 if (IS_SCHEMA(child, "annotation")) { 11262 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 11263 child = child->next; 11264 } 11265 if (type == XML_SCHEMA_TYPE_ALL) { 11266 xmlSchemaParticlePtr part, last = NULL; 11267 11268 while (IS_SCHEMA(child, "element")) { 11269 part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt, 11270 schema, child, &isElemRef, 0); 11271 /* 11272 * SPEC cos-all-limited (2) 11273 * "The {max occurs} of all the particles in the {particles} 11274 * of the ('all') group must be 0 or 1. 11275 */ 11276 if (part != NULL) { 11277 if (isElemRef) 11278 hasRefs++; 11279 if (part->minOccurs > 1) { 11280 xmlSchemaPCustomErr(ctxt, 11281 XML_SCHEMAP_COS_ALL_LIMITED, 11282 NULL, child, 11283 "Invalid value for minOccurs (must be 0 or 1)", 11284 NULL); 11285 /* Reset to 1. */ 11286 part->minOccurs = 1; 11287 } 11288 if (part->maxOccurs > 1) { 11289 xmlSchemaPCustomErr(ctxt, 11290 XML_SCHEMAP_COS_ALL_LIMITED, 11291 NULL, child, 11292 "Invalid value for maxOccurs (must be 0 or 1)", 11293 NULL); 11294 /* Reset to 1. */ 11295 part->maxOccurs = 1; 11296 } 11297 if (last == NULL) 11298 item->children = (xmlSchemaTreeItemPtr) part; 11299 else 11300 last->next = (xmlSchemaTreeItemPtr) part; 11301 last = part; 11302 } 11303 child = child->next; 11304 } 11305 if (child != NULL) { 11306 xmlSchemaPContentErr(ctxt, 11307 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11308 NULL, node, child, NULL, 11309 "(annotation?, (annotation?, element*)"); 11310 } 11311 } else { 11312 /* choice + sequence */ 11313 xmlSchemaTreeItemPtr part = NULL, last = NULL; 11314 11315 while ((IS_SCHEMA(child, "element")) || 11316 (IS_SCHEMA(child, "group")) || 11317 (IS_SCHEMA(child, "any")) || 11318 (IS_SCHEMA(child, "choice")) || 11319 (IS_SCHEMA(child, "sequence"))) { 11320 11321 if (IS_SCHEMA(child, "element")) { 11322 part = (xmlSchemaTreeItemPtr) 11323 xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0); 11324 if (part && isElemRef) 11325 hasRefs++; 11326 } else if (IS_SCHEMA(child, "group")) { 11327 part = 11328 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11329 if (part != NULL) 11330 hasRefs++; 11331 /* 11332 * Handle redefinitions. 11333 */ 11334 if (ctxt->isRedefine && ctxt->redef && 11335 (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) && 11336 part && part->children) 11337 { 11338 if ((xmlSchemaGetQNameRefName(part->children) == 11339 ctxt->redef->refName) && 11340 (xmlSchemaGetQNameRefTargetNs(part->children) == 11341 ctxt->redef->refTargetNs)) 11342 { 11343 /* 11344 * SPEC src-redefine: 11345 * (6.1) "If it has a <group> among its contents at 11346 * some level the actual value of whose ref 11347 * [attribute] is the same as the actual value of 11348 * its own name attribute plus target namespace, then 11349 * all of the following must be true:" 11350 * (6.1.1) "It must have exactly one such group." 11351 */ 11352 if (ctxt->redefCounter != 0) { 11353 xmlChar *str = NULL; 11354 11355 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11356 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11357 "The redefining model group definition " 11358 "'%s' must not contain more than one " 11359 "reference to the redefined definition", 11360 xmlSchemaFormatQName(&str, 11361 ctxt->redef->refTargetNs, 11362 ctxt->redef->refName), 11363 NULL); 11364 FREE_AND_NULL(str) 11365 part = NULL; 11366 } else if (((WXS_PARTICLE(part))->minOccurs != 1) || 11367 ((WXS_PARTICLE(part))->maxOccurs != 1)) 11368 { 11369 xmlChar *str = NULL; 11370 /* 11371 * SPEC src-redefine: 11372 * (6.1.2) "The actual value of both that 11373 * group's minOccurs and maxOccurs [attribute] 11374 * must be 1 (or absent). 11375 */ 11376 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11377 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11378 "The redefining model group definition " 11379 "'%s' must not contain a reference to the " 11380 "redefined definition with a " 11381 "maxOccurs/minOccurs other than 1", 11382 xmlSchemaFormatQName(&str, 11383 ctxt->redef->refTargetNs, 11384 ctxt->redef->refName), 11385 NULL); 11386 FREE_AND_NULL(str) 11387 part = NULL; 11388 } 11389 ctxt->redef->reference = WXS_BASIC_CAST part; 11390 ctxt->redefCounter++; 11391 } 11392 } 11393 } else if (IS_SCHEMA(child, "any")) { 11394 part = (xmlSchemaTreeItemPtr) 11395 xmlSchemaParseAny(ctxt, schema, child); 11396 } else if (IS_SCHEMA(child, "choice")) { 11397 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11398 XML_SCHEMA_TYPE_CHOICE, 1); 11399 } else if (IS_SCHEMA(child, "sequence")) { 11400 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11401 XML_SCHEMA_TYPE_SEQUENCE, 1); 11402 } 11403 if (part != NULL) { 11404 if (last == NULL) 11405 item->children = part; 11406 else 11407 last->next = part; 11408 last = part; 11409 } 11410 child = child->next; 11411 } 11412 if (child != NULL) { 11413 xmlSchemaPContentErr(ctxt, 11414 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11415 NULL, node, child, NULL, 11416 "(annotation?, (element | group | choice | sequence | any)*)"); 11417 } 11418 } 11419 if ((max == 0) && (min == 0)) 11420 return (NULL); 11421 if (hasRefs) { 11422 /* 11423 * We need to resolve references. 11424 */ 11425 WXS_ADD_PENDING(ctxt, item); 11426 } 11427 if (withParticle) 11428 return ((xmlSchemaTreeItemPtr) particle); 11429 else 11430 return ((xmlSchemaTreeItemPtr) item); 11431 } 11432 11433 /** 11434 * xmlSchemaParseRestriction: 11435 * @ctxt: a schema validation context 11436 * @schema: the schema being built 11437 * @node: a subtree containing XML Schema informations 11438 * 11439 * parse a XML schema Restriction definition 11440 * *WARNING* this interface is highly subject to change 11441 * 11442 * Returns the type definition or NULL in case of error 11443 */ 11444 static xmlSchemaTypePtr 11445 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11446 xmlNodePtr node, xmlSchemaTypeType parentType) 11447 { 11448 xmlSchemaTypePtr type; 11449 xmlNodePtr child = NULL; 11450 xmlAttrPtr attr; 11451 11452 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11453 return (NULL); 11454 /* Not a component, don't create it. */ 11455 type = ctxt->ctxtType; 11456 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 11457 11458 /* 11459 * Check for illegal attributes. 11460 */ 11461 attr = node->properties; 11462 while (attr != NULL) { 11463 if (attr->ns == NULL) { 11464 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11465 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11466 xmlSchemaPIllegalAttrErr(ctxt, 11467 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11468 } 11469 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11470 xmlSchemaPIllegalAttrErr(ctxt, 11471 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11472 } 11473 attr = attr->next; 11474 } 11475 /* 11476 * Extract and validate attributes. 11477 */ 11478 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11479 /* 11480 * Attribute 11481 */ 11482 /* 11483 * Extract the base type. The "base" attribute is mandatory if inside 11484 * a complex type or if redefining. 11485 * 11486 * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> " 11487 * among its [children]), the simple type definition which is 11488 * the {content type} of the type definition resolved to by 11489 * the actual value of the base [attribute]" 11490 */ 11491 if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base", 11492 &(type->baseNs), &(type->base)) == 0) 11493 { 11494 if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) { 11495 xmlSchemaPMissingAttrErr(ctxt, 11496 XML_SCHEMAP_S4S_ATTR_MISSING, 11497 NULL, node, "base", NULL); 11498 } else if ((ctxt->isRedefine) && 11499 (type->flags & XML_SCHEMAS_TYPE_GLOBAL)) 11500 { 11501 if (type->base == NULL) { 11502 xmlSchemaPMissingAttrErr(ctxt, 11503 XML_SCHEMAP_S4S_ATTR_MISSING, 11504 NULL, node, "base", NULL); 11505 } else if ((! xmlStrEqual(type->base, type->name)) || 11506 (! xmlStrEqual(type->baseNs, type->targetNamespace))) 11507 { 11508 xmlChar *str1 = NULL, *str2 = NULL; 11509 /* 11510 * REDEFINE: SPEC src-redefine (5) 11511 * "Within the [children], each <simpleType> must have a 11512 * <restriction> among its [children] ... the actual value of 11513 * whose base [attribute] must be the same as the actual value 11514 * of its own name attribute plus target namespace;" 11515 */ 11516 xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE, 11517 NULL, node, "This is a redefinition, but the QName " 11518 "value '%s' of the 'base' attribute does not match the " 11519 "type's designation '%s'", 11520 xmlSchemaFormatQName(&str1, type->baseNs, type->base), 11521 xmlSchemaFormatQName(&str2, type->targetNamespace, 11522 type->name), NULL); 11523 FREE_AND_NULL(str1); 11524 FREE_AND_NULL(str2); 11525 /* Avoid confusion and erase the values. */ 11526 type->base = NULL; 11527 type->baseNs = NULL; 11528 } 11529 } 11530 } 11531 /* 11532 * And now for the children... 11533 */ 11534 child = node->children; 11535 if (IS_SCHEMA(child, "annotation")) { 11536 /* 11537 * Add the annotation to the simple type ancestor. 11538 */ 11539 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11540 xmlSchemaParseAnnotation(ctxt, child, 1)); 11541 child = child->next; 11542 } 11543 if (parentType == XML_SCHEMA_TYPE_SIMPLE) { 11544 /* 11545 * Corresponds to <simpleType><restriction><simpleType>. 11546 */ 11547 if (IS_SCHEMA(child, "simpleType")) { 11548 if (type->base != NULL) { 11549 /* 11550 * src-restriction-base-or-simpleType 11551 * Either the base [attribute] or the simpleType [child] of the 11552 * <restriction> element must be present, but not both. 11553 */ 11554 xmlSchemaPContentErr(ctxt, 11555 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11556 NULL, node, child, 11557 "The attribute 'base' and the <simpleType> child are " 11558 "mutually exclusive", NULL); 11559 } else { 11560 type->baseType = (xmlSchemaTypePtr) 11561 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11562 } 11563 child = child->next; 11564 } else if (type->base == NULL) { 11565 xmlSchemaPContentErr(ctxt, 11566 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11567 NULL, node, child, 11568 "Either the attribute 'base' or a <simpleType> child " 11569 "must be present", NULL); 11570 } 11571 } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11572 /* 11573 * Corresponds to <complexType><complexContent><restriction>... 11574 * followed by: 11575 * 11576 * Model groups <all>, <choice> and <sequence>. 11577 */ 11578 if (IS_SCHEMA(child, "all")) { 11579 type->subtypes = (xmlSchemaTypePtr) 11580 xmlSchemaParseModelGroup(ctxt, schema, child, 11581 XML_SCHEMA_TYPE_ALL, 1); 11582 child = child->next; 11583 } else if (IS_SCHEMA(child, "choice")) { 11584 type->subtypes = (xmlSchemaTypePtr) 11585 xmlSchemaParseModelGroup(ctxt, 11586 schema, child, XML_SCHEMA_TYPE_CHOICE, 1); 11587 child = child->next; 11588 } else if (IS_SCHEMA(child, "sequence")) { 11589 type->subtypes = (xmlSchemaTypePtr) 11590 xmlSchemaParseModelGroup(ctxt, schema, child, 11591 XML_SCHEMA_TYPE_SEQUENCE, 1); 11592 child = child->next; 11593 /* 11594 * Model group reference <group>. 11595 */ 11596 } else if (IS_SCHEMA(child, "group")) { 11597 type->subtypes = (xmlSchemaTypePtr) 11598 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11599 /* 11600 * Note that the reference will be resolved in 11601 * xmlSchemaResolveTypeReferences(); 11602 */ 11603 child = child->next; 11604 } 11605 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11606 /* 11607 * Corresponds to <complexType><simpleContent><restriction>... 11608 * 11609 * "1.1 the simple type definition corresponding to the <simpleType> 11610 * among the [children] of <restriction> if there is one;" 11611 */ 11612 if (IS_SCHEMA(child, "simpleType")) { 11613 /* 11614 * We will store the to-be-restricted simple type in 11615 * type->contentTypeDef *temporarily*. 11616 */ 11617 type->contentTypeDef = (xmlSchemaTypePtr) 11618 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11619 if ( type->contentTypeDef == NULL) 11620 return (NULL); 11621 child = child->next; 11622 } 11623 } 11624 11625 if ((parentType == XML_SCHEMA_TYPE_SIMPLE) || 11626 (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) { 11627 xmlSchemaFacetPtr facet, lastfacet = NULL; 11628 /* 11629 * Corresponds to <complexType><simpleContent><restriction>... 11630 * <simpleType><restriction>... 11631 */ 11632 11633 /* 11634 * Add the facets to the simple type ancestor. 11635 */ 11636 /* 11637 * TODO: Datatypes: 4.1.3 Constraints on XML Representation of 11638 * Simple Type Definition Schema Representation Constraint: 11639 * *Single Facet Value* 11640 */ 11641 while ((IS_SCHEMA(child, "minInclusive")) || 11642 (IS_SCHEMA(child, "minExclusive")) || 11643 (IS_SCHEMA(child, "maxInclusive")) || 11644 (IS_SCHEMA(child, "maxExclusive")) || 11645 (IS_SCHEMA(child, "totalDigits")) || 11646 (IS_SCHEMA(child, "fractionDigits")) || 11647 (IS_SCHEMA(child, "pattern")) || 11648 (IS_SCHEMA(child, "enumeration")) || 11649 (IS_SCHEMA(child, "whiteSpace")) || 11650 (IS_SCHEMA(child, "length")) || 11651 (IS_SCHEMA(child, "maxLength")) || 11652 (IS_SCHEMA(child, "minLength"))) { 11653 facet = xmlSchemaParseFacet(ctxt, schema, child); 11654 if (facet != NULL) { 11655 if (lastfacet == NULL) 11656 type->facets = facet; 11657 else 11658 lastfacet->next = facet; 11659 lastfacet = facet; 11660 lastfacet->next = NULL; 11661 } 11662 child = child->next; 11663 } 11664 /* 11665 * Create links for derivation and validation. 11666 */ 11667 if (type->facets != NULL) { 11668 xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL; 11669 11670 facet = type->facets; 11671 do { 11672 facetLink = (xmlSchemaFacetLinkPtr) 11673 xmlMalloc(sizeof(xmlSchemaFacetLink)); 11674 if (facetLink == NULL) { 11675 xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL); 11676 xmlFree(facetLink); 11677 return (NULL); 11678 } 11679 facetLink->facet = facet; 11680 facetLink->next = NULL; 11681 if (lastFacetLink == NULL) 11682 type->facetSet = facetLink; 11683 else 11684 lastFacetLink->next = facetLink; 11685 lastFacetLink = facetLink; 11686 facet = facet->next; 11687 } while (facet != NULL); 11688 } 11689 } 11690 if (type->type == XML_SCHEMA_TYPE_COMPLEX) { 11691 /* 11692 * Attribute uses/declarations. 11693 */ 11694 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11695 (xmlSchemaItemListPtr *) &(type->attrUses), 11696 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 11697 return(NULL); 11698 /* 11699 * Attribute wildcard. 11700 */ 11701 if (IS_SCHEMA(child, "anyAttribute")) { 11702 type->attributeWildcard = 11703 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11704 child = child->next; 11705 } 11706 } 11707 if (child != NULL) { 11708 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11709 xmlSchemaPContentErr(ctxt, 11710 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11711 NULL, node, child, NULL, 11712 "annotation?, (group | all | choice | sequence)?, " 11713 "((attribute | attributeGroup)*, anyAttribute?))"); 11714 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11715 xmlSchemaPContentErr(ctxt, 11716 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11717 NULL, node, child, NULL, 11718 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11719 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11720 "length | minLength | maxLength | enumeration | whiteSpace | " 11721 "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))"); 11722 } else { 11723 /* Simple type */ 11724 xmlSchemaPContentErr(ctxt, 11725 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11726 NULL, node, child, NULL, 11727 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11728 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11729 "length | minLength | maxLength | enumeration | whiteSpace | " 11730 "pattern)*))"); 11731 } 11732 } 11733 return (NULL); 11734 } 11735 11736 /** 11737 * xmlSchemaParseExtension: 11738 * @ctxt: a schema validation context 11739 * @schema: the schema being built 11740 * @node: a subtree containing XML Schema informations 11741 * 11742 * Parses an <extension>, which is found inside a 11743 * <simpleContent> or <complexContent>. 11744 * *WARNING* this interface is highly subject to change. 11745 * 11746 * TODO: Returns the type definition or NULL in case of error 11747 */ 11748 static xmlSchemaTypePtr 11749 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11750 xmlNodePtr node, xmlSchemaTypeType parentType) 11751 { 11752 xmlSchemaTypePtr type; 11753 xmlNodePtr child = NULL; 11754 xmlAttrPtr attr; 11755 11756 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11757 return (NULL); 11758 /* Not a component, don't create it. */ 11759 type = ctxt->ctxtType; 11760 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION; 11761 11762 /* 11763 * Check for illegal attributes. 11764 */ 11765 attr = node->properties; 11766 while (attr != NULL) { 11767 if (attr->ns == NULL) { 11768 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11769 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11770 xmlSchemaPIllegalAttrErr(ctxt, 11771 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11772 } 11773 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11774 xmlSchemaPIllegalAttrErr(ctxt, 11775 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11776 } 11777 attr = attr->next; 11778 } 11779 11780 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11781 11782 /* 11783 * Attribute "base" - mandatory. 11784 */ 11785 if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node, 11786 "base", &(type->baseNs), &(type->base)) == 0) && 11787 (type->base == NULL)) { 11788 xmlSchemaPMissingAttrErr(ctxt, 11789 XML_SCHEMAP_S4S_ATTR_MISSING, 11790 NULL, node, "base", NULL); 11791 } 11792 /* 11793 * And now for the children... 11794 */ 11795 child = node->children; 11796 if (IS_SCHEMA(child, "annotation")) { 11797 /* 11798 * Add the annotation to the type ancestor. 11799 */ 11800 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11801 xmlSchemaParseAnnotation(ctxt, child, 1)); 11802 child = child->next; 11803 } 11804 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11805 /* 11806 * Corresponds to <complexType><complexContent><extension>... and: 11807 * 11808 * Model groups <all>, <choice>, <sequence> and <group>. 11809 */ 11810 if (IS_SCHEMA(child, "all")) { 11811 type->subtypes = (xmlSchemaTypePtr) 11812 xmlSchemaParseModelGroup(ctxt, schema, 11813 child, XML_SCHEMA_TYPE_ALL, 1); 11814 child = child->next; 11815 } else if (IS_SCHEMA(child, "choice")) { 11816 type->subtypes = (xmlSchemaTypePtr) 11817 xmlSchemaParseModelGroup(ctxt, schema, 11818 child, XML_SCHEMA_TYPE_CHOICE, 1); 11819 child = child->next; 11820 } else if (IS_SCHEMA(child, "sequence")) { 11821 type->subtypes = (xmlSchemaTypePtr) 11822 xmlSchemaParseModelGroup(ctxt, schema, 11823 child, XML_SCHEMA_TYPE_SEQUENCE, 1); 11824 child = child->next; 11825 } else if (IS_SCHEMA(child, "group")) { 11826 type->subtypes = (xmlSchemaTypePtr) 11827 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11828 /* 11829 * Note that the reference will be resolved in 11830 * xmlSchemaResolveTypeReferences(); 11831 */ 11832 child = child->next; 11833 } 11834 } 11835 if (child != NULL) { 11836 /* 11837 * Attribute uses/declarations. 11838 */ 11839 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11840 (xmlSchemaItemListPtr *) &(type->attrUses), 11841 XML_SCHEMA_TYPE_EXTENSION, NULL) == -1) 11842 return(NULL); 11843 /* 11844 * Attribute wildcard. 11845 */ 11846 if (IS_SCHEMA(child, "anyAttribute")) { 11847 ctxt->ctxtType->attributeWildcard = 11848 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11849 child = child->next; 11850 } 11851 } 11852 if (child != NULL) { 11853 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11854 /* Complex content extension. */ 11855 xmlSchemaPContentErr(ctxt, 11856 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11857 NULL, node, child, NULL, 11858 "(annotation?, ((group | all | choice | sequence)?, " 11859 "((attribute | attributeGroup)*, anyAttribute?)))"); 11860 } else { 11861 /* Simple content extension. */ 11862 xmlSchemaPContentErr(ctxt, 11863 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11864 NULL, node, child, NULL, 11865 "(annotation?, ((attribute | attributeGroup)*, " 11866 "anyAttribute?))"); 11867 } 11868 } 11869 return (NULL); 11870 } 11871 11872 /** 11873 * xmlSchemaParseSimpleContent: 11874 * @ctxt: a schema validation context 11875 * @schema: the schema being built 11876 * @node: a subtree containing XML Schema informations 11877 * 11878 * parse a XML schema SimpleContent definition 11879 * *WARNING* this interface is highly subject to change 11880 * 11881 * Returns the type definition or NULL in case of error 11882 */ 11883 static int 11884 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt, 11885 xmlSchemaPtr schema, xmlNodePtr node, 11886 int *hasRestrictionOrExtension) 11887 { 11888 xmlSchemaTypePtr type; 11889 xmlNodePtr child = NULL; 11890 xmlAttrPtr attr; 11891 11892 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 11893 (hasRestrictionOrExtension == NULL)) 11894 return (-1); 11895 *hasRestrictionOrExtension = 0; 11896 /* Not a component, don't create it. */ 11897 type = ctxt->ctxtType; 11898 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 11899 /* 11900 * Check for illegal attributes. 11901 */ 11902 attr = node->properties; 11903 while (attr != NULL) { 11904 if (attr->ns == NULL) { 11905 if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) { 11906 xmlSchemaPIllegalAttrErr(ctxt, 11907 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11908 } 11909 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11910 xmlSchemaPIllegalAttrErr(ctxt, 11911 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11912 } 11913 attr = attr->next; 11914 } 11915 11916 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11917 11918 /* 11919 * And now for the children... 11920 */ 11921 child = node->children; 11922 if (IS_SCHEMA(child, "annotation")) { 11923 /* 11924 * Add the annotation to the complex type ancestor. 11925 */ 11926 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11927 xmlSchemaParseAnnotation(ctxt, child, 1)); 11928 child = child->next; 11929 } 11930 if (child == NULL) { 11931 xmlSchemaPContentErr(ctxt, 11932 XML_SCHEMAP_S4S_ELEM_MISSING, 11933 NULL, node, NULL, NULL, 11934 "(annotation?, (restriction | extension))"); 11935 } 11936 if (child == NULL) { 11937 xmlSchemaPContentErr(ctxt, 11938 XML_SCHEMAP_S4S_ELEM_MISSING, 11939 NULL, node, NULL, NULL, 11940 "(annotation?, (restriction | extension))"); 11941 } 11942 if (IS_SCHEMA(child, "restriction")) { 11943 xmlSchemaParseRestriction(ctxt, schema, child, 11944 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 11945 (*hasRestrictionOrExtension) = 1; 11946 child = child->next; 11947 } else if (IS_SCHEMA(child, "extension")) { 11948 xmlSchemaParseExtension(ctxt, schema, child, 11949 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 11950 (*hasRestrictionOrExtension) = 1; 11951 child = child->next; 11952 } 11953 if (child != NULL) { 11954 xmlSchemaPContentErr(ctxt, 11955 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11956 NULL, node, child, NULL, 11957 "(annotation?, (restriction | extension))"); 11958 } 11959 return (0); 11960 } 11961 11962 /** 11963 * xmlSchemaParseComplexContent: 11964 * @ctxt: a schema validation context 11965 * @schema: the schema being built 11966 * @node: a subtree containing XML Schema informations 11967 * 11968 * parse a XML schema ComplexContent definition 11969 * *WARNING* this interface is highly subject to change 11970 * 11971 * Returns the type definition or NULL in case of error 11972 */ 11973 static int 11974 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt, 11975 xmlSchemaPtr schema, xmlNodePtr node, 11976 int *hasRestrictionOrExtension) 11977 { 11978 xmlSchemaTypePtr type; 11979 xmlNodePtr child = NULL; 11980 xmlAttrPtr attr; 11981 11982 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 11983 (hasRestrictionOrExtension == NULL)) 11984 return (-1); 11985 *hasRestrictionOrExtension = 0; 11986 /* Not a component, don't create it. */ 11987 type = ctxt->ctxtType; 11988 /* 11989 * Check for illegal attributes. 11990 */ 11991 attr = node->properties; 11992 while (attr != NULL) { 11993 if (attr->ns == NULL) { 11994 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11995 (!xmlStrEqual(attr->name, BAD_CAST "mixed"))) 11996 { 11997 xmlSchemaPIllegalAttrErr(ctxt, 11998 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11999 } 12000 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12001 xmlSchemaPIllegalAttrErr(ctxt, 12002 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12003 } 12004 attr = attr->next; 12005 } 12006 12007 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12008 12009 /* 12010 * Set the 'mixed' on the complex type ancestor. 12011 */ 12012 if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) { 12013 if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0) 12014 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12015 } 12016 child = node->children; 12017 if (IS_SCHEMA(child, "annotation")) { 12018 /* 12019 * Add the annotation to the complex type ancestor. 12020 */ 12021 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 12022 xmlSchemaParseAnnotation(ctxt, child, 1)); 12023 child = child->next; 12024 } 12025 if (child == NULL) { 12026 xmlSchemaPContentErr(ctxt, 12027 XML_SCHEMAP_S4S_ELEM_MISSING, 12028 NULL, node, NULL, 12029 NULL, "(annotation?, (restriction | extension))"); 12030 } 12031 if (child == NULL) { 12032 xmlSchemaPContentErr(ctxt, 12033 XML_SCHEMAP_S4S_ELEM_MISSING, 12034 NULL, node, NULL, 12035 NULL, "(annotation?, (restriction | extension))"); 12036 } 12037 if (IS_SCHEMA(child, "restriction")) { 12038 xmlSchemaParseRestriction(ctxt, schema, child, 12039 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12040 (*hasRestrictionOrExtension) = 1; 12041 child = child->next; 12042 } else if (IS_SCHEMA(child, "extension")) { 12043 xmlSchemaParseExtension(ctxt, schema, child, 12044 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12045 (*hasRestrictionOrExtension) = 1; 12046 child = child->next; 12047 } 12048 if (child != NULL) { 12049 xmlSchemaPContentErr(ctxt, 12050 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12051 NULL, node, child, 12052 NULL, "(annotation?, (restriction | extension))"); 12053 } 12054 return (0); 12055 } 12056 12057 /** 12058 * xmlSchemaParseComplexType: 12059 * @ctxt: a schema validation context 12060 * @schema: the schema being built 12061 * @node: a subtree containing XML Schema informations 12062 * 12063 * parse a XML schema Complex Type definition 12064 * *WARNING* this interface is highly subject to change 12065 * 12066 * Returns the type definition or NULL in case of error 12067 */ 12068 static xmlSchemaTypePtr 12069 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 12070 xmlNodePtr node, int topLevel) 12071 { 12072 xmlSchemaTypePtr type, ctxtType; 12073 xmlNodePtr child = NULL; 12074 const xmlChar *name = NULL; 12075 xmlAttrPtr attr; 12076 const xmlChar *attrValue; 12077 #ifdef ENABLE_NAMED_LOCALS 12078 char buf[40]; 12079 #endif 12080 int final = 0, block = 0, hasRestrictionOrExtension = 0; 12081 12082 12083 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 12084 return (NULL); 12085 12086 ctxtType = ctxt->ctxtType; 12087 12088 if (topLevel) { 12089 attr = xmlSchemaGetPropNode(node, "name"); 12090 if (attr == NULL) { 12091 xmlSchemaPMissingAttrErr(ctxt, 12092 XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL); 12093 return (NULL); 12094 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 12095 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 12096 return (NULL); 12097 } 12098 } 12099 12100 if (topLevel == 0) { 12101 /* 12102 * Parse as local complex type definition. 12103 */ 12104 #ifdef ENABLE_NAMED_LOCALS 12105 snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1); 12106 type = xmlSchemaAddType(ctxt, schema, 12107 XML_SCHEMA_TYPE_COMPLEX, 12108 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 12109 ctxt->targetNamespace, node, 0); 12110 #else 12111 type = xmlSchemaAddType(ctxt, schema, 12112 XML_SCHEMA_TYPE_COMPLEX, 12113 NULL, ctxt->targetNamespace, node, 0); 12114 #endif 12115 if (type == NULL) 12116 return (NULL); 12117 name = type->name; 12118 type->node = node; 12119 type->type = XML_SCHEMA_TYPE_COMPLEX; 12120 /* 12121 * TODO: We need the target namespace. 12122 */ 12123 } else { 12124 /* 12125 * Parse as global complex type definition. 12126 */ 12127 type = xmlSchemaAddType(ctxt, schema, 12128 XML_SCHEMA_TYPE_COMPLEX, 12129 name, ctxt->targetNamespace, node, 1); 12130 if (type == NULL) 12131 return (NULL); 12132 type->node = node; 12133 type->type = XML_SCHEMA_TYPE_COMPLEX; 12134 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 12135 } 12136 type->targetNamespace = ctxt->targetNamespace; 12137 /* 12138 * Handle attributes. 12139 */ 12140 attr = node->properties; 12141 while (attr != NULL) { 12142 if (attr->ns == NULL) { 12143 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 12144 /* 12145 * Attribute "id". 12146 */ 12147 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12148 } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) { 12149 /* 12150 * Attribute "mixed". 12151 */ 12152 if (xmlSchemaPGetBoolNodeValue(ctxt, 12153 NULL, (xmlNodePtr) attr)) 12154 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12155 } else if (topLevel) { 12156 /* 12157 * Attributes of global complex type definitions. 12158 */ 12159 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 12160 /* Pass. */ 12161 } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) { 12162 /* 12163 * Attribute "abstract". 12164 */ 12165 if (xmlSchemaPGetBoolNodeValue(ctxt, 12166 NULL, (xmlNodePtr) attr)) 12167 type->flags |= XML_SCHEMAS_TYPE_ABSTRACT; 12168 } else if (xmlStrEqual(attr->name, BAD_CAST "final")) { 12169 /* 12170 * Attribute "final". 12171 */ 12172 attrValue = xmlSchemaGetNodeContent(ctxt, 12173 (xmlNodePtr) attr); 12174 if (xmlSchemaPValAttrBlockFinal(attrValue, 12175 &(type->flags), 12176 -1, 12177 XML_SCHEMAS_TYPE_FINAL_EXTENSION, 12178 XML_SCHEMAS_TYPE_FINAL_RESTRICTION, 12179 -1, -1, -1) != 0) 12180 { 12181 xmlSchemaPSimpleTypeErr(ctxt, 12182 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12183 NULL, (xmlNodePtr) attr, NULL, 12184 "(#all | List of (extension | restriction))", 12185 attrValue, NULL, NULL, NULL); 12186 } else 12187 final = 1; 12188 } else if (xmlStrEqual(attr->name, BAD_CAST "block")) { 12189 /* 12190 * Attribute "block". 12191 */ 12192 attrValue = xmlSchemaGetNodeContent(ctxt, 12193 (xmlNodePtr) attr); 12194 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 12195 -1, 12196 XML_SCHEMAS_TYPE_BLOCK_EXTENSION, 12197 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION, 12198 -1, -1, -1) != 0) { 12199 xmlSchemaPSimpleTypeErr(ctxt, 12200 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12201 NULL, (xmlNodePtr) attr, NULL, 12202 "(#all | List of (extension | restriction)) ", 12203 attrValue, NULL, NULL, NULL); 12204 } else 12205 block = 1; 12206 } else { 12207 xmlSchemaPIllegalAttrErr(ctxt, 12208 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12209 } 12210 } else { 12211 xmlSchemaPIllegalAttrErr(ctxt, 12212 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12213 } 12214 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12215 xmlSchemaPIllegalAttrErr(ctxt, 12216 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12217 } 12218 attr = attr->next; 12219 } 12220 if (! block) { 12221 /* 12222 * Apply default "block" values. 12223 */ 12224 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 12225 type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 12226 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 12227 type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 12228 } 12229 if (! final) { 12230 /* 12231 * Apply default "block" values. 12232 */ 12233 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 12234 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 12235 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 12236 type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION; 12237 } 12238 /* 12239 * And now for the children... 12240 */ 12241 child = node->children; 12242 if (IS_SCHEMA(child, "annotation")) { 12243 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 12244 child = child->next; 12245 } 12246 ctxt->ctxtType = type; 12247 if (IS_SCHEMA(child, "simpleContent")) { 12248 /* 12249 * <complexType><simpleContent>... 12250 * 3.4.3 : 2.2 12251 * Specifying mixed='true' when the <simpleContent> 12252 * alternative is chosen has no effect 12253 */ 12254 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 12255 type->flags ^= XML_SCHEMAS_TYPE_MIXED; 12256 xmlSchemaParseSimpleContent(ctxt, schema, child, 12257 &hasRestrictionOrExtension); 12258 child = child->next; 12259 } else if (IS_SCHEMA(child, "complexContent")) { 12260 /* 12261 * <complexType><complexContent>... 12262 */ 12263 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 12264 xmlSchemaParseComplexContent(ctxt, schema, child, 12265 &hasRestrictionOrExtension); 12266 child = child->next; 12267 } else { 12268 /* 12269 * E.g <complexType><sequence>... or <complexType><attribute>... etc. 12270 * 12271 * SPEC 12272 * "...the third alternative (neither <simpleContent> nor 12273 * <complexContent>) is chosen. This case is understood as shorthand 12274 * for complex content restricting the ur-type definition, and the 12275 * details of the mappings should be modified as necessary. 12276 */ 12277 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 12278 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 12279 /* 12280 * Parse model groups. 12281 */ 12282 if (IS_SCHEMA(child, "all")) { 12283 type->subtypes = (xmlSchemaTypePtr) 12284 xmlSchemaParseModelGroup(ctxt, schema, child, 12285 XML_SCHEMA_TYPE_ALL, 1); 12286 child = child->next; 12287 } else if (IS_SCHEMA(child, "choice")) { 12288 type->subtypes = (xmlSchemaTypePtr) 12289 xmlSchemaParseModelGroup(ctxt, schema, child, 12290 XML_SCHEMA_TYPE_CHOICE, 1); 12291 child = child->next; 12292 } else if (IS_SCHEMA(child, "sequence")) { 12293 type->subtypes = (xmlSchemaTypePtr) 12294 xmlSchemaParseModelGroup(ctxt, schema, child, 12295 XML_SCHEMA_TYPE_SEQUENCE, 1); 12296 child = child->next; 12297 } else if (IS_SCHEMA(child, "group")) { 12298 type->subtypes = (xmlSchemaTypePtr) 12299 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 12300 /* 12301 * Note that the reference will be resolved in 12302 * xmlSchemaResolveTypeReferences(); 12303 */ 12304 child = child->next; 12305 } 12306 /* 12307 * Parse attribute decls/refs. 12308 */ 12309 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 12310 (xmlSchemaItemListPtr *) &(type->attrUses), 12311 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 12312 return(NULL); 12313 /* 12314 * Parse attribute wildcard. 12315 */ 12316 if (IS_SCHEMA(child, "anyAttribute")) { 12317 type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child); 12318 child = child->next; 12319 } 12320 } 12321 if (child != NULL) { 12322 xmlSchemaPContentErr(ctxt, 12323 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12324 NULL, node, child, 12325 NULL, "(annotation?, (simpleContent | complexContent | " 12326 "((group | all | choice | sequence)?, ((attribute | " 12327 "attributeGroup)*, anyAttribute?))))"); 12328 } 12329 /* 12330 * REDEFINE: SPEC src-redefine (5) 12331 */ 12332 if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) { 12333 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 12334 NULL, node, "This is a redefinition, thus the " 12335 "<complexType> must have a <restriction> or <extension> " 12336 "grand-child", NULL); 12337 } 12338 ctxt->ctxtType = ctxtType; 12339 return (type); 12340 } 12341 12342 /************************************************************************ 12343 * * 12344 * Validating using Schemas * 12345 * * 12346 ************************************************************************/ 12347 12348 /************************************************************************ 12349 * * 12350 * Reading/Writing Schemas * 12351 * * 12352 ************************************************************************/ 12353 12354 #if 0 /* Will be enabled if it is clear what options are needed. */ 12355 /** 12356 * xmlSchemaParserCtxtSetOptions: 12357 * @ctxt: a schema parser context 12358 * @options: a combination of xmlSchemaParserOption 12359 * 12360 * Sets the options to be used during the parse. 12361 * 12362 * Returns 0 in case of success, -1 in case of an 12363 * API error. 12364 */ 12365 static int 12366 xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt, 12367 int options) 12368 12369 { 12370 int i; 12371 12372 if (ctxt == NULL) 12373 return (-1); 12374 /* 12375 * WARNING: Change the start value if adding to the 12376 * xmlSchemaParseOption. 12377 */ 12378 for (i = 1; i < (int) sizeof(int) * 8; i++) { 12379 if (options & 1<<i) { 12380 return (-1); 12381 } 12382 } 12383 ctxt->options = options; 12384 return (0); 12385 } 12386 12387 /** 12388 * xmlSchemaValidCtxtGetOptions: 12389 * @ctxt: a schema parser context 12390 * 12391 * Returns the option combination of the parser context. 12392 */ 12393 static int 12394 xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt) 12395 12396 { 12397 if (ctxt == NULL) 12398 return (-1); 12399 else 12400 return (ctxt->options); 12401 } 12402 #endif 12403 12404 /** 12405 * xmlSchemaNewParserCtxt: 12406 * @URL: the location of the schema 12407 * 12408 * Create an XML Schemas parse context for that file/resource expected 12409 * to contain an XML Schemas file. 12410 * 12411 * Returns the parser context or NULL in case of error 12412 */ 12413 xmlSchemaParserCtxtPtr 12414 xmlSchemaNewParserCtxt(const char *URL) 12415 { 12416 xmlSchemaParserCtxtPtr ret; 12417 12418 if (URL == NULL) 12419 return (NULL); 12420 12421 ret = xmlSchemaParserCtxtCreate(); 12422 if (ret == NULL) 12423 return(NULL); 12424 ret->dict = xmlDictCreate(); 12425 ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1); 12426 return (ret); 12427 } 12428 12429 /** 12430 * xmlSchemaNewMemParserCtxt: 12431 * @buffer: a pointer to a char array containing the schemas 12432 * @size: the size of the array 12433 * 12434 * Create an XML Schemas parse context for that memory buffer expected 12435 * to contain an XML Schemas file. 12436 * 12437 * Returns the parser context or NULL in case of error 12438 */ 12439 xmlSchemaParserCtxtPtr 12440 xmlSchemaNewMemParserCtxt(const char *buffer, int size) 12441 { 12442 xmlSchemaParserCtxtPtr ret; 12443 12444 if ((buffer == NULL) || (size <= 0)) 12445 return (NULL); 12446 ret = xmlSchemaParserCtxtCreate(); 12447 if (ret == NULL) 12448 return(NULL); 12449 ret->buffer = buffer; 12450 ret->size = size; 12451 ret->dict = xmlDictCreate(); 12452 return (ret); 12453 } 12454 12455 /** 12456 * xmlSchemaNewDocParserCtxt: 12457 * @doc: a preparsed document tree 12458 * 12459 * Create an XML Schemas parse context for that document. 12460 * NB. The document may be modified during the parsing process. 12461 * 12462 * Returns the parser context or NULL in case of error 12463 */ 12464 xmlSchemaParserCtxtPtr 12465 xmlSchemaNewDocParserCtxt(xmlDocPtr doc) 12466 { 12467 xmlSchemaParserCtxtPtr ret; 12468 12469 if (doc == NULL) 12470 return (NULL); 12471 ret = xmlSchemaParserCtxtCreate(); 12472 if (ret == NULL) 12473 return(NULL); 12474 ret->doc = doc; 12475 ret->dict = xmlDictCreate(); 12476 /* The application has responsibility for the document */ 12477 ret->preserve = 1; 12478 12479 return (ret); 12480 } 12481 12482 /** 12483 * xmlSchemaFreeParserCtxt: 12484 * @ctxt: the schema parser context 12485 * 12486 * Free the resources associated to the schema parser context 12487 */ 12488 void 12489 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt) 12490 { 12491 if (ctxt == NULL) 12492 return; 12493 if (ctxt->doc != NULL && !ctxt->preserve) 12494 xmlFreeDoc(ctxt->doc); 12495 if (ctxt->vctxt != NULL) { 12496 xmlSchemaFreeValidCtxt(ctxt->vctxt); 12497 } 12498 if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) { 12499 xmlSchemaConstructionCtxtFree(ctxt->constructor); 12500 ctxt->constructor = NULL; 12501 ctxt->ownsConstructor = 0; 12502 } 12503 if (ctxt->attrProhibs != NULL) 12504 xmlSchemaItemListFree(ctxt->attrProhibs); 12505 xmlDictFree(ctxt->dict); 12506 xmlFree(ctxt); 12507 } 12508 12509 /************************************************************************ 12510 * * 12511 * Building the content models * 12512 * * 12513 ************************************************************************/ 12514 12515 static void 12516 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt, 12517 xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end) 12518 { 12519 xmlAutomataStatePtr start, tmp; 12520 xmlSchemaElementPtr elemDecl, member; 12521 xmlSchemaSubstGroupPtr substGroup; 12522 int i; 12523 12524 elemDecl = (xmlSchemaElementPtr) particle->children; 12525 /* 12526 * Wrap the substitution group with a CHOICE. 12527 */ 12528 start = pctxt->state; 12529 if (end == NULL) 12530 end = xmlAutomataNewState(pctxt->am); 12531 substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl); 12532 if (substGroup == NULL) { 12533 xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle), 12534 XML_SCHEMAP_INTERNAL, 12535 "Internal error: xmlSchemaBuildContentModelForSubstGroup, " 12536 "declaration is marked having a subst. group but none " 12537 "available.\n", elemDecl->name, NULL); 12538 return; 12539 } 12540 if (counter >= 0) { 12541 /* 12542 * NOTE that we put the declaration in, even if it's abstract. 12543 * However, an error will be raised during *validation* if an element 12544 * information item shall be validated against an abstract element 12545 * declaration. 12546 */ 12547 tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter); 12548 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12549 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12550 /* 12551 * Add subst. group members. 12552 */ 12553 for (i = 0; i < substGroup->members->nbItems; i++) { 12554 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12555 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12556 member->name, member->targetNamespace, member); 12557 } 12558 } else if (particle->maxOccurs == 1) { 12559 /* 12560 * NOTE that we put the declaration in, even if it's abstract, 12561 */ 12562 xmlAutomataNewEpsilon(pctxt->am, 12563 xmlAutomataNewTransition2(pctxt->am, 12564 start, NULL, 12565 elemDecl->name, elemDecl->targetNamespace, elemDecl), end); 12566 /* 12567 * Add subst. group members. 12568 */ 12569 for (i = 0; i < substGroup->members->nbItems; i++) { 12570 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12571 /* 12572 * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2() 12573 * was incorrectly used instead of xmlAutomataNewTransition2() 12574 * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL 12575 * section in xmlSchemaBuildAContentModel() ). 12576 * TODO: Check if xmlAutomataNewOnceTrans2() was instead 12577 * intended for the above "counter" section originally. I.e., 12578 * check xs:all with subst-groups. 12579 * 12580 * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL, 12581 * member->name, member->targetNamespace, 12582 * 1, 1, member); 12583 */ 12584 tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL, 12585 member->name, member->targetNamespace, member); 12586 xmlAutomataNewEpsilon(pctxt->am, tmp, end); 12587 } 12588 } else { 12589 xmlAutomataStatePtr hop; 12590 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12591 UNBOUNDED : particle->maxOccurs - 1; 12592 int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12593 12594 counter = 12595 xmlAutomataNewCounter(pctxt->am, minOccurs, 12596 maxOccurs); 12597 hop = xmlAutomataNewState(pctxt->am); 12598 12599 xmlAutomataNewEpsilon(pctxt->am, 12600 xmlAutomataNewTransition2(pctxt->am, 12601 start, NULL, 12602 elemDecl->name, elemDecl->targetNamespace, elemDecl), 12603 hop); 12604 /* 12605 * Add subst. group members. 12606 */ 12607 for (i = 0; i < substGroup->members->nbItems; i++) { 12608 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12609 xmlAutomataNewEpsilon(pctxt->am, 12610 xmlAutomataNewTransition2(pctxt->am, 12611 start, NULL, 12612 member->name, member->targetNamespace, member), 12613 hop); 12614 } 12615 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12616 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12617 } 12618 if (particle->minOccurs == 0) 12619 xmlAutomataNewEpsilon(pctxt->am, start, end); 12620 pctxt->state = end; 12621 } 12622 12623 static void 12624 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt, 12625 xmlSchemaParticlePtr particle) 12626 { 12627 if (((xmlSchemaElementPtr) particle->children)->flags & 12628 XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 12629 /* 12630 * Substitution groups. 12631 */ 12632 xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL); 12633 } else { 12634 xmlSchemaElementPtr elemDecl; 12635 xmlAutomataStatePtr start; 12636 12637 elemDecl = (xmlSchemaElementPtr) particle->children; 12638 12639 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) 12640 return; 12641 if (particle->maxOccurs == 1) { 12642 start = ctxt->state; 12643 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12644 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12645 } else if ((particle->maxOccurs >= UNBOUNDED) && 12646 (particle->minOccurs < 2)) { 12647 /* Special case. */ 12648 start = ctxt->state; 12649 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12650 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12651 ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state, 12652 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12653 } else { 12654 int counter; 12655 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12656 UNBOUNDED : particle->maxOccurs - 1; 12657 int minOccurs = particle->minOccurs < 1 ? 12658 0 : particle->minOccurs - 1; 12659 12660 start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL); 12661 counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs); 12662 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12663 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12664 xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter); 12665 ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state, 12666 NULL, counter); 12667 } 12668 if (particle->minOccurs == 0) 12669 xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state); 12670 } 12671 } 12672 12673 /** 12674 * xmlSchemaBuildAContentModel: 12675 * @ctxt: the schema parser context 12676 * @particle: the particle component 12677 * @name: the complex type's name whose content is being built 12678 * 12679 * Create the automaton for the {content type} of a complex type. 12680 * 12681 */ 12682 static void 12683 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt, 12684 xmlSchemaParticlePtr particle) 12685 { 12686 if (particle == NULL) { 12687 PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL"); 12688 return; 12689 } 12690 if (particle->children == NULL) { 12691 /* 12692 * Just return in this case. A missing "term" of the particle 12693 * might arise due to an invalid "term" component. 12694 */ 12695 return; 12696 } 12697 12698 switch (particle->children->type) { 12699 case XML_SCHEMA_TYPE_ANY: { 12700 xmlAutomataStatePtr start, end; 12701 xmlSchemaWildcardPtr wild; 12702 xmlSchemaWildcardNsPtr ns; 12703 12704 wild = (xmlSchemaWildcardPtr) particle->children; 12705 12706 start = pctxt->state; 12707 end = xmlAutomataNewState(pctxt->am); 12708 12709 if (particle->maxOccurs == 1) { 12710 if (wild->any == 1) { 12711 /* 12712 * We need to add both transitions: 12713 * 12714 * 1. the {"*", "*"} for elements in a namespace. 12715 */ 12716 pctxt->state = 12717 xmlAutomataNewTransition2(pctxt->am, 12718 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12719 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12720 /* 12721 * 2. the {"*"} for elements in no namespace. 12722 */ 12723 pctxt->state = 12724 xmlAutomataNewTransition2(pctxt->am, 12725 start, NULL, BAD_CAST "*", NULL, wild); 12726 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12727 12728 } else if (wild->nsSet != NULL) { 12729 ns = wild->nsSet; 12730 do { 12731 pctxt->state = start; 12732 pctxt->state = xmlAutomataNewTransition2(pctxt->am, 12733 pctxt->state, NULL, BAD_CAST "*", ns->value, wild); 12734 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12735 ns = ns->next; 12736 } while (ns != NULL); 12737 12738 } else if (wild->negNsSet != NULL) { 12739 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12740 start, end, BAD_CAST "*", wild->negNsSet->value, 12741 wild); 12742 } 12743 } else { 12744 int counter; 12745 xmlAutomataStatePtr hop; 12746 int maxOccurs = 12747 particle->maxOccurs == UNBOUNDED ? UNBOUNDED : particle->maxOccurs - 1; 12748 int minOccurs = 12749 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12750 12751 counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 12752 hop = xmlAutomataNewState(pctxt->am); 12753 if (wild->any == 1) { 12754 pctxt->state = 12755 xmlAutomataNewTransition2(pctxt->am, 12756 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12757 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12758 pctxt->state = 12759 xmlAutomataNewTransition2(pctxt->am, 12760 start, NULL, BAD_CAST "*", NULL, wild); 12761 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12762 } else if (wild->nsSet != NULL) { 12763 ns = wild->nsSet; 12764 do { 12765 pctxt->state = 12766 xmlAutomataNewTransition2(pctxt->am, 12767 start, NULL, BAD_CAST "*", ns->value, wild); 12768 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12769 ns = ns->next; 12770 } while (ns != NULL); 12771 12772 } else if (wild->negNsSet != NULL) { 12773 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12774 start, hop, BAD_CAST "*", wild->negNsSet->value, 12775 wild); 12776 } 12777 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12778 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12779 } 12780 if (particle->minOccurs == 0) { 12781 xmlAutomataNewEpsilon(pctxt->am, start, end); 12782 } 12783 pctxt->state = end; 12784 break; 12785 } 12786 case XML_SCHEMA_TYPE_ELEMENT: 12787 xmlSchemaBuildContentModelForElement(pctxt, particle); 12788 break; 12789 case XML_SCHEMA_TYPE_SEQUENCE:{ 12790 xmlSchemaTreeItemPtr sub; 12791 12792 /* 12793 * If max and min occurances are default (1) then 12794 * simply iterate over the particles of the <sequence>. 12795 */ 12796 if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) { 12797 sub = particle->children->children; 12798 while (sub != NULL) { 12799 xmlSchemaBuildAContentModel(pctxt, 12800 (xmlSchemaParticlePtr) sub); 12801 sub = sub->next; 12802 } 12803 } else { 12804 xmlAutomataStatePtr oldstate = pctxt->state; 12805 12806 if (particle->maxOccurs >= UNBOUNDED) { 12807 if (particle->minOccurs > 1) { 12808 xmlAutomataStatePtr tmp; 12809 int counter; 12810 12811 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12812 oldstate, NULL); 12813 oldstate = pctxt->state; 12814 12815 counter = xmlAutomataNewCounter(pctxt->am, 12816 particle->minOccurs - 1, UNBOUNDED); 12817 12818 sub = particle->children->children; 12819 while (sub != NULL) { 12820 xmlSchemaBuildAContentModel(pctxt, 12821 (xmlSchemaParticlePtr) sub); 12822 sub = sub->next; 12823 } 12824 tmp = pctxt->state; 12825 xmlAutomataNewCountedTrans(pctxt->am, tmp, 12826 oldstate, counter); 12827 pctxt->state = 12828 xmlAutomataNewCounterTrans(pctxt->am, tmp, 12829 NULL, counter); 12830 12831 } else { 12832 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12833 oldstate, NULL); 12834 oldstate = pctxt->state; 12835 12836 sub = particle->children->children; 12837 while (sub != NULL) { 12838 xmlSchemaBuildAContentModel(pctxt, 12839 (xmlSchemaParticlePtr) sub); 12840 sub = sub->next; 12841 } 12842 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, 12843 oldstate); 12844 /* 12845 * epsilon needed to block previous trans from 12846 * being allowed to enter back from another 12847 * construct 12848 */ 12849 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12850 pctxt->state, NULL); 12851 if (particle->minOccurs == 0) { 12852 xmlAutomataNewEpsilon(pctxt->am, 12853 oldstate, pctxt->state); 12854 } 12855 } 12856 } else if ((particle->maxOccurs > 1) 12857 || (particle->minOccurs > 1)) { 12858 xmlAutomataStatePtr tmp; 12859 int counter; 12860 12861 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12862 oldstate, NULL); 12863 oldstate = pctxt->state; 12864 12865 counter = xmlAutomataNewCounter(pctxt->am, 12866 particle->minOccurs - 1, 12867 particle->maxOccurs - 1); 12868 12869 sub = particle->children->children; 12870 while (sub != NULL) { 12871 xmlSchemaBuildAContentModel(pctxt, 12872 (xmlSchemaParticlePtr) sub); 12873 sub = sub->next; 12874 } 12875 tmp = pctxt->state; 12876 xmlAutomataNewCountedTrans(pctxt->am, 12877 tmp, oldstate, counter); 12878 pctxt->state = 12879 xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL, 12880 counter); 12881 if (particle->minOccurs == 0) { 12882 xmlAutomataNewEpsilon(pctxt->am, 12883 oldstate, pctxt->state); 12884 } 12885 } else { 12886 sub = particle->children->children; 12887 while (sub != NULL) { 12888 xmlSchemaBuildAContentModel(pctxt, 12889 (xmlSchemaParticlePtr) sub); 12890 sub = sub->next; 12891 } 12892 if (particle->minOccurs == 0) { 12893 xmlAutomataNewEpsilon(pctxt->am, oldstate, 12894 pctxt->state); 12895 } 12896 } 12897 } 12898 break; 12899 } 12900 case XML_SCHEMA_TYPE_CHOICE:{ 12901 xmlSchemaTreeItemPtr sub; 12902 xmlAutomataStatePtr start, end; 12903 12904 start = pctxt->state; 12905 end = xmlAutomataNewState(pctxt->am); 12906 12907 /* 12908 * iterate over the subtypes and remerge the end with an 12909 * epsilon transition 12910 */ 12911 if (particle->maxOccurs == 1) { 12912 sub = particle->children->children; 12913 while (sub != NULL) { 12914 pctxt->state = start; 12915 xmlSchemaBuildAContentModel(pctxt, 12916 (xmlSchemaParticlePtr) sub); 12917 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12918 sub = sub->next; 12919 } 12920 } else { 12921 int counter; 12922 xmlAutomataStatePtr hop, base; 12923 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12924 UNBOUNDED : particle->maxOccurs - 1; 12925 int minOccurs = 12926 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12927 12928 /* 12929 * use a counter to keep track of the number of transtions 12930 * which went through the choice. 12931 */ 12932 counter = 12933 xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 12934 hop = xmlAutomataNewState(pctxt->am); 12935 base = xmlAutomataNewState(pctxt->am); 12936 12937 sub = particle->children->children; 12938 while (sub != NULL) { 12939 pctxt->state = base; 12940 xmlSchemaBuildAContentModel(pctxt, 12941 (xmlSchemaParticlePtr) sub); 12942 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12943 sub = sub->next; 12944 } 12945 xmlAutomataNewEpsilon(pctxt->am, start, base); 12946 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter); 12947 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12948 } 12949 if (particle->minOccurs == 0) { 12950 xmlAutomataNewEpsilon(pctxt->am, start, end); 12951 } 12952 pctxt->state = end; 12953 break; 12954 } 12955 case XML_SCHEMA_TYPE_ALL:{ 12956 xmlAutomataStatePtr start; 12957 xmlSchemaParticlePtr sub; 12958 xmlSchemaElementPtr elemDecl; 12959 int lax; 12960 12961 sub = (xmlSchemaParticlePtr) particle->children->children; 12962 if (sub == NULL) 12963 break; 12964 start = pctxt->state; 12965 while (sub != NULL) { 12966 pctxt->state = start; 12967 12968 elemDecl = (xmlSchemaElementPtr) sub->children; 12969 if (elemDecl == NULL) { 12970 PERROR_INT("xmlSchemaBuildAContentModel", 12971 "<element> particle has no term"); 12972 return; 12973 }; 12974 /* 12975 * NOTE: The {max occurs} of all the particles in the 12976 * {particles} of the group must be 0 or 1; this is 12977 * already ensured during the parse of the content of 12978 * <all>. 12979 */ 12980 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 12981 int counter; 12982 12983 /* 12984 * This is an abstract group, we need to share 12985 * the same counter for all the element transitions 12986 * derived from the group 12987 */ 12988 counter = xmlAutomataNewCounter(pctxt->am, 12989 sub->minOccurs, sub->maxOccurs); 12990 xmlSchemaBuildContentModelForSubstGroup(pctxt, 12991 sub, counter, pctxt->state); 12992 } else { 12993 if ((sub->minOccurs == 1) && 12994 (sub->maxOccurs == 1)) { 12995 xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state, 12996 pctxt->state, 12997 elemDecl->name, 12998 elemDecl->targetNamespace, 12999 1, 1, elemDecl); 13000 } else if ((sub->minOccurs == 0) && 13001 (sub->maxOccurs == 1)) { 13002 13003 xmlAutomataNewCountTrans2(pctxt->am, pctxt->state, 13004 pctxt->state, 13005 elemDecl->name, 13006 elemDecl->targetNamespace, 13007 0, 13008 1, 13009 elemDecl); 13010 } 13011 } 13012 sub = (xmlSchemaParticlePtr) sub->next; 13013 } 13014 lax = particle->minOccurs == 0; 13015 pctxt->state = 13016 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, lax); 13017 break; 13018 } 13019 case XML_SCHEMA_TYPE_GROUP: 13020 /* 13021 * If we hit a model group definition, then this means that 13022 * it was empty, thus was not substituted for the containing 13023 * model group. Just do nothing in this case. 13024 * TODO: But the group should be substituted and not occur at 13025 * all in the content model at this point. Fix this. 13026 */ 13027 break; 13028 default: 13029 xmlSchemaInternalErr2(ACTXT_CAST pctxt, 13030 "xmlSchemaBuildAContentModel", 13031 "found unexpected term of type '%s' in content model", 13032 WXS_ITEM_TYPE_NAME(particle->children), NULL); 13033 return; 13034 } 13035 } 13036 13037 /** 13038 * xmlSchemaBuildContentModel: 13039 * @ctxt: the schema parser context 13040 * @type: the complex type definition 13041 * @name: the element name 13042 * 13043 * Builds the content model of the complex type. 13044 */ 13045 static void 13046 xmlSchemaBuildContentModel(xmlSchemaTypePtr type, 13047 xmlSchemaParserCtxtPtr ctxt) 13048 { 13049 if ((type->type != XML_SCHEMA_TYPE_COMPLEX) || 13050 (type->contModel != NULL) || 13051 ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) && 13052 (type->contentType != XML_SCHEMA_CONTENT_MIXED))) 13053 return; 13054 13055 #ifdef DEBUG_CONTENT 13056 xmlGenericError(xmlGenericErrorContext, 13057 "Building content model for %s\n", name); 13058 #endif 13059 ctxt->am = NULL; 13060 ctxt->am = xmlNewAutomata(); 13061 if (ctxt->am == NULL) { 13062 xmlGenericError(xmlGenericErrorContext, 13063 "Cannot create automata for complex type %s\n", type->name); 13064 return; 13065 } 13066 ctxt->state = xmlAutomataGetInitState(ctxt->am); 13067 /* 13068 * Build the automaton. 13069 */ 13070 xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type)); 13071 xmlAutomataSetFinalState(ctxt->am, ctxt->state); 13072 type->contModel = xmlAutomataCompile(ctxt->am); 13073 if (type->contModel == NULL) { 13074 xmlSchemaPCustomErr(ctxt, 13075 XML_SCHEMAP_INTERNAL, 13076 WXS_BASIC_CAST type, type->node, 13077 "Failed to compile the content model", NULL); 13078 } else if (xmlRegexpIsDeterminist(type->contModel) != 1) { 13079 xmlSchemaPCustomErr(ctxt, 13080 XML_SCHEMAP_NOT_DETERMINISTIC, 13081 /* XML_SCHEMAS_ERR_NOTDETERMINIST, */ 13082 WXS_BASIC_CAST type, type->node, 13083 "The content model is not determinist", NULL); 13084 } else { 13085 #ifdef DEBUG_CONTENT_REGEXP 13086 xmlGenericError(xmlGenericErrorContext, 13087 "Content model of %s:\n", type->name); 13088 xmlRegexpPrint(stderr, type->contModel); 13089 #endif 13090 } 13091 ctxt->state = NULL; 13092 xmlFreeAutomata(ctxt->am); 13093 ctxt->am = NULL; 13094 } 13095 13096 /** 13097 * xmlSchemaResolveElementReferences: 13098 * @elem: the schema element context 13099 * @ctxt: the schema parser context 13100 * 13101 * Resolves the references of an element declaration 13102 * or particle, which has an element declaration as it's 13103 * term. 13104 */ 13105 static void 13106 xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl, 13107 xmlSchemaParserCtxtPtr ctxt) 13108 { 13109 if ((ctxt == NULL) || (elemDecl == NULL) || 13110 ((elemDecl != NULL) && 13111 (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED))) 13112 return; 13113 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED; 13114 13115 if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) { 13116 xmlSchemaTypePtr type; 13117 13118 /* (type definition) ... otherwise the type definition resolved 13119 * to by the actual value of the type [attribute] ... 13120 */ 13121 type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType, 13122 elemDecl->namedTypeNs); 13123 if (type == NULL) { 13124 xmlSchemaPResCompAttrErr(ctxt, 13125 XML_SCHEMAP_SRC_RESOLVE, 13126 WXS_BASIC_CAST elemDecl, elemDecl->node, 13127 "type", elemDecl->namedType, elemDecl->namedTypeNs, 13128 XML_SCHEMA_TYPE_BASIC, "type definition"); 13129 } else 13130 elemDecl->subtypes = type; 13131 } 13132 if (elemDecl->substGroup != NULL) { 13133 xmlSchemaElementPtr substHead; 13134 13135 /* 13136 * FIXME TODO: Do we need a new field in _xmlSchemaElement for 13137 * substitutionGroup? 13138 */ 13139 substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup, 13140 elemDecl->substGroupNs); 13141 if (substHead == NULL) { 13142 xmlSchemaPResCompAttrErr(ctxt, 13143 XML_SCHEMAP_SRC_RESOLVE, 13144 WXS_BASIC_CAST elemDecl, NULL, 13145 "substitutionGroup", elemDecl->substGroup, 13146 elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL); 13147 } else { 13148 xmlSchemaResolveElementReferences(substHead, ctxt); 13149 /* 13150 * Set the "substitution group affiliation". 13151 * NOTE that now we use the "refDecl" field for this. 13152 */ 13153 WXS_SUBST_HEAD(elemDecl) = substHead; 13154 /* 13155 * The type definitions is set to: 13156 * SPEC "...the {type definition} of the element 13157 * declaration resolved to by the actual value 13158 * of the substitutionGroup [attribute], if present" 13159 */ 13160 if (elemDecl->subtypes == NULL) 13161 elemDecl->subtypes = substHead->subtypes; 13162 } 13163 } 13164 /* 13165 * SPEC "The definition of anyType serves as the default type definition 13166 * for element declarations whose XML representation does not specify one." 13167 */ 13168 if ((elemDecl->subtypes == NULL) && 13169 (elemDecl->namedType == NULL) && 13170 (elemDecl->substGroup == NULL)) 13171 elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 13172 } 13173 13174 /** 13175 * xmlSchemaResolveUnionMemberTypes: 13176 * @ctxt: the schema parser context 13177 * @type: the schema simple type definition 13178 * 13179 * Checks and builds the "member type definitions" property of the union 13180 * simple type. This handles part (1), part (2) is done in 13181 * xmlSchemaFinishMemberTypeDefinitionsProperty() 13182 * 13183 * Returns -1 in case of an internal error, 0 otherwise. 13184 */ 13185 static int 13186 xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt, 13187 xmlSchemaTypePtr type) 13188 { 13189 13190 xmlSchemaTypeLinkPtr link, lastLink, newLink; 13191 xmlSchemaTypePtr memberType; 13192 13193 /* 13194 * SPEC (1) "If the <union> alternative is chosen, then [Definition:] 13195 * define the explicit members as the type definitions resolved 13196 * to by the items in the actual value of the memberTypes [attribute], 13197 * if any, followed by the type definitions corresponding to the 13198 * <simpleType>s among the [children] of <union>, if any." 13199 */ 13200 /* 13201 * Resolve references. 13202 */ 13203 link = type->memberTypes; 13204 lastLink = NULL; 13205 while (link != NULL) { 13206 const xmlChar *name, *nsName; 13207 13208 name = ((xmlSchemaQNameRefPtr) link->type)->name; 13209 nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace; 13210 13211 memberType = xmlSchemaGetType(ctxt->schema, name, nsName); 13212 if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) { 13213 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 13214 WXS_BASIC_CAST type, type->node, "memberTypes", 13215 name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL); 13216 /* 13217 * Remove the member type link. 13218 */ 13219 if (lastLink == NULL) 13220 type->memberTypes = link->next; 13221 else 13222 lastLink->next = link->next; 13223 newLink = link; 13224 link = link->next; 13225 xmlFree(newLink); 13226 } else { 13227 link->type = memberType; 13228 lastLink = link; 13229 link = link->next; 13230 } 13231 } 13232 /* 13233 * Add local simple types, 13234 */ 13235 memberType = type->subtypes; 13236 while (memberType != NULL) { 13237 link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink)); 13238 if (link == NULL) { 13239 xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL); 13240 return (-1); 13241 } 13242 link->type = memberType; 13243 link->next = NULL; 13244 if (lastLink == NULL) 13245 type->memberTypes = link; 13246 else 13247 lastLink->next = link; 13248 lastLink = link; 13249 memberType = memberType->next; 13250 } 13251 return (0); 13252 } 13253 13254 /** 13255 * xmlSchemaIsDerivedFromBuiltInType: 13256 * @ctxt: the schema parser context 13257 * @type: the type definition 13258 * @valType: the value type 13259 * 13260 * 13261 * Returns 1 if the type has the given value type, or 13262 * is derived from such a type. 13263 */ 13264 static int 13265 xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13266 { 13267 if (type == NULL) 13268 return (0); 13269 if (WXS_IS_COMPLEX(type)) 13270 return (0); 13271 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13272 if (type->builtInType == valType) 13273 return(1); 13274 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13275 (type->builtInType == XML_SCHEMAS_ANYTYPE)) 13276 return (0); 13277 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13278 } 13279 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13280 } 13281 13282 #if 0 13283 /** 13284 * xmlSchemaIsDerivedFromBuiltInType: 13285 * @ctxt: the schema parser context 13286 * @type: the type definition 13287 * @valType: the value type 13288 * 13289 * 13290 * Returns 1 if the type has the given value type, or 13291 * is derived from such a type. 13292 */ 13293 static int 13294 xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13295 { 13296 if (type == NULL) 13297 return (0); 13298 if (WXS_IS_COMPLEX(type)) 13299 return (0); 13300 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13301 if (type->builtInType == valType) 13302 return(1); 13303 return (0); 13304 } else 13305 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13306 13307 return (0); 13308 } 13309 13310 static xmlSchemaTypePtr 13311 xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type) 13312 { 13313 if (type == NULL) 13314 return (NULL); 13315 if (WXS_IS_COMPLEX(type)) 13316 return (NULL); 13317 if (type->type == XML_SCHEMA_TYPE_BASIC) 13318 return(type); 13319 return(xmlSchemaQueryBuiltInType(type->subtypes)); 13320 } 13321 #endif 13322 13323 /** 13324 * xmlSchemaGetPrimitiveType: 13325 * @type: the simpleType definition 13326 * 13327 * Returns the primitive type of the given type or 13328 * NULL in case of error. 13329 */ 13330 static xmlSchemaTypePtr 13331 xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type) 13332 { 13333 13334 while (type != NULL) { 13335 /* 13336 * Note that anySimpleType is actually not a primitive type 13337 * but we need that here. 13338 */ 13339 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13340 (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE)) 13341 return (type); 13342 type = type->baseType; 13343 } 13344 13345 return (NULL); 13346 } 13347 13348 #if 0 13349 /** 13350 * xmlSchemaGetBuiltInTypeAncestor: 13351 * @type: the simpleType definition 13352 * 13353 * Returns the primitive type of the given type or 13354 * NULL in case of error. 13355 */ 13356 static xmlSchemaTypePtr 13357 xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type) 13358 { 13359 if (WXS_IS_LIST(type) || WXS_IS_UNION(type)) 13360 return (0); 13361 while (type != NULL) { 13362 if (type->type == XML_SCHEMA_TYPE_BASIC) 13363 return (type); 13364 type = type->baseType; 13365 } 13366 13367 return (NULL); 13368 } 13369 #endif 13370 13371 /** 13372 * xmlSchemaCloneWildcardNsConstraints: 13373 * @ctxt: the schema parser context 13374 * @dest: the destination wildcard 13375 * @source: the source wildcard 13376 * 13377 * Clones the namespace constraints of source 13378 * and assignes them to dest. 13379 * Returns -1 on internal error, 0 otherwise. 13380 */ 13381 static int 13382 xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt, 13383 xmlSchemaWildcardPtr dest, 13384 xmlSchemaWildcardPtr source) 13385 { 13386 xmlSchemaWildcardNsPtr cur, tmp, last; 13387 13388 if ((source == NULL) || (dest == NULL)) 13389 return(-1); 13390 dest->any = source->any; 13391 cur = source->nsSet; 13392 last = NULL; 13393 while (cur != NULL) { 13394 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13395 if (tmp == NULL) 13396 return(-1); 13397 tmp->value = cur->value; 13398 if (last == NULL) 13399 dest->nsSet = tmp; 13400 else 13401 last->next = tmp; 13402 last = tmp; 13403 cur = cur->next; 13404 } 13405 if (dest->negNsSet != NULL) 13406 xmlSchemaFreeWildcardNsSet(dest->negNsSet); 13407 if (source->negNsSet != NULL) { 13408 dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13409 if (dest->negNsSet == NULL) 13410 return(-1); 13411 dest->negNsSet->value = source->negNsSet->value; 13412 } else 13413 dest->negNsSet = NULL; 13414 return(0); 13415 } 13416 13417 /** 13418 * xmlSchemaUnionWildcards: 13419 * @ctxt: the schema parser context 13420 * @completeWild: the first wildcard 13421 * @curWild: the second wildcard 13422 * 13423 * Unions the namespace constraints of the given wildcards. 13424 * @completeWild will hold the resulting union. 13425 * Returns a positive error code on failure, -1 in case of an 13426 * internal error, 0 otherwise. 13427 */ 13428 static int 13429 xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, 13430 xmlSchemaWildcardPtr completeWild, 13431 xmlSchemaWildcardPtr curWild) 13432 { 13433 xmlSchemaWildcardNsPtr cur, curB, tmp; 13434 13435 /* 13436 * 1 If O1 and O2 are the same value, then that value must be the 13437 * value. 13438 */ 13439 if ((completeWild->any == curWild->any) && 13440 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13441 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13442 13443 if ((completeWild->negNsSet == NULL) || 13444 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13445 13446 if (completeWild->nsSet != NULL) { 13447 int found = 0; 13448 13449 /* 13450 * Check equality of sets. 13451 */ 13452 cur = completeWild->nsSet; 13453 while (cur != NULL) { 13454 found = 0; 13455 curB = curWild->nsSet; 13456 while (curB != NULL) { 13457 if (cur->value == curB->value) { 13458 found = 1; 13459 break; 13460 } 13461 curB = curB->next; 13462 } 13463 if (!found) 13464 break; 13465 cur = cur->next; 13466 } 13467 if (found) 13468 return(0); 13469 } else 13470 return(0); 13471 } 13472 } 13473 /* 13474 * 2 If either O1 or O2 is any, then any must be the value 13475 */ 13476 if (completeWild->any != curWild->any) { 13477 if (completeWild->any == 0) { 13478 completeWild->any = 1; 13479 if (completeWild->nsSet != NULL) { 13480 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13481 completeWild->nsSet = NULL; 13482 } 13483 if (completeWild->negNsSet != NULL) { 13484 xmlFree(completeWild->negNsSet); 13485 completeWild->negNsSet = NULL; 13486 } 13487 } 13488 return (0); 13489 } 13490 /* 13491 * 3 If both O1 and O2 are sets of (namespace names or absent), 13492 * then the union of those sets must be the value. 13493 */ 13494 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13495 int found; 13496 xmlSchemaWildcardNsPtr start; 13497 13498 cur = curWild->nsSet; 13499 start = completeWild->nsSet; 13500 while (cur != NULL) { 13501 found = 0; 13502 curB = start; 13503 while (curB != NULL) { 13504 if (cur->value == curB->value) { 13505 found = 1; 13506 break; 13507 } 13508 curB = curB->next; 13509 } 13510 if (!found) { 13511 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13512 if (tmp == NULL) 13513 return (-1); 13514 tmp->value = cur->value; 13515 tmp->next = completeWild->nsSet; 13516 completeWild->nsSet = tmp; 13517 } 13518 cur = cur->next; 13519 } 13520 13521 return(0); 13522 } 13523 /* 13524 * 4 If the two are negations of different values (namespace names 13525 * or absent), then a pair of not and absent must be the value. 13526 */ 13527 if ((completeWild->negNsSet != NULL) && 13528 (curWild->negNsSet != NULL) && 13529 (completeWild->negNsSet->value != curWild->negNsSet->value)) { 13530 completeWild->negNsSet->value = NULL; 13531 13532 return(0); 13533 } 13534 /* 13535 * 5. 13536 */ 13537 if (((completeWild->negNsSet != NULL) && 13538 (completeWild->negNsSet->value != NULL) && 13539 (curWild->nsSet != NULL)) || 13540 ((curWild->negNsSet != NULL) && 13541 (curWild->negNsSet->value != NULL) && 13542 (completeWild->nsSet != NULL))) { 13543 13544 int nsFound, absentFound = 0; 13545 13546 if (completeWild->nsSet != NULL) { 13547 cur = completeWild->nsSet; 13548 curB = curWild->negNsSet; 13549 } else { 13550 cur = curWild->nsSet; 13551 curB = completeWild->negNsSet; 13552 } 13553 nsFound = 0; 13554 while (cur != NULL) { 13555 if (cur->value == NULL) 13556 absentFound = 1; 13557 else if (cur->value == curB->value) 13558 nsFound = 1; 13559 if (nsFound && absentFound) 13560 break; 13561 cur = cur->next; 13562 } 13563 13564 if (nsFound && absentFound) { 13565 /* 13566 * 5.1 If the set S includes both the negated namespace 13567 * name and absent, then any must be the value. 13568 */ 13569 completeWild->any = 1; 13570 if (completeWild->nsSet != NULL) { 13571 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13572 completeWild->nsSet = NULL; 13573 } 13574 if (completeWild->negNsSet != NULL) { 13575 xmlFree(completeWild->negNsSet); 13576 completeWild->negNsSet = NULL; 13577 } 13578 } else if (nsFound && (!absentFound)) { 13579 /* 13580 * 5.2 If the set S includes the negated namespace name 13581 * but not absent, then a pair of not and absent must 13582 * be the value. 13583 */ 13584 if (completeWild->nsSet != NULL) { 13585 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13586 completeWild->nsSet = NULL; 13587 } 13588 if (completeWild->negNsSet == NULL) { 13589 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13590 if (completeWild->negNsSet == NULL) 13591 return (-1); 13592 } 13593 completeWild->negNsSet->value = NULL; 13594 } else if ((!nsFound) && absentFound) { 13595 /* 13596 * 5.3 If the set S includes absent but not the negated 13597 * namespace name, then the union is not expressible. 13598 */ 13599 xmlSchemaPErr(ctxt, completeWild->node, 13600 XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, 13601 "The union of the wilcard is not expressible.\n", 13602 NULL, NULL); 13603 return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE); 13604 } else if ((!nsFound) && (!absentFound)) { 13605 /* 13606 * 5.4 If the set S does not include either the negated namespace 13607 * name or absent, then whichever of O1 or O2 is a pair of not 13608 * and a namespace name must be the value. 13609 */ 13610 if (completeWild->negNsSet == NULL) { 13611 if (completeWild->nsSet != NULL) { 13612 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13613 completeWild->nsSet = NULL; 13614 } 13615 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13616 if (completeWild->negNsSet == NULL) 13617 return (-1); 13618 completeWild->negNsSet->value = curWild->negNsSet->value; 13619 } 13620 } 13621 return (0); 13622 } 13623 /* 13624 * 6. 13625 */ 13626 if (((completeWild->negNsSet != NULL) && 13627 (completeWild->negNsSet->value == NULL) && 13628 (curWild->nsSet != NULL)) || 13629 ((curWild->negNsSet != NULL) && 13630 (curWild->negNsSet->value == NULL) && 13631 (completeWild->nsSet != NULL))) { 13632 13633 if (completeWild->nsSet != NULL) { 13634 cur = completeWild->nsSet; 13635 } else { 13636 cur = curWild->nsSet; 13637 } 13638 while (cur != NULL) { 13639 if (cur->value == NULL) { 13640 /* 13641 * 6.1 If the set S includes absent, then any must be the 13642 * value. 13643 */ 13644 completeWild->any = 1; 13645 if (completeWild->nsSet != NULL) { 13646 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13647 completeWild->nsSet = NULL; 13648 } 13649 if (completeWild->negNsSet != NULL) { 13650 xmlFree(completeWild->negNsSet); 13651 completeWild->negNsSet = NULL; 13652 } 13653 return (0); 13654 } 13655 cur = cur->next; 13656 } 13657 if (completeWild->negNsSet == NULL) { 13658 /* 13659 * 6.2 If the set S does not include absent, then a pair of not 13660 * and absent must be the value. 13661 */ 13662 if (completeWild->nsSet != NULL) { 13663 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13664 completeWild->nsSet = NULL; 13665 } 13666 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13667 if (completeWild->negNsSet == NULL) 13668 return (-1); 13669 completeWild->negNsSet->value = NULL; 13670 } 13671 return (0); 13672 } 13673 return (0); 13674 13675 } 13676 13677 /** 13678 * xmlSchemaIntersectWildcards: 13679 * @ctxt: the schema parser context 13680 * @completeWild: the first wildcard 13681 * @curWild: the second wildcard 13682 * 13683 * Intersects the namespace constraints of the given wildcards. 13684 * @completeWild will hold the resulting intersection. 13685 * Returns a positive error code on failure, -1 in case of an 13686 * internal error, 0 otherwise. 13687 */ 13688 static int 13689 xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt, 13690 xmlSchemaWildcardPtr completeWild, 13691 xmlSchemaWildcardPtr curWild) 13692 { 13693 xmlSchemaWildcardNsPtr cur, curB, prev, tmp; 13694 13695 /* 13696 * 1 If O1 and O2 are the same value, then that value must be the 13697 * value. 13698 */ 13699 if ((completeWild->any == curWild->any) && 13700 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13701 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13702 13703 if ((completeWild->negNsSet == NULL) || 13704 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13705 13706 if (completeWild->nsSet != NULL) { 13707 int found = 0; 13708 13709 /* 13710 * Check equality of sets. 13711 */ 13712 cur = completeWild->nsSet; 13713 while (cur != NULL) { 13714 found = 0; 13715 curB = curWild->nsSet; 13716 while (curB != NULL) { 13717 if (cur->value == curB->value) { 13718 found = 1; 13719 break; 13720 } 13721 curB = curB->next; 13722 } 13723 if (!found) 13724 break; 13725 cur = cur->next; 13726 } 13727 if (found) 13728 return(0); 13729 } else 13730 return(0); 13731 } 13732 } 13733 /* 13734 * 2 If either O1 or O2 is any, then the other must be the value. 13735 */ 13736 if ((completeWild->any != curWild->any) && (completeWild->any)) { 13737 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13738 return(-1); 13739 return(0); 13740 } 13741 /* 13742 * 3 If either O1 or O2 is a pair of not and a value (a namespace 13743 * name or absent) and the other is a set of (namespace names or 13744 * absent), then that set, minus the negated value if it was in 13745 * the set, minus absent if it was in the set, must be the value. 13746 */ 13747 if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) || 13748 ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) { 13749 const xmlChar *neg; 13750 13751 if (completeWild->nsSet == NULL) { 13752 neg = completeWild->negNsSet->value; 13753 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13754 return(-1); 13755 } else 13756 neg = curWild->negNsSet->value; 13757 /* 13758 * Remove absent and negated. 13759 */ 13760 prev = NULL; 13761 cur = completeWild->nsSet; 13762 while (cur != NULL) { 13763 if (cur->value == NULL) { 13764 if (prev == NULL) 13765 completeWild->nsSet = cur->next; 13766 else 13767 prev->next = cur->next; 13768 xmlFree(cur); 13769 break; 13770 } 13771 prev = cur; 13772 cur = cur->next; 13773 } 13774 if (neg != NULL) { 13775 prev = NULL; 13776 cur = completeWild->nsSet; 13777 while (cur != NULL) { 13778 if (cur->value == neg) { 13779 if (prev == NULL) 13780 completeWild->nsSet = cur->next; 13781 else 13782 prev->next = cur->next; 13783 xmlFree(cur); 13784 break; 13785 } 13786 prev = cur; 13787 cur = cur->next; 13788 } 13789 } 13790 13791 return(0); 13792 } 13793 /* 13794 * 4 If both O1 and O2 are sets of (namespace names or absent), 13795 * then the intersection of those sets must be the value. 13796 */ 13797 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13798 int found; 13799 13800 cur = completeWild->nsSet; 13801 prev = NULL; 13802 while (cur != NULL) { 13803 found = 0; 13804 curB = curWild->nsSet; 13805 while (curB != NULL) { 13806 if (cur->value == curB->value) { 13807 found = 1; 13808 break; 13809 } 13810 curB = curB->next; 13811 } 13812 if (!found) { 13813 if (prev == NULL) 13814 completeWild->nsSet = cur->next; 13815 else 13816 prev->next = cur->next; 13817 tmp = cur->next; 13818 xmlFree(cur); 13819 cur = tmp; 13820 continue; 13821 } 13822 prev = cur; 13823 cur = cur->next; 13824 } 13825 13826 return(0); 13827 } 13828 /* 5 If the two are negations of different namespace names, 13829 * then the intersection is not expressible 13830 */ 13831 if ((completeWild->negNsSet != NULL) && 13832 (curWild->negNsSet != NULL) && 13833 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13834 (completeWild->negNsSet->value != NULL) && 13835 (curWild->negNsSet->value != NULL)) { 13836 13837 xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, 13838 "The intersection of the wilcard is not expressible.\n", 13839 NULL, NULL); 13840 return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE); 13841 } 13842 /* 13843 * 6 If the one is a negation of a namespace name and the other 13844 * is a negation of absent, then the one which is the negation 13845 * of a namespace name must be the value. 13846 */ 13847 if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) && 13848 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13849 (completeWild->negNsSet->value == NULL)) { 13850 completeWild->negNsSet->value = curWild->negNsSet->value; 13851 } 13852 return(0); 13853 } 13854 13855 /** 13856 * xmlSchemaIsWildcardNsConstraintSubset: 13857 * @ctxt: the schema parser context 13858 * @sub: the first wildcard 13859 * @super: the second wildcard 13860 * 13861 * Schema Component Constraint: Wildcard Subset (cos-ns-subset) 13862 * 13863 * Returns 0 if the namespace constraint of @sub is an intensional 13864 * subset of @super, 1 otherwise. 13865 */ 13866 static int 13867 xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub, 13868 xmlSchemaWildcardPtr super) 13869 { 13870 /* 13871 * 1 super must be any. 13872 */ 13873 if (super->any) 13874 return (0); 13875 /* 13876 * 2.1 sub must be a pair of not and a namespace name or absent. 13877 * 2.2 super must be a pair of not and the same value. 13878 */ 13879 if ((sub->negNsSet != NULL) && 13880 (super->negNsSet != NULL) && 13881 (sub->negNsSet->value == sub->negNsSet->value)) 13882 return (0); 13883 /* 13884 * 3.1 sub must be a set whose members are either namespace names or absent. 13885 */ 13886 if (sub->nsSet != NULL) { 13887 /* 13888 * 3.2.1 super must be the same set or a superset thereof. 13889 */ 13890 if (super->nsSet != NULL) { 13891 xmlSchemaWildcardNsPtr cur, curB; 13892 int found = 0; 13893 13894 cur = sub->nsSet; 13895 while (cur != NULL) { 13896 found = 0; 13897 curB = super->nsSet; 13898 while (curB != NULL) { 13899 if (cur->value == curB->value) { 13900 found = 1; 13901 break; 13902 } 13903 curB = curB->next; 13904 } 13905 if (!found) 13906 return (1); 13907 cur = cur->next; 13908 } 13909 if (found) 13910 return (0); 13911 } else if (super->negNsSet != NULL) { 13912 xmlSchemaWildcardNsPtr cur; 13913 /* 13914 * 3.2.2 super must be a pair of not and a namespace name or 13915 * absent and that value must not be in sub's set. 13916 */ 13917 cur = sub->nsSet; 13918 while (cur != NULL) { 13919 if (cur->value == super->negNsSet->value) 13920 return (1); 13921 cur = cur->next; 13922 } 13923 return (0); 13924 } 13925 } 13926 return (1); 13927 } 13928 13929 static int 13930 xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse, 13931 int *fixed, 13932 const xmlChar **value, 13933 xmlSchemaValPtr *val) 13934 { 13935 *fixed = 0; 13936 *value = NULL; 13937 if (val != 0) 13938 *val = NULL; 13939 13940 if (attruse->defValue != NULL) { 13941 *value = attruse->defValue; 13942 if (val != NULL) 13943 *val = attruse->defVal; 13944 if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED) 13945 *fixed = 1; 13946 return(1); 13947 } else if ((attruse->attrDecl != NULL) && 13948 (attruse->attrDecl->defValue != NULL)) { 13949 *value = attruse->attrDecl->defValue; 13950 if (val != NULL) 13951 *val = attruse->attrDecl->defVal; 13952 if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED) 13953 *fixed = 1; 13954 return(1); 13955 } 13956 return(0); 13957 } 13958 /** 13959 * xmlSchemaCheckCVCWildcardNamespace: 13960 * @wild: the wildcard 13961 * @ns: the namespace 13962 * 13963 * Validation Rule: Wildcard allows Namespace Name 13964 * (cvc-wildcard-namespace) 13965 * 13966 * Returns 0 if the given namespace matches the wildcard, 13967 * 1 otherwise and -1 on API errors. 13968 */ 13969 static int 13970 xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild, 13971 const xmlChar* ns) 13972 { 13973 if (wild == NULL) 13974 return(-1); 13975 13976 if (wild->any) 13977 return(0); 13978 else if (wild->nsSet != NULL) { 13979 xmlSchemaWildcardNsPtr cur; 13980 13981 cur = wild->nsSet; 13982 while (cur != NULL) { 13983 if (xmlStrEqual(cur->value, ns)) 13984 return(0); 13985 cur = cur->next; 13986 } 13987 } else if ((wild->negNsSet != NULL) && (ns != NULL) && 13988 (!xmlStrEqual(wild->negNsSet->value, ns))) 13989 return(0); 13990 13991 return(1); 13992 } 13993 13994 #define XML_SCHEMA_ACTION_DERIVE 0 13995 #define XML_SCHEMA_ACTION_REDEFINE 1 13996 13997 #define WXS_ACTION_STR(a) \ 13998 ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined" 13999 14000 /* 14001 * Schema Component Constraint: 14002 * Derivation Valid (Restriction, Complex) 14003 * derivation-ok-restriction (2) - (4) 14004 * 14005 * ATTENTION: 14006 * In XML Schema 1.1 this will be: 14007 * Validation Rule: 14008 * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3) 14009 * 14010 */ 14011 static int 14012 xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt, 14013 int action, 14014 xmlSchemaBasicItemPtr item, 14015 xmlSchemaBasicItemPtr baseItem, 14016 xmlSchemaItemListPtr uses, 14017 xmlSchemaItemListPtr baseUses, 14018 xmlSchemaWildcardPtr wild, 14019 xmlSchemaWildcardPtr baseWild) 14020 { 14021 xmlSchemaAttributeUsePtr cur = NULL, bcur; 14022 int i, j, found; /* err = 0; */ 14023 const xmlChar *bEffValue; 14024 int effFixed; 14025 14026 if (uses != NULL) { 14027 for (i = 0; i < uses->nbItems; i++) { 14028 cur = uses->items[i]; 14029 found = 0; 14030 if (baseUses == NULL) 14031 goto not_found; 14032 for (j = 0; j < baseUses->nbItems; j++) { 14033 bcur = baseUses->items[j]; 14034 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14035 WXS_ATTRUSE_DECL_NAME(bcur)) && 14036 (WXS_ATTRUSE_DECL_TNS(cur) == 14037 WXS_ATTRUSE_DECL_TNS(bcur))) 14038 { 14039 /* 14040 * (2.1) "If there is an attribute use in the {attribute 14041 * uses} of the {base type definition} (call this B) whose 14042 * {attribute declaration} has the same {name} and {target 14043 * namespace}, then all of the following must be true:" 14044 */ 14045 found = 1; 14046 14047 if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && 14048 (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED)) 14049 { 14050 xmlChar *str = NULL; 14051 /* 14052 * (2.1.1) "one of the following must be true:" 14053 * (2.1.1.1) "B's {required} is false." 14054 * (2.1.1.2) "R's {required} is true." 14055 */ 14056 xmlSchemaPAttrUseErr4(pctxt, 14057 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1, 14058 WXS_ITEM_NODE(item), item, cur, 14059 "The 'optional' attribute use is inconsistent " 14060 "with the corresponding 'required' attribute use of " 14061 "the %s %s", 14062 WXS_ACTION_STR(action), 14063 xmlSchemaGetComponentDesignation(&str, baseItem), 14064 NULL, NULL); 14065 FREE_AND_NULL(str); 14066 /* err = pctxt->err; */ 14067 } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 14068 WXS_ATTRUSE_TYPEDEF(cur), 14069 WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0) 14070 { 14071 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 14072 14073 /* 14074 * SPEC (2.1.2) "R's {attribute declaration}'s 14075 * {type definition} must be validly derived from 14076 * B's {type definition} given the empty set as 14077 * defined in Type Derivation OK (Simple) (3.14.6)." 14078 */ 14079 xmlSchemaPAttrUseErr4(pctxt, 14080 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2, 14081 WXS_ITEM_NODE(item), item, cur, 14082 "The attribute declaration's %s " 14083 "is not validly derived from " 14084 "the corresponding %s of the " 14085 "attribute declaration in the %s %s", 14086 xmlSchemaGetComponentDesignation(&strA, 14087 WXS_ATTRUSE_TYPEDEF(cur)), 14088 xmlSchemaGetComponentDesignation(&strB, 14089 WXS_ATTRUSE_TYPEDEF(bcur)), 14090 WXS_ACTION_STR(action), 14091 xmlSchemaGetComponentDesignation(&strC, baseItem)); 14092 /* xmlSchemaGetComponentDesignation(&str, baseItem), */ 14093 FREE_AND_NULL(strA); 14094 FREE_AND_NULL(strB); 14095 FREE_AND_NULL(strC); 14096 /* err = pctxt->err; */ 14097 } else { 14098 /* 14099 * 2.1.3 [Definition:] Let the effective value 14100 * constraint of an attribute use be its {value 14101 * constraint}, if present, otherwise its {attribute 14102 * declaration}'s {value constraint} . 14103 */ 14104 xmlSchemaGetEffectiveValueConstraint(bcur, 14105 &effFixed, &bEffValue, NULL); 14106 /* 14107 * 2.1.3 ... one of the following must be true 14108 * 14109 * 2.1.3.1 B's effective value constraint is 14110 * absent or default. 14111 */ 14112 if ((bEffValue != NULL) && 14113 (effFixed == 1)) { 14114 const xmlChar *rEffValue = NULL; 14115 14116 xmlSchemaGetEffectiveValueConstraint(bcur, 14117 &effFixed, &rEffValue, NULL); 14118 /* 14119 * 2.1.3.2 R's effective value constraint is 14120 * fixed with the same string as B's. 14121 * MAYBE TODO: Compare the computed values. 14122 * Hmm, it says "same string" so 14123 * string-equality might really be sufficient. 14124 */ 14125 if ((effFixed == 0) || 14126 (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue))) 14127 { 14128 xmlChar *str = NULL; 14129 14130 xmlSchemaPAttrUseErr4(pctxt, 14131 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3, 14132 WXS_ITEM_NODE(item), item, cur, 14133 "The effective value constraint of the " 14134 "attribute use is inconsistent with " 14135 "its correspondent in the %s %s", 14136 WXS_ACTION_STR(action), 14137 xmlSchemaGetComponentDesignation(&str, 14138 baseItem), 14139 NULL, NULL); 14140 FREE_AND_NULL(str); 14141 /* err = pctxt->err; */ 14142 } 14143 } 14144 } 14145 break; 14146 } 14147 } 14148 not_found: 14149 if (!found) { 14150 /* 14151 * (2.2) "otherwise the {base type definition} must have an 14152 * {attribute wildcard} and the {target namespace} of the 14153 * R's {attribute declaration} must be valid with respect 14154 * to that wildcard, as defined in Wildcard allows Namespace 14155 * Name (3.10.4)." 14156 */ 14157 if ((baseWild == NULL) || 14158 (xmlSchemaCheckCVCWildcardNamespace(baseWild, 14159 (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0)) 14160 { 14161 xmlChar *str = NULL; 14162 14163 xmlSchemaPAttrUseErr4(pctxt, 14164 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2, 14165 WXS_ITEM_NODE(item), item, cur, 14166 "Neither a matching attribute use, " 14167 "nor a matching wildcard exists in the %s %s", 14168 WXS_ACTION_STR(action), 14169 xmlSchemaGetComponentDesignation(&str, baseItem), 14170 NULL, NULL); 14171 FREE_AND_NULL(str); 14172 /* err = pctxt->err; */ 14173 } 14174 } 14175 } 14176 } 14177 /* 14178 * SPEC derivation-ok-restriction (3): 14179 * (3) "For each attribute use in the {attribute uses} of the {base type 14180 * definition} whose {required} is true, there must be an attribute 14181 * use with an {attribute declaration} with the same {name} and 14182 * {target namespace} as its {attribute declaration} in the {attribute 14183 * uses} of the complex type definition itself whose {required} is true. 14184 */ 14185 if (baseUses != NULL) { 14186 for (j = 0; j < baseUses->nbItems; j++) { 14187 bcur = baseUses->items[j]; 14188 if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED) 14189 continue; 14190 found = 0; 14191 if (uses != NULL) { 14192 for (i = 0; i < uses->nbItems; i++) { 14193 cur = uses->items[i]; 14194 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14195 WXS_ATTRUSE_DECL_NAME(bcur)) && 14196 (WXS_ATTRUSE_DECL_TNS(cur) == 14197 WXS_ATTRUSE_DECL_TNS(bcur))) { 14198 found = 1; 14199 break; 14200 } 14201 } 14202 } 14203 if (!found) { 14204 xmlChar *strA = NULL, *strB = NULL; 14205 14206 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14207 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3, 14208 NULL, item, 14209 "A matching attribute use for the " 14210 "'required' %s of the %s %s is missing", 14211 xmlSchemaGetComponentDesignation(&strA, bcur), 14212 WXS_ACTION_STR(action), 14213 xmlSchemaGetComponentDesignation(&strB, baseItem), 14214 NULL); 14215 FREE_AND_NULL(strA); 14216 FREE_AND_NULL(strB); 14217 } 14218 } 14219 } 14220 /* 14221 * derivation-ok-restriction (4) 14222 */ 14223 if (wild != NULL) { 14224 /* 14225 * (4) "If there is an {attribute wildcard}, all of the 14226 * following must be true:" 14227 */ 14228 if (baseWild == NULL) { 14229 xmlChar *str = NULL; 14230 14231 /* 14232 * (4.1) "The {base type definition} must also have one." 14233 */ 14234 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14235 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, 14236 NULL, item, 14237 "The %s has an attribute wildcard, " 14238 "but the %s %s '%s' does not have one", 14239 WXS_ITEM_TYPE_NAME(item), 14240 WXS_ACTION_STR(action), 14241 WXS_ITEM_TYPE_NAME(baseItem), 14242 xmlSchemaGetComponentQName(&str, baseItem)); 14243 FREE_AND_NULL(str); 14244 return(pctxt->err); 14245 } else if ((baseWild->any == 0) && 14246 xmlSchemaCheckCOSNSSubset(wild, baseWild)) 14247 { 14248 xmlChar *str = NULL; 14249 /* 14250 * (4.2) "The complex type definition's {attribute wildcard}'s 14251 * {namespace constraint} must be a subset of the {base type 14252 * definition}'s {attribute wildcard}'s {namespace constraint}, 14253 * as defined by Wildcard Subset (3.10.6)." 14254 */ 14255 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14256 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, 14257 NULL, item, 14258 "The attribute wildcard is not a valid " 14259 "subset of the wildcard in the %s %s '%s'", 14260 WXS_ACTION_STR(action), 14261 WXS_ITEM_TYPE_NAME(baseItem), 14262 xmlSchemaGetComponentQName(&str, baseItem), 14263 NULL); 14264 FREE_AND_NULL(str); 14265 return(pctxt->err); 14266 } 14267 /* 4.3 Unless the {base type definition} is the ur-type 14268 * definition, the complex type definition's {attribute 14269 * wildcard}'s {process contents} must be identical to or 14270 * stronger than the {base type definition}'s {attribute 14271 * wildcard}'s {process contents}, where strict is stronger 14272 * than lax is stronger than skip. 14273 */ 14274 if ((! WXS_IS_ANYTYPE(baseItem)) && 14275 (wild->processContents < baseWild->processContents)) { 14276 xmlChar *str = NULL; 14277 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14278 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, 14279 NULL, baseItem, 14280 "The {process contents} of the attribute wildcard is " 14281 "weaker than the one in the %s %s '%s'", 14282 WXS_ACTION_STR(action), 14283 WXS_ITEM_TYPE_NAME(baseItem), 14284 xmlSchemaGetComponentQName(&str, baseItem), 14285 NULL); 14286 FREE_AND_NULL(str) 14287 return(pctxt->err); 14288 } 14289 } 14290 return(0); 14291 } 14292 14293 14294 static int 14295 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 14296 xmlSchemaBasicItemPtr item, 14297 xmlSchemaWildcardPtr *completeWild, 14298 xmlSchemaItemListPtr list, 14299 xmlSchemaItemListPtr prohibs); 14300 /** 14301 * xmlSchemaFixupTypeAttributeUses: 14302 * @ctxt: the schema parser context 14303 * @type: the complex type definition 14304 * 14305 * 14306 * Builds the wildcard and the attribute uses on the given complex type. 14307 * Returns -1 if an internal error occurs, 0 otherwise. 14308 * 14309 * ATTENTION TODO: Experimantally this uses pointer comparisons for 14310 * strings, so recheck this if we start to hardcode some schemata, since 14311 * they might not be in the same dict. 14312 * NOTE: It is allowed to "extend" the xs:anyType type. 14313 */ 14314 static int 14315 xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt, 14316 xmlSchemaTypePtr type) 14317 { 14318 xmlSchemaTypePtr baseType = NULL; 14319 xmlSchemaAttributeUsePtr use; 14320 xmlSchemaItemListPtr uses, baseUses, prohibs = NULL; 14321 14322 if (type->baseType == NULL) { 14323 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14324 "no base type"); 14325 return (-1); 14326 } 14327 baseType = type->baseType; 14328 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14329 if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1) 14330 return(-1); 14331 14332 uses = type->attrUses; 14333 baseUses = baseType->attrUses; 14334 /* 14335 * Expand attribute group references. And build the 'complete' 14336 * wildcard, i.e. intersect multiple wildcards. 14337 * Move attribute prohibitions into a separate list. 14338 */ 14339 if (uses != NULL) { 14340 if (WXS_IS_RESTRICTION(type)) { 14341 /* 14342 * This one will transfer all attr. prohibitions 14343 * into pctxt->attrProhibs. 14344 */ 14345 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14346 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14347 pctxt->attrProhibs) == -1) 14348 { 14349 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14350 "failed to expand attributes"); 14351 } 14352 if (pctxt->attrProhibs->nbItems != 0) 14353 prohibs = pctxt->attrProhibs; 14354 } else { 14355 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14356 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14357 NULL) == -1) 14358 { 14359 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14360 "failed to expand attributes"); 14361 } 14362 } 14363 } 14364 /* 14365 * Inherit the attribute uses of the base type. 14366 */ 14367 if (baseUses != NULL) { 14368 int i, j; 14369 xmlSchemaAttributeUseProhibPtr pro; 14370 14371 if (WXS_IS_RESTRICTION(type)) { 14372 int usesCount; 14373 xmlSchemaAttributeUsePtr tmp; 14374 14375 if (uses != NULL) 14376 usesCount = uses->nbItems; 14377 else 14378 usesCount = 0; 14379 14380 /* Restriction. */ 14381 for (i = 0; i < baseUses->nbItems; i++) { 14382 use = baseUses->items[i]; 14383 if (prohibs) { 14384 /* 14385 * Filter out prohibited uses. 14386 */ 14387 for (j = 0; j < prohibs->nbItems; j++) { 14388 pro = prohibs->items[j]; 14389 if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) && 14390 (WXS_ATTRUSE_DECL_TNS(use) == 14391 pro->targetNamespace)) 14392 { 14393 goto inherit_next; 14394 } 14395 } 14396 } 14397 if (usesCount) { 14398 /* 14399 * Filter out existing uses. 14400 */ 14401 for (j = 0; j < usesCount; j++) { 14402 tmp = uses->items[j]; 14403 if ((WXS_ATTRUSE_DECL_NAME(use) == 14404 WXS_ATTRUSE_DECL_NAME(tmp)) && 14405 (WXS_ATTRUSE_DECL_TNS(use) == 14406 WXS_ATTRUSE_DECL_TNS(tmp))) 14407 { 14408 goto inherit_next; 14409 } 14410 } 14411 } 14412 if (uses == NULL) { 14413 type->attrUses = xmlSchemaItemListCreate(); 14414 if (type->attrUses == NULL) 14415 goto exit_failure; 14416 uses = type->attrUses; 14417 } 14418 xmlSchemaItemListAddSize(uses, 2, use); 14419 inherit_next: {} 14420 } 14421 } else { 14422 /* Extension. */ 14423 for (i = 0; i < baseUses->nbItems; i++) { 14424 use = baseUses->items[i]; 14425 if (uses == NULL) { 14426 type->attrUses = xmlSchemaItemListCreate(); 14427 if (type->attrUses == NULL) 14428 goto exit_failure; 14429 uses = type->attrUses; 14430 } 14431 xmlSchemaItemListAddSize(uses, baseUses->nbItems, use); 14432 } 14433 } 14434 } 14435 /* 14436 * Shrink attr. uses. 14437 */ 14438 if (uses) { 14439 if (uses->nbItems == 0) { 14440 xmlSchemaItemListFree(uses); 14441 type->attrUses = NULL; 14442 } 14443 /* 14444 * TODO: We could shrink the size of the array 14445 * to fit the actual number of items. 14446 */ 14447 } 14448 /* 14449 * Compute the complete wildcard. 14450 */ 14451 if (WXS_IS_EXTENSION(type)) { 14452 if (baseType->attributeWildcard != NULL) { 14453 /* 14454 * (3.2.2.1) "If the base wildcard is non-absent, then 14455 * the appropriate case among the following:" 14456 */ 14457 if (type->attributeWildcard != NULL) { 14458 /* 14459 * Union the complete wildcard with the base wildcard. 14460 * SPEC {attribute wildcard} 14461 * (3.2.2.1.2) "otherwise a wildcard whose {process contents} 14462 * and {annotation} are those of the complete wildcard, 14463 * and whose {namespace constraint} is the intensional union 14464 * of the {namespace constraint} of the complete wildcard 14465 * and of the base wildcard, as defined in Attribute 14466 * Wildcard Union (3.10.6)." 14467 */ 14468 if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard, 14469 baseType->attributeWildcard) == -1) 14470 goto exit_failure; 14471 } else { 14472 /* 14473 * (3.2.2.1.1) "If the complete wildcard is absent, 14474 * then the base wildcard." 14475 */ 14476 type->attributeWildcard = baseType->attributeWildcard; 14477 } 14478 } else { 14479 /* 14480 * (3.2.2.2) "otherwise (the base wildcard is absent) the 14481 * complete wildcard" 14482 * NOOP 14483 */ 14484 } 14485 } else { 14486 /* 14487 * SPEC {attribute wildcard} 14488 * (3.1) "If the <restriction> alternative is chosen, then the 14489 * complete wildcard;" 14490 * NOOP 14491 */ 14492 } 14493 14494 return (0); 14495 14496 exit_failure: 14497 return(-1); 14498 } 14499 14500 /** 14501 * xmlSchemaTypeFinalContains: 14502 * @schema: the schema 14503 * @type: the type definition 14504 * @final: the final 14505 * 14506 * Evaluates if a type definition contains the given "final". 14507 * This does take "finalDefault" into account as well. 14508 * 14509 * Returns 1 if the type does containt the given "final", 14510 * 0 otherwise. 14511 */ 14512 static int 14513 xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final) 14514 { 14515 if (type == NULL) 14516 return (0); 14517 if (type->flags & final) 14518 return (1); 14519 else 14520 return (0); 14521 } 14522 14523 /** 14524 * xmlSchemaGetUnionSimpleTypeMemberTypes: 14525 * @type: the Union Simple Type 14526 * 14527 * Returns a list of member types of @type if existing, 14528 * returns NULL otherwise. 14529 */ 14530 static xmlSchemaTypeLinkPtr 14531 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type) 14532 { 14533 while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) { 14534 if (type->memberTypes != NULL) 14535 return (type->memberTypes); 14536 else 14537 type = type->baseType; 14538 } 14539 return (NULL); 14540 } 14541 14542 /** 14543 * xmlSchemaGetParticleTotalRangeMin: 14544 * @particle: the particle 14545 * 14546 * Schema Component Constraint: Effective Total Range 14547 * (all and sequence) + (choice) 14548 * 14549 * Returns the minimun Effective Total Range. 14550 */ 14551 static int 14552 xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle) 14553 { 14554 if ((particle->children == NULL) || 14555 (particle->minOccurs == 0)) 14556 return (0); 14557 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14558 int min = -1, cur; 14559 xmlSchemaParticlePtr part = 14560 (xmlSchemaParticlePtr) particle->children->children; 14561 14562 if (part == NULL) 14563 return (0); 14564 while (part != NULL) { 14565 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14566 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14567 cur = part->minOccurs; 14568 else 14569 cur = xmlSchemaGetParticleTotalRangeMin(part); 14570 if (cur == 0) 14571 return (0); 14572 if ((min > cur) || (min == -1)) 14573 min = cur; 14574 part = (xmlSchemaParticlePtr) part->next; 14575 } 14576 return (particle->minOccurs * min); 14577 } else { 14578 /* <all> and <sequence> */ 14579 int sum = 0; 14580 xmlSchemaParticlePtr part = 14581 (xmlSchemaParticlePtr) particle->children->children; 14582 14583 if (part == NULL) 14584 return (0); 14585 do { 14586 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14587 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14588 sum += part->minOccurs; 14589 else 14590 sum += xmlSchemaGetParticleTotalRangeMin(part); 14591 part = (xmlSchemaParticlePtr) part->next; 14592 } while (part != NULL); 14593 return (particle->minOccurs * sum); 14594 } 14595 } 14596 14597 #if 0 14598 /** 14599 * xmlSchemaGetParticleTotalRangeMax: 14600 * @particle: the particle 14601 * 14602 * Schema Component Constraint: Effective Total Range 14603 * (all and sequence) + (choice) 14604 * 14605 * Returns the maximum Effective Total Range. 14606 */ 14607 static int 14608 xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle) 14609 { 14610 if ((particle->children == NULL) || 14611 (particle->children->children == NULL)) 14612 return (0); 14613 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14614 int max = -1, cur; 14615 xmlSchemaParticlePtr part = 14616 (xmlSchemaParticlePtr) particle->children->children; 14617 14618 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14619 if (part->children == NULL) 14620 continue; 14621 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14622 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14623 cur = part->maxOccurs; 14624 else 14625 cur = xmlSchemaGetParticleTotalRangeMax(part); 14626 if (cur == UNBOUNDED) 14627 return (UNBOUNDED); 14628 if ((max < cur) || (max == -1)) 14629 max = cur; 14630 } 14631 /* TODO: Handle overflows? */ 14632 return (particle->maxOccurs * max); 14633 } else { 14634 /* <all> and <sequence> */ 14635 int sum = 0, cur; 14636 xmlSchemaParticlePtr part = 14637 (xmlSchemaParticlePtr) particle->children->children; 14638 14639 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14640 if (part->children == NULL) 14641 continue; 14642 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14643 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14644 cur = part->maxOccurs; 14645 else 14646 cur = xmlSchemaGetParticleTotalRangeMax(part); 14647 if (cur == UNBOUNDED) 14648 return (UNBOUNDED); 14649 if ((cur > 0) && (particle->maxOccurs == UNBOUNDED)) 14650 return (UNBOUNDED); 14651 sum += cur; 14652 } 14653 /* TODO: Handle overflows? */ 14654 return (particle->maxOccurs * sum); 14655 } 14656 } 14657 #endif 14658 14659 /** 14660 * xmlSchemaIsParticleEmptiable: 14661 * @particle: the particle 14662 * 14663 * Schema Component Constraint: Particle Emptiable 14664 * Checks whether the given particle is emptiable. 14665 * 14666 * Returns 1 if emptiable, 0 otherwise. 14667 */ 14668 static int 14669 xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle) 14670 { 14671 /* 14672 * SPEC (1) "Its {min occurs} is 0." 14673 */ 14674 if ((particle == NULL) || (particle->minOccurs == 0) || 14675 (particle->children == NULL)) 14676 return (1); 14677 /* 14678 * SPEC (2) "Its {term} is a group and the minimum part of the 14679 * effective total range of that group, [...] is 0." 14680 */ 14681 if (WXS_IS_MODEL_GROUP(particle->children)) { 14682 if (xmlSchemaGetParticleTotalRangeMin(particle) == 0) 14683 return (1); 14684 } 14685 return (0); 14686 } 14687 14688 /** 14689 * xmlSchemaCheckCOSSTDerivedOK: 14690 * @actxt: a context 14691 * @type: the derived simple type definition 14692 * @baseType: the base type definition 14693 * @subset: the subset of ('restriction', ect.) 14694 * 14695 * Schema Component Constraint: 14696 * Type Derivation OK (Simple) (cos-st-derived-OK) 14697 * 14698 * Checks wheter @type can be validly 14699 * derived from @baseType. 14700 * 14701 * Returns 0 on success, an positive error code otherwise. 14702 */ 14703 static int 14704 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 14705 xmlSchemaTypePtr type, 14706 xmlSchemaTypePtr baseType, 14707 int subset) 14708 { 14709 /* 14710 * 1 They are the same type definition. 14711 * TODO: The identy check might have to be more complex than this. 14712 */ 14713 if (type == baseType) 14714 return (0); 14715 /* 14716 * 2.1 restriction is not in the subset, or in the {final} 14717 * of its own {base type definition}; 14718 * 14719 * NOTE that this will be used also via "xsi:type". 14720 * 14721 * TODO: Revise this, it looks strange. How can the "type" 14722 * not be fixed or *in* fixing? 14723 */ 14724 if (WXS_IS_TYPE_NOT_FIXED(type)) 14725 if (xmlSchemaTypeFixup(type, actxt) == -1) 14726 return(-1); 14727 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14728 if (xmlSchemaTypeFixup(baseType, actxt) == -1) 14729 return(-1); 14730 if ((subset & SUBSET_RESTRICTION) || 14731 (xmlSchemaTypeFinalContains(type->baseType, 14732 XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) { 14733 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1); 14734 } 14735 /* 2.2 */ 14736 if (type->baseType == baseType) { 14737 /* 14738 * 2.2.1 D's base type definition is B. 14739 */ 14740 return (0); 14741 } 14742 /* 14743 * 2.2.2 D's base type definition is not the ur-type definition 14744 * and is validly derived from B given the subset, as defined by this 14745 * constraint. 14746 */ 14747 if ((! WXS_IS_ANYTYPE(type->baseType)) && 14748 (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 14749 baseType, subset) == 0)) { 14750 return (0); 14751 } 14752 /* 14753 * 2.2.3 D's {variety} is list or union and B is the simple ur-type 14754 * definition. 14755 */ 14756 if (WXS_IS_ANY_SIMPLE_TYPE(baseType) && 14757 (WXS_IS_LIST(type) || WXS_IS_UNION(type))) { 14758 return (0); 14759 } 14760 /* 14761 * 2.2.4 B's {variety} is union and D is validly derived from a type 14762 * definition in B's {member type definitions} given the subset, as 14763 * defined by this constraint. 14764 * 14765 * NOTE: This seems not to involve built-in types, since there is no 14766 * built-in Union Simple Type. 14767 */ 14768 if (WXS_IS_UNION(baseType)) { 14769 xmlSchemaTypeLinkPtr cur; 14770 14771 cur = baseType->memberTypes; 14772 while (cur != NULL) { 14773 if (WXS_IS_TYPE_NOT_FIXED(cur->type)) 14774 if (xmlSchemaTypeFixup(cur->type, actxt) == -1) 14775 return(-1); 14776 if (xmlSchemaCheckCOSSTDerivedOK(actxt, 14777 type, cur->type, subset) == 0) 14778 { 14779 /* 14780 * It just has to be validly derived from at least one 14781 * member-type. 14782 */ 14783 return (0); 14784 } 14785 cur = cur->next; 14786 } 14787 } 14788 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2); 14789 } 14790 14791 /** 14792 * xmlSchemaCheckTypeDefCircularInternal: 14793 * @pctxt: the schema parser context 14794 * @ctxtType: the type definition 14795 * @ancestor: an ancestor of @ctxtType 14796 * 14797 * Checks st-props-correct (2) + ct-props-correct (3). 14798 * Circular type definitions are not allowed. 14799 * 14800 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is 14801 * circular, 0 otherwise. 14802 */ 14803 static int 14804 xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt, 14805 xmlSchemaTypePtr ctxtType, 14806 xmlSchemaTypePtr ancestor) 14807 { 14808 int ret; 14809 14810 if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC)) 14811 return (0); 14812 14813 if (ctxtType == ancestor) { 14814 xmlSchemaPCustomErr(pctxt, 14815 XML_SCHEMAP_ST_PROPS_CORRECT_2, 14816 WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType), 14817 "The definition is circular", NULL); 14818 return (XML_SCHEMAP_ST_PROPS_CORRECT_2); 14819 } 14820 if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) { 14821 /* 14822 * Avoid inifinite recursion on circular types not yet checked. 14823 */ 14824 return (0); 14825 } 14826 ancestor->flags |= XML_SCHEMAS_TYPE_MARKED; 14827 ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType, 14828 ancestor->baseType); 14829 ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED; 14830 return (ret); 14831 } 14832 14833 /** 14834 * xmlSchemaCheckTypeDefCircular: 14835 * @item: the complex/simple type definition 14836 * @ctxt: the parser context 14837 * @name: the name 14838 * 14839 * Checks for circular type definitions. 14840 */ 14841 static void 14842 xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item, 14843 xmlSchemaParserCtxtPtr ctxt) 14844 { 14845 if ((item == NULL) || 14846 (item->type == XML_SCHEMA_TYPE_BASIC) || 14847 (item->baseType == NULL)) 14848 return; 14849 xmlSchemaCheckTypeDefCircularInternal(ctxt, item, 14850 item->baseType); 14851 } 14852 14853 /* 14854 * Simple Type Definition Representation OK (src-simple-type) 4 14855 * 14856 * "4 Circular union type definition is disallowed. That is, if the 14857 * <union> alternative is chosen, there must not be any entries in the 14858 * memberTypes [attribute] at any depth which resolve to the component 14859 * corresponding to the <simpleType>." 14860 * 14861 * Note that this should work on the *representation* of a component, 14862 * thus assumes any union types in the member types not being yet 14863 * substituted. At this stage we need the variety of the types 14864 * to be already computed. 14865 */ 14866 static int 14867 xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt, 14868 xmlSchemaTypePtr ctxType, 14869 xmlSchemaTypeLinkPtr members) 14870 { 14871 xmlSchemaTypeLinkPtr member; 14872 xmlSchemaTypePtr memberType; 14873 14874 member = members; 14875 while (member != NULL) { 14876 memberType = member->type; 14877 while ((memberType != NULL) && 14878 (memberType->type != XML_SCHEMA_TYPE_BASIC)) { 14879 if (memberType == ctxType) { 14880 xmlSchemaPCustomErr(pctxt, 14881 XML_SCHEMAP_SRC_SIMPLE_TYPE_4, 14882 WXS_BASIC_CAST ctxType, NULL, 14883 "The union type definition is circular", NULL); 14884 return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4); 14885 } 14886 if ((WXS_IS_UNION(memberType)) && 14887 ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0)) 14888 { 14889 int res; 14890 memberType->flags |= XML_SCHEMAS_TYPE_MARKED; 14891 res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, 14892 ctxType, 14893 xmlSchemaGetUnionSimpleTypeMemberTypes(memberType)); 14894 memberType->flags ^= XML_SCHEMAS_TYPE_MARKED; 14895 if (res != 0) 14896 return(res); 14897 } 14898 memberType = memberType->baseType; 14899 } 14900 member = member->next; 14901 } 14902 return(0); 14903 } 14904 14905 static int 14906 xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt, 14907 xmlSchemaTypePtr type) 14908 { 14909 if (! WXS_IS_UNION(type)) 14910 return(0); 14911 return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type, 14912 type->memberTypes)); 14913 } 14914 14915 /** 14916 * xmlSchemaResolveTypeReferences: 14917 * @item: the complex/simple type definition 14918 * @ctxt: the parser context 14919 * @name: the name 14920 * 14921 * Resolvese type definition references 14922 */ 14923 static void 14924 xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef, 14925 xmlSchemaParserCtxtPtr ctxt) 14926 { 14927 if (typeDef == NULL) 14928 return; 14929 14930 /* 14931 * Resolve the base type. 14932 */ 14933 if (typeDef->baseType == NULL) { 14934 typeDef->baseType = xmlSchemaGetType(ctxt->schema, 14935 typeDef->base, typeDef->baseNs); 14936 if (typeDef->baseType == NULL) { 14937 xmlSchemaPResCompAttrErr(ctxt, 14938 XML_SCHEMAP_SRC_RESOLVE, 14939 WXS_BASIC_CAST typeDef, typeDef->node, 14940 "base", typeDef->base, typeDef->baseNs, 14941 XML_SCHEMA_TYPE_SIMPLE, NULL); 14942 return; 14943 } 14944 } 14945 if (WXS_IS_SIMPLE(typeDef)) { 14946 if (WXS_IS_UNION(typeDef)) { 14947 /* 14948 * Resolve the memberTypes. 14949 */ 14950 xmlSchemaResolveUnionMemberTypes(ctxt, typeDef); 14951 return; 14952 } else if (WXS_IS_LIST(typeDef)) { 14953 /* 14954 * Resolve the itemType. 14955 */ 14956 if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) { 14957 14958 typeDef->subtypes = xmlSchemaGetType(ctxt->schema, 14959 typeDef->base, typeDef->baseNs); 14960 14961 if ((typeDef->subtypes == NULL) || 14962 (! WXS_IS_SIMPLE(typeDef->subtypes))) 14963 { 14964 typeDef->subtypes = NULL; 14965 xmlSchemaPResCompAttrErr(ctxt, 14966 XML_SCHEMAP_SRC_RESOLVE, 14967 WXS_BASIC_CAST typeDef, typeDef->node, 14968 "itemType", typeDef->base, typeDef->baseNs, 14969 XML_SCHEMA_TYPE_SIMPLE, NULL); 14970 } 14971 } 14972 return; 14973 } 14974 } 14975 /* 14976 * The ball of letters below means, that if we have a particle 14977 * which has a QName-helper component as its {term}, we want 14978 * to resolve it... 14979 */ 14980 else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) && 14981 ((WXS_TYPE_CONTENTTYPE(typeDef))->type == 14982 XML_SCHEMA_TYPE_PARTICLE) && 14983 (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) && 14984 ((WXS_TYPE_PARTICLE_TERM(typeDef))->type == 14985 XML_SCHEMA_EXTRA_QNAMEREF)) 14986 { 14987 xmlSchemaQNameRefPtr ref = 14988 WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef); 14989 xmlSchemaModelGroupDefPtr groupDef; 14990 14991 /* 14992 * URGENT TODO: Test this. 14993 */ 14994 WXS_TYPE_PARTICLE_TERM(typeDef) = NULL; 14995 /* 14996 * Resolve the MG definition reference. 14997 */ 14998 groupDef = 14999 WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema, 15000 ref->itemType, ref->name, ref->targetNamespace); 15001 if (groupDef == NULL) { 15002 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 15003 NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), 15004 "ref", ref->name, ref->targetNamespace, ref->itemType, 15005 NULL); 15006 /* Remove the particle. */ 15007 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15008 } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL) 15009 /* Remove the particle. */ 15010 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15011 else { 15012 /* 15013 * Assign the MG definition's {model group} to the 15014 * particle's {term}. 15015 */ 15016 WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef); 15017 15018 if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) { 15019 /* 15020 * SPEC cos-all-limited (1.2) 15021 * "1.2 the {term} property of a particle with 15022 * {max occurs}=1 which is part of a pair which constitutes 15023 * the {content type} of a complex type definition." 15024 */ 15025 if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) { 15026 xmlSchemaCustomErr(ACTXT_CAST ctxt, 15027 /* TODO: error code */ 15028 XML_SCHEMAP_COS_ALL_LIMITED, 15029 WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL, 15030 "The particle's {max occurs} must be 1, since the " 15031 "reference resolves to an 'all' model group", 15032 NULL, NULL); 15033 } 15034 } 15035 } 15036 } 15037 } 15038 15039 15040 15041 /** 15042 * xmlSchemaCheckSTPropsCorrect: 15043 * @ctxt: the schema parser context 15044 * @type: the simple type definition 15045 * 15046 * Checks st-props-correct. 15047 * 15048 * Returns 0 if the properties are correct, 15049 * if not, a positive error code and -1 on internal 15050 * errors. 15051 */ 15052 static int 15053 xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt, 15054 xmlSchemaTypePtr type) 15055 { 15056 xmlSchemaTypePtr baseType = type->baseType; 15057 xmlChar *str = NULL; 15058 15059 /* STATE: error funcs converted. */ 15060 /* 15061 * Schema Component Constraint: Simple Type Definition Properties Correct 15062 * 15063 * NOTE: This is somehow redundant, since we actually built a simple type 15064 * to have all the needed information; this acts as an self test. 15065 */ 15066 /* Base type: If the datatype has been derived by restriction 15067 * then the Simple Type Definition component from which it is derived, 15068 * otherwise the Simple Type Definition for anySimpleType (4.1.6). 15069 */ 15070 if (baseType == NULL) { 15071 /* 15072 * TODO: Think about: "modulo the impact of Missing 15073 * Sub-components (5.3)." 15074 */ 15075 xmlSchemaPCustomErr(ctxt, 15076 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15077 WXS_BASIC_CAST type, NULL, 15078 "No base type existent", NULL); 15079 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15080 15081 } 15082 if (! WXS_IS_SIMPLE(baseType)) { 15083 xmlSchemaPCustomErr(ctxt, 15084 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15085 WXS_BASIC_CAST type, NULL, 15086 "The base type '%s' is not a simple type", 15087 xmlSchemaGetComponentQName(&str, baseType)); 15088 FREE_AND_NULL(str) 15089 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15090 } 15091 if ( (WXS_IS_LIST(type) || WXS_IS_UNION(type)) && 15092 (WXS_IS_RESTRICTION(type) == 0) && 15093 (! WXS_IS_ANY_SIMPLE_TYPE(baseType))) { 15094 xmlSchemaPCustomErr(ctxt, 15095 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15096 WXS_BASIC_CAST type, NULL, 15097 "A type, derived by list or union, must have " 15098 "the simple ur-type definition as base type, not '%s'", 15099 xmlSchemaGetComponentQName(&str, baseType)); 15100 FREE_AND_NULL(str) 15101 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15102 } 15103 /* 15104 * Variety: One of {atomic, list, union}. 15105 */ 15106 if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) && 15107 (! WXS_IS_LIST(type))) { 15108 xmlSchemaPCustomErr(ctxt, 15109 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15110 WXS_BASIC_CAST type, NULL, 15111 "The variety is absent", NULL); 15112 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15113 } 15114 /* TODO: Finish this. Hmm, is this finished? */ 15115 15116 /* 15117 * 3 The {final} of the {base type definition} must not contain restriction. 15118 */ 15119 if (xmlSchemaTypeFinalContains(baseType, 15120 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15121 xmlSchemaPCustomErr(ctxt, 15122 XML_SCHEMAP_ST_PROPS_CORRECT_3, 15123 WXS_BASIC_CAST type, NULL, 15124 "The 'final' of its base type '%s' must not contain " 15125 "'restriction'", 15126 xmlSchemaGetComponentQName(&str, baseType)); 15127 FREE_AND_NULL(str) 15128 return (XML_SCHEMAP_ST_PROPS_CORRECT_3); 15129 } 15130 15131 /* 15132 * 2 All simple type definitions must be derived ultimately from the simple 15133 * ur-type definition (so circular definitions are disallowed). That is, it 15134 * must be possible to reach a built-in primitive datatype or the simple 15135 * ur-type definition by repeatedly following the {base type definition}. 15136 * 15137 * NOTE: this is done in xmlSchemaCheckTypeDefCircular(). 15138 */ 15139 return (0); 15140 } 15141 15142 /** 15143 * xmlSchemaCheckCOSSTRestricts: 15144 * @ctxt: the schema parser context 15145 * @type: the simple type definition 15146 * 15147 * Schema Component Constraint: 15148 * Derivation Valid (Restriction, Simple) (cos-st-restricts) 15149 15150 * Checks if the given @type (simpleType) is derived validly by restriction. 15151 * STATUS: 15152 * 15153 * Returns -1 on internal errors, 0 if the type is validly derived, 15154 * a positive error code otherwise. 15155 */ 15156 static int 15157 xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt, 15158 xmlSchemaTypePtr type) 15159 { 15160 xmlChar *str = NULL; 15161 15162 if (type->type != XML_SCHEMA_TYPE_SIMPLE) { 15163 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15164 "given type is not a user-derived simpleType"); 15165 return (-1); 15166 } 15167 15168 if (WXS_IS_ATOMIC(type)) { 15169 xmlSchemaTypePtr primitive; 15170 /* 15171 * 1.1 The {base type definition} must be an atomic simple 15172 * type definition or a built-in primitive datatype. 15173 */ 15174 if (! WXS_IS_ATOMIC(type->baseType)) { 15175 xmlSchemaPCustomErr(pctxt, 15176 XML_SCHEMAP_COS_ST_RESTRICTS_1_1, 15177 WXS_BASIC_CAST type, NULL, 15178 "The base type '%s' is not an atomic simple type", 15179 xmlSchemaGetComponentQName(&str, type->baseType)); 15180 FREE_AND_NULL(str) 15181 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1); 15182 } 15183 /* 1.2 The {final} of the {base type definition} must not contain 15184 * restriction. 15185 */ 15186 /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */ 15187 if (xmlSchemaTypeFinalContains(type->baseType, 15188 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15189 xmlSchemaPCustomErr(pctxt, 15190 XML_SCHEMAP_COS_ST_RESTRICTS_1_2, 15191 WXS_BASIC_CAST type, NULL, 15192 "The final of its base type '%s' must not contain 'restriction'", 15193 xmlSchemaGetComponentQName(&str, type->baseType)); 15194 FREE_AND_NULL(str) 15195 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2); 15196 } 15197 15198 /* 15199 * 1.3.1 DF must be an allowed constraining facet for the {primitive 15200 * type definition}, as specified in the appropriate subsection of 3.2 15201 * Primitive datatypes. 15202 */ 15203 if (type->facets != NULL) { 15204 xmlSchemaFacetPtr facet; 15205 int ok = 1; 15206 15207 primitive = xmlSchemaGetPrimitiveType(type); 15208 if (primitive == NULL) { 15209 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15210 "failed to get primitive type"); 15211 return (-1); 15212 } 15213 facet = type->facets; 15214 do { 15215 if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) { 15216 ok = 0; 15217 xmlSchemaPIllegalFacetAtomicErr(pctxt, 15218 XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1, 15219 type, primitive, facet); 15220 } 15221 facet = facet->next; 15222 } while (facet != NULL); 15223 if (ok == 0) 15224 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1); 15225 } 15226 /* 15227 * SPEC (1.3.2) "If there is a facet of the same kind in the {facets} 15228 * of the {base type definition} (call this BF),then the DF's {value} 15229 * must be a valid restriction of BF's {value} as defined in 15230 * [XML Schemas: Datatypes]." 15231 * 15232 * NOTE (1.3.2) Facet derivation constraints are currently handled in 15233 * xmlSchemaDeriveAndValidateFacets() 15234 */ 15235 } else if (WXS_IS_LIST(type)) { 15236 xmlSchemaTypePtr itemType = NULL; 15237 15238 itemType = type->subtypes; 15239 if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) { 15240 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15241 "failed to evaluate the item type"); 15242 return (-1); 15243 } 15244 if (WXS_IS_TYPE_NOT_FIXED(itemType)) 15245 xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt); 15246 /* 15247 * 2.1 The {item type definition} must have a {variety} of atomic or 15248 * union (in which case all the {member type definitions} 15249 * must be atomic). 15250 */ 15251 if ((! WXS_IS_ATOMIC(itemType)) && 15252 (! WXS_IS_UNION(itemType))) { 15253 xmlSchemaPCustomErr(pctxt, 15254 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15255 WXS_BASIC_CAST type, NULL, 15256 "The item type '%s' does not have a variety of atomic or union", 15257 xmlSchemaGetComponentQName(&str, itemType)); 15258 FREE_AND_NULL(str) 15259 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15260 } else if (WXS_IS_UNION(itemType)) { 15261 xmlSchemaTypeLinkPtr member; 15262 15263 member = itemType->memberTypes; 15264 while (member != NULL) { 15265 if (! WXS_IS_ATOMIC(member->type)) { 15266 xmlSchemaPCustomErr(pctxt, 15267 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15268 WXS_BASIC_CAST type, NULL, 15269 "The item type is a union type, but the " 15270 "member type '%s' of this item type is not atomic", 15271 xmlSchemaGetComponentQName(&str, member->type)); 15272 FREE_AND_NULL(str) 15273 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15274 } 15275 member = member->next; 15276 } 15277 } 15278 15279 if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) { 15280 xmlSchemaFacetPtr facet; 15281 /* 15282 * This is the case if we have: <simpleType><list .. 15283 */ 15284 /* 15285 * 2.3.1 15286 * 2.3.1.1 The {final} of the {item type definition} must not 15287 * contain list. 15288 */ 15289 if (xmlSchemaTypeFinalContains(itemType, 15290 XML_SCHEMAS_TYPE_FINAL_LIST)) { 15291 xmlSchemaPCustomErr(pctxt, 15292 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1, 15293 WXS_BASIC_CAST type, NULL, 15294 "The final of its item type '%s' must not contain 'list'", 15295 xmlSchemaGetComponentQName(&str, itemType)); 15296 FREE_AND_NULL(str) 15297 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1); 15298 } 15299 /* 15300 * 2.3.1.2 The {facets} must only contain the whiteSpace 15301 * facet component. 15302 * OPTIMIZE TODO: the S4S already disallows any facet 15303 * to be specified. 15304 */ 15305 if (type->facets != NULL) { 15306 facet = type->facets; 15307 do { 15308 if (facet->type != XML_SCHEMA_FACET_WHITESPACE) { 15309 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15310 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2, 15311 type, facet); 15312 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2); 15313 } 15314 facet = facet->next; 15315 } while (facet != NULL); 15316 } 15317 /* 15318 * MAYBE TODO: (Hmm, not really) Datatypes states: 15319 * A list datatype can be derived from an atomic datatype 15320 * whose lexical space allows space (such as string or anyURI)or 15321 * a union datatype any of whose {member type definitions}'s 15322 * lexical space allows space. 15323 */ 15324 } else { 15325 /* 15326 * This is the case if we have: <simpleType><restriction ... 15327 * I.e. the variety of "list" is inherited. 15328 */ 15329 /* 15330 * 2.3.2 15331 * 2.3.2.1 The {base type definition} must have a {variety} of list. 15332 */ 15333 if (! WXS_IS_LIST(type->baseType)) { 15334 xmlSchemaPCustomErr(pctxt, 15335 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1, 15336 WXS_BASIC_CAST type, NULL, 15337 "The base type '%s' must be a list type", 15338 xmlSchemaGetComponentQName(&str, type->baseType)); 15339 FREE_AND_NULL(str) 15340 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1); 15341 } 15342 /* 15343 * 2.3.2.2 The {final} of the {base type definition} must not 15344 * contain restriction. 15345 */ 15346 if (xmlSchemaTypeFinalContains(type->baseType, 15347 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15348 xmlSchemaPCustomErr(pctxt, 15349 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2, 15350 WXS_BASIC_CAST type, NULL, 15351 "The 'final' of the base type '%s' must not contain 'restriction'", 15352 xmlSchemaGetComponentQName(&str, type->baseType)); 15353 FREE_AND_NULL(str) 15354 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2); 15355 } 15356 /* 15357 * 2.3.2.3 The {item type definition} must be validly derived 15358 * from the {base type definition}'s {item type definition} given 15359 * the empty set, as defined in Type Derivation OK (Simple) (3.14.6). 15360 */ 15361 { 15362 xmlSchemaTypePtr baseItemType; 15363 15364 baseItemType = type->baseType->subtypes; 15365 if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) { 15366 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15367 "failed to eval the item type of a base type"); 15368 return (-1); 15369 } 15370 if ((itemType != baseItemType) && 15371 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType, 15372 baseItemType, 0) != 0)) { 15373 xmlChar *strBIT = NULL, *strBT = NULL; 15374 xmlSchemaPCustomErrExt(pctxt, 15375 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, 15376 WXS_BASIC_CAST type, NULL, 15377 "The item type '%s' is not validly derived from " 15378 "the item type '%s' of the base type '%s'", 15379 xmlSchemaGetComponentQName(&str, itemType), 15380 xmlSchemaGetComponentQName(&strBIT, baseItemType), 15381 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15382 15383 FREE_AND_NULL(str) 15384 FREE_AND_NULL(strBIT) 15385 FREE_AND_NULL(strBT) 15386 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3); 15387 } 15388 } 15389 15390 if (type->facets != NULL) { 15391 xmlSchemaFacetPtr facet; 15392 int ok = 1; 15393 /* 15394 * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern 15395 * and enumeration facet components are allowed among the {facets}. 15396 */ 15397 facet = type->facets; 15398 do { 15399 switch (facet->type) { 15400 case XML_SCHEMA_FACET_LENGTH: 15401 case XML_SCHEMA_FACET_MINLENGTH: 15402 case XML_SCHEMA_FACET_MAXLENGTH: 15403 case XML_SCHEMA_FACET_WHITESPACE: 15404 /* 15405 * TODO: 2.5.1.2 List datatypes 15406 * The value of whiteSpace is fixed to the value collapse. 15407 */ 15408 case XML_SCHEMA_FACET_PATTERN: 15409 case XML_SCHEMA_FACET_ENUMERATION: 15410 break; 15411 default: { 15412 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15413 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4, 15414 type, facet); 15415 /* 15416 * We could return, but it's nicer to report all 15417 * invalid facets. 15418 */ 15419 ok = 0; 15420 } 15421 } 15422 facet = facet->next; 15423 } while (facet != NULL); 15424 if (ok == 0) 15425 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4); 15426 /* 15427 * SPEC (2.3.2.5) (same as 1.3.2) 15428 * 15429 * NOTE (2.3.2.5) This is currently done in 15430 * xmlSchemaDeriveAndValidateFacets() 15431 */ 15432 } 15433 } 15434 } else if (WXS_IS_UNION(type)) { 15435 /* 15436 * 3.1 The {member type definitions} must all have {variety} of 15437 * atomic or list. 15438 */ 15439 xmlSchemaTypeLinkPtr member; 15440 15441 member = type->memberTypes; 15442 while (member != NULL) { 15443 if (WXS_IS_TYPE_NOT_FIXED(member->type)) 15444 xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt); 15445 15446 if ((! WXS_IS_ATOMIC(member->type)) && 15447 (! WXS_IS_LIST(member->type))) { 15448 xmlSchemaPCustomErr(pctxt, 15449 XML_SCHEMAP_COS_ST_RESTRICTS_3_1, 15450 WXS_BASIC_CAST type, NULL, 15451 "The member type '%s' is neither an atomic, nor a list type", 15452 xmlSchemaGetComponentQName(&str, member->type)); 15453 FREE_AND_NULL(str) 15454 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1); 15455 } 15456 member = member->next; 15457 } 15458 /* 15459 * 3.3.1 If the {base type definition} is the simple ur-type 15460 * definition 15461 */ 15462 if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) { 15463 /* 15464 * 3.3.1.1 All of the {member type definitions} must have a 15465 * {final} which does not contain union. 15466 */ 15467 member = type->memberTypes; 15468 while (member != NULL) { 15469 if (xmlSchemaTypeFinalContains(member->type, 15470 XML_SCHEMAS_TYPE_FINAL_UNION)) { 15471 xmlSchemaPCustomErr(pctxt, 15472 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1, 15473 WXS_BASIC_CAST type, NULL, 15474 "The 'final' of member type '%s' contains 'union'", 15475 xmlSchemaGetComponentQName(&str, member->type)); 15476 FREE_AND_NULL(str) 15477 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1); 15478 } 15479 member = member->next; 15480 } 15481 /* 15482 * 3.3.1.2 The {facets} must be empty. 15483 */ 15484 if (type->facetSet != NULL) { 15485 xmlSchemaPCustomErr(pctxt, 15486 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2, 15487 WXS_BASIC_CAST type, NULL, 15488 "No facets allowed", NULL); 15489 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2); 15490 } 15491 } else { 15492 /* 15493 * 3.3.2.1 The {base type definition} must have a {variety} of union. 15494 * I.e. the variety of "list" is inherited. 15495 */ 15496 if (! WXS_IS_UNION(type->baseType)) { 15497 xmlSchemaPCustomErr(pctxt, 15498 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1, 15499 WXS_BASIC_CAST type, NULL, 15500 "The base type '%s' is not a union type", 15501 xmlSchemaGetComponentQName(&str, type->baseType)); 15502 FREE_AND_NULL(str) 15503 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1); 15504 } 15505 /* 15506 * 3.3.2.2 The {final} of the {base type definition} must not contain restriction. 15507 */ 15508 if (xmlSchemaTypeFinalContains(type->baseType, 15509 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15510 xmlSchemaPCustomErr(pctxt, 15511 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2, 15512 WXS_BASIC_CAST type, NULL, 15513 "The 'final' of its base type '%s' must not contain 'restriction'", 15514 xmlSchemaGetComponentQName(&str, type->baseType)); 15515 FREE_AND_NULL(str) 15516 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2); 15517 } 15518 /* 15519 * 3.3.2.3 The {member type definitions}, in order, must be validly 15520 * derived from the corresponding type definitions in the {base 15521 * type definition}'s {member type definitions} given the empty set, 15522 * as defined in Type Derivation OK (Simple) (3.14.6). 15523 */ 15524 { 15525 xmlSchemaTypeLinkPtr baseMember; 15526 15527 /* 15528 * OPTIMIZE: if the type is restricting, it has no local defined 15529 * member types and inherits the member types of the base type; 15530 * thus a check for equality can be skipped. 15531 */ 15532 /* 15533 * Even worse: I cannot see a scenario where a restricting 15534 * union simple type can have other member types as the member 15535 * types of it's base type. This check seems not necessary with 15536 * respect to the derivation process in libxml2. 15537 * But necessary if constructing types with an API. 15538 */ 15539 if (type->memberTypes != NULL) { 15540 member = type->memberTypes; 15541 baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType); 15542 if ((member == NULL) && (baseMember != NULL)) { 15543 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15544 "different number of member types in base"); 15545 } 15546 while (member != NULL) { 15547 if (baseMember == NULL) { 15548 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15549 "different number of member types in base"); 15550 } else if ((member->type != baseMember->type) && 15551 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 15552 member->type, baseMember->type, 0) != 0)) { 15553 xmlChar *strBMT = NULL, *strBT = NULL; 15554 15555 xmlSchemaPCustomErrExt(pctxt, 15556 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, 15557 WXS_BASIC_CAST type, NULL, 15558 "The member type %s is not validly " 15559 "derived from its corresponding member " 15560 "type %s of the base type %s", 15561 xmlSchemaGetComponentQName(&str, member->type), 15562 xmlSchemaGetComponentQName(&strBMT, baseMember->type), 15563 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15564 FREE_AND_NULL(str) 15565 FREE_AND_NULL(strBMT) 15566 FREE_AND_NULL(strBT) 15567 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3); 15568 } 15569 member = member->next; 15570 baseMember = baseMember->next; 15571 } 15572 } 15573 } 15574 /* 15575 * 3.3.2.4 Only pattern and enumeration facet components are 15576 * allowed among the {facets}. 15577 */ 15578 if (type->facets != NULL) { 15579 xmlSchemaFacetPtr facet; 15580 int ok = 1; 15581 15582 facet = type->facets; 15583 do { 15584 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 15585 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 15586 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15587 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4, 15588 type, facet); 15589 ok = 0; 15590 } 15591 facet = facet->next; 15592 } while (facet != NULL); 15593 if (ok == 0) 15594 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4); 15595 15596 } 15597 /* 15598 * SPEC (3.3.2.5) (same as 1.3.2) 15599 * 15600 * NOTE (3.3.2.5) This is currently done in 15601 * xmlSchemaDeriveAndValidateFacets() 15602 */ 15603 } 15604 } 15605 15606 return (0); 15607 } 15608 15609 /** 15610 * xmlSchemaCheckSRCSimpleType: 15611 * @ctxt: the schema parser context 15612 * @type: the simple type definition 15613 * 15614 * Checks crc-simple-type constraints. 15615 * 15616 * Returns 0 if the constraints are satisfied, 15617 * if not a positive error code and -1 on internal 15618 * errors. 15619 */ 15620 #if 0 15621 static int 15622 xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt, 15623 xmlSchemaTypePtr type) 15624 { 15625 /* 15626 * src-simple-type.1 The corresponding simple type definition, if any, 15627 * must satisfy the conditions set out in Constraints on Simple Type 15628 * Definition Schema Components (3.14.6). 15629 */ 15630 if (WXS_IS_RESTRICTION(type)) { 15631 /* 15632 * src-simple-type.2 "If the <restriction> alternative is chosen, 15633 * either it must have a base [attribute] or a <simpleType> among its 15634 * [children], but not both." 15635 * NOTE: This is checked in the parse function of <restriction>. 15636 */ 15637 /* 15638 * 15639 */ 15640 } else if (WXS_IS_LIST(type)) { 15641 /* src-simple-type.3 "If the <list> alternative is chosen, either it must have 15642 * an itemType [attribute] or a <simpleType> among its [children], 15643 * but not both." 15644 * 15645 * NOTE: This is checked in the parse function of <list>. 15646 */ 15647 } else if (WXS_IS_UNION(type)) { 15648 /* 15649 * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular(). 15650 */ 15651 } 15652 return (0); 15653 } 15654 #endif 15655 15656 static int 15657 xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt) 15658 { 15659 if (ctxt->vctxt == NULL) { 15660 ctxt->vctxt = xmlSchemaNewValidCtxt(NULL); 15661 if (ctxt->vctxt == NULL) { 15662 xmlSchemaPErr(ctxt, NULL, 15663 XML_SCHEMAP_INTERNAL, 15664 "Internal error: xmlSchemaCreateVCtxtOnPCtxt, " 15665 "failed to create a temp. validation context.\n", 15666 NULL, NULL); 15667 return (-1); 15668 } 15669 /* TODO: Pass user data. */ 15670 xmlSchemaSetValidErrors(ctxt->vctxt, 15671 ctxt->error, ctxt->warning, ctxt->errCtxt); 15672 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, 15673 ctxt->serror, ctxt->errCtxt); 15674 } 15675 return (0); 15676 } 15677 15678 static int 15679 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt, 15680 xmlNodePtr node, 15681 xmlSchemaTypePtr type, 15682 const xmlChar *value, 15683 xmlSchemaValPtr *retVal, 15684 int fireErrors, 15685 int normalize, 15686 int isNormalized); 15687 15688 /** 15689 * xmlSchemaParseCheckCOSValidDefault: 15690 * @pctxt: the schema parser context 15691 * @type: the simple type definition 15692 * @value: the default value 15693 * @node: an optional node (the holder of the value) 15694 * 15695 * Schema Component Constraint: Element Default Valid (Immediate) 15696 * (cos-valid-default) 15697 * This will be used by the parser only. For the validator there's 15698 * an other version. 15699 * 15700 * Returns 0 if the constraints are satisfied, 15701 * if not, a positive error code and -1 on internal 15702 * errors. 15703 */ 15704 static int 15705 xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt, 15706 xmlNodePtr node, 15707 xmlSchemaTypePtr type, 15708 const xmlChar *value, 15709 xmlSchemaValPtr *val) 15710 { 15711 int ret = 0; 15712 15713 /* 15714 * cos-valid-default: 15715 * Schema Component Constraint: Element Default Valid (Immediate) 15716 * For a string to be a valid default with respect to a type 15717 * definition the appropriate case among the following must be true: 15718 */ 15719 if WXS_IS_COMPLEX(type) { 15720 /* 15721 * Complex type. 15722 * 15723 * SPEC (2.1) "its {content type} must be a simple type definition 15724 * or mixed." 15725 * SPEC (2.2.2) "If the {content type} is mixed, then the {content 15726 * type}'s particle must be emptiable as defined by 15727 * Particle Emptiable (3.9.6)." 15728 */ 15729 if ((! WXS_HAS_SIMPLE_CONTENT(type)) && 15730 ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) { 15731 /* NOTE that this covers (2.2.2) as well. */ 15732 xmlSchemaPCustomErr(pctxt, 15733 XML_SCHEMAP_COS_VALID_DEFAULT_2_1, 15734 WXS_BASIC_CAST type, type->node, 15735 "For a string to be a valid default, the type definition " 15736 "must be a simple type or a complex type with mixed content " 15737 "and a particle emptiable", NULL); 15738 return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1); 15739 } 15740 } 15741 /* 15742 * 1 If the type definition is a simple type definition, then the string 15743 * must be valid with respect to that definition as defined by String 15744 * Valid (3.14.4). 15745 * 15746 * AND 15747 * 15748 * 2.2.1 If the {content type} is a simple type definition, then the 15749 * string must be valid with respect to that simple type definition 15750 * as defined by String Valid (3.14.4). 15751 */ 15752 if (WXS_IS_SIMPLE(type)) 15753 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15754 type, value, val, 1, 1, 0); 15755 else if (WXS_HAS_SIMPLE_CONTENT(type)) 15756 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15757 type->contentTypeDef, value, val, 1, 1, 0); 15758 else 15759 return (ret); 15760 15761 if (ret < 0) { 15762 PERROR_INT("xmlSchemaParseCheckCOSValidDefault", 15763 "calling xmlSchemaVCheckCVCSimpleType()"); 15764 } 15765 15766 return (ret); 15767 } 15768 15769 /** 15770 * xmlSchemaCheckCTPropsCorrect: 15771 * @ctxt: the schema parser context 15772 * @type: the complex type definition 15773 * 15774 *.(4.6) Constraints on Complex Type Definition Schema Components 15775 * Schema Component Constraint: 15776 * Complex Type Definition Properties Correct (ct-props-correct) 15777 * STATUS: (seems) complete 15778 * 15779 * Returns 0 if the constraints are satisfied, a positive 15780 * error code if not and -1 if an internal error occured. 15781 */ 15782 static int 15783 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 15784 xmlSchemaTypePtr type) 15785 { 15786 /* 15787 * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily. 15788 * 15789 * SPEC (1) "The values of the properties of a complex type definition must 15790 * be as described in the property tableau in The Complex Type Definition 15791 * Schema Component (3.4.1), modulo the impact of Missing 15792 * Sub-components (5.3)." 15793 */ 15794 if ((type->baseType != NULL) && 15795 (WXS_IS_SIMPLE(type->baseType)) && 15796 (WXS_IS_EXTENSION(type) == 0)) { 15797 /* 15798 * SPEC (2) "If the {base type definition} is a simple type definition, 15799 * the {derivation method} must be extension." 15800 */ 15801 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15802 XML_SCHEMAP_SRC_CT_1, 15803 NULL, WXS_BASIC_CAST type, 15804 "If the base type is a simple type, the derivation method must be " 15805 "'extension'", NULL, NULL); 15806 return (XML_SCHEMAP_SRC_CT_1); 15807 } 15808 /* 15809 * SPEC (3) "Circular definitions are disallowed, except for the ur-type 15810 * definition. That is, it must be possible to reach the ur-type 15811 * definition by repeatedly following the {base type definition}." 15812 * 15813 * NOTE (3) is done in xmlSchemaCheckTypeDefCircular(). 15814 */ 15815 /* 15816 * NOTE that (4) and (5) need the following: 15817 * - attribute uses need to be already inherited (apply attr. prohibitions) 15818 * - attribute group references need to be expanded already 15819 * - simple types need to be typefixed already 15820 */ 15821 if (type->attrUses && 15822 (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1)) 15823 { 15824 xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses; 15825 xmlSchemaAttributeUsePtr use, tmp; 15826 int i, j, hasId = 0; 15827 15828 for (i = uses->nbItems -1; i >= 0; i--) { 15829 use = uses->items[i]; 15830 15831 /* 15832 * SPEC ct-props-correct 15833 * (4) "Two distinct attribute declarations in the 15834 * {attribute uses} must not have identical {name}s and 15835 * {target namespace}s." 15836 */ 15837 if (i > 0) { 15838 for (j = i -1; j >= 0; j--) { 15839 tmp = uses->items[j]; 15840 if ((WXS_ATTRUSE_DECL_NAME(use) == 15841 WXS_ATTRUSE_DECL_NAME(tmp)) && 15842 (WXS_ATTRUSE_DECL_TNS(use) == 15843 WXS_ATTRUSE_DECL_TNS(tmp))) 15844 { 15845 xmlChar *str = NULL; 15846 15847 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15848 XML_SCHEMAP_AG_PROPS_CORRECT, 15849 NULL, WXS_BASIC_CAST type, 15850 "Duplicate %s", 15851 xmlSchemaGetComponentDesignation(&str, use), 15852 NULL); 15853 FREE_AND_NULL(str); 15854 /* 15855 * Remove the duplicate. 15856 */ 15857 if (xmlSchemaItemListRemove(uses, i) == -1) 15858 goto exit_failure; 15859 goto next_use; 15860 } 15861 } 15862 } 15863 /* 15864 * SPEC ct-props-correct 15865 * (5) "Two distinct attribute declarations in the 15866 * {attribute uses} must not have {type definition}s which 15867 * are or are derived from ID." 15868 */ 15869 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 15870 if (xmlSchemaIsDerivedFromBuiltInType( 15871 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 15872 { 15873 if (hasId) { 15874 xmlChar *str = NULL; 15875 15876 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15877 XML_SCHEMAP_AG_PROPS_CORRECT, 15878 NULL, WXS_BASIC_CAST type, 15879 "There must not exist more than one attribute " 15880 "declaration of type 'xs:ID' " 15881 "(or derived from 'xs:ID'). The %s violates this " 15882 "constraint", 15883 xmlSchemaGetComponentDesignation(&str, use), 15884 NULL); 15885 FREE_AND_NULL(str); 15886 if (xmlSchemaItemListRemove(uses, i) == -1) 15887 goto exit_failure; 15888 } 15889 15890 hasId = 1; 15891 } 15892 } 15893 next_use: {} 15894 } 15895 } 15896 return (0); 15897 exit_failure: 15898 return(-1); 15899 } 15900 15901 static int 15902 xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA, 15903 xmlSchemaTypePtr typeB) 15904 { 15905 /* 15906 * TODO: This should implement component-identity 15907 * in the future. 15908 */ 15909 if ((typeA == NULL) || (typeB == NULL)) 15910 return (0); 15911 return (typeA == typeB); 15912 } 15913 15914 /** 15915 * xmlSchemaCheckCOSCTDerivedOK: 15916 * @ctxt: the schema parser context 15917 * @type: the to-be derived complex type definition 15918 * @baseType: the base complex type definition 15919 * @set: the given set 15920 * 15921 * Schema Component Constraint: 15922 * Type Derivation OK (Complex) (cos-ct-derived-ok) 15923 * 15924 * STATUS: completed 15925 * 15926 * Returns 0 if the constraints are satisfied, or 1 15927 * if not. 15928 */ 15929 static int 15930 xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 15931 xmlSchemaTypePtr type, 15932 xmlSchemaTypePtr baseType, 15933 int set) 15934 { 15935 int equal = xmlSchemaAreEqualTypes(type, baseType); 15936 /* TODO: Error codes. */ 15937 /* 15938 * SPEC "For a complex type definition (call it D, for derived) 15939 * to be validly derived from a type definition (call this 15940 * B, for base) given a subset of {extension, restriction} 15941 * all of the following must be true:" 15942 */ 15943 if (! equal) { 15944 /* 15945 * SPEC (1) "If B and D are not the same type definition, then the 15946 * {derivation method} of D must not be in the subset." 15947 */ 15948 if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) || 15949 ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type)))) 15950 return (1); 15951 } else { 15952 /* 15953 * SPEC (2.1) "B and D must be the same type definition." 15954 */ 15955 return (0); 15956 } 15957 /* 15958 * SPEC (2.2) "B must be D's {base type definition}." 15959 */ 15960 if (type->baseType == baseType) 15961 return (0); 15962 /* 15963 * SPEC (2.3.1) "D's {base type definition} must not be the ur-type 15964 * definition." 15965 */ 15966 if (WXS_IS_ANYTYPE(type->baseType)) 15967 return (1); 15968 15969 if (WXS_IS_COMPLEX(type->baseType)) { 15970 /* 15971 * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it 15972 * must be validly derived from B given the subset as defined by this 15973 * constraint." 15974 */ 15975 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType, 15976 baseType, set)); 15977 } else { 15978 /* 15979 * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it 15980 * must be validly derived from B given the subset as defined in Type 15981 * Derivation OK (Simple) (3.14.6). 15982 */ 15983 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 15984 baseType, set)); 15985 } 15986 } 15987 15988 /** 15989 * xmlSchemaCheckCOSDerivedOK: 15990 * @type: the derived simple type definition 15991 * @baseType: the base type definition 15992 * 15993 * Calls: 15994 * Type Derivation OK (Simple) AND Type Derivation OK (Complex) 15995 * 15996 * Checks wheter @type can be validly derived from @baseType. 15997 * 15998 * Returns 0 on success, an positive error code otherwise. 15999 */ 16000 static int 16001 xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 16002 xmlSchemaTypePtr type, 16003 xmlSchemaTypePtr baseType, 16004 int set) 16005 { 16006 if (WXS_IS_SIMPLE(type)) 16007 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set)); 16008 else 16009 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set)); 16010 } 16011 16012 /** 16013 * xmlSchemaCheckCOSCTExtends: 16014 * @ctxt: the schema parser context 16015 * @type: the complex type definition 16016 * 16017 * (3.4.6) Constraints on Complex Type Definition Schema Components 16018 * Schema Component Constraint: 16019 * Derivation Valid (Extension) (cos-ct-extends) 16020 * 16021 * STATUS: 16022 * missing: 16023 * (1.5) 16024 * (1.4.3.2.2.2) "Particle Valid (Extension)" 16025 * 16026 * Returns 0 if the constraints are satisfied, a positive 16027 * error code if not and -1 if an internal error occured. 16028 */ 16029 static int 16030 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt, 16031 xmlSchemaTypePtr type) 16032 { 16033 xmlSchemaTypePtr base = type->baseType; 16034 /* 16035 * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used 16036 * temporarily only. 16037 */ 16038 /* 16039 * SPEC (1) "If the {base type definition} is a complex type definition, 16040 * then all of the following must be true:" 16041 */ 16042 if (WXS_IS_COMPLEX(base)) { 16043 /* 16044 * SPEC (1.1) "The {final} of the {base type definition} must not 16045 * contain extension." 16046 */ 16047 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16048 xmlSchemaPCustomErr(ctxt, 16049 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16050 WXS_BASIC_CAST type, NULL, 16051 "The 'final' of the base type definition " 16052 "contains 'extension'", NULL); 16053 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16054 } 16055 16056 /* 16057 * ATTENTION: The constrains (1.2) and (1.3) are not applied, 16058 * since they are automatically satisfied through the 16059 * inheriting mechanism. 16060 * Note that even if redefining components, the inheriting mechanism 16061 * is used. 16062 */ 16063 #if 0 16064 /* 16065 * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute 16066 * uses} 16067 * of the complex type definition itself, that is, for every attribute 16068 * use in the {attribute uses} of the {base type definition}, there 16069 * must be an attribute use in the {attribute uses} of the complex 16070 * type definition itself whose {attribute declaration} has the same 16071 * {name}, {target namespace} and {type definition} as its attribute 16072 * declaration" 16073 */ 16074 if (base->attrUses != NULL) { 16075 int i, j, found; 16076 xmlSchemaAttributeUsePtr use, buse; 16077 16078 for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) { 16079 buse = (WXS_LIST_CAST base->attrUses)->items[i]; 16080 found = 0; 16081 if (type->attrUses != NULL) { 16082 use = (WXS_LIST_CAST type->attrUses)->items[j]; 16083 for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++) 16084 { 16085 if ((WXS_ATTRUSE_DECL_NAME(use) == 16086 WXS_ATTRUSE_DECL_NAME(buse)) && 16087 (WXS_ATTRUSE_DECL_TNS(use) == 16088 WXS_ATTRUSE_DECL_TNS(buse)) && 16089 (WXS_ATTRUSE_TYPEDEF(use) == 16090 WXS_ATTRUSE_TYPEDEF(buse)) 16091 { 16092 found = 1; 16093 break; 16094 } 16095 } 16096 } 16097 if (! found) { 16098 xmlChar *str = NULL; 16099 16100 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16101 XML_SCHEMAP_COS_CT_EXTENDS_1_2, 16102 NULL, WXS_BASIC_CAST type, 16103 /* 16104 * TODO: The report does not indicate that also the 16105 * type needs to be the same. 16106 */ 16107 "This type is missing a matching correspondent " 16108 "for its {base type}'s %s in its {attribute uses}", 16109 xmlSchemaGetComponentDesignation(&str, 16110 buse->children), 16111 NULL); 16112 FREE_AND_NULL(str) 16113 } 16114 } 16115 } 16116 /* 16117 * SPEC (1.3) "If it has an {attribute wildcard}, the complex type 16118 * definition must also have one, and the base type definition's 16119 * {attribute wildcard}'s {namespace constraint} must be a subset 16120 * of the complex type definition's {attribute wildcard}'s {namespace 16121 * constraint}, as defined by Wildcard Subset (3.10.6)." 16122 */ 16123 16124 /* 16125 * MAYBE TODO: Enable if ever needed. But this will be needed only 16126 * if created the type via a schema construction API. 16127 */ 16128 if (base->attributeWildcard != NULL) { 16129 if (type->attributeWilcard == NULL) { 16130 xmlChar *str = NULL; 16131 16132 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16133 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16134 NULL, type, 16135 "The base %s has an attribute wildcard, " 16136 "but this type is missing an attribute wildcard", 16137 xmlSchemaGetComponentDesignation(&str, base)); 16138 FREE_AND_NULL(str) 16139 16140 } else if (xmlSchemaCheckCOSNSSubset( 16141 base->attributeWildcard, type->attributeWildcard)) 16142 { 16143 xmlChar *str = NULL; 16144 16145 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16146 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16147 NULL, type, 16148 "The attribute wildcard is not a valid " 16149 "superset of the one in the base %s", 16150 xmlSchemaGetComponentDesignation(&str, base)); 16151 FREE_AND_NULL(str) 16152 } 16153 } 16154 #endif 16155 /* 16156 * SPEC (1.4) "One of the following must be true:" 16157 */ 16158 if ((type->contentTypeDef != NULL) && 16159 (type->contentTypeDef == base->contentTypeDef)) { 16160 /* 16161 * SPEC (1.4.1) "The {content type} of the {base type definition} 16162 * and the {content type} of the complex type definition itself 16163 * must be the same simple type definition" 16164 * PASS 16165 */ 16166 } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) && 16167 (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) { 16168 /* 16169 * SPEC (1.4.2) "The {content type} of both the {base type 16170 * definition} and the complex type definition itself must 16171 * be empty." 16172 * PASS 16173 */ 16174 } else { 16175 /* 16176 * SPEC (1.4.3) "All of the following must be true:" 16177 */ 16178 if (type->subtypes == NULL) { 16179 /* 16180 * SPEC 1.4.3.1 The {content type} of the complex type 16181 * definition itself must specify a particle. 16182 */ 16183 xmlSchemaPCustomErr(ctxt, 16184 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16185 WXS_BASIC_CAST type, NULL, 16186 "The content type must specify a particle", NULL); 16187 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16188 } 16189 /* 16190 * SPEC (1.4.3.2) "One of the following must be true:" 16191 */ 16192 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16193 /* 16194 * SPEC (1.4.3.2.1) "The {content type} of the {base type 16195 * definition} must be empty. 16196 * PASS 16197 */ 16198 } else { 16199 /* 16200 * SPEC (1.4.3.2.2) "All of the following must be true:" 16201 */ 16202 if ((type->contentType != base->contentType) || 16203 ((type->contentType != XML_SCHEMA_CONTENT_MIXED) && 16204 (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) { 16205 /* 16206 * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed 16207 * or both must be element-only." 16208 */ 16209 xmlSchemaPCustomErr(ctxt, 16210 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16211 WXS_BASIC_CAST type, NULL, 16212 "The content type of both, the type and its base " 16213 "type, must either 'mixed' or 'element-only'", NULL); 16214 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16215 } 16216 /* 16217 * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the 16218 * complex type definition must be a valid extension 16219 * of the {base type definition}'s particle, as defined 16220 * in Particle Valid (Extension) (3.9.6)." 16221 * 16222 * NOTE that we won't check "Particle Valid (Extension)", 16223 * since it is ensured by the derivation process in 16224 * xmlSchemaTypeFixup(). We need to implement this when heading 16225 * for a construction API 16226 * TODO: !! This is needed to be checked if redefining a type !! 16227 */ 16228 } 16229 /* 16230 * URGENT TODO (1.5) 16231 */ 16232 } 16233 } else { 16234 /* 16235 * SPEC (2) "If the {base type definition} is a simple type definition, 16236 * then all of the following must be true:" 16237 */ 16238 if (type->contentTypeDef != base) { 16239 /* 16240 * SPEC (2.1) "The {content type} must be the same simple type 16241 * definition." 16242 */ 16243 xmlSchemaPCustomErr(ctxt, 16244 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16245 WXS_BASIC_CAST type, NULL, 16246 "The content type must be the simple base type", NULL); 16247 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16248 } 16249 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16250 /* 16251 * SPEC (2.2) "The {final} of the {base type definition} must not 16252 * contain extension" 16253 * NOTE that this is the same as (1.1). 16254 */ 16255 xmlSchemaPCustomErr(ctxt, 16256 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16257 WXS_BASIC_CAST type, NULL, 16258 "The 'final' of the base type definition " 16259 "contains 'extension'", NULL); 16260 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16261 } 16262 } 16263 return (0); 16264 } 16265 16266 /** 16267 * xmlSchemaCheckDerivationOKRestriction: 16268 * @ctxt: the schema parser context 16269 * @type: the complex type definition 16270 * 16271 * (3.4.6) Constraints on Complex Type Definition Schema Components 16272 * Schema Component Constraint: 16273 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction) 16274 * 16275 * STATUS: 16276 * missing: 16277 * (5.4.2) ??? 16278 * 16279 * ATTENTION: 16280 * In XML Schema 1.1 this will be: 16281 * Validation Rule: Checking complex type subsumption 16282 * 16283 * Returns 0 if the constraints are satisfied, a positive 16284 * error code if not and -1 if an internal error occured. 16285 */ 16286 static int 16287 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt, 16288 xmlSchemaTypePtr type) 16289 { 16290 xmlSchemaTypePtr base; 16291 16292 /* 16293 * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used 16294 * temporarily only. 16295 */ 16296 base = type->baseType; 16297 if (! WXS_IS_COMPLEX(base)) { 16298 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16299 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16300 type->node, WXS_BASIC_CAST type, 16301 "The base type must be a complex type", NULL, NULL); 16302 return(ctxt->err); 16303 } 16304 if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) { 16305 /* 16306 * SPEC (1) "The {base type definition} must be a complex type 16307 * definition whose {final} does not contain restriction." 16308 */ 16309 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16310 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16311 type->node, WXS_BASIC_CAST type, 16312 "The 'final' of the base type definition " 16313 "contains 'restriction'", NULL, NULL); 16314 return (ctxt->err); 16315 } 16316 /* 16317 * SPEC (2), (3) and (4) 16318 * Those are handled in a separate function, since the 16319 * same constraints are needed for redefinition of 16320 * attribute groups as well. 16321 */ 16322 if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt, 16323 XML_SCHEMA_ACTION_DERIVE, 16324 WXS_BASIC_CAST type, WXS_BASIC_CAST base, 16325 type->attrUses, base->attrUses, 16326 type->attributeWildcard, 16327 base->attributeWildcard) == -1) 16328 { 16329 return(-1); 16330 } 16331 /* 16332 * SPEC (5) "One of the following must be true:" 16333 */ 16334 if (base->builtInType == XML_SCHEMAS_ANYTYPE) { 16335 /* 16336 * SPEC (5.1) "The {base type definition} must be the 16337 * ur-type definition." 16338 * PASS 16339 */ 16340 } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16341 (type->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16342 /* 16343 * SPEC (5.2.1) "The {content type} of the complex type definition 16344 * must be a simple type definition" 16345 * 16346 * SPEC (5.2.2) "One of the following must be true:" 16347 */ 16348 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16349 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) 16350 { 16351 int err; 16352 /* 16353 * SPEC (5.2.2.1) "The {content type} of the {base type 16354 * definition} must be a simple type definition from which 16355 * the {content type} is validly derived given the empty 16356 * set as defined in Type Derivation OK (Simple) (3.14.6)." 16357 * 16358 * ATTENTION TODO: This seems not needed if the type implicitely 16359 * derived from the base type. 16360 * 16361 */ 16362 err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt, 16363 type->contentTypeDef, base->contentTypeDef, 0); 16364 if (err != 0) { 16365 xmlChar *strA = NULL, *strB = NULL; 16366 16367 if (err == -1) 16368 return(-1); 16369 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16370 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16371 NULL, WXS_BASIC_CAST type, 16372 "The {content type} %s is not validly derived from the " 16373 "base type's {content type} %s", 16374 xmlSchemaGetComponentDesignation(&strA, 16375 type->contentTypeDef), 16376 xmlSchemaGetComponentDesignation(&strB, 16377 base->contentTypeDef)); 16378 FREE_AND_NULL(strA); 16379 FREE_AND_NULL(strB); 16380 return(ctxt->err); 16381 } 16382 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16383 (xmlSchemaIsParticleEmptiable( 16384 (xmlSchemaParticlePtr) base->subtypes))) { 16385 /* 16386 * SPEC (5.2.2.2) "The {base type definition} must be mixed 16387 * and have a particle which is emptiable as defined in 16388 * Particle Emptiable (3.9.6)." 16389 * PASS 16390 */ 16391 } else { 16392 xmlSchemaPCustomErr(ctxt, 16393 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16394 WXS_BASIC_CAST type, NULL, 16395 "The content type of the base type must be either " 16396 "a simple type or 'mixed' and an emptiable particle", NULL); 16397 return (ctxt->err); 16398 } 16399 } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16400 /* 16401 * SPEC (5.3.1) "The {content type} of the complex type itself must 16402 * be empty" 16403 */ 16404 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16405 /* 16406 * SPEC (5.3.2.1) "The {content type} of the {base type 16407 * definition} must also be empty." 16408 * PASS 16409 */ 16410 } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16411 (base->contentType == XML_SCHEMA_CONTENT_MIXED)) && 16412 xmlSchemaIsParticleEmptiable( 16413 (xmlSchemaParticlePtr) base->subtypes)) { 16414 /* 16415 * SPEC (5.3.2.2) "The {content type} of the {base type 16416 * definition} must be elementOnly or mixed and have a particle 16417 * which is emptiable as defined in Particle Emptiable (3.9.6)." 16418 * PASS 16419 */ 16420 } else { 16421 xmlSchemaPCustomErr(ctxt, 16422 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16423 WXS_BASIC_CAST type, NULL, 16424 "The content type of the base type must be either " 16425 "empty or 'mixed' (or 'elements-only') and an emptiable " 16426 "particle", NULL); 16427 return (ctxt->err); 16428 } 16429 } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16430 WXS_HAS_MIXED_CONTENT(type)) { 16431 /* 16432 * SPEC (5.4.1.1) "The {content type} of the complex type definition 16433 * itself must be element-only" 16434 */ 16435 if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) { 16436 /* 16437 * SPEC (5.4.1.2) "The {content type} of the complex type 16438 * definition itself and of the {base type definition} must be 16439 * mixed" 16440 */ 16441 xmlSchemaPCustomErr(ctxt, 16442 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16443 WXS_BASIC_CAST type, NULL, 16444 "If the content type is 'mixed', then the content type of the " 16445 "base type must also be 'mixed'", NULL); 16446 return (ctxt->err); 16447 } 16448 /* 16449 * SPEC (5.4.2) "The particle of the complex type definition itself 16450 * must be a valid restriction of the particle of the {content 16451 * type} of the {base type definition} as defined in Particle Valid 16452 * (Restriction) (3.9.6). 16453 * 16454 * URGENT TODO: (5.4.2) 16455 */ 16456 } else { 16457 xmlSchemaPCustomErr(ctxt, 16458 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16459 WXS_BASIC_CAST type, NULL, 16460 "The type is not a valid restriction of its base type", NULL); 16461 return (ctxt->err); 16462 } 16463 return (0); 16464 } 16465 16466 /** 16467 * xmlSchemaCheckCTComponent: 16468 * @ctxt: the schema parser context 16469 * @type: the complex type definition 16470 * 16471 * (3.4.6) Constraints on Complex Type Definition Schema Components 16472 * 16473 * Returns 0 if the constraints are satisfied, a positive 16474 * error code if not and -1 if an internal error occured. 16475 */ 16476 static int 16477 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt, 16478 xmlSchemaTypePtr type) 16479 { 16480 int ret; 16481 /* 16482 * Complex Type Definition Properties Correct 16483 */ 16484 ret = xmlSchemaCheckCTPropsCorrect(ctxt, type); 16485 if (ret != 0) 16486 return (ret); 16487 if (WXS_IS_EXTENSION(type)) 16488 ret = xmlSchemaCheckCOSCTExtends(ctxt, type); 16489 else 16490 ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type); 16491 return (ret); 16492 } 16493 16494 /** 16495 * xmlSchemaCheckSRCCT: 16496 * @ctxt: the schema parser context 16497 * @type: the complex type definition 16498 * 16499 * (3.4.3) Constraints on XML Representations of Complex Type Definitions: 16500 * Schema Representation Constraint: 16501 * Complex Type Definition Representation OK (src-ct) 16502 * 16503 * Returns 0 if the constraints are satisfied, a positive 16504 * error code if not and -1 if an internal error occured. 16505 */ 16506 static int 16507 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt, 16508 xmlSchemaTypePtr type) 16509 { 16510 xmlSchemaTypePtr base; 16511 int ret = 0; 16512 16513 /* 16514 * TODO: Adjust the error codes here, as I used 16515 * XML_SCHEMAP_SRC_CT_1 only yet. 16516 */ 16517 base = type->baseType; 16518 if (! WXS_HAS_SIMPLE_CONTENT(type)) { 16519 /* 16520 * 1 If the <complexContent> alternative is chosen, the type definition 16521 * resolved to by the actual value of the base [attribute] 16522 * must be a complex type definition; 16523 */ 16524 if (! WXS_IS_COMPLEX(base)) { 16525 xmlChar *str = NULL; 16526 xmlSchemaPCustomErr(ctxt, 16527 XML_SCHEMAP_SRC_CT_1, 16528 WXS_BASIC_CAST type, type->node, 16529 "If using <complexContent>, the base type is expected to be " 16530 "a complex type. The base type '%s' is a simple type", 16531 xmlSchemaFormatQName(&str, base->targetNamespace, 16532 base->name)); 16533 FREE_AND_NULL(str) 16534 return (XML_SCHEMAP_SRC_CT_1); 16535 } 16536 } else { 16537 /* 16538 * SPEC 16539 * 2 If the <simpleContent> alternative is chosen, all of the 16540 * following must be true: 16541 * 2.1 The type definition resolved to by the actual value of the 16542 * base [attribute] must be one of the following: 16543 */ 16544 if (WXS_IS_SIMPLE(base)) { 16545 if (WXS_IS_EXTENSION(type) == 0) { 16546 xmlChar *str = NULL; 16547 /* 16548 * 2.1.3 only if the <extension> alternative is also 16549 * chosen, a simple type definition. 16550 */ 16551 /* TODO: Change error code to ..._SRC_CT_2_1_3. */ 16552 xmlSchemaPCustomErr(ctxt, 16553 XML_SCHEMAP_SRC_CT_1, 16554 WXS_BASIC_CAST type, NULL, 16555 "If using <simpleContent> and <restriction>, the base " 16556 "type must be a complex type. The base type '%s' is " 16557 "a simple type", 16558 xmlSchemaFormatQName(&str, base->targetNamespace, 16559 base->name)); 16560 FREE_AND_NULL(str) 16561 return (XML_SCHEMAP_SRC_CT_1); 16562 } 16563 } else { 16564 /* Base type is a complex type. */ 16565 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16566 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16567 /* 16568 * 2.1.1 a complex type definition whose {content type} is a 16569 * simple type definition; 16570 * PASS 16571 */ 16572 if (base->contentTypeDef == NULL) { 16573 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL, 16574 WXS_BASIC_CAST type, NULL, 16575 "Internal error: xmlSchemaCheckSRCCT, " 16576 "'%s', base type has no content type", 16577 type->name); 16578 return (-1); 16579 } 16580 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16581 (WXS_IS_RESTRICTION(type))) { 16582 16583 /* 16584 * 2.1.2 only if the <restriction> alternative is also 16585 * chosen, a complex type definition whose {content type} 16586 * is mixed and a particle emptiable. 16587 */ 16588 if (! xmlSchemaIsParticleEmptiable( 16589 (xmlSchemaParticlePtr) base->subtypes)) { 16590 ret = XML_SCHEMAP_SRC_CT_1; 16591 } else 16592 /* 16593 * Attention: at this point the <simpleType> child is in 16594 * ->contentTypeDef (put there during parsing). 16595 */ 16596 if (type->contentTypeDef == NULL) { 16597 xmlChar *str = NULL; 16598 /* 16599 * 2.2 If clause 2.1.2 above is satisfied, then there 16600 * must be a <simpleType> among the [children] of 16601 * <restriction>. 16602 */ 16603 /* TODO: Change error code to ..._SRC_CT_2_2. */ 16604 xmlSchemaPCustomErr(ctxt, 16605 XML_SCHEMAP_SRC_CT_1, 16606 WXS_BASIC_CAST type, NULL, 16607 "A <simpleType> is expected among the children " 16608 "of <restriction>, if <simpleContent> is used and " 16609 "the base type '%s' is a complex type", 16610 xmlSchemaFormatQName(&str, base->targetNamespace, 16611 base->name)); 16612 FREE_AND_NULL(str) 16613 return (XML_SCHEMAP_SRC_CT_1); 16614 } 16615 } else { 16616 ret = XML_SCHEMAP_SRC_CT_1; 16617 } 16618 } 16619 if (ret > 0) { 16620 xmlChar *str = NULL; 16621 if (WXS_IS_RESTRICTION(type)) { 16622 xmlSchemaPCustomErr(ctxt, 16623 XML_SCHEMAP_SRC_CT_1, 16624 WXS_BASIC_CAST type, NULL, 16625 "If <simpleContent> and <restriction> is used, the " 16626 "base type must be a simple type or a complex type with " 16627 "mixed content and particle emptiable. The base type " 16628 "'%s' is none of those", 16629 xmlSchemaFormatQName(&str, base->targetNamespace, 16630 base->name)); 16631 } else { 16632 xmlSchemaPCustomErr(ctxt, 16633 XML_SCHEMAP_SRC_CT_1, 16634 WXS_BASIC_CAST type, NULL, 16635 "If <simpleContent> and <extension> is used, the " 16636 "base type must be a simple type. The base type '%s' " 16637 "is a complex type", 16638 xmlSchemaFormatQName(&str, base->targetNamespace, 16639 base->name)); 16640 } 16641 FREE_AND_NULL(str) 16642 } 16643 } 16644 /* 16645 * SPEC (3) "The corresponding complex type definition component must 16646 * satisfy the conditions set out in Constraints on Complex Type 16647 * Definition Schema Components (3.4.6);" 16648 * NOTE (3) will be done in xmlSchemaTypeFixup(). 16649 */ 16650 /* 16651 * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification 16652 * above for {attribute wildcard} is satisfied, the intensional 16653 * intersection must be expressible, as defined in Attribute Wildcard 16654 * Intersection (3.10.6). 16655 * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses(). 16656 */ 16657 return (ret); 16658 } 16659 16660 #ifdef ENABLE_PARTICLE_RESTRICTION 16661 /** 16662 * xmlSchemaCheckParticleRangeOK: 16663 * @ctxt: the schema parser context 16664 * @type: the complex type definition 16665 * 16666 * (3.9.6) Constraints on Particle Schema Components 16667 * Schema Component Constraint: 16668 * Occurrence Range OK (range-ok) 16669 * 16670 * STATUS: complete 16671 * 16672 * Returns 0 if the constraints are satisfied, a positive 16673 * error code if not and -1 if an internal error occured. 16674 */ 16675 static int 16676 xmlSchemaCheckParticleRangeOK(int rmin, int rmax, 16677 int bmin, int bmax) 16678 { 16679 if (rmin < bmin) 16680 return (1); 16681 if ((bmax != UNBOUNDED) && 16682 (rmax > bmax)) 16683 return (1); 16684 return (0); 16685 } 16686 16687 /** 16688 * xmlSchemaCheckRCaseNameAndTypeOK: 16689 * @ctxt: the schema parser context 16690 * @r: the restricting element declaration particle 16691 * @b: the base element declaration particle 16692 * 16693 * (3.9.6) Constraints on Particle Schema Components 16694 * Schema Component Constraint: 16695 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK) 16696 * (rcase-NameAndTypeOK) 16697 * 16698 * STATUS: 16699 * MISSING (3.2.3) 16700 * CLARIFY: (3.2.2) 16701 * 16702 * Returns 0 if the constraints are satisfied, a positive 16703 * error code if not and -1 if an internal error occured. 16704 */ 16705 static int 16706 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt, 16707 xmlSchemaParticlePtr r, 16708 xmlSchemaParticlePtr b) 16709 { 16710 xmlSchemaElementPtr elemR, elemB; 16711 16712 /* TODO: Error codes (rcase-NameAndTypeOK). */ 16713 elemR = (xmlSchemaElementPtr) r->children; 16714 elemB = (xmlSchemaElementPtr) b->children; 16715 /* 16716 * SPEC (1) "The declarations' {name}s and {target namespace}s are 16717 * the same." 16718 */ 16719 if ((elemR != elemB) && 16720 ((! xmlStrEqual(elemR->name, elemB->name)) || 16721 (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace)))) 16722 return (1); 16723 /* 16724 * SPEC (2) "R's occurrence range is a valid restriction of B's 16725 * occurrence range as defined by Occurrence Range OK (3.9.6)." 16726 */ 16727 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16728 b->minOccurs, b->maxOccurs) != 0) 16729 return (1); 16730 /* 16731 * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's 16732 * {scope} are global." 16733 */ 16734 if (elemR == elemB) 16735 return (0); 16736 /* 16737 * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false." 16738 */ 16739 if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) && 16740 (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE)) 16741 return (1); 16742 /* 16743 * SPEC (3.2.2) "either B's declaration's {value constraint} is absent, 16744 * or is not fixed, or R's declaration's {value constraint} is fixed 16745 * with the same value." 16746 */ 16747 if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) && 16748 ((elemR->value == NULL) || 16749 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) || 16750 /* TODO: Equality of the initial value or normalized or canonical? */ 16751 (! xmlStrEqual(elemR->value, elemB->value)))) 16752 return (1); 16753 /* 16754 * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint 16755 * definitions} is a subset of B's declaration's {identity-constraint 16756 * definitions}, if any." 16757 */ 16758 if (elemB->idcs != NULL) { 16759 /* TODO */ 16760 } 16761 /* 16762 * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a 16763 * superset of B's declaration's {disallowed substitutions}." 16764 */ 16765 if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) && 16766 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) || 16767 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) && 16768 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) || 16769 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) && 16770 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0))) 16771 return (1); 16772 /* 16773 * SPEC (3.2.5) "R's {type definition} is validly derived given 16774 * {extension, list, union} from B's {type definition}" 16775 * 16776 * BADSPEC TODO: What's the point of adding "list" and "union" to the 16777 * set, if the corresponding constraints handle "restriction" and 16778 * "extension" only? 16779 * 16780 */ 16781 { 16782 int set = 0; 16783 16784 set |= SUBSET_EXTENSION; 16785 set |= SUBSET_LIST; 16786 set |= SUBSET_UNION; 16787 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes, 16788 elemB->subtypes, set) != 0) 16789 return (1); 16790 } 16791 return (0); 16792 } 16793 16794 /** 16795 * xmlSchemaCheckRCaseNSCompat: 16796 * @ctxt: the schema parser context 16797 * @r: the restricting element declaration particle 16798 * @b: the base wildcard particle 16799 * 16800 * (3.9.6) Constraints on Particle Schema Components 16801 * Schema Component Constraint: 16802 * Particle Derivation OK (Elt:Any -- NSCompat) 16803 * (rcase-NSCompat) 16804 * 16805 * STATUS: complete 16806 * 16807 * Returns 0 if the constraints are satisfied, a positive 16808 * error code if not and -1 if an internal error occured. 16809 */ 16810 static int 16811 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt, 16812 xmlSchemaParticlePtr r, 16813 xmlSchemaParticlePtr b) 16814 { 16815 /* TODO:Error codes (rcase-NSCompat). */ 16816 /* 16817 * SPEC "For an element declaration particle to be a valid restriction 16818 * of a wildcard particle all of the following must be true:" 16819 * 16820 * SPEC (1) "The element declaration's {target namespace} is valid 16821 * with respect to the wildcard's {namespace constraint} as defined by 16822 * Wildcard allows Namespace Name (3.10.4)." 16823 */ 16824 if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children, 16825 ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0) 16826 return (1); 16827 /* 16828 * SPEC (2) "R's occurrence range is a valid restriction of B's 16829 * occurrence range as defined by Occurrence Range OK (3.9.6)." 16830 */ 16831 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16832 b->minOccurs, b->maxOccurs) != 0) 16833 return (1); 16834 16835 return (0); 16836 } 16837 16838 /** 16839 * xmlSchemaCheckRCaseRecurseAsIfGroup: 16840 * @ctxt: the schema parser context 16841 * @r: the restricting element declaration particle 16842 * @b: the base model group particle 16843 * 16844 * (3.9.6) Constraints on Particle Schema Components 16845 * Schema Component Constraint: 16846 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup) 16847 * (rcase-RecurseAsIfGroup) 16848 * 16849 * STATUS: TODO 16850 * 16851 * Returns 0 if the constraints are satisfied, a positive 16852 * error code if not and -1 if an internal error occured. 16853 */ 16854 static int 16855 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt, 16856 xmlSchemaParticlePtr r, 16857 xmlSchemaParticlePtr b) 16858 { 16859 /* TODO: Error codes (rcase-RecurseAsIfGroup). */ 16860 TODO 16861 return (0); 16862 } 16863 16864 /** 16865 * xmlSchemaCheckRCaseNSSubset: 16866 * @ctxt: the schema parser context 16867 * @r: the restricting wildcard particle 16868 * @b: the base wildcard particle 16869 * 16870 * (3.9.6) Constraints on Particle Schema Components 16871 * Schema Component Constraint: 16872 * Particle Derivation OK (Any:Any -- NSSubset) 16873 * (rcase-NSSubset) 16874 * 16875 * STATUS: complete 16876 * 16877 * Returns 0 if the constraints are satisfied, a positive 16878 * error code if not and -1 if an internal error occured. 16879 */ 16880 static int 16881 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt, 16882 xmlSchemaParticlePtr r, 16883 xmlSchemaParticlePtr b, 16884 int isAnyTypeBase) 16885 { 16886 /* TODO: Error codes (rcase-NSSubset). */ 16887 /* 16888 * SPEC (1) "R's occurrence range is a valid restriction of B's 16889 * occurrence range as defined by Occurrence Range OK (3.9.6)." 16890 */ 16891 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16892 b->minOccurs, b->maxOccurs)) 16893 return (1); 16894 /* 16895 * SPEC (2) "R's {namespace constraint} must be an intensional subset 16896 * of B's {namespace constraint} as defined by Wildcard Subset (3.10.6)." 16897 */ 16898 if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children, 16899 (xmlSchemaWildcardPtr) b->children)) 16900 return (1); 16901 /* 16902 * SPEC (3) "Unless B is the content model wildcard of the ur-type 16903 * definition, R's {process contents} must be identical to or stronger 16904 * than B's {process contents}, where strict is stronger than lax is 16905 * stronger than skip." 16906 */ 16907 if (! isAnyTypeBase) { 16908 if ( ((xmlSchemaWildcardPtr) r->children)->processContents < 16909 ((xmlSchemaWildcardPtr) b->children)->processContents) 16910 return (1); 16911 } 16912 16913 return (0); 16914 } 16915 16916 /** 16917 * xmlSchemaCheckCOSParticleRestrict: 16918 * @ctxt: the schema parser context 16919 * @type: the complex type definition 16920 * 16921 * (3.9.6) Constraints on Particle Schema Components 16922 * Schema Component Constraint: 16923 * Particle Valid (Restriction) (cos-particle-restrict) 16924 * 16925 * STATUS: TODO 16926 * 16927 * Returns 0 if the constraints are satisfied, a positive 16928 * error code if not and -1 if an internal error occured. 16929 */ 16930 static int 16931 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt, 16932 xmlSchemaParticlePtr r, 16933 xmlSchemaParticlePtr b) 16934 { 16935 int ret = 0; 16936 16937 /*part = WXS_TYPE_PARTICLE(type); 16938 basePart = WXS_TYPE_PARTICLE(base); 16939 */ 16940 16941 TODO 16942 16943 /* 16944 * SPEC (1) "They are the same particle." 16945 */ 16946 if (r == b) 16947 return (0); 16948 16949 16950 return (0); 16951 } 16952 16953 #if 0 16954 /** 16955 * xmlSchemaCheckRCaseNSRecurseCheckCardinality: 16956 * @ctxt: the schema parser context 16957 * @r: the model group particle 16958 * @b: the base wildcard particle 16959 * 16960 * (3.9.6) Constraints on Particle Schema Components 16961 * Schema Component Constraint: 16962 * Particle Derivation OK (All/Choice/Sequence:Any -- 16963 * NSRecurseCheckCardinality) 16964 * (rcase-NSRecurseCheckCardinality) 16965 * 16966 * STATUS: TODO: subst-groups 16967 * 16968 * Returns 0 if the constraints are satisfied, a positive 16969 * error code if not and -1 if an internal error occured. 16970 */ 16971 static int 16972 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt, 16973 xmlSchemaParticlePtr r, 16974 xmlSchemaParticlePtr b) 16975 { 16976 xmlSchemaParticlePtr part; 16977 /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */ 16978 if ((r->children == NULL) || (r->children->children == NULL)) 16979 return (-1); 16980 /* 16981 * SPEC "For a group particle to be a valid restriction of a 16982 * wildcard particle..." 16983 * 16984 * SPEC (1) "Every member of the {particles} of the group is a valid 16985 * restriction of the wildcard as defined by 16986 * Particle Valid (Restriction) (3.9.6)." 16987 */ 16988 part = (xmlSchemaParticlePtr) r->children->children; 16989 do { 16990 if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b)) 16991 return (1); 16992 part = (xmlSchemaParticlePtr) part->next; 16993 } while (part != NULL); 16994 /* 16995 * SPEC (2) "The effective total range of the group [...] is a 16996 * valid restriction of B's occurrence range as defined by 16997 * Occurrence Range OK (3.9.6)." 16998 */ 16999 if (xmlSchemaCheckParticleRangeOK( 17000 xmlSchemaGetParticleTotalRangeMin(r), 17001 xmlSchemaGetParticleTotalRangeMax(r), 17002 b->minOccurs, b->maxOccurs) != 0) 17003 return (1); 17004 return (0); 17005 } 17006 #endif 17007 17008 /** 17009 * xmlSchemaCheckRCaseRecurse: 17010 * @ctxt: the schema parser context 17011 * @r: the <all> or <sequence> model group particle 17012 * @b: the base <all> or <sequence> model group particle 17013 * 17014 * (3.9.6) Constraints on Particle Schema Components 17015 * Schema Component Constraint: 17016 * Particle Derivation OK (All:All,Sequence:Sequence -- 17017 Recurse) 17018 * (rcase-Recurse) 17019 * 17020 * STATUS: ? 17021 * TODO: subst-groups 17022 * 17023 * Returns 0 if the constraints are satisfied, a positive 17024 * error code if not and -1 if an internal error occured. 17025 */ 17026 static int 17027 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt, 17028 xmlSchemaParticlePtr r, 17029 xmlSchemaParticlePtr b) 17030 { 17031 /* xmlSchemaParticlePtr part; */ 17032 /* TODO: Error codes (rcase-Recurse). */ 17033 if ((r->children == NULL) || (b->children == NULL) || 17034 (r->children->type != b->children->type)) 17035 return (-1); 17036 /* 17037 * SPEC "For an all or sequence group particle to be a valid 17038 * restriction of another group particle with the same {compositor}..." 17039 * 17040 * SPEC (1) "R's occurrence range is a valid restriction of B's 17041 * occurrence range as defined by Occurrence Range OK (3.9.6)." 17042 */ 17043 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 17044 b->minOccurs, b->maxOccurs)) 17045 return (1); 17046 17047 17048 return (0); 17049 } 17050 17051 #endif 17052 17053 #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \ 17054 xmlSchemaPCustomErrExt(pctxt, \ 17055 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17056 WXS_BASIC_CAST fac1, fac1->node, \ 17057 "It is an error for both '%s' and '%s' to be specified on the "\ 17058 "same type definition", \ 17059 BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \ 17060 BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL); 17061 17062 #define FACET_RESTR_ERR(fac1, msg) \ 17063 xmlSchemaPCustomErr(pctxt, \ 17064 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17065 WXS_BASIC_CAST fac1, fac1->node, \ 17066 msg, NULL); 17067 17068 #define FACET_RESTR_FIXED_ERR(fac) \ 17069 xmlSchemaPCustomErr(pctxt, \ 17070 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17071 WXS_BASIC_CAST fac, fac->node, \ 17072 "The base type's facet is 'fixed', thus the value must not " \ 17073 "differ", NULL); 17074 17075 static void 17076 xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt, 17077 xmlSchemaFacetPtr facet1, 17078 xmlSchemaFacetPtr facet2, 17079 int lessGreater, 17080 int orEqual, 17081 int ofBase) 17082 { 17083 xmlChar *msg = NULL; 17084 17085 msg = xmlStrdup(BAD_CAST "'"); 17086 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type)); 17087 msg = xmlStrcat(msg, BAD_CAST "' has to be"); 17088 if (lessGreater == 0) 17089 msg = xmlStrcat(msg, BAD_CAST " equal to"); 17090 if (lessGreater == 1) 17091 msg = xmlStrcat(msg, BAD_CAST " greater than"); 17092 else 17093 msg = xmlStrcat(msg, BAD_CAST " less than"); 17094 17095 if (orEqual) 17096 msg = xmlStrcat(msg, BAD_CAST " or equal to"); 17097 msg = xmlStrcat(msg, BAD_CAST " '"); 17098 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type)); 17099 if (ofBase) 17100 msg = xmlStrcat(msg, BAD_CAST "' of the base type"); 17101 else 17102 msg = xmlStrcat(msg, BAD_CAST "'"); 17103 17104 xmlSchemaPCustomErr(pctxt, 17105 XML_SCHEMAP_INVALID_FACET_VALUE, 17106 WXS_BASIC_CAST facet1, NULL, 17107 (const char *) msg, NULL); 17108 17109 if (msg != NULL) 17110 xmlFree(msg); 17111 } 17112 17113 /* 17114 * xmlSchemaDeriveAndValidateFacets: 17115 * 17116 * Schema Component Constraint: Simple Type Restriction (Facets) 17117 * (st-restrict-facets) 17118 */ 17119 static int 17120 xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt, 17121 xmlSchemaTypePtr type) 17122 { 17123 xmlSchemaTypePtr base = type->baseType; 17124 xmlSchemaFacetLinkPtr link, cur, last = NULL; 17125 xmlSchemaFacetPtr facet, bfacet, 17126 flength = NULL, ftotdig = NULL, ffracdig = NULL, 17127 fmaxlen = NULL, fminlen = NULL, /* facets of the current type */ 17128 fmininc = NULL, fmaxinc = NULL, 17129 fminexc = NULL, fmaxexc = NULL, 17130 bflength = NULL, bftotdig = NULL, bffracdig = NULL, 17131 bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */ 17132 bfmininc = NULL, bfmaxinc = NULL, 17133 bfminexc = NULL, bfmaxexc = NULL; 17134 int res; /* err = 0, fixedErr; */ 17135 17136 /* 17137 * SPEC st-restrict-facets 1: 17138 * "The {variety} of R is the same as that of B." 17139 */ 17140 /* 17141 * SPEC st-restrict-facets 2: 17142 * "If {variety} is atomic, the {primitive type definition} 17143 * of R is the same as that of B." 17144 * 17145 * NOTE: we leave 1 & 2 out for now, since this will be 17146 * satisfied by the derivation process. 17147 * CONSTRUCTION TODO: Maybe needed if using a construction API. 17148 */ 17149 /* 17150 * SPEC st-restrict-facets 3: 17151 * "The {facets} of R are the union of S and the {facets} 17152 * of B, eliminating duplicates. To eliminate duplicates, 17153 * when a facet of the same kind occurs in both S and the 17154 * {facets} of B, the one in the {facets} of B is not 17155 * included, with the exception of enumeration and pattern 17156 * facets, for which multiple occurrences with distinct values 17157 * are allowed." 17158 */ 17159 17160 if ((type->facetSet == NULL) && (base->facetSet == NULL)) 17161 return (0); 17162 17163 last = type->facetSet; 17164 if (last != NULL) 17165 while (last->next != NULL) 17166 last = last->next; 17167 17168 for (cur = type->facetSet; cur != NULL; cur = cur->next) { 17169 facet = cur->facet; 17170 switch (facet->type) { 17171 case XML_SCHEMA_FACET_LENGTH: 17172 flength = facet; break; 17173 case XML_SCHEMA_FACET_MINLENGTH: 17174 fminlen = facet; break; 17175 case XML_SCHEMA_FACET_MININCLUSIVE: 17176 fmininc = facet; break; 17177 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17178 fminexc = facet; break; 17179 case XML_SCHEMA_FACET_MAXLENGTH: 17180 fmaxlen = facet; break; 17181 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17182 fmaxinc = facet; break; 17183 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17184 fmaxexc = facet; break; 17185 case XML_SCHEMA_FACET_TOTALDIGITS: 17186 ftotdig = facet; break; 17187 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17188 ffracdig = facet; break; 17189 default: 17190 break; 17191 } 17192 } 17193 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17194 facet = cur->facet; 17195 switch (facet->type) { 17196 case XML_SCHEMA_FACET_LENGTH: 17197 bflength = facet; break; 17198 case XML_SCHEMA_FACET_MINLENGTH: 17199 bfminlen = facet; break; 17200 case XML_SCHEMA_FACET_MININCLUSIVE: 17201 bfmininc = facet; break; 17202 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17203 bfminexc = facet; break; 17204 case XML_SCHEMA_FACET_MAXLENGTH: 17205 bfmaxlen = facet; break; 17206 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17207 bfmaxinc = facet; break; 17208 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17209 bfmaxexc = facet; break; 17210 case XML_SCHEMA_FACET_TOTALDIGITS: 17211 bftotdig = facet; break; 17212 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17213 bffracdig = facet; break; 17214 default: 17215 break; 17216 } 17217 } 17218 /* 17219 * length and minLength or maxLength (2.2) + (3.2) 17220 */ 17221 if (flength && (fminlen || fmaxlen)) { 17222 FACET_RESTR_ERR(flength, "It is an error for both 'length' and " 17223 "either of 'minLength' or 'maxLength' to be specified on " 17224 "the same type definition") 17225 } 17226 /* 17227 * Mutual exclusions in the same derivation step. 17228 */ 17229 if ((fmaxinc) && (fmaxexc)) { 17230 /* 17231 * SCC "maxInclusive and maxExclusive" 17232 */ 17233 FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc) 17234 } 17235 if ((fmininc) && (fminexc)) { 17236 /* 17237 * SCC "minInclusive and minExclusive" 17238 */ 17239 FACET_RESTR_MUTUAL_ERR(fmininc, fminexc) 17240 } 17241 17242 if (flength && bflength) { 17243 /* 17244 * SCC "length valid restriction" 17245 * The values have to be equal. 17246 */ 17247 res = xmlSchemaCompareValues(flength->val, bflength->val); 17248 if (res == -2) 17249 goto internal_error; 17250 if (res != 0) 17251 xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1); 17252 if ((res != 0) && (bflength->fixed)) { 17253 FACET_RESTR_FIXED_ERR(flength) 17254 } 17255 17256 } 17257 if (fminlen && bfminlen) { 17258 /* 17259 * SCC "minLength valid restriction" 17260 * minLength >= BASE minLength 17261 */ 17262 res = xmlSchemaCompareValues(fminlen->val, bfminlen->val); 17263 if (res == -2) 17264 goto internal_error; 17265 if (res == -1) 17266 xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1); 17267 if ((res != 0) && (bfminlen->fixed)) { 17268 FACET_RESTR_FIXED_ERR(fminlen) 17269 } 17270 } 17271 if (fmaxlen && bfmaxlen) { 17272 /* 17273 * SCC "maxLength valid restriction" 17274 * maxLength <= BASE minLength 17275 */ 17276 res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val); 17277 if (res == -2) 17278 goto internal_error; 17279 if (res == 1) 17280 xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1); 17281 if ((res != 0) && (bfmaxlen->fixed)) { 17282 FACET_RESTR_FIXED_ERR(fmaxlen) 17283 } 17284 } 17285 /* 17286 * SCC "length and minLength or maxLength" 17287 */ 17288 if (! flength) 17289 flength = bflength; 17290 if (flength) { 17291 if (! fminlen) 17292 flength = bflength; 17293 if (fminlen) { 17294 /* (1.1) length >= minLength */ 17295 res = xmlSchemaCompareValues(flength->val, fminlen->val); 17296 if (res == -2) 17297 goto internal_error; 17298 if (res == -1) 17299 xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0); 17300 } 17301 if (! fmaxlen) 17302 fmaxlen = bfmaxlen; 17303 if (fmaxlen) { 17304 /* (2.1) length <= maxLength */ 17305 res = xmlSchemaCompareValues(flength->val, fmaxlen->val); 17306 if (res == -2) 17307 goto internal_error; 17308 if (res == 1) 17309 xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0); 17310 } 17311 } 17312 if (fmaxinc) { 17313 /* 17314 * "maxInclusive" 17315 */ 17316 if (fmininc) { 17317 /* SCC "maxInclusive >= minInclusive" */ 17318 res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val); 17319 if (res == -2) 17320 goto internal_error; 17321 if (res == -1) { 17322 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0); 17323 } 17324 } 17325 /* 17326 * SCC "maxInclusive valid restriction" 17327 */ 17328 if (bfmaxinc) { 17329 /* maxInclusive <= BASE maxInclusive */ 17330 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val); 17331 if (res == -2) 17332 goto internal_error; 17333 if (res == 1) 17334 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1); 17335 if ((res != 0) && (bfmaxinc->fixed)) { 17336 FACET_RESTR_FIXED_ERR(fmaxinc) 17337 } 17338 } 17339 if (bfmaxexc) { 17340 /* maxInclusive < BASE maxExclusive */ 17341 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val); 17342 if (res == -2) 17343 goto internal_error; 17344 if (res != -1) { 17345 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1); 17346 } 17347 } 17348 if (bfmininc) { 17349 /* maxInclusive >= BASE minInclusive */ 17350 res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val); 17351 if (res == -2) 17352 goto internal_error; 17353 if (res == -1) { 17354 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1); 17355 } 17356 } 17357 if (bfminexc) { 17358 /* maxInclusive > BASE minExclusive */ 17359 res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val); 17360 if (res == -2) 17361 goto internal_error; 17362 if (res != 1) { 17363 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1); 17364 } 17365 } 17366 } 17367 if (fmaxexc) { 17368 /* 17369 * "maxExclusive >= minExclusive" 17370 */ 17371 if (fminexc) { 17372 res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val); 17373 if (res == -2) 17374 goto internal_error; 17375 if (res == -1) { 17376 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0); 17377 } 17378 } 17379 /* 17380 * "maxExclusive valid restriction" 17381 */ 17382 if (bfmaxexc) { 17383 /* maxExclusive <= BASE maxExclusive */ 17384 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val); 17385 if (res == -2) 17386 goto internal_error; 17387 if (res == 1) { 17388 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1); 17389 } 17390 if ((res != 0) && (bfmaxexc->fixed)) { 17391 FACET_RESTR_FIXED_ERR(fmaxexc) 17392 } 17393 } 17394 if (bfmaxinc) { 17395 /* maxExclusive <= BASE maxInclusive */ 17396 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val); 17397 if (res == -2) 17398 goto internal_error; 17399 if (res == 1) { 17400 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1); 17401 } 17402 } 17403 if (bfmininc) { 17404 /* maxExclusive > BASE minInclusive */ 17405 res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val); 17406 if (res == -2) 17407 goto internal_error; 17408 if (res != 1) { 17409 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1); 17410 } 17411 } 17412 if (bfminexc) { 17413 /* maxExclusive > BASE minExclusive */ 17414 res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val); 17415 if (res == -2) 17416 goto internal_error; 17417 if (res != 1) { 17418 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1); 17419 } 17420 } 17421 } 17422 if (fminexc) { 17423 /* 17424 * "minExclusive < maxInclusive" 17425 */ 17426 if (fmaxinc) { 17427 res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val); 17428 if (res == -2) 17429 goto internal_error; 17430 if (res != -1) { 17431 xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0); 17432 } 17433 } 17434 /* 17435 * "minExclusive valid restriction" 17436 */ 17437 if (bfminexc) { 17438 /* minExclusive >= BASE minExclusive */ 17439 res = xmlSchemaCompareValues(fminexc->val, bfminexc->val); 17440 if (res == -2) 17441 goto internal_error; 17442 if (res == -1) { 17443 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1); 17444 } 17445 if ((res != 0) && (bfminexc->fixed)) { 17446 FACET_RESTR_FIXED_ERR(fminexc) 17447 } 17448 } 17449 if (bfmaxinc) { 17450 /* minExclusive <= BASE maxInclusive */ 17451 res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val); 17452 if (res == -2) 17453 goto internal_error; 17454 if (res == 1) { 17455 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1); 17456 } 17457 } 17458 if (bfmininc) { 17459 /* minExclusive >= BASE minInclusive */ 17460 res = xmlSchemaCompareValues(fminexc->val, bfmininc->val); 17461 if (res == -2) 17462 goto internal_error; 17463 if (res == -1) { 17464 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1); 17465 } 17466 } 17467 if (bfmaxexc) { 17468 /* minExclusive < BASE maxExclusive */ 17469 res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val); 17470 if (res == -2) 17471 goto internal_error; 17472 if (res != -1) { 17473 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1); 17474 } 17475 } 17476 } 17477 if (fmininc) { 17478 /* 17479 * "minInclusive < maxExclusive" 17480 */ 17481 if (fmaxexc) { 17482 res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val); 17483 if (res == -2) 17484 goto internal_error; 17485 if (res != -1) { 17486 xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0); 17487 } 17488 } 17489 /* 17490 * "minExclusive valid restriction" 17491 */ 17492 if (bfmininc) { 17493 /* minInclusive >= BASE minInclusive */ 17494 res = xmlSchemaCompareValues(fmininc->val, bfmininc->val); 17495 if (res == -2) 17496 goto internal_error; 17497 if (res == -1) { 17498 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1); 17499 } 17500 if ((res != 0) && (bfmininc->fixed)) { 17501 FACET_RESTR_FIXED_ERR(fmininc) 17502 } 17503 } 17504 if (bfmaxinc) { 17505 /* minInclusive <= BASE maxInclusive */ 17506 res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val); 17507 if (res == -2) 17508 goto internal_error; 17509 if (res == 1) { 17510 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1); 17511 } 17512 } 17513 if (bfminexc) { 17514 /* minInclusive > BASE minExclusive */ 17515 res = xmlSchemaCompareValues(fmininc->val, bfminexc->val); 17516 if (res == -2) 17517 goto internal_error; 17518 if (res != 1) 17519 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1); 17520 } 17521 if (bfmaxexc) { 17522 /* minInclusive < BASE maxExclusive */ 17523 res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val); 17524 if (res == -2) 17525 goto internal_error; 17526 if (res != -1) 17527 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1); 17528 } 17529 } 17530 if (ftotdig && bftotdig) { 17531 /* 17532 * SCC " totalDigits valid restriction" 17533 * totalDigits <= BASE totalDigits 17534 */ 17535 res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val); 17536 if (res == -2) 17537 goto internal_error; 17538 if (res == 1) 17539 xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig, 17540 -1, 1, 1); 17541 if ((res != 0) && (bftotdig->fixed)) { 17542 FACET_RESTR_FIXED_ERR(ftotdig) 17543 } 17544 } 17545 if (ffracdig && bffracdig) { 17546 /* 17547 * SCC "fractionDigits valid restriction" 17548 * fractionDigits <= BASE fractionDigits 17549 */ 17550 res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val); 17551 if (res == -2) 17552 goto internal_error; 17553 if (res == 1) 17554 xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig, 17555 -1, 1, 1); 17556 if ((res != 0) && (bffracdig->fixed)) { 17557 FACET_RESTR_FIXED_ERR(ffracdig) 17558 } 17559 } 17560 /* 17561 * SCC "fractionDigits less than or equal to totalDigits" 17562 */ 17563 if (! ftotdig) 17564 ftotdig = bftotdig; 17565 if (! ffracdig) 17566 ffracdig = bffracdig; 17567 if (ftotdig && ffracdig) { 17568 res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val); 17569 if (res == -2) 17570 goto internal_error; 17571 if (res == 1) 17572 xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig, 17573 -1, 1, 0); 17574 } 17575 /* 17576 * *Enumerations* won' be added here, since only the first set 17577 * of enumerations in the ancestor-or-self axis is used 17578 * for validation, plus we need to use the base type of those 17579 * enumerations for whitespace. 17580 * 17581 * *Patterns*: won't be add here, since they are ORed at 17582 * type level and ANDed at ancestor level. This will 17583 * happed during validation by walking the base axis 17584 * of the type. 17585 */ 17586 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17587 bfacet = cur->facet; 17588 /* 17589 * Special handling of enumerations and patterns. 17590 * TODO: hmm, they should not appear in the set, so remove this. 17591 */ 17592 if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) || 17593 (bfacet->type == XML_SCHEMA_FACET_ENUMERATION)) 17594 continue; 17595 /* 17596 * Search for a duplicate facet in the current type. 17597 */ 17598 link = type->facetSet; 17599 /* err = 0; */ 17600 /* fixedErr = 0; */ 17601 while (link != NULL) { 17602 facet = link->facet; 17603 if (facet->type == bfacet->type) { 17604 switch (facet->type) { 17605 case XML_SCHEMA_FACET_WHITESPACE: 17606 /* 17607 * The whitespace must be stronger. 17608 */ 17609 if (facet->whitespace < bfacet->whitespace) { 17610 FACET_RESTR_ERR(facet, 17611 "The 'whitespace' value has to be equal to " 17612 "or stronger than the 'whitespace' value of " 17613 "the base type") 17614 } 17615 if ((bfacet->fixed) && 17616 (facet->whitespace != bfacet->whitespace)) { 17617 FACET_RESTR_FIXED_ERR(facet) 17618 } 17619 break; 17620 default: 17621 break; 17622 } 17623 /* Duplicate found. */ 17624 break; 17625 } 17626 link = link->next; 17627 } 17628 /* 17629 * If no duplicate was found: add the base types's facet 17630 * to the set. 17631 */ 17632 if (link == NULL) { 17633 link = (xmlSchemaFacetLinkPtr) 17634 xmlMalloc(sizeof(xmlSchemaFacetLink)); 17635 if (link == NULL) { 17636 xmlSchemaPErrMemory(pctxt, 17637 "deriving facets, creating a facet link", NULL); 17638 return (-1); 17639 } 17640 link->facet = cur->facet; 17641 link->next = NULL; 17642 if (last == NULL) 17643 type->facetSet = link; 17644 else 17645 last->next = link; 17646 last = link; 17647 } 17648 17649 } 17650 17651 return (0); 17652 internal_error: 17653 PERROR_INT("xmlSchemaDeriveAndValidateFacets", 17654 "an error occured"); 17655 return (-1); 17656 } 17657 17658 static int 17659 xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt, 17660 xmlSchemaTypePtr type) 17661 { 17662 xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink; 17663 /* 17664 * The actual value is then formed by replacing any union type 17665 * definition in the explicit members with the members of their 17666 * {member type definitions}, in order. 17667 * 17668 * TODO: There's a bug entry at 17669 * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html" 17670 * which indicates that we'll keep the union types the future. 17671 */ 17672 link = type->memberTypes; 17673 while (link != NULL) { 17674 17675 if (WXS_IS_TYPE_NOT_FIXED(link->type)) 17676 xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt); 17677 17678 if (WXS_IS_UNION(link->type)) { 17679 subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type); 17680 if (subLink != NULL) { 17681 link->type = subLink->type; 17682 if (subLink->next != NULL) { 17683 lastLink = link->next; 17684 subLink = subLink->next; 17685 prevLink = link; 17686 while (subLink != NULL) { 17687 newLink = (xmlSchemaTypeLinkPtr) 17688 xmlMalloc(sizeof(xmlSchemaTypeLink)); 17689 if (newLink == NULL) { 17690 xmlSchemaPErrMemory(pctxt, "allocating a type link", 17691 NULL); 17692 return (-1); 17693 } 17694 newLink->type = subLink->type; 17695 prevLink->next = newLink; 17696 prevLink = newLink; 17697 newLink->next = lastLink; 17698 17699 subLink = subLink->next; 17700 } 17701 } 17702 } 17703 } 17704 link = link->next; 17705 } 17706 return (0); 17707 } 17708 17709 static void 17710 xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type) 17711 { 17712 int has = 0, needVal = 0, normVal = 0; 17713 17714 has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0; 17715 if (has) { 17716 needVal = (type->baseType->flags & 17717 XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0; 17718 normVal = (type->baseType->flags & 17719 XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0; 17720 } 17721 if (type->facets != NULL) { 17722 xmlSchemaFacetPtr fac; 17723 17724 for (fac = type->facets; fac != NULL; fac = fac->next) { 17725 switch (fac->type) { 17726 case XML_SCHEMA_FACET_WHITESPACE: 17727 break; 17728 case XML_SCHEMA_FACET_PATTERN: 17729 normVal = 1; 17730 has = 1; 17731 break; 17732 case XML_SCHEMA_FACET_ENUMERATION: 17733 needVal = 1; 17734 normVal = 1; 17735 has = 1; 17736 break; 17737 default: 17738 has = 1; 17739 break; 17740 } 17741 } 17742 } 17743 if (normVal) 17744 type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED; 17745 if (needVal) 17746 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17747 if (has) 17748 type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS; 17749 17750 if (has && (! needVal) && WXS_IS_ATOMIC(type)) { 17751 xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type); 17752 /* 17753 * OPTIMIZE VAL TODO: Some facets need a computed value. 17754 */ 17755 if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) && 17756 (prim->builtInType != XML_SCHEMAS_STRING)) { 17757 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17758 } 17759 } 17760 } 17761 17762 static int 17763 xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type) 17764 { 17765 17766 17767 /* 17768 * Evaluate the whitespace-facet value. 17769 */ 17770 if (WXS_IS_LIST(type)) { 17771 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17772 return (0); 17773 } else if (WXS_IS_UNION(type)) 17774 return (0); 17775 17776 if (type->facetSet != NULL) { 17777 xmlSchemaFacetLinkPtr lin; 17778 17779 for (lin = type->facetSet; lin != NULL; lin = lin->next) { 17780 if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) { 17781 switch (lin->facet->whitespace) { 17782 case XML_SCHEMAS_FACET_PRESERVE: 17783 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17784 break; 17785 case XML_SCHEMAS_FACET_REPLACE: 17786 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17787 break; 17788 case XML_SCHEMAS_FACET_COLLAPSE: 17789 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17790 break; 17791 default: 17792 return (-1); 17793 } 17794 return (0); 17795 } 17796 } 17797 } 17798 /* 17799 * For all atomic datatypes other than string (and types derived 17800 * by restriction from it) the value of whiteSpace is fixed to 17801 * collapse 17802 */ 17803 { 17804 xmlSchemaTypePtr anc; 17805 17806 for (anc = type->baseType; anc != NULL && 17807 anc->builtInType != XML_SCHEMAS_ANYTYPE; 17808 anc = anc->baseType) { 17809 17810 if (anc->type == XML_SCHEMA_TYPE_BASIC) { 17811 if (anc->builtInType == XML_SCHEMAS_NORMSTRING) { 17812 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17813 17814 } else if ((anc->builtInType == XML_SCHEMAS_STRING) || 17815 (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) { 17816 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17817 17818 } else 17819 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17820 break; 17821 } 17822 } 17823 } 17824 return (0); 17825 } 17826 17827 static int 17828 xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt, 17829 xmlSchemaTypePtr type) 17830 { 17831 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 17832 return(0); 17833 if (! WXS_IS_TYPE_NOT_FIXED_1(type)) 17834 return(0); 17835 type->flags |= XML_SCHEMAS_TYPE_FIXUP_1; 17836 17837 if (WXS_IS_LIST(type)) { 17838 /* 17839 * Corresponds to <simpleType><list>... 17840 */ 17841 if (type->subtypes == NULL) { 17842 /* 17843 * This one is really needed, so get out. 17844 */ 17845 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17846 "list type has no item-type assigned"); 17847 return(-1); 17848 } 17849 } else if (WXS_IS_UNION(type)) { 17850 /* 17851 * Corresponds to <simpleType><union>... 17852 */ 17853 if (type->memberTypes == NULL) { 17854 /* 17855 * This one is really needed, so get out. 17856 */ 17857 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17858 "union type has no member-types assigned"); 17859 return(-1); 17860 } 17861 } else { 17862 /* 17863 * Corresponds to <simpleType><restriction>... 17864 */ 17865 if (type->baseType == NULL) { 17866 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17867 "type has no base-type assigned"); 17868 return(-1); 17869 } 17870 if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType)) 17871 if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1) 17872 return(-1); 17873 /* 17874 * Variety 17875 * If the <restriction> alternative is chosen, then the 17876 * {variety} of the {base type definition}. 17877 */ 17878 if (WXS_IS_ATOMIC(type->baseType)) 17879 type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC; 17880 else if (WXS_IS_LIST(type->baseType)) { 17881 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 17882 /* 17883 * Inherit the itemType. 17884 */ 17885 type->subtypes = type->baseType->subtypes; 17886 } else if (WXS_IS_UNION(type->baseType)) { 17887 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 17888 /* 17889 * NOTE that we won't assign the memberTypes of the base, 17890 * since this will make trouble when freeing them; we will 17891 * use a lookup function to access them instead. 17892 */ 17893 } 17894 } 17895 return(0); 17896 } 17897 17898 #ifdef DEBUG_TYPE 17899 static void 17900 xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt, 17901 xmlSchemaTypePtr type) 17902 { 17903 if (type->node != NULL) { 17904 xmlGenericError(xmlGenericErrorContext, 17905 "Type of %s : %s:%d :", name, 17906 type->node->doc->URL, 17907 xmlGetLineNo(type->node)); 17908 } else { 17909 xmlGenericError(xmlGenericErrorContext, "Type of %s :", name); 17910 } 17911 if ((WXS_IS_SIMPLE(type)) ||