Annotation of embedaddon/libxml2/xmlschemas.c, revision 1.1
1.1 ! misho 1: /*
! 2: * schemas.c : implementation of the XML Schema handling and
! 3: * schema validity checking
! 4: *
! 5: * See Copyright for the status of this software.
! 6: *
! 7: * Daniel Veillard <veillard@redhat.com>
! 8: */
! 9:
! 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 if (lastNs != NULL)
! 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: if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
! 10347: /*
! 10348: * We included/redefined and then try to import a schema,
! 10349: * but the new location provided for import was different.
! 10350: */
! 10351: if (schemaLocation == NULL)
! 10352: schemaLocation = BAD_CAST "in_memory_buffer";
! 10353: if (!xmlStrEqual(schemaLocation,
! 10354: bkt->schemaLocation)) {
! 10355: xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
! 10356: invokingNode, NULL,
! 10357: "The schema document '%s' cannot be imported, since "
! 10358: "it was already included or redefined",
! 10359: schemaLocation, NULL);
! 10360: goto exit;
! 10361: }
! 10362: } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
! 10363: /*
! 10364: * We imported and then try to include/redefine a schema,
! 10365: * but the new location provided for the include/redefine
! 10366: * was different.
! 10367: */
! 10368: if (schemaLocation == NULL)
! 10369: schemaLocation = BAD_CAST "in_memory_buffer";
! 10370: if (!xmlStrEqual(schemaLocation,
! 10371: bkt->schemaLocation)) {
! 10372: xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
! 10373: invokingNode, NULL,
! 10374: "The schema document '%s' cannot be included or "
! 10375: "redefined, since it was already imported",
! 10376: schemaLocation, NULL);
! 10377: goto exit;
! 10378: }
! 10379: }
! 10380: }
! 10381:
! 10382: if (WXS_IS_BUCKET_IMPMAIN(type)) {
! 10383: /*
! 10384: * Given that the schemaLocation [attribute] is only a hint, it is open
! 10385: * to applications to ignore all but the first <import> for a given
! 10386: * namespace, regardless of the �actual value� of schemaLocation, but
! 10387: * such a strategy risks missing useful information when new
! 10388: * schemaLocations are offered.
! 10389: *
! 10390: * We will use the first <import> that comes with a location.
! 10391: * Further <import>s *with* a location, will result in an error.
! 10392: * TODO: Better would be to just report a warning here, but
! 10393: * we'll try it this way until someone complains.
! 10394: *
! 10395: * Schema Document Location Strategy:
! 10396: * 3 Based on the namespace name, identify an existing schema document,
! 10397: * either as a resource which is an XML document or a <schema> element
! 10398: * information item, in some local schema repository;
! 10399: * 5 Attempt to resolve the namespace name to locate such a resource.
! 10400: *
! 10401: * NOTE: (3) and (5) are not supported.
! 10402: */
! 10403: if (bkt != NULL) {
! 10404: relation->bucket = bkt;
! 10405: goto exit;
! 10406: }
! 10407: bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
! 10408: importNamespace, 1);
! 10409:
! 10410: if (bkt != NULL) {
! 10411: relation->bucket = bkt;
! 10412: if (bkt->schemaLocation == NULL) {
! 10413: /* First given location of the schema; load the doc. */
! 10414: bkt->schemaLocation = schemaLocation;
! 10415: } else {
! 10416: if (!xmlStrEqual(schemaLocation,
! 10417: bkt->schemaLocation)) {
! 10418: /*
! 10419: * Additional location given; just skip it.
! 10420: * URGENT TODO: We should report a warning here.
! 10421: * res = XML_SCHEMAP_SRC_IMPORT;
! 10422: */
! 10423: if (schemaLocation == NULL)
! 10424: schemaLocation = BAD_CAST "in_memory_buffer";
! 10425:
! 10426: xmlSchemaCustomWarning(ACTXT_CAST pctxt,
! 10427: XML_SCHEMAP_WARN_SKIP_SCHEMA,
! 10428: invokingNode, NULL,
! 10429: "Skipping import of schema located at '%s' for the "
! 10430: "namespace '%s', since this namespace was already "
! 10431: "imported with the schema located at '%s'",
! 10432: schemaLocation, importNamespace, bkt->schemaLocation);
! 10433: }
! 10434: goto exit;
! 10435: }
! 10436: }
! 10437: /*
! 10438: * No bucket + first location: load the doc and create a
! 10439: * bucket.
! 10440: */
! 10441: } else {
! 10442: /* <include> and <redefine> */
! 10443: if (bkt != NULL) {
! 10444:
! 10445: if ((bkt->origTargetNamespace == NULL) &&
! 10446: (bkt->targetNamespace != sourceTargetNamespace)) {
! 10447: xmlSchemaBucketPtr chamel;
! 10448:
! 10449: /*
! 10450: * Chameleon include/redefine: skip loading only if it was
! 10451: * aleady build for the targetNamespace of the including
! 10452: * schema.
! 10453: */
! 10454: /*
! 10455: * URGENT TODO: If the schema is a chameleon-include then copy
! 10456: * the components into the including schema and modify the
! 10457: * targetNamespace of those components, do nothing otherwise.
! 10458: * NOTE: This is currently worked-around by compiling the
! 10459: * chameleon for every destinct including targetNamespace; thus
! 10460: * not performant at the moment.
! 10461: * TODO: Check when the namespace in wildcards for chameleons
! 10462: * needs to be converted: before we built wildcard intersections
! 10463: * or after.
! 10464: * Answer: after!
! 10465: */
! 10466: chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
! 10467: schemaLocation, sourceTargetNamespace);
! 10468: if (chamel != NULL) {
! 10469: /* A fitting chameleon was already parsed; NOP. */
! 10470: relation->bucket = chamel;
! 10471: goto exit;
! 10472: }
! 10473: /*
! 10474: * We need to parse the chameleon again for a different
! 10475: * targetNamespace.
! 10476: * CHAMELEON TODO: Optimize this by only parsing the
! 10477: * chameleon once, and then copying the components to
! 10478: * the new targetNamespace.
! 10479: */
! 10480: bkt = NULL;
! 10481: } else {
! 10482: relation->bucket = bkt;
! 10483: goto exit;
! 10484: }
! 10485: }
! 10486: }
! 10487: if ((bkt != NULL) && (bkt->doc != NULL)) {
! 10488: PERROR_INT("xmlSchemaAddSchemaDoc",
! 10489: "trying to load a schema doc, but a doc is already "
! 10490: "assigned to the schema bucket");
! 10491: goto exit_failure;
! 10492: }
! 10493:
! 10494: doc_load:
! 10495: /*
! 10496: * Load the document.
! 10497: */
! 10498: if (schemaDoc != NULL) {
! 10499: doc = schemaDoc;
! 10500: /* Don' free this one, since it was provided by the caller. */
! 10501: preserveDoc = 1;
! 10502: /* TODO: Does the context or the doc hold the location? */
! 10503: if (schemaDoc->URL != NULL)
! 10504: schemaLocation = xmlDictLookup(pctxt->dict,
! 10505: schemaDoc->URL, -1);
! 10506: else
! 10507: schemaLocation = BAD_CAST "in_memory_buffer";
! 10508: } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
! 10509: xmlParserCtxtPtr parserCtxt;
! 10510:
! 10511: parserCtxt = xmlNewParserCtxt();
! 10512: if (parserCtxt == NULL) {
! 10513: xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
! 10514: "allocating a parser context", NULL);
! 10515: goto exit_failure;
! 10516: }
! 10517: if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
! 10518: /*
! 10519: * TODO: Do we have to burden the schema parser dict with all
! 10520: * the content of the schema doc?
! 10521: */
! 10522: xmlDictFree(parserCtxt->dict);
! 10523: parserCtxt->dict = pctxt->dict;
! 10524: xmlDictReference(parserCtxt->dict);
! 10525: }
! 10526: if (schemaLocation != NULL) {
! 10527: /* Parse from file. */
! 10528: doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
! 10529: NULL, SCHEMAS_PARSE_OPTIONS);
! 10530: } else if (schemaBuffer != NULL) {
! 10531: /* Parse from memory buffer. */
! 10532: doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
! 10533: NULL, NULL, SCHEMAS_PARSE_OPTIONS);
! 10534: schemaLocation = BAD_CAST "in_memory_buffer";
! 10535: if (doc != NULL)
! 10536: doc->URL = xmlStrdup(schemaLocation);
! 10537: }
! 10538: /*
! 10539: * For <import>:
! 10540: * 2.1 The referent is (a fragment of) a resource which is an
! 10541: * XML document (see clause 1.1), which in turn corresponds to
! 10542: * a <schema> element information item in a well-formed information
! 10543: * set, which in turn corresponds to a valid schema.
! 10544: * TODO: (2.1) fragments of XML documents are not supported.
! 10545: *
! 10546: * 2.2 The referent is a <schema> element information item in
! 10547: * a well-formed information set, which in turn corresponds
! 10548: * to a valid schema.
! 10549: * TODO: (2.2) is not supported.
! 10550: */
! 10551: if (doc == NULL) {
! 10552: xmlErrorPtr lerr;
! 10553: lerr = xmlGetLastError();
! 10554: /*
! 10555: * Check if this a parser error, or if the document could
! 10556: * just not be located.
! 10557: * TODO: Try to find specific error codes to react only on
! 10558: * localisation failures.
! 10559: */
! 10560: if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
! 10561: /*
! 10562: * We assume a parser error here.
! 10563: */
! 10564: located = 1;
! 10565: /* TODO: Error code ?? */
! 10566: res = XML_SCHEMAP_SRC_IMPORT_2_1;
! 10567: xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
! 10568: invokingNode, NULL,
! 10569: "Failed to parse the XML resource '%s'",
! 10570: schemaLocation, NULL);
! 10571: }
! 10572: }
! 10573: xmlFreeParserCtxt(parserCtxt);
! 10574: if ((doc == NULL) && located)
! 10575: goto exit_error;
! 10576: } else {
! 10577: xmlSchemaPErr(pctxt, NULL,
! 10578: XML_SCHEMAP_NOTHING_TO_PARSE,
! 10579: "No information for parsing was provided with the "
! 10580: "given schema parser context.\n",
! 10581: NULL, NULL);
! 10582: goto exit_failure;
! 10583: }
! 10584: /*
! 10585: * Preprocess the document.
! 10586: */
! 10587: if (doc != NULL) {
! 10588: xmlNodePtr docElem = NULL;
! 10589:
! 10590: located = 1;
! 10591: docElem = xmlDocGetRootElement(doc);
! 10592: if (docElem == NULL) {
! 10593: xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
! 10594: invokingNode, NULL,
! 10595: "The document '%s' has no document element",
! 10596: schemaLocation, NULL);
! 10597: goto exit_error;
! 10598: }
! 10599: /*
! 10600: * Remove all the blank text nodes.
! 10601: */
! 10602: xmlSchemaCleanupDoc(pctxt, docElem);
! 10603: /*
! 10604: * Check the schema's top level element.
! 10605: */
! 10606: if (!IS_SCHEMA(docElem, "schema")) {
! 10607: xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
! 10608: invokingNode, NULL,
! 10609: "The XML document '%s' is not a schema document",
! 10610: schemaLocation, NULL);
! 10611: goto exit_error;
! 10612: }
! 10613: /*
! 10614: * Note that we don't apply a type check for the
! 10615: * targetNamespace value here.
! 10616: */
! 10617: targetNamespace = xmlSchemaGetProp(pctxt, docElem,
! 10618: "targetNamespace");
! 10619: }
! 10620:
! 10621: /* after_doc_loading: */
! 10622: if ((bkt == NULL) && located) {
! 10623: /* Only create a bucket if the schema was located. */
! 10624: bkt = xmlSchemaBucketCreate(pctxt, type,
! 10625: targetNamespace);
! 10626: if (bkt == NULL)
! 10627: goto exit_failure;
! 10628: }
! 10629: if (bkt != NULL) {
! 10630: bkt->schemaLocation = schemaLocation;
! 10631: bkt->located = located;
! 10632: if (doc != NULL) {
! 10633: bkt->doc = doc;
! 10634: bkt->targetNamespace = targetNamespace;
! 10635: bkt->origTargetNamespace = targetNamespace;
! 10636: if (preserveDoc)
! 10637: bkt->preserveDoc = 1;
! 10638: }
! 10639: if (WXS_IS_BUCKET_IMPMAIN(type))
! 10640: bkt->imported++;
! 10641: /*
! 10642: * Add it to the graph of schemas.
! 10643: */
! 10644: if (relation != NULL)
! 10645: relation->bucket = bkt;
! 10646: }
! 10647:
! 10648: exit:
! 10649: /*
! 10650: * Return the bucket explicitely; this is needed for the
! 10651: * main schema.
! 10652: */
! 10653: if (bucket != NULL)
! 10654: *bucket = bkt;
! 10655: return (0);
! 10656:
! 10657: exit_error:
! 10658: if ((doc != NULL) && (! preserveDoc)) {
! 10659: xmlFreeDoc(doc);
! 10660: if (bkt != NULL)
! 10661: bkt->doc = NULL;
! 10662: }
! 10663: return(pctxt->err);
! 10664:
! 10665: exit_failure:
! 10666: if ((doc != NULL) && (! preserveDoc)) {
! 10667: xmlFreeDoc(doc);
! 10668: if (bkt != NULL)
! 10669: bkt->doc = NULL;
! 10670: }
! 10671: return (-1);
! 10672: }
! 10673:
! 10674: /**
! 10675: * xmlSchemaParseImport:
! 10676: * @ctxt: a schema validation context
! 10677: * @schema: the schema being built
! 10678: * @node: a subtree containing XML Schema informations
! 10679: *
! 10680: * parse a XML schema Import definition
! 10681: * *WARNING* this interface is highly subject to change
! 10682: *
! 10683: * Returns 0 in case of success, a positive error code if
! 10684: * not valid and -1 in case of an internal error.
! 10685: */
! 10686: static int
! 10687: xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
! 10688: xmlNodePtr node)
! 10689: {
! 10690: xmlNodePtr child;
! 10691: const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
! 10692: const xmlChar *thisTargetNamespace;
! 10693: xmlAttrPtr attr;
! 10694: int ret = 0;
! 10695: xmlSchemaBucketPtr bucket = NULL;
! 10696:
! 10697: if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
! 10698: return (-1);
! 10699:
! 10700: /*
! 10701: * Check for illegal attributes.
! 10702: */
! 10703: attr = node->properties;
! 10704: while (attr != NULL) {
! 10705: if (attr->ns == NULL) {
! 10706: if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
! 10707: (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
! 10708: (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
! 10709: xmlSchemaPIllegalAttrErr(pctxt,
! 10710: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 10711: }
! 10712: } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
! 10713: xmlSchemaPIllegalAttrErr(pctxt,
! 10714: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 10715: }
! 10716: attr = attr->next;
! 10717: }
! 10718: /*
! 10719: * Extract and validate attributes.
! 10720: */
! 10721: if (xmlSchemaPValAttr(pctxt, NULL, node,
! 10722: "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
! 10723: &namespaceName) != 0) {
! 10724: xmlSchemaPSimpleTypeErr(pctxt,
! 10725: XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
! 10726: NULL, node,
! 10727: xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
! 10728: NULL, namespaceName, NULL, NULL, NULL);
! 10729: return (pctxt->err);
! 10730: }
! 10731:
! 10732: if (xmlSchemaPValAttr(pctxt, NULL, node,
! 10733: "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
! 10734: &schemaLocation) != 0) {
! 10735: xmlSchemaPSimpleTypeErr(pctxt,
! 10736: XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
! 10737: NULL, node,
! 10738: xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
! 10739: NULL, namespaceName, NULL, NULL, NULL);
! 10740: return (pctxt->err);
! 10741: }
! 10742: /*
! 10743: * And now for the children...
! 10744: */
! 10745: child = node->children;
! 10746: if (IS_SCHEMA(child, "annotation")) {
! 10747: /*
! 10748: * the annotation here is simply discarded ...
! 10749: * TODO: really?
! 10750: */
! 10751: child = child->next;
! 10752: }
! 10753: if (child != NULL) {
! 10754: xmlSchemaPContentErr(pctxt,
! 10755: XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
! 10756: NULL, node, child, NULL,
! 10757: "(annotation?)");
! 10758: }
! 10759: /*
! 10760: * Apply additional constraints.
! 10761: *
! 10762: * Note that it is important to use the original @targetNamespace
! 10763: * (or none at all), to rule out imports of schemas _with_ a
! 10764: * @targetNamespace if the importing schema is a chameleon schema
! 10765: * (with no @targetNamespace).
! 10766: */
! 10767: thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
! 10768: if (namespaceName != NULL) {
! 10769: /*
! 10770: * 1.1 If the namespace [attribute] is present, then its �actual value�
! 10771: * must not match the �actual value� of the enclosing <schema>'s
! 10772: * targetNamespace [attribute].
! 10773: */
! 10774: if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
! 10775: xmlSchemaPCustomErr(pctxt,
! 10776: XML_SCHEMAP_SRC_IMPORT_1_1,
! 10777: NULL, node,
! 10778: "The value of the attribute 'namespace' must not match "
! 10779: "the target namespace '%s' of the importing schema",
! 10780: thisTargetNamespace);
! 10781: return (pctxt->err);
! 10782: }
! 10783: } else {
! 10784: /*
! 10785: * 1.2 If the namespace [attribute] is not present, then the enclosing
! 10786: * <schema> must have a targetNamespace [attribute].
! 10787: */
! 10788: if (thisTargetNamespace == NULL) {
! 10789: xmlSchemaPCustomErr(pctxt,
! 10790: XML_SCHEMAP_SRC_IMPORT_1_2,
! 10791: NULL, node,
! 10792: "The attribute 'namespace' must be existent if "
! 10793: "the importing schema has no target namespace",
! 10794: NULL);
! 10795: return (pctxt->err);
! 10796: }
! 10797: }
! 10798: /*
! 10799: * Locate and acquire the schema document.
! 10800: */
! 10801: if (schemaLocation != NULL)
! 10802: schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
! 10803: schemaLocation, node);
! 10804: ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
! 10805: schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
! 10806: namespaceName, &bucket);
! 10807:
! 10808: if (ret != 0)
! 10809: return(ret);
! 10810:
! 10811: /*
! 10812: * For <import>: "It is *not* an error for the application
! 10813: * schema reference strategy to fail."
! 10814: * So just don't parse if no schema document was found.
! 10815: * Note that we will get no bucket if the schema could not be
! 10816: * located or if there was no schemaLocation.
! 10817: */
! 10818: if ((bucket == NULL) && (schemaLocation != NULL)) {
! 10819: xmlSchemaCustomWarning(ACTXT_CAST pctxt,
! 10820: XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
! 10821: node, NULL,
! 10822: "Failed to locate a schema at location '%s'. "
! 10823: "Skipping the import", schemaLocation, NULL, NULL);
! 10824: }
! 10825:
! 10826: if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
! 10827: ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
! 10828: }
! 10829:
! 10830: return (ret);
! 10831: }
! 10832:
! 10833: static int
! 10834: xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
! 10835: xmlSchemaPtr schema,
! 10836: xmlNodePtr node,
! 10837: xmlChar **schemaLocation,
! 10838: int type)
! 10839: {
! 10840: xmlAttrPtr attr;
! 10841:
! 10842: if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
! 10843: (schemaLocation == NULL))
! 10844: return (-1);
! 10845:
! 10846: *schemaLocation = NULL;
! 10847: /*
! 10848: * Check for illegal attributes.
! 10849: * Applies for both <include> and <redefine>.
! 10850: */
! 10851: attr = node->properties;
! 10852: while (attr != NULL) {
! 10853: if (attr->ns == NULL) {
! 10854: if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
! 10855: (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
! 10856: xmlSchemaPIllegalAttrErr(pctxt,
! 10857: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 10858: }
! 10859: } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
! 10860: xmlSchemaPIllegalAttrErr(pctxt,
! 10861: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 10862: }
! 10863: attr = attr->next;
! 10864: }
! 10865: xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
! 10866: /*
! 10867: * Preliminary step, extract the URI-Reference and make an URI
! 10868: * from the base.
! 10869: */
! 10870: /*
! 10871: * Attribute "schemaLocation" is mandatory.
! 10872: */
! 10873: attr = xmlSchemaGetPropNode(node, "schemaLocation");
! 10874: if (attr != NULL) {
! 10875: xmlChar *base = NULL;
! 10876: xmlChar *uri = NULL;
! 10877:
! 10878: if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
! 10879: xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
! 10880: (const xmlChar **) schemaLocation) != 0)
! 10881: goto exit_error;
! 10882: base = xmlNodeGetBase(node->doc, node);
! 10883: if (base == NULL) {
! 10884: uri = xmlBuildURI(*schemaLocation, node->doc->URL);
! 10885: } else {
! 10886: uri = xmlBuildURI(*schemaLocation, base);
! 10887: xmlFree(base);
! 10888: }
! 10889: if (uri == NULL) {
! 10890: PERROR_INT("xmlSchemaParseIncludeOrRedefine",
! 10891: "could not build an URI from the schemaLocation")
! 10892: goto exit_failure;
! 10893: }
! 10894: (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
! 10895: xmlFree(uri);
! 10896: } else {
! 10897: xmlSchemaPMissingAttrErr(pctxt,
! 10898: XML_SCHEMAP_S4S_ATTR_MISSING,
! 10899: NULL, node, "schemaLocation", NULL);
! 10900: goto exit_error;
! 10901: }
! 10902: /*
! 10903: * Report self-inclusion and self-redefinition.
! 10904: */
! 10905: if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
! 10906: if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
! 10907: xmlSchemaPCustomErr(pctxt,
! 10908: XML_SCHEMAP_SRC_REDEFINE,
! 10909: NULL, node,
! 10910: "The schema document '%s' cannot redefine itself.",
! 10911: *schemaLocation);
! 10912: } else {
! 10913: xmlSchemaPCustomErr(pctxt,
! 10914: XML_SCHEMAP_SRC_INCLUDE,
! 10915: NULL, node,
! 10916: "The schema document '%s' cannot include itself.",
! 10917: *schemaLocation);
! 10918: }
! 10919: goto exit_error;
! 10920: }
! 10921:
! 10922: return(0);
! 10923: exit_error:
! 10924: return(pctxt->err);
! 10925: exit_failure:
! 10926: return(-1);
! 10927: }
! 10928:
! 10929: static int
! 10930: xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
! 10931: xmlSchemaPtr schema,
! 10932: xmlNodePtr node,
! 10933: int type)
! 10934: {
! 10935: xmlNodePtr child = NULL;
! 10936: const xmlChar *schemaLocation = NULL;
! 10937: int res = 0; /* hasRedefinitions = 0 */
! 10938: int isChameleon = 0, wasChameleon = 0;
! 10939: xmlSchemaBucketPtr bucket = NULL;
! 10940:
! 10941: if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
! 10942: return (-1);
! 10943:
! 10944: /*
! 10945: * Parse attributes. Note that the returned schemaLocation will
! 10946: * be already converted to an absolute URI.
! 10947: */
! 10948: res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
! 10949: node, (xmlChar **) (&schemaLocation), type);
! 10950: if (res != 0)
! 10951: return(res);
! 10952: /*
! 10953: * Load and add the schema document.
! 10954: */
! 10955: res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
! 10956: NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
! 10957: if (res != 0)
! 10958: return(res);
! 10959: /*
! 10960: * If we get no schema bucket back, then this means that the schema
! 10961: * document could not be located or was broken XML or was not
! 10962: * a schema document.
! 10963: */
! 10964: if ((bucket == NULL) || (bucket->doc == NULL)) {
! 10965: if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
! 10966: /*
! 10967: * WARNING for <include>:
! 10968: * We will raise an error if the schema cannot be located
! 10969: * for inclusions, since the that was the feedback from the
! 10970: * schema people. I.e. the following spec piece will *not* be
! 10971: * satisfied:
! 10972: * SPEC src-include: "It is not an error for the �actual value� of the
! 10973: * schemaLocation [attribute] to fail to resolve it all, in which
! 10974: * case no corresponding inclusion is performed.
! 10975: * So do we need a warning report here?"
! 10976: */
! 10977: res = XML_SCHEMAP_SRC_INCLUDE;
! 10978: xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
! 10979: node, NULL,
! 10980: "Failed to load the document '%s' for inclusion",
! 10981: schemaLocation, NULL);
! 10982: } else {
! 10983: /*
! 10984: * NOTE: This was changed to raise an error even if no redefinitions
! 10985: * are specified.
! 10986: *
! 10987: * SPEC src-redefine (1)
! 10988: * "If there are any element information items among the [children]
! 10989: * other than <annotation> then the �actual value� of the
! 10990: * schemaLocation [attribute] must successfully resolve."
! 10991: * TODO: Ask the WG if a the location has always to resolve
! 10992: * here as well!
! 10993: */
! 10994: res = XML_SCHEMAP_SRC_REDEFINE;
! 10995: xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
! 10996: node, NULL,
! 10997: "Failed to load the document '%s' for redefinition",
! 10998: schemaLocation, NULL);
! 10999: }
! 11000: } else {
! 11001: /*
! 11002: * Check targetNamespace sanity before parsing the new schema.
! 11003: * TODO: Note that we won't check further content if the
! 11004: * targetNamespace was bad.
! 11005: */
! 11006: if (bucket->origTargetNamespace != NULL) {
! 11007: /*
! 11008: * SPEC src-include (2.1)
! 11009: * "SII has a targetNamespace [attribute], and its �actual
! 11010: * value� is identical to the �actual value� of the targetNamespace
! 11011: * [attribute] of SII� (which must have such an [attribute])."
! 11012: */
! 11013: if (pctxt->targetNamespace == NULL) {
! 11014: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 11015: XML_SCHEMAP_SRC_INCLUDE,
! 11016: node, NULL,
! 11017: "The target namespace of the included/redefined schema "
! 11018: "'%s' has to be absent, since the including/redefining "
! 11019: "schema has no target namespace",
! 11020: schemaLocation, NULL);
! 11021: goto exit_error;
! 11022: } else if (!xmlStrEqual(bucket->origTargetNamespace,
! 11023: pctxt->targetNamespace)) {
! 11024: /* TODO: Change error function. */
! 11025: xmlSchemaPCustomErrExt(pctxt,
! 11026: XML_SCHEMAP_SRC_INCLUDE,
! 11027: NULL, node,
! 11028: "The target namespace '%s' of the included/redefined "
! 11029: "schema '%s' differs from '%s' of the "
! 11030: "including/redefining schema",
! 11031: bucket->origTargetNamespace, schemaLocation,
! 11032: pctxt->targetNamespace);
! 11033: goto exit_error;
! 11034: }
! 11035: } else if (pctxt->targetNamespace != NULL) {
! 11036: /*
! 11037: * Chameleons: the original target namespace will
! 11038: * differ from the resulting namespace.
! 11039: */
! 11040: isChameleon = 1;
! 11041: if (bucket->parsed &&
! 11042: bucket->origTargetNamespace != NULL) {
! 11043: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 11044: XML_SCHEMAP_SRC_INCLUDE,
! 11045: node, NULL,
! 11046: "The target namespace of the included/redefined schema "
! 11047: "'%s' has to be absent or the same as the "
! 11048: "including/redefining schema's target namespace",
! 11049: schemaLocation, NULL);
! 11050: goto exit_error;
! 11051: }
! 11052: bucket->targetNamespace = pctxt->targetNamespace;
! 11053: }
! 11054: }
! 11055: /*
! 11056: * Parse the schema.
! 11057: */
! 11058: if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
! 11059: if (isChameleon) {
! 11060: /* TODO: Get rid of this flag on the schema itself. */
! 11061: if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
! 11062: schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
! 11063: } else
! 11064: wasChameleon = 1;
! 11065: }
! 11066: xmlSchemaParseNewDoc(pctxt, schema, bucket);
! 11067: /* Restore chameleon flag. */
! 11068: if (isChameleon && (!wasChameleon))
! 11069: schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
! 11070: }
! 11071: /*
! 11072: * And now for the children...
! 11073: */
! 11074: child = node->children;
! 11075: if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
! 11076: /*
! 11077: * Parse (simpleType | complexType | group | attributeGroup))*
! 11078: */
! 11079: pctxt->redefined = bucket;
! 11080: /*
! 11081: * How to proceed if the redefined schema was not located?
! 11082: */
! 11083: pctxt->isRedefine = 1;
! 11084: while (IS_SCHEMA(child, "annotation") ||
! 11085: IS_SCHEMA(child, "simpleType") ||
! 11086: IS_SCHEMA(child, "complexType") ||
! 11087: IS_SCHEMA(child, "group") ||
! 11088: IS_SCHEMA(child, "attributeGroup")) {
! 11089: if (IS_SCHEMA(child, "annotation")) {
! 11090: /*
! 11091: * TODO: discard or not?
! 11092: */
! 11093: } else if (IS_SCHEMA(child, "simpleType")) {
! 11094: xmlSchemaParseSimpleType(pctxt, schema, child, 1);
! 11095: } else if (IS_SCHEMA(child, "complexType")) {
! 11096: xmlSchemaParseComplexType(pctxt, schema, child, 1);
! 11097: /* hasRedefinitions = 1; */
! 11098: } else if (IS_SCHEMA(child, "group")) {
! 11099: /* hasRedefinitions = 1; */
! 11100: xmlSchemaParseModelGroupDefinition(pctxt,
! 11101: schema, child);
! 11102: } else if (IS_SCHEMA(child, "attributeGroup")) {
! 11103: /* hasRedefinitions = 1; */
! 11104: xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
! 11105: child);
! 11106: }
! 11107: child = child->next;
! 11108: }
! 11109: pctxt->redefined = NULL;
! 11110: pctxt->isRedefine = 0;
! 11111: } else {
! 11112: if (IS_SCHEMA(child, "annotation")) {
! 11113: /*
! 11114: * TODO: discard or not?
! 11115: */
! 11116: child = child->next;
! 11117: }
! 11118: }
! 11119: if (child != NULL) {
! 11120: res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
! 11121: if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
! 11122: xmlSchemaPContentErr(pctxt, res,
! 11123: NULL, node, child, NULL,
! 11124: "(annotation | (simpleType | complexType | group | attributeGroup))*");
! 11125: } else {
! 11126: xmlSchemaPContentErr(pctxt, res,
! 11127: NULL, node, child, NULL,
! 11128: "(annotation?)");
! 11129: }
! 11130: }
! 11131: return(res);
! 11132:
! 11133: exit_error:
! 11134: return(pctxt->err);
! 11135: }
! 11136:
! 11137: static int
! 11138: xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
! 11139: xmlNodePtr node)
! 11140: {
! 11141: int res;
! 11142: #ifndef ENABLE_REDEFINE
! 11143: TODO
! 11144: return(0);
! 11145: #endif
! 11146: res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
! 11147: XML_SCHEMA_SCHEMA_REDEFINE);
! 11148: if (res != 0)
! 11149: return(res);
! 11150: return(0);
! 11151: }
! 11152:
! 11153: static int
! 11154: xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
! 11155: xmlNodePtr node)
! 11156: {
! 11157: int res;
! 11158:
! 11159: res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
! 11160: XML_SCHEMA_SCHEMA_INCLUDE);
! 11161: if (res != 0)
! 11162: return(res);
! 11163: return(0);
! 11164: }
! 11165:
! 11166: /**
! 11167: * xmlSchemaParseModelGroup:
! 11168: * @ctxt: a schema validation context
! 11169: * @schema: the schema being built
! 11170: * @node: a subtree containing XML Schema informations
! 11171: * @type: the "compositor" type
! 11172: * @particleNeeded: if a a model group with a particle
! 11173: *
! 11174: * parse a XML schema Sequence definition.
! 11175: * Applies parts of:
! 11176: * Schema Representation Constraint:
! 11177: * Redefinition Constraints and Semantics (src-redefine)
! 11178: * (6.1), (6.1.1), (6.1.2)
! 11179: *
! 11180: * Schema Component Constraint:
! 11181: * All Group Limited (cos-all-limited) (2)
! 11182: * TODO: Actually this should go to component-level checks,
! 11183: * but is done here due to performance. Move it to an other layer
! 11184: * is schema construction via an API is implemented.
! 11185: *
! 11186: * *WARNING* this interface is highly subject to change
! 11187: *
! 11188: * Returns -1 in case of error, 0 if the declaration is improper and
! 11189: * 1 in case of success.
! 11190: */
! 11191: static xmlSchemaTreeItemPtr
! 11192: xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
! 11193: xmlNodePtr node, xmlSchemaTypeType type,
! 11194: int withParticle)
! 11195: {
! 11196: xmlSchemaModelGroupPtr item;
! 11197: xmlSchemaParticlePtr particle = NULL;
! 11198: xmlNodePtr child = NULL;
! 11199: xmlAttrPtr attr;
! 11200: int min = 1, max = 1, isElemRef, hasRefs = 0;
! 11201:
! 11202: if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
! 11203: return (NULL);
! 11204: /*
! 11205: * Create a model group with the given compositor.
! 11206: */
! 11207: item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
! 11208: if (item == NULL)
! 11209: return (NULL);
! 11210:
! 11211: if (withParticle) {
! 11212: if (type == XML_SCHEMA_TYPE_ALL) {
! 11213: min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
! 11214: max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
! 11215: } else {
! 11216: /* choice + sequence */
! 11217: min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
! 11218: max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
! 11219: "(xs:nonNegativeInteger | unbounded)");
! 11220: }
! 11221: xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
! 11222: /*
! 11223: * Create a particle
! 11224: */
! 11225: particle = xmlSchemaAddParticle(ctxt, node, min, max);
! 11226: if (particle == NULL)
! 11227: return (NULL);
! 11228: particle->children = (xmlSchemaTreeItemPtr) item;
! 11229: /*
! 11230: * Check for illegal attributes.
! 11231: */
! 11232: attr = node->properties;
! 11233: while (attr != NULL) {
! 11234: if (attr->ns == NULL) {
! 11235: if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
! 11236: (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
! 11237: (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
! 11238: xmlSchemaPIllegalAttrErr(ctxt,
! 11239: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 11240: }
! 11241: } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
! 11242: xmlSchemaPIllegalAttrErr(ctxt,
! 11243: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 11244: }
! 11245: attr = attr->next;
! 11246: }
! 11247: } else {
! 11248: /*
! 11249: * Check for illegal attributes.
! 11250: */
! 11251: attr = node->properties;
! 11252: while (attr != NULL) {
! 11253: if (attr->ns == NULL) {
! 11254: if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
! 11255: xmlSchemaPIllegalAttrErr(ctxt,
! 11256: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 11257: }
! 11258: } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
! 11259: xmlSchemaPIllegalAttrErr(ctxt,
! 11260: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 11261: }
! 11262: attr = attr->next;
! 11263: }
! 11264: }
! 11265:
! 11266: /*
! 11267: * Extract and validate attributes.
! 11268: */
! 11269: xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
! 11270: /*
! 11271: * And now for the children...
! 11272: */
! 11273: child = node->children;
! 11274: if (IS_SCHEMA(child, "annotation")) {
! 11275: item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
! 11276: child = child->next;
! 11277: }
! 11278: if (type == XML_SCHEMA_TYPE_ALL) {
! 11279: xmlSchemaParticlePtr part, last = NULL;
! 11280:
! 11281: while (IS_SCHEMA(child, "element")) {
! 11282: part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
! 11283: schema, child, &isElemRef, 0);
! 11284: /*
! 11285: * SPEC cos-all-limited (2)
! 11286: * "The {max occurs} of all the particles in the {particles}
! 11287: * of the ('all') group must be 0 or 1.
! 11288: */
! 11289: if (part != NULL) {
! 11290: if (isElemRef)
! 11291: hasRefs++;
! 11292: if (part->minOccurs > 1) {
! 11293: xmlSchemaPCustomErr(ctxt,
! 11294: XML_SCHEMAP_COS_ALL_LIMITED,
! 11295: NULL, child,
! 11296: "Invalid value for minOccurs (must be 0 or 1)",
! 11297: NULL);
! 11298: /* Reset to 1. */
! 11299: part->minOccurs = 1;
! 11300: }
! 11301: if (part->maxOccurs > 1) {
! 11302: xmlSchemaPCustomErr(ctxt,
! 11303: XML_SCHEMAP_COS_ALL_LIMITED,
! 11304: NULL, child,
! 11305: "Invalid value for maxOccurs (must be 0 or 1)",
! 11306: NULL);
! 11307: /* Reset to 1. */
! 11308: part->maxOccurs = 1;
! 11309: }
! 11310: if (last == NULL)
! 11311: item->children = (xmlSchemaTreeItemPtr) part;
! 11312: else
! 11313: last->next = (xmlSchemaTreeItemPtr) part;
! 11314: last = part;
! 11315: }
! 11316: child = child->next;
! 11317: }
! 11318: if (child != NULL) {
! 11319: xmlSchemaPContentErr(ctxt,
! 11320: XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
! 11321: NULL, node, child, NULL,
! 11322: "(annotation?, (annotation?, element*)");
! 11323: }
! 11324: } else {
! 11325: /* choice + sequence */
! 11326: xmlSchemaTreeItemPtr part = NULL, last = NULL;
! 11327:
! 11328: while ((IS_SCHEMA(child, "element")) ||
! 11329: (IS_SCHEMA(child, "group")) ||
! 11330: (IS_SCHEMA(child, "any")) ||
! 11331: (IS_SCHEMA(child, "choice")) ||
! 11332: (IS_SCHEMA(child, "sequence"))) {
! 11333:
! 11334: if (IS_SCHEMA(child, "element")) {
! 11335: part = (xmlSchemaTreeItemPtr)
! 11336: xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
! 11337: if (part && isElemRef)
! 11338: hasRefs++;
! 11339: } else if (IS_SCHEMA(child, "group")) {
! 11340: part =
! 11341: xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
! 11342: if (part != NULL)
! 11343: hasRefs++;
! 11344: /*
! 11345: * Handle redefinitions.
! 11346: */
! 11347: if (ctxt->isRedefine && ctxt->redef &&
! 11348: (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
! 11349: part && part->children)
! 11350: {
! 11351: if ((xmlSchemaGetQNameRefName(part->children) ==
! 11352: ctxt->redef->refName) &&
! 11353: (xmlSchemaGetQNameRefTargetNs(part->children) ==
! 11354: ctxt->redef->refTargetNs))
! 11355: {
! 11356: /*
! 11357: * SPEC src-redefine:
! 11358: * (6.1) "If it has a <group> among its contents at
! 11359: * some level the �actual value� of whose ref
! 11360: * [attribute] is the same as the �actual value� of
! 11361: * its own name attribute plus target namespace, then
! 11362: * all of the following must be true:"
! 11363: * (6.1.1) "It must have exactly one such group."
! 11364: */
! 11365: if (ctxt->redefCounter != 0) {
! 11366: xmlChar *str = NULL;
! 11367:
! 11368: xmlSchemaCustomErr(ACTXT_CAST ctxt,
! 11369: XML_SCHEMAP_SRC_REDEFINE, child, NULL,
! 11370: "The redefining model group definition "
! 11371: "'%s' must not contain more than one "
! 11372: "reference to the redefined definition",
! 11373: xmlSchemaFormatQName(&str,
! 11374: ctxt->redef->refTargetNs,
! 11375: ctxt->redef->refName),
! 11376: NULL);
! 11377: FREE_AND_NULL(str)
! 11378: part = NULL;
! 11379: } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
! 11380: ((WXS_PARTICLE(part))->maxOccurs != 1))
! 11381: {
! 11382: xmlChar *str = NULL;
! 11383: /*
! 11384: * SPEC src-redefine:
! 11385: * (6.1.2) "The �actual value� of both that
! 11386: * group's minOccurs and maxOccurs [attribute]
! 11387: * must be 1 (or �absent�).
! 11388: */
! 11389: xmlSchemaCustomErr(ACTXT_CAST ctxt,
! 11390: XML_SCHEMAP_SRC_REDEFINE, child, NULL,
! 11391: "The redefining model group definition "
! 11392: "'%s' must not contain a reference to the "
! 11393: "redefined definition with a "
! 11394: "maxOccurs/minOccurs other than 1",
! 11395: xmlSchemaFormatQName(&str,
! 11396: ctxt->redef->refTargetNs,
! 11397: ctxt->redef->refName),
! 11398: NULL);
! 11399: FREE_AND_NULL(str)
! 11400: part = NULL;
! 11401: }
! 11402: ctxt->redef->reference = WXS_BASIC_CAST part;
! 11403: ctxt->redefCounter++;
! 11404: }
! 11405: }
! 11406: } else if (IS_SCHEMA(child, "any")) {
! 11407: part = (xmlSchemaTreeItemPtr)
! 11408: xmlSchemaParseAny(ctxt, schema, child);
! 11409: } else if (IS_SCHEMA(child, "choice")) {
! 11410: part = xmlSchemaParseModelGroup(ctxt, schema, child,
! 11411: XML_SCHEMA_TYPE_CHOICE, 1);
! 11412: } else if (IS_SCHEMA(child, "sequence")) {
! 11413: part = xmlSchemaParseModelGroup(ctxt, schema, child,
! 11414: XML_SCHEMA_TYPE_SEQUENCE, 1);
! 11415: }
! 11416: if (part != NULL) {
! 11417: if (last == NULL)
! 11418: item->children = part;
! 11419: else
! 11420: last->next = part;
! 11421: last = part;
! 11422: }
! 11423: child = child->next;
! 11424: }
! 11425: if (child != NULL) {
! 11426: xmlSchemaPContentErr(ctxt,
! 11427: XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
! 11428: NULL, node, child, NULL,
! 11429: "(annotation?, (element | group | choice | sequence | any)*)");
! 11430: }
! 11431: }
! 11432: if ((max == 0) && (min == 0))
! 11433: return (NULL);
! 11434: if (hasRefs) {
! 11435: /*
! 11436: * We need to resolve references.
! 11437: */
! 11438: WXS_ADD_PENDING(ctxt, item);
! 11439: }
! 11440: if (withParticle)
! 11441: return ((xmlSchemaTreeItemPtr) particle);
! 11442: else
! 11443: return ((xmlSchemaTreeItemPtr) item);
! 11444: }
! 11445:
! 11446: /**
! 11447: * xmlSchemaParseRestriction:
! 11448: * @ctxt: a schema validation context
! 11449: * @schema: the schema being built
! 11450: * @node: a subtree containing XML Schema informations
! 11451: *
! 11452: * parse a XML schema Restriction definition
! 11453: * *WARNING* this interface is highly subject to change
! 11454: *
! 11455: * Returns the type definition or NULL in case of error
! 11456: */
! 11457: static xmlSchemaTypePtr
! 11458: xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
! 11459: xmlNodePtr node, xmlSchemaTypeType parentType)
! 11460: {
! 11461: xmlSchemaTypePtr type;
! 11462: xmlNodePtr child = NULL;
! 11463: xmlAttrPtr attr;
! 11464:
! 11465: if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
! 11466: return (NULL);
! 11467: /* Not a component, don't create it. */
! 11468: type = ctxt->ctxtType;
! 11469: type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
! 11470:
! 11471: /*
! 11472: * Check for illegal attributes.
! 11473: */
! 11474: attr = node->properties;
! 11475: while (attr != NULL) {
! 11476: if (attr->ns == NULL) {
! 11477: if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
! 11478: (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
! 11479: xmlSchemaPIllegalAttrErr(ctxt,
! 11480: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 11481: }
! 11482: } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
! 11483: xmlSchemaPIllegalAttrErr(ctxt,
! 11484: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 11485: }
! 11486: attr = attr->next;
! 11487: }
! 11488: /*
! 11489: * Extract and validate attributes.
! 11490: */
! 11491: xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
! 11492: /*
! 11493: * Attribute
! 11494: */
! 11495: /*
! 11496: * Extract the base type. The "base" attribute is mandatory if inside
! 11497: * a complex type or if redefining.
! 11498: *
! 11499: * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
! 11500: * among its [children]), the simple type definition which is
! 11501: * the {content type} of the type definition �resolved� to by
! 11502: * the �actual value� of the base [attribute]"
! 11503: */
! 11504: if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
! 11505: &(type->baseNs), &(type->base)) == 0)
! 11506: {
! 11507: if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
! 11508: xmlSchemaPMissingAttrErr(ctxt,
! 11509: XML_SCHEMAP_S4S_ATTR_MISSING,
! 11510: NULL, node, "base", NULL);
! 11511: } else if ((ctxt->isRedefine) &&
! 11512: (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
! 11513: {
! 11514: if (type->base == NULL) {
! 11515: xmlSchemaPMissingAttrErr(ctxt,
! 11516: XML_SCHEMAP_S4S_ATTR_MISSING,
! 11517: NULL, node, "base", NULL);
! 11518: } else if ((! xmlStrEqual(type->base, type->name)) ||
! 11519: (! xmlStrEqual(type->baseNs, type->targetNamespace)))
! 11520: {
! 11521: xmlChar *str1 = NULL, *str2 = NULL;
! 11522: /*
! 11523: * REDEFINE: SPEC src-redefine (5)
! 11524: * "Within the [children], each <simpleType> must have a
! 11525: * <restriction> among its [children] ... the �actual value� of
! 11526: * whose base [attribute] must be the same as the �actual value�
! 11527: * of its own name attribute plus target namespace;"
! 11528: */
! 11529: xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
! 11530: NULL, node, "This is a redefinition, but the QName "
! 11531: "value '%s' of the 'base' attribute does not match the "
! 11532: "type's designation '%s'",
! 11533: xmlSchemaFormatQName(&str1, type->baseNs, type->base),
! 11534: xmlSchemaFormatQName(&str2, type->targetNamespace,
! 11535: type->name), NULL);
! 11536: FREE_AND_NULL(str1);
! 11537: FREE_AND_NULL(str2);
! 11538: /* Avoid confusion and erase the values. */
! 11539: type->base = NULL;
! 11540: type->baseNs = NULL;
! 11541: }
! 11542: }
! 11543: }
! 11544: /*
! 11545: * And now for the children...
! 11546: */
! 11547: child = node->children;
! 11548: if (IS_SCHEMA(child, "annotation")) {
! 11549: /*
! 11550: * Add the annotation to the simple type ancestor.
! 11551: */
! 11552: xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
! 11553: xmlSchemaParseAnnotation(ctxt, child, 1));
! 11554: child = child->next;
! 11555: }
! 11556: if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
! 11557: /*
! 11558: * Corresponds to <simpleType><restriction><simpleType>.
! 11559: */
! 11560: if (IS_SCHEMA(child, "simpleType")) {
! 11561: if (type->base != NULL) {
! 11562: /*
! 11563: * src-restriction-base-or-simpleType
! 11564: * Either the base [attribute] or the simpleType [child] of the
! 11565: * <restriction> element must be present, but not both.
! 11566: */
! 11567: xmlSchemaPContentErr(ctxt,
! 11568: XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
! 11569: NULL, node, child,
! 11570: "The attribute 'base' and the <simpleType> child are "
! 11571: "mutually exclusive", NULL);
! 11572: } else {
! 11573: type->baseType = (xmlSchemaTypePtr)
! 11574: xmlSchemaParseSimpleType(ctxt, schema, child, 0);
! 11575: }
! 11576: child = child->next;
! 11577: } else if (type->base == NULL) {
! 11578: xmlSchemaPContentErr(ctxt,
! 11579: XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
! 11580: NULL, node, child,
! 11581: "Either the attribute 'base' or a <simpleType> child "
! 11582: "must be present", NULL);
! 11583: }
! 11584: } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
! 11585: /*
! 11586: * Corresponds to <complexType><complexContent><restriction>...
! 11587: * followed by:
! 11588: *
! 11589: * Model groups <all>, <choice> and <sequence>.
! 11590: */
! 11591: if (IS_SCHEMA(child, "all")) {
! 11592: type->subtypes = (xmlSchemaTypePtr)
! 11593: xmlSchemaParseModelGroup(ctxt, schema, child,
! 11594: XML_SCHEMA_TYPE_ALL, 1);
! 11595: child = child->next;
! 11596: } else if (IS_SCHEMA(child, "choice")) {
! 11597: type->subtypes = (xmlSchemaTypePtr)
! 11598: xmlSchemaParseModelGroup(ctxt,
! 11599: schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
! 11600: child = child->next;
! 11601: } else if (IS_SCHEMA(child, "sequence")) {
! 11602: type->subtypes = (xmlSchemaTypePtr)
! 11603: xmlSchemaParseModelGroup(ctxt, schema, child,
! 11604: XML_SCHEMA_TYPE_SEQUENCE, 1);
! 11605: child = child->next;
! 11606: /*
! 11607: * Model group reference <group>.
! 11608: */
! 11609: } else if (IS_SCHEMA(child, "group")) {
! 11610: type->subtypes = (xmlSchemaTypePtr)
! 11611: xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
! 11612: /*
! 11613: * Note that the reference will be resolved in
! 11614: * xmlSchemaResolveTypeReferences();
! 11615: */
! 11616: child = child->next;
! 11617: }
! 11618: } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
! 11619: /*
! 11620: * Corresponds to <complexType><simpleContent><restriction>...
! 11621: *
! 11622: * "1.1 the simple type definition corresponding to the <simpleType>
! 11623: * among the [children] of <restriction> if there is one;"
! 11624: */
! 11625: if (IS_SCHEMA(child, "simpleType")) {
! 11626: /*
! 11627: * We will store the to-be-restricted simple type in
! 11628: * type->contentTypeDef *temporarily*.
! 11629: */
! 11630: type->contentTypeDef = (xmlSchemaTypePtr)
! 11631: xmlSchemaParseSimpleType(ctxt, schema, child, 0);
! 11632: if ( type->contentTypeDef == NULL)
! 11633: return (NULL);
! 11634: child = child->next;
! 11635: }
! 11636: }
! 11637:
! 11638: if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
! 11639: (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
! 11640: xmlSchemaFacetPtr facet, lastfacet = NULL;
! 11641: /*
! 11642: * Corresponds to <complexType><simpleContent><restriction>...
! 11643: * <simpleType><restriction>...
! 11644: */
! 11645:
! 11646: /*
! 11647: * Add the facets to the simple type ancestor.
! 11648: */
! 11649: /*
! 11650: * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
! 11651: * Simple Type Definition Schema Representation Constraint:
! 11652: * *Single Facet Value*
! 11653: */
! 11654: while ((IS_SCHEMA(child, "minInclusive")) ||
! 11655: (IS_SCHEMA(child, "minExclusive")) ||
! 11656: (IS_SCHEMA(child, "maxInclusive")) ||
! 11657: (IS_SCHEMA(child, "maxExclusive")) ||
! 11658: (IS_SCHEMA(child, "totalDigits")) ||
! 11659: (IS_SCHEMA(child, "fractionDigits")) ||
! 11660: (IS_SCHEMA(child, "pattern")) ||
! 11661: (IS_SCHEMA(child, "enumeration")) ||
! 11662: (IS_SCHEMA(child, "whiteSpace")) ||
! 11663: (IS_SCHEMA(child, "length")) ||
! 11664: (IS_SCHEMA(child, "maxLength")) ||
! 11665: (IS_SCHEMA(child, "minLength"))) {
! 11666: facet = xmlSchemaParseFacet(ctxt, schema, child);
! 11667: if (facet != NULL) {
! 11668: if (lastfacet == NULL)
! 11669: type->facets = facet;
! 11670: else
! 11671: lastfacet->next = facet;
! 11672: lastfacet = facet;
! 11673: lastfacet->next = NULL;
! 11674: }
! 11675: child = child->next;
! 11676: }
! 11677: /*
! 11678: * Create links for derivation and validation.
! 11679: */
! 11680: if (type->facets != NULL) {
! 11681: xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
! 11682:
! 11683: facet = type->facets;
! 11684: do {
! 11685: facetLink = (xmlSchemaFacetLinkPtr)
! 11686: xmlMalloc(sizeof(xmlSchemaFacetLink));
! 11687: if (facetLink == NULL) {
! 11688: xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
! 11689: xmlFree(facetLink);
! 11690: return (NULL);
! 11691: }
! 11692: facetLink->facet = facet;
! 11693: facetLink->next = NULL;
! 11694: if (lastFacetLink == NULL)
! 11695: type->facetSet = facetLink;
! 11696: else
! 11697: lastFacetLink->next = facetLink;
! 11698: lastFacetLink = facetLink;
! 11699: facet = facet->next;
! 11700: } while (facet != NULL);
! 11701: }
! 11702: }
! 11703: if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
! 11704: /*
! 11705: * Attribute uses/declarations.
! 11706: */
! 11707: if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
! 11708: (xmlSchemaItemListPtr *) &(type->attrUses),
! 11709: XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
! 11710: return(NULL);
! 11711: /*
! 11712: * Attribute wildcard.
! 11713: */
! 11714: if (IS_SCHEMA(child, "anyAttribute")) {
! 11715: type->attributeWildcard =
! 11716: xmlSchemaParseAnyAttribute(ctxt, schema, child);
! 11717: child = child->next;
! 11718: }
! 11719: }
! 11720: if (child != NULL) {
! 11721: if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
! 11722: xmlSchemaPContentErr(ctxt,
! 11723: XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
! 11724: NULL, node, child, NULL,
! 11725: "annotation?, (group | all | choice | sequence)?, "
! 11726: "((attribute | attributeGroup)*, anyAttribute?))");
! 11727: } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
! 11728: xmlSchemaPContentErr(ctxt,
! 11729: XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
! 11730: NULL, node, child, NULL,
! 11731: "(annotation?, (simpleType?, (minExclusive | minInclusive | "
! 11732: "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
! 11733: "length | minLength | maxLength | enumeration | whiteSpace | "
! 11734: "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
! 11735: } else {
! 11736: /* Simple type */
! 11737: xmlSchemaPContentErr(ctxt,
! 11738: XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
! 11739: NULL, node, child, NULL,
! 11740: "(annotation?, (simpleType?, (minExclusive | minInclusive | "
! 11741: "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
! 11742: "length | minLength | maxLength | enumeration | whiteSpace | "
! 11743: "pattern)*))");
! 11744: }
! 11745: }
! 11746: return (NULL);
! 11747: }
! 11748:
! 11749: /**
! 11750: * xmlSchemaParseExtension:
! 11751: * @ctxt: a schema validation context
! 11752: * @schema: the schema being built
! 11753: * @node: a subtree containing XML Schema informations
! 11754: *
! 11755: * Parses an <extension>, which is found inside a
! 11756: * <simpleContent> or <complexContent>.
! 11757: * *WARNING* this interface is highly subject to change.
! 11758: *
! 11759: * TODO: Returns the type definition or NULL in case of error
! 11760: */
! 11761: static xmlSchemaTypePtr
! 11762: xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
! 11763: xmlNodePtr node, xmlSchemaTypeType parentType)
! 11764: {
! 11765: xmlSchemaTypePtr type;
! 11766: xmlNodePtr child = NULL;
! 11767: xmlAttrPtr attr;
! 11768:
! 11769: if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
! 11770: return (NULL);
! 11771: /* Not a component, don't create it. */
! 11772: type = ctxt->ctxtType;
! 11773: type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
! 11774:
! 11775: /*
! 11776: * Check for illegal attributes.
! 11777: */
! 11778: attr = node->properties;
! 11779: while (attr != NULL) {
! 11780: if (attr->ns == NULL) {
! 11781: if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
! 11782: (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
! 11783: xmlSchemaPIllegalAttrErr(ctxt,
! 11784: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 11785: }
! 11786: } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
! 11787: xmlSchemaPIllegalAttrErr(ctxt,
! 11788: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 11789: }
! 11790: attr = attr->next;
! 11791: }
! 11792:
! 11793: xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
! 11794:
! 11795: /*
! 11796: * Attribute "base" - mandatory.
! 11797: */
! 11798: if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
! 11799: "base", &(type->baseNs), &(type->base)) == 0) &&
! 11800: (type->base == NULL)) {
! 11801: xmlSchemaPMissingAttrErr(ctxt,
! 11802: XML_SCHEMAP_S4S_ATTR_MISSING,
! 11803: NULL, node, "base", NULL);
! 11804: }
! 11805: /*
! 11806: * And now for the children...
! 11807: */
! 11808: child = node->children;
! 11809: if (IS_SCHEMA(child, "annotation")) {
! 11810: /*
! 11811: * Add the annotation to the type ancestor.
! 11812: */
! 11813: xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
! 11814: xmlSchemaParseAnnotation(ctxt, child, 1));
! 11815: child = child->next;
! 11816: }
! 11817: if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
! 11818: /*
! 11819: * Corresponds to <complexType><complexContent><extension>... and:
! 11820: *
! 11821: * Model groups <all>, <choice>, <sequence> and <group>.
! 11822: */
! 11823: if (IS_SCHEMA(child, "all")) {
! 11824: type->subtypes = (xmlSchemaTypePtr)
! 11825: xmlSchemaParseModelGroup(ctxt, schema,
! 11826: child, XML_SCHEMA_TYPE_ALL, 1);
! 11827: child = child->next;
! 11828: } else if (IS_SCHEMA(child, "choice")) {
! 11829: type->subtypes = (xmlSchemaTypePtr)
! 11830: xmlSchemaParseModelGroup(ctxt, schema,
! 11831: child, XML_SCHEMA_TYPE_CHOICE, 1);
! 11832: child = child->next;
! 11833: } else if (IS_SCHEMA(child, "sequence")) {
! 11834: type->subtypes = (xmlSchemaTypePtr)
! 11835: xmlSchemaParseModelGroup(ctxt, schema,
! 11836: child, XML_SCHEMA_TYPE_SEQUENCE, 1);
! 11837: child = child->next;
! 11838: } else if (IS_SCHEMA(child, "group")) {
! 11839: type->subtypes = (xmlSchemaTypePtr)
! 11840: xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
! 11841: /*
! 11842: * Note that the reference will be resolved in
! 11843: * xmlSchemaResolveTypeReferences();
! 11844: */
! 11845: child = child->next;
! 11846: }
! 11847: }
! 11848: if (child != NULL) {
! 11849: /*
! 11850: * Attribute uses/declarations.
! 11851: */
! 11852: if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
! 11853: (xmlSchemaItemListPtr *) &(type->attrUses),
! 11854: XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
! 11855: return(NULL);
! 11856: /*
! 11857: * Attribute wildcard.
! 11858: */
! 11859: if (IS_SCHEMA(child, "anyAttribute")) {
! 11860: ctxt->ctxtType->attributeWildcard =
! 11861: xmlSchemaParseAnyAttribute(ctxt, schema, child);
! 11862: child = child->next;
! 11863: }
! 11864: }
! 11865: if (child != NULL) {
! 11866: if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
! 11867: /* Complex content extension. */
! 11868: xmlSchemaPContentErr(ctxt,
! 11869: XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
! 11870: NULL, node, child, NULL,
! 11871: "(annotation?, ((group | all | choice | sequence)?, "
! 11872: "((attribute | attributeGroup)*, anyAttribute?)))");
! 11873: } else {
! 11874: /* Simple content extension. */
! 11875: xmlSchemaPContentErr(ctxt,
! 11876: XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
! 11877: NULL, node, child, NULL,
! 11878: "(annotation?, ((attribute | attributeGroup)*, "
! 11879: "anyAttribute?))");
! 11880: }
! 11881: }
! 11882: return (NULL);
! 11883: }
! 11884:
! 11885: /**
! 11886: * xmlSchemaParseSimpleContent:
! 11887: * @ctxt: a schema validation context
! 11888: * @schema: the schema being built
! 11889: * @node: a subtree containing XML Schema informations
! 11890: *
! 11891: * parse a XML schema SimpleContent definition
! 11892: * *WARNING* this interface is highly subject to change
! 11893: *
! 11894: * Returns the type definition or NULL in case of error
! 11895: */
! 11896: static int
! 11897: xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
! 11898: xmlSchemaPtr schema, xmlNodePtr node,
! 11899: int *hasRestrictionOrExtension)
! 11900: {
! 11901: xmlSchemaTypePtr type;
! 11902: xmlNodePtr child = NULL;
! 11903: xmlAttrPtr attr;
! 11904:
! 11905: if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
! 11906: (hasRestrictionOrExtension == NULL))
! 11907: return (-1);
! 11908: *hasRestrictionOrExtension = 0;
! 11909: /* Not a component, don't create it. */
! 11910: type = ctxt->ctxtType;
! 11911: type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
! 11912: /*
! 11913: * Check for illegal attributes.
! 11914: */
! 11915: attr = node->properties;
! 11916: while (attr != NULL) {
! 11917: if (attr->ns == NULL) {
! 11918: if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
! 11919: xmlSchemaPIllegalAttrErr(ctxt,
! 11920: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 11921: }
! 11922: } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
! 11923: xmlSchemaPIllegalAttrErr(ctxt,
! 11924: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 11925: }
! 11926: attr = attr->next;
! 11927: }
! 11928:
! 11929: xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
! 11930:
! 11931: /*
! 11932: * And now for the children...
! 11933: */
! 11934: child = node->children;
! 11935: if (IS_SCHEMA(child, "annotation")) {
! 11936: /*
! 11937: * Add the annotation to the complex type ancestor.
! 11938: */
! 11939: xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
! 11940: xmlSchemaParseAnnotation(ctxt, child, 1));
! 11941: child = child->next;
! 11942: }
! 11943: if (child == NULL) {
! 11944: xmlSchemaPContentErr(ctxt,
! 11945: XML_SCHEMAP_S4S_ELEM_MISSING,
! 11946: NULL, node, NULL, NULL,
! 11947: "(annotation?, (restriction | extension))");
! 11948: }
! 11949: if (child == NULL) {
! 11950: xmlSchemaPContentErr(ctxt,
! 11951: XML_SCHEMAP_S4S_ELEM_MISSING,
! 11952: NULL, node, NULL, NULL,
! 11953: "(annotation?, (restriction | extension))");
! 11954: }
! 11955: if (IS_SCHEMA(child, "restriction")) {
! 11956: xmlSchemaParseRestriction(ctxt, schema, child,
! 11957: XML_SCHEMA_TYPE_SIMPLE_CONTENT);
! 11958: (*hasRestrictionOrExtension) = 1;
! 11959: child = child->next;
! 11960: } else if (IS_SCHEMA(child, "extension")) {
! 11961: xmlSchemaParseExtension(ctxt, schema, child,
! 11962: XML_SCHEMA_TYPE_SIMPLE_CONTENT);
! 11963: (*hasRestrictionOrExtension) = 1;
! 11964: child = child->next;
! 11965: }
! 11966: if (child != NULL) {
! 11967: xmlSchemaPContentErr(ctxt,
! 11968: XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
! 11969: NULL, node, child, NULL,
! 11970: "(annotation?, (restriction | extension))");
! 11971: }
! 11972: return (0);
! 11973: }
! 11974:
! 11975: /**
! 11976: * xmlSchemaParseComplexContent:
! 11977: * @ctxt: a schema validation context
! 11978: * @schema: the schema being built
! 11979: * @node: a subtree containing XML Schema informations
! 11980: *
! 11981: * parse a XML schema ComplexContent definition
! 11982: * *WARNING* this interface is highly subject to change
! 11983: *
! 11984: * Returns the type definition or NULL in case of error
! 11985: */
! 11986: static int
! 11987: xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
! 11988: xmlSchemaPtr schema, xmlNodePtr node,
! 11989: int *hasRestrictionOrExtension)
! 11990: {
! 11991: xmlSchemaTypePtr type;
! 11992: xmlNodePtr child = NULL;
! 11993: xmlAttrPtr attr;
! 11994:
! 11995: if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
! 11996: (hasRestrictionOrExtension == NULL))
! 11997: return (-1);
! 11998: *hasRestrictionOrExtension = 0;
! 11999: /* Not a component, don't create it. */
! 12000: type = ctxt->ctxtType;
! 12001: /*
! 12002: * Check for illegal attributes.
! 12003: */
! 12004: attr = node->properties;
! 12005: while (attr != NULL) {
! 12006: if (attr->ns == NULL) {
! 12007: if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
! 12008: (!xmlStrEqual(attr->name, BAD_CAST "mixed")))
! 12009: {
! 12010: xmlSchemaPIllegalAttrErr(ctxt,
! 12011: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 12012: }
! 12013: } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
! 12014: xmlSchemaPIllegalAttrErr(ctxt,
! 12015: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 12016: }
! 12017: attr = attr->next;
! 12018: }
! 12019:
! 12020: xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
! 12021:
! 12022: /*
! 12023: * Set the 'mixed' on the complex type ancestor.
! 12024: */
! 12025: if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) {
! 12026: if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
! 12027: type->flags |= XML_SCHEMAS_TYPE_MIXED;
! 12028: }
! 12029: child = node->children;
! 12030: if (IS_SCHEMA(child, "annotation")) {
! 12031: /*
! 12032: * Add the annotation to the complex type ancestor.
! 12033: */
! 12034: xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
! 12035: xmlSchemaParseAnnotation(ctxt, child, 1));
! 12036: child = child->next;
! 12037: }
! 12038: if (child == NULL) {
! 12039: xmlSchemaPContentErr(ctxt,
! 12040: XML_SCHEMAP_S4S_ELEM_MISSING,
! 12041: NULL, node, NULL,
! 12042: NULL, "(annotation?, (restriction | extension))");
! 12043: }
! 12044: if (child == NULL) {
! 12045: xmlSchemaPContentErr(ctxt,
! 12046: XML_SCHEMAP_S4S_ELEM_MISSING,
! 12047: NULL, node, NULL,
! 12048: NULL, "(annotation?, (restriction | extension))");
! 12049: }
! 12050: if (IS_SCHEMA(child, "restriction")) {
! 12051: xmlSchemaParseRestriction(ctxt, schema, child,
! 12052: XML_SCHEMA_TYPE_COMPLEX_CONTENT);
! 12053: (*hasRestrictionOrExtension) = 1;
! 12054: child = child->next;
! 12055: } else if (IS_SCHEMA(child, "extension")) {
! 12056: xmlSchemaParseExtension(ctxt, schema, child,
! 12057: XML_SCHEMA_TYPE_COMPLEX_CONTENT);
! 12058: (*hasRestrictionOrExtension) = 1;
! 12059: child = child->next;
! 12060: }
! 12061: if (child != NULL) {
! 12062: xmlSchemaPContentErr(ctxt,
! 12063: XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
! 12064: NULL, node, child,
! 12065: NULL, "(annotation?, (restriction | extension))");
! 12066: }
! 12067: return (0);
! 12068: }
! 12069:
! 12070: /**
! 12071: * xmlSchemaParseComplexType:
! 12072: * @ctxt: a schema validation context
! 12073: * @schema: the schema being built
! 12074: * @node: a subtree containing XML Schema informations
! 12075: *
! 12076: * parse a XML schema Complex Type definition
! 12077: * *WARNING* this interface is highly subject to change
! 12078: *
! 12079: * Returns the type definition or NULL in case of error
! 12080: */
! 12081: static xmlSchemaTypePtr
! 12082: xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
! 12083: xmlNodePtr node, int topLevel)
! 12084: {
! 12085: xmlSchemaTypePtr type, ctxtType;
! 12086: xmlNodePtr child = NULL;
! 12087: const xmlChar *name = NULL;
! 12088: xmlAttrPtr attr;
! 12089: const xmlChar *attrValue;
! 12090: #ifdef ENABLE_NAMED_LOCALS
! 12091: char buf[40];
! 12092: #endif
! 12093: int final = 0, block = 0, hasRestrictionOrExtension = 0;
! 12094:
! 12095:
! 12096: if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
! 12097: return (NULL);
! 12098:
! 12099: ctxtType = ctxt->ctxtType;
! 12100:
! 12101: if (topLevel) {
! 12102: attr = xmlSchemaGetPropNode(node, "name");
! 12103: if (attr == NULL) {
! 12104: xmlSchemaPMissingAttrErr(ctxt,
! 12105: XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
! 12106: return (NULL);
! 12107: } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
! 12108: xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
! 12109: return (NULL);
! 12110: }
! 12111: }
! 12112:
! 12113: if (topLevel == 0) {
! 12114: /*
! 12115: * Parse as local complex type definition.
! 12116: */
! 12117: #ifdef ENABLE_NAMED_LOCALS
! 12118: snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
! 12119: type = xmlSchemaAddType(ctxt, schema,
! 12120: XML_SCHEMA_TYPE_COMPLEX,
! 12121: xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
! 12122: ctxt->targetNamespace, node, 0);
! 12123: #else
! 12124: type = xmlSchemaAddType(ctxt, schema,
! 12125: XML_SCHEMA_TYPE_COMPLEX,
! 12126: NULL, ctxt->targetNamespace, node, 0);
! 12127: #endif
! 12128: if (type == NULL)
! 12129: return (NULL);
! 12130: name = type->name;
! 12131: type->node = node;
! 12132: type->type = XML_SCHEMA_TYPE_COMPLEX;
! 12133: /*
! 12134: * TODO: We need the target namespace.
! 12135: */
! 12136: } else {
! 12137: /*
! 12138: * Parse as global complex type definition.
! 12139: */
! 12140: type = xmlSchemaAddType(ctxt, schema,
! 12141: XML_SCHEMA_TYPE_COMPLEX,
! 12142: name, ctxt->targetNamespace, node, 1);
! 12143: if (type == NULL)
! 12144: return (NULL);
! 12145: type->node = node;
! 12146: type->type = XML_SCHEMA_TYPE_COMPLEX;
! 12147: type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
! 12148: }
! 12149: type->targetNamespace = ctxt->targetNamespace;
! 12150: /*
! 12151: * Handle attributes.
! 12152: */
! 12153: attr = node->properties;
! 12154: while (attr != NULL) {
! 12155: if (attr->ns == NULL) {
! 12156: if (xmlStrEqual(attr->name, BAD_CAST "id")) {
! 12157: /*
! 12158: * Attribute "id".
! 12159: */
! 12160: xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
! 12161: } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
! 12162: /*
! 12163: * Attribute "mixed".
! 12164: */
! 12165: if (xmlSchemaPGetBoolNodeValue(ctxt,
! 12166: NULL, (xmlNodePtr) attr))
! 12167: type->flags |= XML_SCHEMAS_TYPE_MIXED;
! 12168: } else if (topLevel) {
! 12169: /*
! 12170: * Attributes of global complex type definitions.
! 12171: */
! 12172: if (xmlStrEqual(attr->name, BAD_CAST "name")) {
! 12173: /* Pass. */
! 12174: } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
! 12175: /*
! 12176: * Attribute "abstract".
! 12177: */
! 12178: if (xmlSchemaPGetBoolNodeValue(ctxt,
! 12179: NULL, (xmlNodePtr) attr))
! 12180: type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
! 12181: } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
! 12182: /*
! 12183: * Attribute "final".
! 12184: */
! 12185: attrValue = xmlSchemaGetNodeContent(ctxt,
! 12186: (xmlNodePtr) attr);
! 12187: if (xmlSchemaPValAttrBlockFinal(attrValue,
! 12188: &(type->flags),
! 12189: -1,
! 12190: XML_SCHEMAS_TYPE_FINAL_EXTENSION,
! 12191: XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
! 12192: -1, -1, -1) != 0)
! 12193: {
! 12194: xmlSchemaPSimpleTypeErr(ctxt,
! 12195: XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
! 12196: NULL, (xmlNodePtr) attr, NULL,
! 12197: "(#all | List of (extension | restriction))",
! 12198: attrValue, NULL, NULL, NULL);
! 12199: } else
! 12200: final = 1;
! 12201: } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
! 12202: /*
! 12203: * Attribute "block".
! 12204: */
! 12205: attrValue = xmlSchemaGetNodeContent(ctxt,
! 12206: (xmlNodePtr) attr);
! 12207: if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
! 12208: -1,
! 12209: XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
! 12210: XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
! 12211: -1, -1, -1) != 0) {
! 12212: xmlSchemaPSimpleTypeErr(ctxt,
! 12213: XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
! 12214: NULL, (xmlNodePtr) attr, NULL,
! 12215: "(#all | List of (extension | restriction)) ",
! 12216: attrValue, NULL, NULL, NULL);
! 12217: } else
! 12218: block = 1;
! 12219: } else {
! 12220: xmlSchemaPIllegalAttrErr(ctxt,
! 12221: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 12222: }
! 12223: } else {
! 12224: xmlSchemaPIllegalAttrErr(ctxt,
! 12225: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 12226: }
! 12227: } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
! 12228: xmlSchemaPIllegalAttrErr(ctxt,
! 12229: XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
! 12230: }
! 12231: attr = attr->next;
! 12232: }
! 12233: if (! block) {
! 12234: /*
! 12235: * Apply default "block" values.
! 12236: */
! 12237: if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
! 12238: type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
! 12239: if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
! 12240: type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
! 12241: }
! 12242: if (! final) {
! 12243: /*
! 12244: * Apply default "block" values.
! 12245: */
! 12246: if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
! 12247: type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
! 12248: if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
! 12249: type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
! 12250: }
! 12251: /*
! 12252: * And now for the children...
! 12253: */
! 12254: child = node->children;
! 12255: if (IS_SCHEMA(child, "annotation")) {
! 12256: type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
! 12257: child = child->next;
! 12258: }
! 12259: ctxt->ctxtType = type;
! 12260: if (IS_SCHEMA(child, "simpleContent")) {
! 12261: /*
! 12262: * <complexType><simpleContent>...
! 12263: * 3.4.3 : 2.2
! 12264: * Specifying mixed='true' when the <simpleContent>
! 12265: * alternative is chosen has no effect
! 12266: */
! 12267: if (type->flags & XML_SCHEMAS_TYPE_MIXED)
! 12268: type->flags ^= XML_SCHEMAS_TYPE_MIXED;
! 12269: xmlSchemaParseSimpleContent(ctxt, schema, child,
! 12270: &hasRestrictionOrExtension);
! 12271: child = child->next;
! 12272: } else if (IS_SCHEMA(child, "complexContent")) {
! 12273: /*
! 12274: * <complexType><complexContent>...
! 12275: */
! 12276: type->contentType = XML_SCHEMA_CONTENT_EMPTY;
! 12277: xmlSchemaParseComplexContent(ctxt, schema, child,
! 12278: &hasRestrictionOrExtension);
! 12279: child = child->next;
! 12280: } else {
! 12281: /*
! 12282: * E.g <complexType><sequence>... or <complexType><attribute>... etc.
! 12283: *
! 12284: * SPEC
! 12285: * "...the third alternative (neither <simpleContent> nor
! 12286: * <complexContent>) is chosen. This case is understood as shorthand
! 12287: * for complex content restricting the �ur-type definition�, and the
! 12288: * details of the mappings should be modified as necessary.
! 12289: */
! 12290: type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
! 12291: type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
! 12292: /*
! 12293: * Parse model groups.
! 12294: */
! 12295: if (IS_SCHEMA(child, "all")) {
! 12296: type->subtypes = (xmlSchemaTypePtr)
! 12297: xmlSchemaParseModelGroup(ctxt, schema, child,
! 12298: XML_SCHEMA_TYPE_ALL, 1);
! 12299: child = child->next;
! 12300: } else if (IS_SCHEMA(child, "choice")) {
! 12301: type->subtypes = (xmlSchemaTypePtr)
! 12302: xmlSchemaParseModelGroup(ctxt, schema, child,
! 12303: XML_SCHEMA_TYPE_CHOICE, 1);
! 12304: child = child->next;
! 12305: } else if (IS_SCHEMA(child, "sequence")) {
! 12306: type->subtypes = (xmlSchemaTypePtr)
! 12307: xmlSchemaParseModelGroup(ctxt, schema, child,
! 12308: XML_SCHEMA_TYPE_SEQUENCE, 1);
! 12309: child = child->next;
! 12310: } else if (IS_SCHEMA(child, "group")) {
! 12311: type->subtypes = (xmlSchemaTypePtr)
! 12312: xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
! 12313: /*
! 12314: * Note that the reference will be resolved in
! 12315: * xmlSchemaResolveTypeReferences();
! 12316: */
! 12317: child = child->next;
! 12318: }
! 12319: /*
! 12320: * Parse attribute decls/refs.
! 12321: */
! 12322: if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
! 12323: (xmlSchemaItemListPtr *) &(type->attrUses),
! 12324: XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
! 12325: return(NULL);
! 12326: /*
! 12327: * Parse attribute wildcard.
! 12328: */
! 12329: if (IS_SCHEMA(child, "anyAttribute")) {
! 12330: type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
! 12331: child = child->next;
! 12332: }
! 12333: }
! 12334: if (child != NULL) {
! 12335: xmlSchemaPContentErr(ctxt,
! 12336: XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
! 12337: NULL, node, child,
! 12338: NULL, "(annotation?, (simpleContent | complexContent | "
! 12339: "((group | all | choice | sequence)?, ((attribute | "
! 12340: "attributeGroup)*, anyAttribute?))))");
! 12341: }
! 12342: /*
! 12343: * REDEFINE: SPEC src-redefine (5)
! 12344: */
! 12345: if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
! 12346: xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
! 12347: NULL, node, "This is a redefinition, thus the "
! 12348: "<complexType> must have a <restriction> or <extension> "
! 12349: "grand-child", NULL);
! 12350: }
! 12351: ctxt->ctxtType = ctxtType;
! 12352: return (type);
! 12353: }
! 12354:
! 12355: /************************************************************************
! 12356: * *
! 12357: * Validating using Schemas *
! 12358: * *
! 12359: ************************************************************************/
! 12360:
! 12361: /************************************************************************
! 12362: * *
! 12363: * Reading/Writing Schemas *
! 12364: * *
! 12365: ************************************************************************/
! 12366:
! 12367: #if 0 /* Will be enabled if it is clear what options are needed. */
! 12368: /**
! 12369: * xmlSchemaParserCtxtSetOptions:
! 12370: * @ctxt: a schema parser context
! 12371: * @options: a combination of xmlSchemaParserOption
! 12372: *
! 12373: * Sets the options to be used during the parse.
! 12374: *
! 12375: * Returns 0 in case of success, -1 in case of an
! 12376: * API error.
! 12377: */
! 12378: static int
! 12379: xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
! 12380: int options)
! 12381:
! 12382: {
! 12383: int i;
! 12384:
! 12385: if (ctxt == NULL)
! 12386: return (-1);
! 12387: /*
! 12388: * WARNING: Change the start value if adding to the
! 12389: * xmlSchemaParseOption.
! 12390: */
! 12391: for (i = 1; i < (int) sizeof(int) * 8; i++) {
! 12392: if (options & 1<<i) {
! 12393: return (-1);
! 12394: }
! 12395: }
! 12396: ctxt->options = options;
! 12397: return (0);
! 12398: }
! 12399:
! 12400: /**
! 12401: * xmlSchemaValidCtxtGetOptions:
! 12402: * @ctxt: a schema parser context
! 12403: *
! 12404: * Returns the option combination of the parser context.
! 12405: */
! 12406: static int
! 12407: xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
! 12408:
! 12409: {
! 12410: if (ctxt == NULL)
! 12411: return (-1);
! 12412: else
! 12413: return (ctxt->options);
! 12414: }
! 12415: #endif
! 12416:
! 12417: /**
! 12418: * xmlSchemaNewParserCtxt:
! 12419: * @URL: the location of the schema
! 12420: *
! 12421: * Create an XML Schemas parse context for that file/resource expected
! 12422: * to contain an XML Schemas file.
! 12423: *
! 12424: * Returns the parser context or NULL in case of error
! 12425: */
! 12426: xmlSchemaParserCtxtPtr
! 12427: xmlSchemaNewParserCtxt(const char *URL)
! 12428: {
! 12429: xmlSchemaParserCtxtPtr ret;
! 12430:
! 12431: if (URL == NULL)
! 12432: return (NULL);
! 12433:
! 12434: ret = xmlSchemaParserCtxtCreate();
! 12435: if (ret == NULL)
! 12436: return(NULL);
! 12437: ret->dict = xmlDictCreate();
! 12438: ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
! 12439: return (ret);
! 12440: }
! 12441:
! 12442: /**
! 12443: * xmlSchemaNewMemParserCtxt:
! 12444: * @buffer: a pointer to a char array containing the schemas
! 12445: * @size: the size of the array
! 12446: *
! 12447: * Create an XML Schemas parse context for that memory buffer expected
! 12448: * to contain an XML Schemas file.
! 12449: *
! 12450: * Returns the parser context or NULL in case of error
! 12451: */
! 12452: xmlSchemaParserCtxtPtr
! 12453: xmlSchemaNewMemParserCtxt(const char *buffer, int size)
! 12454: {
! 12455: xmlSchemaParserCtxtPtr ret;
! 12456:
! 12457: if ((buffer == NULL) || (size <= 0))
! 12458: return (NULL);
! 12459: ret = xmlSchemaParserCtxtCreate();
! 12460: if (ret == NULL)
! 12461: return(NULL);
! 12462: ret->buffer = buffer;
! 12463: ret->size = size;
! 12464: ret->dict = xmlDictCreate();
! 12465: return (ret);
! 12466: }
! 12467:
! 12468: /**
! 12469: * xmlSchemaNewDocParserCtxt:
! 12470: * @doc: a preparsed document tree
! 12471: *
! 12472: * Create an XML Schemas parse context for that document.
! 12473: * NB. The document may be modified during the parsing process.
! 12474: *
! 12475: * Returns the parser context or NULL in case of error
! 12476: */
! 12477: xmlSchemaParserCtxtPtr
! 12478: xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
! 12479: {
! 12480: xmlSchemaParserCtxtPtr ret;
! 12481:
! 12482: if (doc == NULL)
! 12483: return (NULL);
! 12484: ret = xmlSchemaParserCtxtCreate();
! 12485: if (ret == NULL)
! 12486: return(NULL);
! 12487: ret->doc = doc;
! 12488: ret->dict = xmlDictCreate();
! 12489: /* The application has responsibility for the document */
! 12490: ret->preserve = 1;
! 12491:
! 12492: return (ret);
! 12493: }
! 12494:
! 12495: /**
! 12496: * xmlSchemaFreeParserCtxt:
! 12497: * @ctxt: the schema parser context
! 12498: *
! 12499: * Free the resources associated to the schema parser context
! 12500: */
! 12501: void
! 12502: xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
! 12503: {
! 12504: if (ctxt == NULL)
! 12505: return;
! 12506: if (ctxt->doc != NULL && !ctxt->preserve)
! 12507: xmlFreeDoc(ctxt->doc);
! 12508: if (ctxt->vctxt != NULL) {
! 12509: xmlSchemaFreeValidCtxt(ctxt->vctxt);
! 12510: }
! 12511: if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
! 12512: xmlSchemaConstructionCtxtFree(ctxt->constructor);
! 12513: ctxt->constructor = NULL;
! 12514: ctxt->ownsConstructor = 0;
! 12515: }
! 12516: if (ctxt->attrProhibs != NULL)
! 12517: xmlSchemaItemListFree(ctxt->attrProhibs);
! 12518: xmlDictFree(ctxt->dict);
! 12519: xmlFree(ctxt);
! 12520: }
! 12521:
! 12522: /************************************************************************
! 12523: * *
! 12524: * Building the content models *
! 12525: * *
! 12526: ************************************************************************/
! 12527:
! 12528: /**
! 12529: * xmlSchemaBuildContentModelForSubstGroup:
! 12530: *
! 12531: * Returns 1 if nillable, 0 otherwise
! 12532: */
! 12533: static int
! 12534: xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
! 12535: xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
! 12536: {
! 12537: xmlAutomataStatePtr start, tmp;
! 12538: xmlSchemaElementPtr elemDecl, member;
! 12539: xmlSchemaSubstGroupPtr substGroup;
! 12540: int i;
! 12541: int ret = 0;
! 12542:
! 12543: elemDecl = (xmlSchemaElementPtr) particle->children;
! 12544: /*
! 12545: * Wrap the substitution group with a CHOICE.
! 12546: */
! 12547: start = pctxt->state;
! 12548: if (end == NULL)
! 12549: end = xmlAutomataNewState(pctxt->am);
! 12550: substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
! 12551: if (substGroup == NULL) {
! 12552: xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
! 12553: XML_SCHEMAP_INTERNAL,
! 12554: "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
! 12555: "declaration is marked having a subst. group but none "
! 12556: "available.\n", elemDecl->name, NULL);
! 12557: return(0);
! 12558: }
! 12559: if (counter >= 0) {
! 12560: /*
! 12561: * NOTE that we put the declaration in, even if it's abstract.
! 12562: * However, an error will be raised during *validation* if an element
! 12563: * information item shall be validated against an abstract element
! 12564: * declaration.
! 12565: */
! 12566: tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
! 12567: xmlAutomataNewTransition2(pctxt->am, tmp, end,
! 12568: elemDecl->name, elemDecl->targetNamespace, elemDecl);
! 12569: /*
! 12570: * Add subst. group members.
! 12571: */
! 12572: for (i = 0; i < substGroup->members->nbItems; i++) {
! 12573: member = (xmlSchemaElementPtr) substGroup->members->items[i];
! 12574: xmlAutomataNewTransition2(pctxt->am, tmp, end,
! 12575: member->name, member->targetNamespace, member);
! 12576: }
! 12577: } else if (particle->maxOccurs == 1) {
! 12578: /*
! 12579: * NOTE that we put the declaration in, even if it's abstract,
! 12580: */
! 12581: xmlAutomataNewEpsilon(pctxt->am,
! 12582: xmlAutomataNewTransition2(pctxt->am,
! 12583: start, NULL,
! 12584: elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
! 12585: /*
! 12586: * Add subst. group members.
! 12587: */
! 12588: for (i = 0; i < substGroup->members->nbItems; i++) {
! 12589: member = (xmlSchemaElementPtr) substGroup->members->items[i];
! 12590: /*
! 12591: * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
! 12592: * was incorrectly used instead of xmlAutomataNewTransition2()
! 12593: * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
! 12594: * section in xmlSchemaBuildAContentModel() ).
! 12595: * TODO: Check if xmlAutomataNewOnceTrans2() was instead
! 12596: * intended for the above "counter" section originally. I.e.,
! 12597: * check xs:all with subst-groups.
! 12598: *
! 12599: * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
! 12600: * member->name, member->targetNamespace,
! 12601: * 1, 1, member);
! 12602: */
! 12603: tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
! 12604: member->name, member->targetNamespace, member);
! 12605: xmlAutomataNewEpsilon(pctxt->am, tmp, end);
! 12606: }
! 12607: } else {
! 12608: xmlAutomataStatePtr hop;
! 12609: int maxOccurs = particle->maxOccurs == UNBOUNDED ?
! 12610: UNBOUNDED : particle->maxOccurs - 1;
! 12611: int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
! 12612:
! 12613: counter =
! 12614: xmlAutomataNewCounter(pctxt->am, minOccurs,
! 12615: maxOccurs);
! 12616: hop = xmlAutomataNewState(pctxt->am);
! 12617:
! 12618: xmlAutomataNewEpsilon(pctxt->am,
! 12619: xmlAutomataNewTransition2(pctxt->am,
! 12620: start, NULL,
! 12621: elemDecl->name, elemDecl->targetNamespace, elemDecl),
! 12622: hop);
! 12623: /*
! 12624: * Add subst. group members.
! 12625: */
! 12626: for (i = 0; i < substGroup->members->nbItems; i++) {
! 12627: member = (xmlSchemaElementPtr) substGroup->members->items[i];
! 12628: xmlAutomataNewEpsilon(pctxt->am,
! 12629: xmlAutomataNewTransition2(pctxt->am,
! 12630: start, NULL,
! 12631: member->name, member->targetNamespace, member),
! 12632: hop);
! 12633: }
! 12634: xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
! 12635: xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
! 12636: }
! 12637: if (particle->minOccurs == 0) {
! 12638: xmlAutomataNewEpsilon(pctxt->am, start, end);
! 12639: ret = 1;
! 12640: }
! 12641: pctxt->state = end;
! 12642: return(ret);
! 12643: }
! 12644:
! 12645: /**
! 12646: * xmlSchemaBuildContentModelForElement:
! 12647: *
! 12648: * Returns 1 if nillable, 0 otherwise
! 12649: */
! 12650: static int
! 12651: xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
! 12652: xmlSchemaParticlePtr particle)
! 12653: {
! 12654: int ret = 0;
! 12655:
! 12656: if (((xmlSchemaElementPtr) particle->children)->flags &
! 12657: XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
! 12658: /*
! 12659: * Substitution groups.
! 12660: */
! 12661: ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
! 12662: } else {
! 12663: xmlSchemaElementPtr elemDecl;
! 12664: xmlAutomataStatePtr start;
! 12665:
! 12666: elemDecl = (xmlSchemaElementPtr) particle->children;
! 12667:
! 12668: if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
! 12669: return(0);
! 12670: if (particle->maxOccurs == 1) {
! 12671: start = ctxt->state;
! 12672: ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
! 12673: elemDecl->name, elemDecl->targetNamespace, elemDecl);
! 12674: } else if ((particle->maxOccurs >= UNBOUNDED) &&
! 12675: (particle->minOccurs < 2)) {
! 12676: /* Special case. */
! 12677: start = ctxt->state;
! 12678: ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
! 12679: elemDecl->name, elemDecl->targetNamespace, elemDecl);
! 12680: ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
! 12681: elemDecl->name, elemDecl->targetNamespace, elemDecl);
! 12682: } else {
! 12683: int counter;
! 12684: int maxOccurs = particle->maxOccurs == UNBOUNDED ?
! 12685: UNBOUNDED : particle->maxOccurs - 1;
! 12686: int minOccurs = particle->minOccurs < 1 ?
! 12687: 0 : particle->minOccurs - 1;
! 12688:
! 12689: start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
! 12690: counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
! 12691: ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
! 12692: elemDecl->name, elemDecl->targetNamespace, elemDecl);
! 12693: xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
! 12694: ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
! 12695: NULL, counter);
! 12696: }
! 12697: if (particle->minOccurs == 0) {
! 12698: xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
! 12699: ret = 1;
! 12700: }
! 12701: }
! 12702: return(ret);
! 12703: }
! 12704:
! 12705: /**
! 12706: * xmlSchemaBuildAContentModel:
! 12707: * @ctxt: the schema parser context
! 12708: * @particle: the particle component
! 12709: * @name: the complex type's name whose content is being built
! 12710: *
! 12711: * Create the automaton for the {content type} of a complex type.
! 12712: *
! 12713: * Returns 1 if the content is nillable, 0 otherwise
! 12714: */
! 12715: static int
! 12716: xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
! 12717: xmlSchemaParticlePtr particle)
! 12718: {
! 12719: int ret = 0, tmp2;
! 12720:
! 12721: if (particle == NULL) {
! 12722: PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
! 12723: return(1);
! 12724: }
! 12725: if (particle->children == NULL) {
! 12726: /*
! 12727: * Just return in this case. A missing "term" of the particle
! 12728: * might arise due to an invalid "term" component.
! 12729: */
! 12730: return(1);
! 12731: }
! 12732:
! 12733: switch (particle->children->type) {
! 12734: case XML_SCHEMA_TYPE_ANY: {
! 12735: xmlAutomataStatePtr start, end;
! 12736: xmlSchemaWildcardPtr wild;
! 12737: xmlSchemaWildcardNsPtr ns;
! 12738:
! 12739: wild = (xmlSchemaWildcardPtr) particle->children;
! 12740:
! 12741: start = pctxt->state;
! 12742: end = xmlAutomataNewState(pctxt->am);
! 12743:
! 12744: if (particle->maxOccurs == 1) {
! 12745: if (wild->any == 1) {
! 12746: /*
! 12747: * We need to add both transitions:
! 12748: *
! 12749: * 1. the {"*", "*"} for elements in a namespace.
! 12750: */
! 12751: pctxt->state =
! 12752: xmlAutomataNewTransition2(pctxt->am,
! 12753: start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
! 12754: xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
! 12755: /*
! 12756: * 2. the {"*"} for elements in no namespace.
! 12757: */
! 12758: pctxt->state =
! 12759: xmlAutomataNewTransition2(pctxt->am,
! 12760: start, NULL, BAD_CAST "*", NULL, wild);
! 12761: xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
! 12762:
! 12763: } else if (wild->nsSet != NULL) {
! 12764: ns = wild->nsSet;
! 12765: do {
! 12766: pctxt->state = start;
! 12767: pctxt->state = xmlAutomataNewTransition2(pctxt->am,
! 12768: pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
! 12769: xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
! 12770: ns = ns->next;
! 12771: } while (ns != NULL);
! 12772:
! 12773: } else if (wild->negNsSet != NULL) {
! 12774: pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
! 12775: start, end, BAD_CAST "*", wild->negNsSet->value,
! 12776: wild);
! 12777: }
! 12778: } else {
! 12779: int counter;
! 12780: xmlAutomataStatePtr hop;
! 12781: int maxOccurs =
! 12782: particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
! 12783: particle->maxOccurs - 1;
! 12784: int minOccurs =
! 12785: particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
! 12786:
! 12787: counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
! 12788: hop = xmlAutomataNewState(pctxt->am);
! 12789: if (wild->any == 1) {
! 12790: pctxt->state =
! 12791: xmlAutomataNewTransition2(pctxt->am,
! 12792: start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
! 12793: xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
! 12794: pctxt->state =
! 12795: xmlAutomataNewTransition2(pctxt->am,
! 12796: start, NULL, BAD_CAST "*", NULL, wild);
! 12797: xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
! 12798: } else if (wild->nsSet != NULL) {
! 12799: ns = wild->nsSet;
! 12800: do {
! 12801: pctxt->state =
! 12802: xmlAutomataNewTransition2(pctxt->am,
! 12803: start, NULL, BAD_CAST "*", ns->value, wild);
! 12804: xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
! 12805: ns = ns->next;
! 12806: } while (ns != NULL);
! 12807:
! 12808: } else if (wild->negNsSet != NULL) {
! 12809: pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
! 12810: start, hop, BAD_CAST "*", wild->negNsSet->value,
! 12811: wild);
! 12812: }
! 12813: xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
! 12814: xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
! 12815: }
! 12816: if (particle->minOccurs == 0) {
! 12817: xmlAutomataNewEpsilon(pctxt->am, start, end);
! 12818: ret = 1;
! 12819: }
! 12820: pctxt->state = end;
! 12821: break;
! 12822: }
! 12823: case XML_SCHEMA_TYPE_ELEMENT:
! 12824: ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
! 12825: break;
! 12826: case XML_SCHEMA_TYPE_SEQUENCE:{
! 12827: xmlSchemaTreeItemPtr sub;
! 12828:
! 12829: ret = 1;
! 12830: /*
! 12831: * If max and min occurances are default (1) then
! 12832: * simply iterate over the particles of the <sequence>.
! 12833: */
! 12834: if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
! 12835: sub = particle->children->children;
! 12836:
! 12837: while (sub != NULL) {
! 12838: tmp2 = xmlSchemaBuildAContentModel(pctxt,
! 12839: (xmlSchemaParticlePtr) sub);
! 12840: if (tmp2 != 1) ret = 0;
! 12841: sub = sub->next;
! 12842: }
! 12843: } else {
! 12844: xmlAutomataStatePtr oldstate = pctxt->state;
! 12845:
! 12846: if (particle->maxOccurs >= UNBOUNDED) {
! 12847: if (particle->minOccurs > 1) {
! 12848: xmlAutomataStatePtr tmp;
! 12849: int counter;
! 12850:
! 12851: pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
! 12852: oldstate, NULL);
! 12853: oldstate = pctxt->state;
! 12854:
! 12855: counter = xmlAutomataNewCounter(pctxt->am,
! 12856: particle->minOccurs - 1, UNBOUNDED);
! 12857:
! 12858: sub = particle->children->children;
! 12859: while (sub != NULL) {
! 12860: tmp2 = xmlSchemaBuildAContentModel(pctxt,
! 12861: (xmlSchemaParticlePtr) sub);
! 12862: if (tmp2 != 1) ret = 0;
! 12863: sub = sub->next;
! 12864: }
! 12865: tmp = pctxt->state;
! 12866: xmlAutomataNewCountedTrans(pctxt->am, tmp,
! 12867: oldstate, counter);
! 12868: pctxt->state =
! 12869: xmlAutomataNewCounterTrans(pctxt->am, tmp,
! 12870: NULL, counter);
! 12871: if (ret == 1)
! 12872: xmlAutomataNewEpsilon(pctxt->am,
! 12873: oldstate, pctxt->state);
! 12874:
! 12875: } else {
! 12876: pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
! 12877: oldstate, NULL);
! 12878: oldstate = pctxt->state;
! 12879:
! 12880: sub = particle->children->children;
! 12881: while (sub != NULL) {
! 12882: tmp2 = xmlSchemaBuildAContentModel(pctxt,
! 12883: (xmlSchemaParticlePtr) sub);
! 12884: if (tmp2 != 1) ret = 0;
! 12885: sub = sub->next;
! 12886: }
! 12887: xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
! 12888: oldstate);
! 12889: /*
! 12890: * epsilon needed to block previous trans from
! 12891: * being allowed to enter back from another
! 12892: * construct
! 12893: */
! 12894: pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
! 12895: pctxt->state, NULL);
! 12896: if (particle->minOccurs == 0) {
! 12897: xmlAutomataNewEpsilon(pctxt->am,
! 12898: oldstate, pctxt->state);
! 12899: ret = 1;
! 12900: }
! 12901: }
! 12902: } else if ((particle->maxOccurs > 1)
! 12903: || (particle->minOccurs > 1)) {
! 12904: xmlAutomataStatePtr tmp;
! 12905: int counter;
! 12906:
! 12907: pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
! 12908: oldstate, NULL);
! 12909: oldstate = pctxt->state;
! 12910:
! 12911: counter = xmlAutomataNewCounter(pctxt->am,
! 12912: particle->minOccurs - 1,
! 12913: particle->maxOccurs - 1);
! 12914:
! 12915: sub = particle->children->children;
! 12916: while (sub != NULL) {
! 12917: tmp2 = xmlSchemaBuildAContentModel(pctxt,
! 12918: (xmlSchemaParticlePtr) sub);
! 12919: if (tmp2 != 1) ret = 0;
! 12920: sub = sub->next;
! 12921: }
! 12922: tmp = pctxt->state;
! 12923: xmlAutomataNewCountedTrans(pctxt->am,
! 12924: tmp, oldstate, counter);
! 12925: pctxt->state =
! 12926: xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
! 12927: counter);
! 12928: if ((particle->minOccurs == 0) || (ret == 1)) {
! 12929: xmlAutomataNewEpsilon(pctxt->am,
! 12930: oldstate, pctxt->state);
! 12931: ret = 1;
! 12932: }
! 12933: } else {
! 12934: sub = particle->children->children;
! 12935: while (sub != NULL) {
! 12936: tmp2 = xmlSchemaBuildAContentModel(pctxt,
! 12937: (xmlSchemaParticlePtr) sub);
! 12938: if (tmp2 != 1) ret = 0;
! 12939: sub = sub->next;
! 12940: }
! 12941: if (particle->minOccurs == 0) {
! 12942: xmlAutomataNewEpsilon(pctxt->am, oldstate,
! 12943: pctxt->state);
! 12944: ret = 1;
! 12945: }
! 12946: }
! 12947: }
! 12948: break;
! 12949: }
! 12950: case XML_SCHEMA_TYPE_CHOICE:{
! 12951: xmlSchemaTreeItemPtr sub;
! 12952: xmlAutomataStatePtr start, end;
! 12953:
! 12954: ret = 0;
! 12955: start = pctxt->state;
! 12956: end = xmlAutomataNewState(pctxt->am);
! 12957:
! 12958: /*
! 12959: * iterate over the subtypes and remerge the end with an
! 12960: * epsilon transition
! 12961: */
! 12962: if (particle->maxOccurs == 1) {
! 12963: sub = particle->children->children;
! 12964: while (sub != NULL) {
! 12965: pctxt->state = start;
! 12966: tmp2 = xmlSchemaBuildAContentModel(pctxt,
! 12967: (xmlSchemaParticlePtr) sub);
! 12968: if (tmp2 == 1) ret = 1;
! 12969: xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
! 12970: sub = sub->next;
! 12971: }
! 12972: } else {
! 12973: int counter;
! 12974: xmlAutomataStatePtr hop, base;
! 12975: int maxOccurs = particle->maxOccurs == UNBOUNDED ?
! 12976: UNBOUNDED : particle->maxOccurs - 1;
! 12977: int minOccurs =
! 12978: particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
! 12979:
! 12980: /*
! 12981: * use a counter to keep track of the number of transtions
! 12982: * which went through the choice.
! 12983: */
! 12984: counter =
! 12985: xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
! 12986: hop = xmlAutomataNewState(pctxt->am);
! 12987: base = xmlAutomataNewState(pctxt->am);
! 12988:
! 12989: sub = particle->children->children;
! 12990: while (sub != NULL) {
! 12991: pctxt->state = base;
! 12992: tmp2 = xmlSchemaBuildAContentModel(pctxt,
! 12993: (xmlSchemaParticlePtr) sub);
! 12994: if (tmp2 == 1) ret = 1;
! 12995: xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
! 12996: sub = sub->next;
! 12997: }
! 12998: xmlAutomataNewEpsilon(pctxt->am, start, base);
! 12999: xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
! 13000: xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
! 13001: if (ret == 1)
! 13002: xmlAutomataNewEpsilon(pctxt->am, base, end);
! 13003: }
! 13004: if (particle->minOccurs == 0) {
! 13005: xmlAutomataNewEpsilon(pctxt->am, start, end);
! 13006: ret = 1;
! 13007: }
! 13008: pctxt->state = end;
! 13009: break;
! 13010: }
! 13011: case XML_SCHEMA_TYPE_ALL:{
! 13012: xmlAutomataStatePtr start, tmp;
! 13013: xmlSchemaParticlePtr sub;
! 13014: xmlSchemaElementPtr elemDecl;
! 13015:
! 13016: ret = 1;
! 13017:
! 13018: sub = (xmlSchemaParticlePtr) particle->children->children;
! 13019: if (sub == NULL)
! 13020: break;
! 13021:
! 13022: ret = 0;
! 13023:
! 13024: start = pctxt->state;
! 13025: tmp = xmlAutomataNewState(pctxt->am);
! 13026: xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
! 13027: pctxt->state = tmp;
! 13028: while (sub != NULL) {
! 13029: pctxt->state = tmp;
! 13030:
! 13031: elemDecl = (xmlSchemaElementPtr) sub->children;
! 13032: if (elemDecl == NULL) {
! 13033: PERROR_INT("xmlSchemaBuildAContentModel",
! 13034: "<element> particle has no term");
! 13035: return(ret);
! 13036: };
! 13037: /*
! 13038: * NOTE: The {max occurs} of all the particles in the
! 13039: * {particles} of the group must be 0 or 1; this is
! 13040: * already ensured during the parse of the content of
! 13041: * <all>.
! 13042: */
! 13043: if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
! 13044: int counter;
! 13045:
! 13046: /*
! 13047: * This is an abstract group, we need to share
! 13048: * the same counter for all the element transitions
! 13049: * derived from the group
! 13050: */
! 13051: counter = xmlAutomataNewCounter(pctxt->am,
! 13052: sub->minOccurs, sub->maxOccurs);
! 13053: xmlSchemaBuildContentModelForSubstGroup(pctxt,
! 13054: sub, counter, pctxt->state);
! 13055: } else {
! 13056: if ((sub->minOccurs == 1) &&
! 13057: (sub->maxOccurs == 1)) {
! 13058: xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
! 13059: pctxt->state,
! 13060: elemDecl->name,
! 13061: elemDecl->targetNamespace,
! 13062: 1, 1, elemDecl);
! 13063: } else if ((sub->minOccurs == 0) &&
! 13064: (sub->maxOccurs == 1)) {
! 13065:
! 13066: xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
! 13067: pctxt->state,
! 13068: elemDecl->name,
! 13069: elemDecl->targetNamespace,
! 13070: 0,
! 13071: 1,
! 13072: elemDecl);
! 13073: }
! 13074: }
! 13075: sub = (xmlSchemaParticlePtr) sub->next;
! 13076: }
! 13077: pctxt->state =
! 13078: xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
! 13079: if (particle->minOccurs == 0) {
! 13080: xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
! 13081: ret = 1;
! 13082: }
! 13083: break;
! 13084: }
! 13085: case XML_SCHEMA_TYPE_GROUP:
! 13086: /*
! 13087: * If we hit a model group definition, then this means that
! 13088: * it was empty, thus was not substituted for the containing
! 13089: * model group. Just do nothing in this case.
! 13090: * TODO: But the group should be substituted and not occur at
! 13091: * all in the content model at this point. Fix this.
! 13092: */
! 13093: ret = 1;
! 13094: break;
! 13095: default:
! 13096: xmlSchemaInternalErr2(ACTXT_CAST pctxt,
! 13097: "xmlSchemaBuildAContentModel",
! 13098: "found unexpected term of type '%s' in content model",
! 13099: WXS_ITEM_TYPE_NAME(particle->children), NULL);
! 13100: return(ret);
! 13101: }
! 13102: return(ret);
! 13103: }
! 13104:
! 13105: /**
! 13106: * xmlSchemaBuildContentModel:
! 13107: * @ctxt: the schema parser context
! 13108: * @type: the complex type definition
! 13109: * @name: the element name
! 13110: *
! 13111: * Builds the content model of the complex type.
! 13112: */
! 13113: static void
! 13114: xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
! 13115: xmlSchemaParserCtxtPtr ctxt)
! 13116: {
! 13117: if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
! 13118: (type->contModel != NULL) ||
! 13119: ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
! 13120: (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
! 13121: return;
! 13122:
! 13123: #ifdef DEBUG_CONTENT
! 13124: xmlGenericError(xmlGenericErrorContext,
! 13125: "Building content model for %s\n", name);
! 13126: #endif
! 13127: ctxt->am = NULL;
! 13128: ctxt->am = xmlNewAutomata();
! 13129: if (ctxt->am == NULL) {
! 13130: xmlGenericError(xmlGenericErrorContext,
! 13131: "Cannot create automata for complex type %s\n", type->name);
! 13132: return;
! 13133: }
! 13134: ctxt->state = xmlAutomataGetInitState(ctxt->am);
! 13135: /*
! 13136: * Build the automaton.
! 13137: */
! 13138: xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
! 13139: xmlAutomataSetFinalState(ctxt->am, ctxt->state);
! 13140: type->contModel = xmlAutomataCompile(ctxt->am);
! 13141: if (type->contModel == NULL) {
! 13142: xmlSchemaPCustomErr(ctxt,
! 13143: XML_SCHEMAP_INTERNAL,
! 13144: WXS_BASIC_CAST type, type->node,
! 13145: "Failed to compile the content model", NULL);
! 13146: } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
! 13147: xmlSchemaPCustomErr(ctxt,
! 13148: XML_SCHEMAP_NOT_DETERMINISTIC,
! 13149: /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
! 13150: WXS_BASIC_CAST type, type->node,
! 13151: "The content model is not determinist", NULL);
! 13152: } else {
! 13153: #ifdef DEBUG_CONTENT_REGEXP
! 13154: xmlGenericError(xmlGenericErrorContext,
! 13155: "Content model of %s:\n", type->name);
! 13156: xmlRegexpPrint(stderr, type->contModel);
! 13157: #endif
! 13158: }
! 13159: ctxt->state = NULL;
! 13160: xmlFreeAutomata(ctxt->am);
! 13161: ctxt->am = NULL;
! 13162: }
! 13163:
! 13164: /**
! 13165: * xmlSchemaResolveElementReferences:
! 13166: * @elem: the schema element context
! 13167: * @ctxt: the schema parser context
! 13168: *
! 13169: * Resolves the references of an element declaration
! 13170: * or particle, which has an element declaration as it's
! 13171: * term.
! 13172: */
! 13173: static void
! 13174: xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
! 13175: xmlSchemaParserCtxtPtr ctxt)
! 13176: {
! 13177: if ((ctxt == NULL) || (elemDecl == NULL) ||
! 13178: ((elemDecl != NULL) &&
! 13179: (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
! 13180: return;
! 13181: elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
! 13182:
! 13183: if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
! 13184: xmlSchemaTypePtr type;
! 13185:
! 13186: /* (type definition) ... otherwise the type definition �resolved�
! 13187: * to by the �actual value� of the type [attribute] ...
! 13188: */
! 13189: type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
! 13190: elemDecl->namedTypeNs);
! 13191: if (type == NULL) {
! 13192: xmlSchemaPResCompAttrErr(ctxt,
! 13193: XML_SCHEMAP_SRC_RESOLVE,
! 13194: WXS_BASIC_CAST elemDecl, elemDecl->node,
! 13195: "type", elemDecl->namedType, elemDecl->namedTypeNs,
! 13196: XML_SCHEMA_TYPE_BASIC, "type definition");
! 13197: } else
! 13198: elemDecl->subtypes = type;
! 13199: }
! 13200: if (elemDecl->substGroup != NULL) {
! 13201: xmlSchemaElementPtr substHead;
! 13202:
! 13203: /*
! 13204: * FIXME TODO: Do we need a new field in _xmlSchemaElement for
! 13205: * substitutionGroup?
! 13206: */
! 13207: substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
! 13208: elemDecl->substGroupNs);
! 13209: if (substHead == NULL) {
! 13210: xmlSchemaPResCompAttrErr(ctxt,
! 13211: XML_SCHEMAP_SRC_RESOLVE,
! 13212: WXS_BASIC_CAST elemDecl, NULL,
! 13213: "substitutionGroup", elemDecl->substGroup,
! 13214: elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
! 13215: } else {
! 13216: xmlSchemaResolveElementReferences(substHead, ctxt);
! 13217: /*
! 13218: * Set the "substitution group affiliation".
! 13219: * NOTE that now we use the "refDecl" field for this.
! 13220: */
! 13221: WXS_SUBST_HEAD(elemDecl) = substHead;
! 13222: /*
! 13223: * The type definitions is set to:
! 13224: * SPEC "...the {type definition} of the element
! 13225: * declaration �resolved� to by the �actual value�
! 13226: * of the substitutionGroup [attribute], if present"
! 13227: */
! 13228: if (elemDecl->subtypes == NULL)
! 13229: elemDecl->subtypes = substHead->subtypes;
! 13230: }
! 13231: }
! 13232: /*
! 13233: * SPEC "The definition of anyType serves as the default type definition
! 13234: * for element declarations whose XML representation does not specify one."
! 13235: */
! 13236: if ((elemDecl->subtypes == NULL) &&
! 13237: (elemDecl->namedType == NULL) &&
! 13238: (elemDecl->substGroup == NULL))
! 13239: elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
! 13240: }
! 13241:
! 13242: /**
! 13243: * xmlSchemaResolveUnionMemberTypes:
! 13244: * @ctxt: the schema parser context
! 13245: * @type: the schema simple type definition
! 13246: *
! 13247: * Checks and builds the "member type definitions" property of the union
! 13248: * simple type. This handles part (1), part (2) is done in
! 13249: * xmlSchemaFinishMemberTypeDefinitionsProperty()
! 13250: *
! 13251: * Returns -1 in case of an internal error, 0 otherwise.
! 13252: */
! 13253: static int
! 13254: xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
! 13255: xmlSchemaTypePtr type)
! 13256: {
! 13257:
! 13258: xmlSchemaTypeLinkPtr link, lastLink, newLink;
! 13259: xmlSchemaTypePtr memberType;
! 13260:
! 13261: /*
! 13262: * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
! 13263: * define the explicit members as the type definitions �resolved�
! 13264: * to by the items in the �actual value� of the memberTypes [attribute],
! 13265: * if any, followed by the type definitions corresponding to the
! 13266: * <simpleType>s among the [children] of <union>, if any."
! 13267: */
! 13268: /*
! 13269: * Resolve references.
! 13270: */
! 13271: link = type->memberTypes;
! 13272: lastLink = NULL;
! 13273: while (link != NULL) {
! 13274: const xmlChar *name, *nsName;
! 13275:
! 13276: name = ((xmlSchemaQNameRefPtr) link->type)->name;
! 13277: nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
! 13278:
! 13279: memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
! 13280: if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
! 13281: xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
! 13282: WXS_BASIC_CAST type, type->node, "memberTypes",
! 13283: name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
! 13284: /*
! 13285: * Remove the member type link.
! 13286: */
! 13287: if (lastLink == NULL)
! 13288: type->memberTypes = link->next;
! 13289: else
! 13290: lastLink->next = link->next;
! 13291: newLink = link;
! 13292: link = link->next;
! 13293: xmlFree(newLink);
! 13294: } else {
! 13295: link->type = memberType;
! 13296: lastLink = link;
! 13297: link = link->next;
! 13298: }
! 13299: }
! 13300: /*
! 13301: * Add local simple types,
! 13302: */
! 13303: memberType = type->subtypes;
! 13304: while (memberType != NULL) {
! 13305: link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
! 13306: if (link == NULL) {
! 13307: xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
! 13308: return (-1);
! 13309: }
! 13310: link->type = memberType;
! 13311: link->next = NULL;
! 13312: if (lastLink == NULL)
! 13313: type->memberTypes = link;
! 13314: else
! 13315: lastLink->next = link;
! 13316: lastLink = link;
! 13317: memberType = memberType->next;
! 13318: }
! 13319: return (0);
! 13320: }
! 13321:
! 13322: /**
! 13323: * xmlSchemaIsDerivedFromBuiltInType:
! 13324: * @ctxt: the schema parser context
! 13325: * @type: the type definition
! 13326: * @valType: the value type
! 13327: *
! 13328: *
! 13329: * Returns 1 if the type has the given value type, or
! 13330: * is derived from such a type.
! 13331: */
! 13332: static int
! 13333: xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
! 13334: {
! 13335: if (type == NULL)
! 13336: return (0);
! 13337: if (WXS_IS_COMPLEX(type))
! 13338: return (0);
! 13339: if (type->type == XML_SCHEMA_TYPE_BASIC) {
! 13340: if (type->builtInType == valType)
! 13341: return(1);
! 13342: if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
! 13343: (type->builtInType == XML_SCHEMAS_ANYTYPE))
! 13344: return (0);
! 13345: return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
! 13346: }
! 13347: return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
! 13348: }
! 13349:
! 13350: #if 0
! 13351: /**
! 13352: * xmlSchemaIsDerivedFromBuiltInType:
! 13353: * @ctxt: the schema parser context
! 13354: * @type: the type definition
! 13355: * @valType: the value type
! 13356: *
! 13357: *
! 13358: * Returns 1 if the type has the given value type, or
! 13359: * is derived from such a type.
! 13360: */
! 13361: static int
! 13362: xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
! 13363: {
! 13364: if (type == NULL)
! 13365: return (0);
! 13366: if (WXS_IS_COMPLEX(type))
! 13367: return (0);
! 13368: if (type->type == XML_SCHEMA_TYPE_BASIC) {
! 13369: if (type->builtInType == valType)
! 13370: return(1);
! 13371: return (0);
! 13372: } else
! 13373: return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
! 13374:
! 13375: return (0);
! 13376: }
! 13377:
! 13378: static xmlSchemaTypePtr
! 13379: xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
! 13380: {
! 13381: if (type == NULL)
! 13382: return (NULL);
! 13383: if (WXS_IS_COMPLEX(type))
! 13384: return (NULL);
! 13385: if (type->type == XML_SCHEMA_TYPE_BASIC)
! 13386: return(type);
! 13387: return(xmlSchemaQueryBuiltInType(type->subtypes));
! 13388: }
! 13389: #endif
! 13390:
! 13391: /**
! 13392: * xmlSchemaGetPrimitiveType:
! 13393: * @type: the simpleType definition
! 13394: *
! 13395: * Returns the primitive type of the given type or
! 13396: * NULL in case of error.
! 13397: */
! 13398: static xmlSchemaTypePtr
! 13399: xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
! 13400: {
! 13401:
! 13402: while (type != NULL) {
! 13403: /*
! 13404: * Note that anySimpleType is actually not a primitive type
! 13405: * but we need that here.
! 13406: */
! 13407: if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
! 13408: (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
! 13409: return (type);
! 13410: type = type->baseType;
! 13411: }
! 13412:
! 13413: return (NULL);
! 13414: }
! 13415:
! 13416: #if 0
! 13417: /**
! 13418: * xmlSchemaGetBuiltInTypeAncestor:
! 13419: * @type: the simpleType definition
! 13420: *
! 13421: * Returns the primitive type of the given type or
! 13422: * NULL in case of error.
! 13423: */
! 13424: static xmlSchemaTypePtr
! 13425: xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
! 13426: {
! 13427: if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
! 13428: return (0);
! 13429: while (type != NULL) {
! 13430: if (type->type == XML_SCHEMA_TYPE_BASIC)
! 13431: return (type);
! 13432: type = type->baseType;
! 13433: }
! 13434:
! 13435: return (NULL);
! 13436: }
! 13437: #endif
! 13438:
! 13439: /**
! 13440: * xmlSchemaCloneWildcardNsConstraints:
! 13441: * @ctxt: the schema parser context
! 13442: * @dest: the destination wildcard
! 13443: * @source: the source wildcard
! 13444: *
! 13445: * Clones the namespace constraints of source
! 13446: * and assignes them to dest.
! 13447: * Returns -1 on internal error, 0 otherwise.
! 13448: */
! 13449: static int
! 13450: xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
! 13451: xmlSchemaWildcardPtr dest,
! 13452: xmlSchemaWildcardPtr source)
! 13453: {
! 13454: xmlSchemaWildcardNsPtr cur, tmp, last;
! 13455:
! 13456: if ((source == NULL) || (dest == NULL))
! 13457: return(-1);
! 13458: dest->any = source->any;
! 13459: cur = source->nsSet;
! 13460: last = NULL;
! 13461: while (cur != NULL) {
! 13462: tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
! 13463: if (tmp == NULL)
! 13464: return(-1);
! 13465: tmp->value = cur->value;
! 13466: if (last == NULL)
! 13467: dest->nsSet = tmp;
! 13468: else
! 13469: last->next = tmp;
! 13470: last = tmp;
! 13471: cur = cur->next;
! 13472: }
! 13473: if (dest->negNsSet != NULL)
! 13474: xmlSchemaFreeWildcardNsSet(dest->negNsSet);
! 13475: if (source->negNsSet != NULL) {
! 13476: dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
! 13477: if (dest->negNsSet == NULL)
! 13478: return(-1);
! 13479: dest->negNsSet->value = source->negNsSet->value;
! 13480: } else
! 13481: dest->negNsSet = NULL;
! 13482: return(0);
! 13483: }
! 13484:
! 13485: /**
! 13486: * xmlSchemaUnionWildcards:
! 13487: * @ctxt: the schema parser context
! 13488: * @completeWild: the first wildcard
! 13489: * @curWild: the second wildcard
! 13490: *
! 13491: * Unions the namespace constraints of the given wildcards.
! 13492: * @completeWild will hold the resulting union.
! 13493: * Returns a positive error code on failure, -1 in case of an
! 13494: * internal error, 0 otherwise.
! 13495: */
! 13496: static int
! 13497: xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
! 13498: xmlSchemaWildcardPtr completeWild,
! 13499: xmlSchemaWildcardPtr curWild)
! 13500: {
! 13501: xmlSchemaWildcardNsPtr cur, curB, tmp;
! 13502:
! 13503: /*
! 13504: * 1 If O1 and O2 are the same value, then that value must be the
! 13505: * value.
! 13506: */
! 13507: if ((completeWild->any == curWild->any) &&
! 13508: ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
! 13509: ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
! 13510:
! 13511: if ((completeWild->negNsSet == NULL) ||
! 13512: (completeWild->negNsSet->value == curWild->negNsSet->value)) {
! 13513:
! 13514: if (completeWild->nsSet != NULL) {
! 13515: int found = 0;
! 13516:
! 13517: /*
! 13518: * Check equality of sets.
! 13519: */
! 13520: cur = completeWild->nsSet;
! 13521: while (cur != NULL) {
! 13522: found = 0;
! 13523: curB = curWild->nsSet;
! 13524: while (curB != NULL) {
! 13525: if (cur->value == curB->value) {
! 13526: found = 1;
! 13527: break;
! 13528: }
! 13529: curB = curB->next;
! 13530: }
! 13531: if (!found)
! 13532: break;
! 13533: cur = cur->next;
! 13534: }
! 13535: if (found)
! 13536: return(0);
! 13537: } else
! 13538: return(0);
! 13539: }
! 13540: }
! 13541: /*
! 13542: * 2 If either O1 or O2 is any, then any must be the value
! 13543: */
! 13544: if (completeWild->any != curWild->any) {
! 13545: if (completeWild->any == 0) {
! 13546: completeWild->any = 1;
! 13547: if (completeWild->nsSet != NULL) {
! 13548: xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
! 13549: completeWild->nsSet = NULL;
! 13550: }
! 13551: if (completeWild->negNsSet != NULL) {
! 13552: xmlFree(completeWild->negNsSet);
! 13553: completeWild->negNsSet = NULL;
! 13554: }
! 13555: }
! 13556: return (0);
! 13557: }
! 13558: /*
! 13559: * 3 If both O1 and O2 are sets of (namespace names or �absent�),
! 13560: * then the union of those sets must be the value.
! 13561: */
! 13562: if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
! 13563: int found;
! 13564: xmlSchemaWildcardNsPtr start;
! 13565:
! 13566: cur = curWild->nsSet;
! 13567: start = completeWild->nsSet;
! 13568: while (cur != NULL) {
! 13569: found = 0;
! 13570: curB = start;
! 13571: while (curB != NULL) {
! 13572: if (cur->value == curB->value) {
! 13573: found = 1;
! 13574: break;
! 13575: }
! 13576: curB = curB->next;
! 13577: }
! 13578: if (!found) {
! 13579: tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
! 13580: if (tmp == NULL)
! 13581: return (-1);
! 13582: tmp->value = cur->value;
! 13583: tmp->next = completeWild->nsSet;
! 13584: completeWild->nsSet = tmp;
! 13585: }
! 13586: cur = cur->next;
! 13587: }
! 13588:
! 13589: return(0);
! 13590: }
! 13591: /*
! 13592: * 4 If the two are negations of different values (namespace names
! 13593: * or �absent�), then a pair of not and �absent� must be the value.
! 13594: */
! 13595: if ((completeWild->negNsSet != NULL) &&
! 13596: (curWild->negNsSet != NULL) &&
! 13597: (completeWild->negNsSet->value != curWild->negNsSet->value)) {
! 13598: completeWild->negNsSet->value = NULL;
! 13599:
! 13600: return(0);
! 13601: }
! 13602: /*
! 13603: * 5.
! 13604: */
! 13605: if (((completeWild->negNsSet != NULL) &&
! 13606: (completeWild->negNsSet->value != NULL) &&
! 13607: (curWild->nsSet != NULL)) ||
! 13608: ((curWild->negNsSet != NULL) &&
! 13609: (curWild->negNsSet->value != NULL) &&
! 13610: (completeWild->nsSet != NULL))) {
! 13611:
! 13612: int nsFound, absentFound = 0;
! 13613:
! 13614: if (completeWild->nsSet != NULL) {
! 13615: cur = completeWild->nsSet;
! 13616: curB = curWild->negNsSet;
! 13617: } else {
! 13618: cur = curWild->nsSet;
! 13619: curB = completeWild->negNsSet;
! 13620: }
! 13621: nsFound = 0;
! 13622: while (cur != NULL) {
! 13623: if (cur->value == NULL)
! 13624: absentFound = 1;
! 13625: else if (cur->value == curB->value)
! 13626: nsFound = 1;
! 13627: if (nsFound && absentFound)
! 13628: break;
! 13629: cur = cur->next;
! 13630: }
! 13631:
! 13632: if (nsFound && absentFound) {
! 13633: /*
! 13634: * 5.1 If the set S includes both the negated namespace
! 13635: * name and �absent�, then any must be the value.
! 13636: */
! 13637: completeWild->any = 1;
! 13638: if (completeWild->nsSet != NULL) {
! 13639: xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
! 13640: completeWild->nsSet = NULL;
! 13641: }
! 13642: if (completeWild->negNsSet != NULL) {
! 13643: xmlFree(completeWild->negNsSet);
! 13644: completeWild->negNsSet = NULL;
! 13645: }
! 13646: } else if (nsFound && (!absentFound)) {
! 13647: /*
! 13648: * 5.2 If the set S includes the negated namespace name
! 13649: * but not �absent�, then a pair of not and �absent� must
! 13650: * be the value.
! 13651: */
! 13652: if (completeWild->nsSet != NULL) {
! 13653: xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
! 13654: completeWild->nsSet = NULL;
! 13655: }
! 13656: if (completeWild->negNsSet == NULL) {
! 13657: completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
! 13658: if (completeWild->negNsSet == NULL)
! 13659: return (-1);
! 13660: }
! 13661: completeWild->negNsSet->value = NULL;
! 13662: } else if ((!nsFound) && absentFound) {
! 13663: /*
! 13664: * 5.3 If the set S includes �absent� but not the negated
! 13665: * namespace name, then the union is not expressible.
! 13666: */
! 13667: xmlSchemaPErr(ctxt, completeWild->node,
! 13668: XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
! 13669: "The union of the wilcard is not expressible.\n",
! 13670: NULL, NULL);
! 13671: return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
! 13672: } else if ((!nsFound) && (!absentFound)) {
! 13673: /*
! 13674: * 5.4 If the set S does not include either the negated namespace
! 13675: * name or �absent�, then whichever of O1 or O2 is a pair of not
! 13676: * and a namespace name must be the value.
! 13677: */
! 13678: if (completeWild->negNsSet == NULL) {
! 13679: if (completeWild->nsSet != NULL) {
! 13680: xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
! 13681: completeWild->nsSet = NULL;
! 13682: }
! 13683: completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
! 13684: if (completeWild->negNsSet == NULL)
! 13685: return (-1);
! 13686: completeWild->negNsSet->value = curWild->negNsSet->value;
! 13687: }
! 13688: }
! 13689: return (0);
! 13690: }
! 13691: /*
! 13692: * 6.
! 13693: */
! 13694: if (((completeWild->negNsSet != NULL) &&
! 13695: (completeWild->negNsSet->value == NULL) &&
! 13696: (curWild->nsSet != NULL)) ||
! 13697: ((curWild->negNsSet != NULL) &&
! 13698: (curWild->negNsSet->value == NULL) &&
! 13699: (completeWild->nsSet != NULL))) {
! 13700:
! 13701: if (completeWild->nsSet != NULL) {
! 13702: cur = completeWild->nsSet;
! 13703: } else {
! 13704: cur = curWild->nsSet;
! 13705: }
! 13706: while (cur != NULL) {
! 13707: if (cur->value == NULL) {
! 13708: /*
! 13709: * 6.1 If the set S includes �absent�, then any must be the
! 13710: * value.
! 13711: */
! 13712: completeWild->any = 1;
! 13713: if (completeWild->nsSet != NULL) {
! 13714: xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
! 13715: completeWild->nsSet = NULL;
! 13716: }
! 13717: if (completeWild->negNsSet != NULL) {
! 13718: xmlFree(completeWild->negNsSet);
! 13719: completeWild->negNsSet = NULL;
! 13720: }
! 13721: return (0);
! 13722: }
! 13723: cur = cur->next;
! 13724: }
! 13725: if (completeWild->negNsSet == NULL) {
! 13726: /*
! 13727: * 6.2 If the set S does not include �absent�, then a pair of not
! 13728: * and �absent� must be the value.
! 13729: */
! 13730: if (completeWild->nsSet != NULL) {
! 13731: xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
! 13732: completeWild->nsSet = NULL;
! 13733: }
! 13734: completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
! 13735: if (completeWild->negNsSet == NULL)
! 13736: return (-1);
! 13737: completeWild->negNsSet->value = NULL;
! 13738: }
! 13739: return (0);
! 13740: }
! 13741: return (0);
! 13742:
! 13743: }
! 13744:
! 13745: /**
! 13746: * xmlSchemaIntersectWildcards:
! 13747: * @ctxt: the schema parser context
! 13748: * @completeWild: the first wildcard
! 13749: * @curWild: the second wildcard
! 13750: *
! 13751: * Intersects the namespace constraints of the given wildcards.
! 13752: * @completeWild will hold the resulting intersection.
! 13753: * Returns a positive error code on failure, -1 in case of an
! 13754: * internal error, 0 otherwise.
! 13755: */
! 13756: static int
! 13757: xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
! 13758: xmlSchemaWildcardPtr completeWild,
! 13759: xmlSchemaWildcardPtr curWild)
! 13760: {
! 13761: xmlSchemaWildcardNsPtr cur, curB, prev, tmp;
! 13762:
! 13763: /*
! 13764: * 1 If O1 and O2 are the same value, then that value must be the
! 13765: * value.
! 13766: */
! 13767: if ((completeWild->any == curWild->any) &&
! 13768: ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
! 13769: ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
! 13770:
! 13771: if ((completeWild->negNsSet == NULL) ||
! 13772: (completeWild->negNsSet->value == curWild->negNsSet->value)) {
! 13773:
! 13774: if (completeWild->nsSet != NULL) {
! 13775: int found = 0;
! 13776:
! 13777: /*
! 13778: * Check equality of sets.
! 13779: */
! 13780: cur = completeWild->nsSet;
! 13781: while (cur != NULL) {
! 13782: found = 0;
! 13783: curB = curWild->nsSet;
! 13784: while (curB != NULL) {
! 13785: if (cur->value == curB->value) {
! 13786: found = 1;
! 13787: break;
! 13788: }
! 13789: curB = curB->next;
! 13790: }
! 13791: if (!found)
! 13792: break;
! 13793: cur = cur->next;
! 13794: }
! 13795: if (found)
! 13796: return(0);
! 13797: } else
! 13798: return(0);
! 13799: }
! 13800: }
! 13801: /*
! 13802: * 2 If either O1 or O2 is any, then the other must be the value.
! 13803: */
! 13804: if ((completeWild->any != curWild->any) && (completeWild->any)) {
! 13805: if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
! 13806: return(-1);
! 13807: return(0);
! 13808: }
! 13809: /*
! 13810: * 3 If either O1 or O2 is a pair of not and a value (a namespace
! 13811: * name or �absent�) and the other is a set of (namespace names or
! 13812: * �absent�), then that set, minus the negated value if it was in
! 13813: * the set, minus �absent� if it was in the set, must be the value.
! 13814: */
! 13815: if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
! 13816: ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
! 13817: const xmlChar *neg;
! 13818:
! 13819: if (completeWild->nsSet == NULL) {
! 13820: neg = completeWild->negNsSet->value;
! 13821: if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
! 13822: return(-1);
! 13823: } else
! 13824: neg = curWild->negNsSet->value;
! 13825: /*
! 13826: * Remove absent and negated.
! 13827: */
! 13828: prev = NULL;
! 13829: cur = completeWild->nsSet;
! 13830: while (cur != NULL) {
! 13831: if (cur->value == NULL) {
! 13832: if (prev == NULL)
! 13833: completeWild->nsSet = cur->next;
! 13834: else
! 13835: prev->next = cur->next;
! 13836: xmlFree(cur);
! 13837: break;
! 13838: }
! 13839: prev = cur;
! 13840: cur = cur->next;
! 13841: }
! 13842: if (neg != NULL) {
! 13843: prev = NULL;
! 13844: cur = completeWild->nsSet;
! 13845: while (cur != NULL) {
! 13846: if (cur->value == neg) {
! 13847: if (prev == NULL)
! 13848: completeWild->nsSet = cur->next;
! 13849: else
! 13850: prev->next = cur->next;
! 13851: xmlFree(cur);
! 13852: break;
! 13853: }
! 13854: prev = cur;
! 13855: cur = cur->next;
! 13856: }
! 13857: }
! 13858:
! 13859: return(0);
! 13860: }
! 13861: /*
! 13862: * 4 If both O1 and O2 are sets of (namespace names or �absent�),
! 13863: * then the intersection of those sets must be the value.
! 13864: */
! 13865: if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
! 13866: int found;
! 13867:
! 13868: cur = completeWild->nsSet;
! 13869: prev = NULL;
! 13870: while (cur != NULL) {
! 13871: found = 0;
! 13872: curB = curWild->nsSet;
! 13873: while (curB != NULL) {
! 13874: if (cur->value == curB->value) {
! 13875: found = 1;
! 13876: break;
! 13877: }
! 13878: curB = curB->next;
! 13879: }
! 13880: if (!found) {
! 13881: if (prev == NULL)
! 13882: completeWild->nsSet = cur->next;
! 13883: else
! 13884: prev->next = cur->next;
! 13885: tmp = cur->next;
! 13886: xmlFree(cur);
! 13887: cur = tmp;
! 13888: continue;
! 13889: }
! 13890: prev = cur;
! 13891: cur = cur->next;
! 13892: }
! 13893:
! 13894: return(0);
! 13895: }
! 13896: /* 5 If the two are negations of different namespace names,
! 13897: * then the intersection is not expressible
! 13898: */
! 13899: if ((completeWild->negNsSet != NULL) &&
! 13900: (curWild->negNsSet != NULL) &&
! 13901: (completeWild->negNsSet->value != curWild->negNsSet->value) &&
! 13902: (completeWild->negNsSet->value != NULL) &&
! 13903: (curWild->negNsSet->value != NULL)) {
! 13904:
! 13905: xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
! 13906: "The intersection of the wilcard is not expressible.\n",
! 13907: NULL, NULL);
! 13908: return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
! 13909: }
! 13910: /*
! 13911: * 6 If the one is a negation of a namespace name and the other
! 13912: * is a negation of �absent�, then the one which is the negation
! 13913: * of a namespace name must be the value.
! 13914: */
! 13915: if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
! 13916: (completeWild->negNsSet->value != curWild->negNsSet->value) &&
! 13917: (completeWild->negNsSet->value == NULL)) {
! 13918: completeWild->negNsSet->value = curWild->negNsSet->value;
! 13919: }
! 13920: return(0);
! 13921: }
! 13922:
! 13923: /**
! 13924: * xmlSchemaIsWildcardNsConstraintSubset:
! 13925: * @ctxt: the schema parser context
! 13926: * @sub: the first wildcard
! 13927: * @super: the second wildcard
! 13928: *
! 13929: * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
! 13930: *
! 13931: * Returns 0 if the namespace constraint of @sub is an intensional
! 13932: * subset of @super, 1 otherwise.
! 13933: */
! 13934: static int
! 13935: xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
! 13936: xmlSchemaWildcardPtr super)
! 13937: {
! 13938: /*
! 13939: * 1 super must be any.
! 13940: */
! 13941: if (super->any)
! 13942: return (0);
! 13943: /*
! 13944: * 2.1 sub must be a pair of not and a namespace name or �absent�.
! 13945: * 2.2 super must be a pair of not and the same value.
! 13946: */
! 13947: if ((sub->negNsSet != NULL) &&
! 13948: (super->negNsSet != NULL) &&
! 13949: (sub->negNsSet->value == sub->negNsSet->value))
! 13950: return (0);
! 13951: /*
! 13952: * 3.1 sub must be a set whose members are either namespace names or �absent�.
! 13953: */
! 13954: if (sub->nsSet != NULL) {
! 13955: /*
! 13956: * 3.2.1 super must be the same set or a superset thereof.
! 13957: */
! 13958: if (super->nsSet != NULL) {
! 13959: xmlSchemaWildcardNsPtr cur, curB;
! 13960: int found = 0;
! 13961:
! 13962: cur = sub->nsSet;
! 13963: while (cur != NULL) {
! 13964: found = 0;
! 13965: curB = super->nsSet;
! 13966: while (curB != NULL) {
! 13967: if (cur->value == curB->value) {
! 13968: found = 1;
! 13969: break;
! 13970: }
! 13971: curB = curB->next;
! 13972: }
! 13973: if (!found)
! 13974: return (1);
! 13975: cur = cur->next;
! 13976: }
! 13977: if (found)
! 13978: return (0);
! 13979: } else if (super->negNsSet != NULL) {
! 13980: xmlSchemaWildcardNsPtr cur;
! 13981: /*
! 13982: * 3.2.2 super must be a pair of not and a namespace name or
! 13983: * �absent� and that value must not be in sub's set.
! 13984: */
! 13985: cur = sub->nsSet;
! 13986: while (cur != NULL) {
! 13987: if (cur->value == super->negNsSet->value)
! 13988: return (1);
! 13989: cur = cur->next;
! 13990: }
! 13991: return (0);
! 13992: }
! 13993: }
! 13994: return (1);
! 13995: }
! 13996:
! 13997: static int
! 13998: xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
! 13999: int *fixed,
! 14000: const xmlChar **value,
! 14001: xmlSchemaValPtr *val)
! 14002: {
! 14003: *fixed = 0;
! 14004: *value = NULL;
! 14005: if (val != 0)
! 14006: *val = NULL;
! 14007:
! 14008: if (attruse->defValue != NULL) {
! 14009: *value = attruse->defValue;
! 14010: if (val != NULL)
! 14011: *val = attruse->defVal;
! 14012: if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
! 14013: *fixed = 1;
! 14014: return(1);
! 14015: } else if ((attruse->attrDecl != NULL) &&
! 14016: (attruse->attrDecl->defValue != NULL)) {
! 14017: *value = attruse->attrDecl->defValue;
! 14018: if (val != NULL)
! 14019: *val = attruse->attrDecl->defVal;
! 14020: if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
! 14021: *fixed = 1;
! 14022: return(1);
! 14023: }
! 14024: return(0);
! 14025: }
! 14026: /**
! 14027: * xmlSchemaCheckCVCWildcardNamespace:
! 14028: * @wild: the wildcard
! 14029: * @ns: the namespace
! 14030: *
! 14031: * Validation Rule: Wildcard allows Namespace Name
! 14032: * (cvc-wildcard-namespace)
! 14033: *
! 14034: * Returns 0 if the given namespace matches the wildcard,
! 14035: * 1 otherwise and -1 on API errors.
! 14036: */
! 14037: static int
! 14038: xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
! 14039: const xmlChar* ns)
! 14040: {
! 14041: if (wild == NULL)
! 14042: return(-1);
! 14043:
! 14044: if (wild->any)
! 14045: return(0);
! 14046: else if (wild->nsSet != NULL) {
! 14047: xmlSchemaWildcardNsPtr cur;
! 14048:
! 14049: cur = wild->nsSet;
! 14050: while (cur != NULL) {
! 14051: if (xmlStrEqual(cur->value, ns))
! 14052: return(0);
! 14053: cur = cur->next;
! 14054: }
! 14055: } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
! 14056: (!xmlStrEqual(wild->negNsSet->value, ns)))
! 14057: return(0);
! 14058:
! 14059: return(1);
! 14060: }
! 14061:
! 14062: #define XML_SCHEMA_ACTION_DERIVE 0
! 14063: #define XML_SCHEMA_ACTION_REDEFINE 1
! 14064:
! 14065: #define WXS_ACTION_STR(a) \
! 14066: ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
! 14067:
! 14068: /*
! 14069: * Schema Component Constraint:
! 14070: * Derivation Valid (Restriction, Complex)
! 14071: * derivation-ok-restriction (2) - (4)
! 14072: *
! 14073: * ATTENTION:
! 14074: * In XML Schema 1.1 this will be:
! 14075: * Validation Rule:
! 14076: * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
! 14077: *
! 14078: */
! 14079: static int
! 14080: xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
! 14081: int action,
! 14082: xmlSchemaBasicItemPtr item,
! 14083: xmlSchemaBasicItemPtr baseItem,
! 14084: xmlSchemaItemListPtr uses,
! 14085: xmlSchemaItemListPtr baseUses,
! 14086: xmlSchemaWildcardPtr wild,
! 14087: xmlSchemaWildcardPtr baseWild)
! 14088: {
! 14089: xmlSchemaAttributeUsePtr cur = NULL, bcur;
! 14090: int i, j, found; /* err = 0; */
! 14091: const xmlChar *bEffValue;
! 14092: int effFixed;
! 14093:
! 14094: if (uses != NULL) {
! 14095: for (i = 0; i < uses->nbItems; i++) {
! 14096: cur = uses->items[i];
! 14097: found = 0;
! 14098: if (baseUses == NULL)
! 14099: goto not_found;
! 14100: for (j = 0; j < baseUses->nbItems; j++) {
! 14101: bcur = baseUses->items[j];
! 14102: if ((WXS_ATTRUSE_DECL_NAME(cur) ==
! 14103: WXS_ATTRUSE_DECL_NAME(bcur)) &&
! 14104: (WXS_ATTRUSE_DECL_TNS(cur) ==
! 14105: WXS_ATTRUSE_DECL_TNS(bcur)))
! 14106: {
! 14107: /*
! 14108: * (2.1) "If there is an attribute use in the {attribute
! 14109: * uses} of the {base type definition} (call this B) whose
! 14110: * {attribute declaration} has the same {name} and {target
! 14111: * namespace}, then all of the following must be true:"
! 14112: */
! 14113: found = 1;
! 14114:
! 14115: if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
! 14116: (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
! 14117: {
! 14118: xmlChar *str = NULL;
! 14119: /*
! 14120: * (2.1.1) "one of the following must be true:"
! 14121: * (2.1.1.1) "B's {required} is false."
! 14122: * (2.1.1.2) "R's {required} is true."
! 14123: */
! 14124: xmlSchemaPAttrUseErr4(pctxt,
! 14125: XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
! 14126: WXS_ITEM_NODE(item), item, cur,
! 14127: "The 'optional' attribute use is inconsistent "
! 14128: "with the corresponding 'required' attribute use of "
! 14129: "the %s %s",
! 14130: WXS_ACTION_STR(action),
! 14131: xmlSchemaGetComponentDesignation(&str, baseItem),
! 14132: NULL, NULL);
! 14133: FREE_AND_NULL(str);
! 14134: /* err = pctxt->err; */
! 14135: } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
! 14136: WXS_ATTRUSE_TYPEDEF(cur),
! 14137: WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
! 14138: {
! 14139: xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
! 14140:
! 14141: /*
! 14142: * SPEC (2.1.2) "R's {attribute declaration}'s
! 14143: * {type definition} must be validly derived from
! 14144: * B's {type definition} given the empty set as
! 14145: * defined in Type Derivation OK (Simple) (�3.14.6)."
! 14146: */
! 14147: xmlSchemaPAttrUseErr4(pctxt,
! 14148: XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
! 14149: WXS_ITEM_NODE(item), item, cur,
! 14150: "The attribute declaration's %s "
! 14151: "is not validly derived from "
! 14152: "the corresponding %s of the "
! 14153: "attribute declaration in the %s %s",
! 14154: xmlSchemaGetComponentDesignation(&strA,
! 14155: WXS_ATTRUSE_TYPEDEF(cur)),
! 14156: xmlSchemaGetComponentDesignation(&strB,
! 14157: WXS_ATTRUSE_TYPEDEF(bcur)),
! 14158: WXS_ACTION_STR(action),
! 14159: xmlSchemaGetComponentDesignation(&strC, baseItem));
! 14160: /* xmlSchemaGetComponentDesignation(&str, baseItem), */
! 14161: FREE_AND_NULL(strA);
! 14162: FREE_AND_NULL(strB);
! 14163: FREE_AND_NULL(strC);
! 14164: /* err = pctxt->err; */
! 14165: } else {
! 14166: /*
! 14167: * 2.1.3 [Definition:] Let the effective value
! 14168: * constraint of an attribute use be its {value
! 14169: * constraint}, if present, otherwise its {attribute
! 14170: * declaration}'s {value constraint} .
! 14171: */
! 14172: xmlSchemaGetEffectiveValueConstraint(bcur,
! 14173: &effFixed, &bEffValue, NULL);
! 14174: /*
! 14175: * 2.1.3 ... one of the following must be true
! 14176: *
! 14177: * 2.1.3.1 B's �effective value constraint� is
! 14178: * �absent� or default.
! 14179: */
! 14180: if ((bEffValue != NULL) &&
! 14181: (effFixed == 1)) {
! 14182: const xmlChar *rEffValue = NULL;
! 14183:
! 14184: xmlSchemaGetEffectiveValueConstraint(bcur,
! 14185: &effFixed, &rEffValue, NULL);
! 14186: /*
! 14187: * 2.1.3.2 R's �effective value constraint� is
! 14188: * fixed with the same string as B's.
! 14189: * MAYBE TODO: Compare the computed values.
! 14190: * Hmm, it says "same string" so
! 14191: * string-equality might really be sufficient.
! 14192: */
! 14193: if ((effFixed == 0) ||
! 14194: (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
! 14195: {
! 14196: xmlChar *str = NULL;
! 14197:
! 14198: xmlSchemaPAttrUseErr4(pctxt,
! 14199: XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
! 14200: WXS_ITEM_NODE(item), item, cur,
! 14201: "The effective value constraint of the "
! 14202: "attribute use is inconsistent with "
! 14203: "its correspondent in the %s %s",
! 14204: WXS_ACTION_STR(action),
! 14205: xmlSchemaGetComponentDesignation(&str,
! 14206: baseItem),
! 14207: NULL, NULL);
! 14208: FREE_AND_NULL(str);
! 14209: /* err = pctxt->err; */
! 14210: }
! 14211: }
! 14212: }
! 14213: break;
! 14214: }
! 14215: }
! 14216: not_found:
! 14217: if (!found) {
! 14218: /*
! 14219: * (2.2) "otherwise the {base type definition} must have an
! 14220: * {attribute wildcard} and the {target namespace} of the
! 14221: * R's {attribute declaration} must be �valid� with respect
! 14222: * to that wildcard, as defined in Wildcard allows Namespace
! 14223: * Name (�3.10.4)."
! 14224: */
! 14225: if ((baseWild == NULL) ||
! 14226: (xmlSchemaCheckCVCWildcardNamespace(baseWild,
! 14227: (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
! 14228: {
! 14229: xmlChar *str = NULL;
! 14230:
! 14231: xmlSchemaPAttrUseErr4(pctxt,
! 14232: XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
! 14233: WXS_ITEM_NODE(item), item, cur,
! 14234: "Neither a matching attribute use, "
! 14235: "nor a matching wildcard exists in the %s %s",
! 14236: WXS_ACTION_STR(action),
! 14237: xmlSchemaGetComponentDesignation(&str, baseItem),
! 14238: NULL, NULL);
! 14239: FREE_AND_NULL(str);
! 14240: /* err = pctxt->err; */
! 14241: }
! 14242: }
! 14243: }
! 14244: }
! 14245: /*
! 14246: * SPEC derivation-ok-restriction (3):
! 14247: * (3) "For each attribute use in the {attribute uses} of the {base type
! 14248: * definition} whose {required} is true, there must be an attribute
! 14249: * use with an {attribute declaration} with the same {name} and
! 14250: * {target namespace} as its {attribute declaration} in the {attribute
! 14251: * uses} of the complex type definition itself whose {required} is true.
! 14252: */
! 14253: if (baseUses != NULL) {
! 14254: for (j = 0; j < baseUses->nbItems; j++) {
! 14255: bcur = baseUses->items[j];
! 14256: if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
! 14257: continue;
! 14258: found = 0;
! 14259: if (uses != NULL) {
! 14260: for (i = 0; i < uses->nbItems; i++) {
! 14261: cur = uses->items[i];
! 14262: if ((WXS_ATTRUSE_DECL_NAME(cur) ==
! 14263: WXS_ATTRUSE_DECL_NAME(bcur)) &&
! 14264: (WXS_ATTRUSE_DECL_TNS(cur) ==
! 14265: WXS_ATTRUSE_DECL_TNS(bcur))) {
! 14266: found = 1;
! 14267: break;
! 14268: }
! 14269: }
! 14270: }
! 14271: if (!found) {
! 14272: xmlChar *strA = NULL, *strB = NULL;
! 14273:
! 14274: xmlSchemaCustomErr4(ACTXT_CAST pctxt,
! 14275: XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
! 14276: NULL, item,
! 14277: "A matching attribute use for the "
! 14278: "'required' %s of the %s %s is missing",
! 14279: xmlSchemaGetComponentDesignation(&strA, bcur),
! 14280: WXS_ACTION_STR(action),
! 14281: xmlSchemaGetComponentDesignation(&strB, baseItem),
! 14282: NULL);
! 14283: FREE_AND_NULL(strA);
! 14284: FREE_AND_NULL(strB);
! 14285: }
! 14286: }
! 14287: }
! 14288: /*
! 14289: * derivation-ok-restriction (4)
! 14290: */
! 14291: if (wild != NULL) {
! 14292: /*
! 14293: * (4) "If there is an {attribute wildcard}, all of the
! 14294: * following must be true:"
! 14295: */
! 14296: if (baseWild == NULL) {
! 14297: xmlChar *str = NULL;
! 14298:
! 14299: /*
! 14300: * (4.1) "The {base type definition} must also have one."
! 14301: */
! 14302: xmlSchemaCustomErr4(ACTXT_CAST pctxt,
! 14303: XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
! 14304: NULL, item,
! 14305: "The %s has an attribute wildcard, "
! 14306: "but the %s %s '%s' does not have one",
! 14307: WXS_ITEM_TYPE_NAME(item),
! 14308: WXS_ACTION_STR(action),
! 14309: WXS_ITEM_TYPE_NAME(baseItem),
! 14310: xmlSchemaGetComponentQName(&str, baseItem));
! 14311: FREE_AND_NULL(str);
! 14312: return(pctxt->err);
! 14313: } else if ((baseWild->any == 0) &&
! 14314: xmlSchemaCheckCOSNSSubset(wild, baseWild))
! 14315: {
! 14316: xmlChar *str = NULL;
! 14317: /*
! 14318: * (4.2) "The complex type definition's {attribute wildcard}'s
! 14319: * {namespace constraint} must be a subset of the {base type
! 14320: * definition}'s {attribute wildcard}'s {namespace constraint},
! 14321: * as defined by Wildcard Subset (�3.10.6)."
! 14322: */
! 14323: xmlSchemaCustomErr4(ACTXT_CAST pctxt,
! 14324: XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
! 14325: NULL, item,
! 14326: "The attribute wildcard is not a valid "
! 14327: "subset of the wildcard in the %s %s '%s'",
! 14328: WXS_ACTION_STR(action),
! 14329: WXS_ITEM_TYPE_NAME(baseItem),
! 14330: xmlSchemaGetComponentQName(&str, baseItem),
! 14331: NULL);
! 14332: FREE_AND_NULL(str);
! 14333: return(pctxt->err);
! 14334: }
! 14335: /* 4.3 Unless the {base type definition} is the �ur-type
! 14336: * definition�, the complex type definition's {attribute
! 14337: * wildcard}'s {process contents} must be identical to or
! 14338: * stronger than the {base type definition}'s {attribute
! 14339: * wildcard}'s {process contents}, where strict is stronger
! 14340: * than lax is stronger than skip.
! 14341: */
! 14342: if ((! WXS_IS_ANYTYPE(baseItem)) &&
! 14343: (wild->processContents < baseWild->processContents)) {
! 14344: xmlChar *str = NULL;
! 14345: xmlSchemaCustomErr4(ACTXT_CAST pctxt,
! 14346: XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
! 14347: NULL, baseItem,
! 14348: "The {process contents} of the attribute wildcard is "
! 14349: "weaker than the one in the %s %s '%s'",
! 14350: WXS_ACTION_STR(action),
! 14351: WXS_ITEM_TYPE_NAME(baseItem),
! 14352: xmlSchemaGetComponentQName(&str, baseItem),
! 14353: NULL);
! 14354: FREE_AND_NULL(str)
! 14355: return(pctxt->err);
! 14356: }
! 14357: }
! 14358: return(0);
! 14359: }
! 14360:
! 14361:
! 14362: static int
! 14363: xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
! 14364: xmlSchemaBasicItemPtr item,
! 14365: xmlSchemaWildcardPtr *completeWild,
! 14366: xmlSchemaItemListPtr list,
! 14367: xmlSchemaItemListPtr prohibs);
! 14368: /**
! 14369: * xmlSchemaFixupTypeAttributeUses:
! 14370: * @ctxt: the schema parser context
! 14371: * @type: the complex type definition
! 14372: *
! 14373: *
! 14374: * Builds the wildcard and the attribute uses on the given complex type.
! 14375: * Returns -1 if an internal error occurs, 0 otherwise.
! 14376: *
! 14377: * ATTENTION TODO: Experimantally this uses pointer comparisons for
! 14378: * strings, so recheck this if we start to hardcode some schemata, since
! 14379: * they might not be in the same dict.
! 14380: * NOTE: It is allowed to "extend" the xs:anyType type.
! 14381: */
! 14382: static int
! 14383: xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
! 14384: xmlSchemaTypePtr type)
! 14385: {
! 14386: xmlSchemaTypePtr baseType = NULL;
! 14387: xmlSchemaAttributeUsePtr use;
! 14388: xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
! 14389:
! 14390: if (type->baseType == NULL) {
! 14391: PERROR_INT("xmlSchemaFixupTypeAttributeUses",
! 14392: "no base type");
! 14393: return (-1);
! 14394: }
! 14395: baseType = type->baseType;
! 14396: if (WXS_IS_TYPE_NOT_FIXED(baseType))
! 14397: if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
! 14398: return(-1);
! 14399:
! 14400: uses = type->attrUses;
! 14401: baseUses = baseType->attrUses;
! 14402: /*
! 14403: * Expand attribute group references. And build the 'complete'
! 14404: * wildcard, i.e. intersect multiple wildcards.
! 14405: * Move attribute prohibitions into a separate list.
! 14406: */
! 14407: if (uses != NULL) {
! 14408: if (WXS_IS_RESTRICTION(type)) {
! 14409: /*
! 14410: * This one will transfer all attr. prohibitions
! 14411: * into pctxt->attrProhibs.
! 14412: */
! 14413: if (xmlSchemaExpandAttributeGroupRefs(pctxt,
! 14414: WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
! 14415: pctxt->attrProhibs) == -1)
! 14416: {
! 14417: PERROR_INT("xmlSchemaFixupTypeAttributeUses",
! 14418: "failed to expand attributes");
! 14419: }
! 14420: if (pctxt->attrProhibs->nbItems != 0)
! 14421: prohibs = pctxt->attrProhibs;
! 14422: } else {
! 14423: if (xmlSchemaExpandAttributeGroupRefs(pctxt,
! 14424: WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
! 14425: NULL) == -1)
! 14426: {
! 14427: PERROR_INT("xmlSchemaFixupTypeAttributeUses",
! 14428: "failed to expand attributes");
! 14429: }
! 14430: }
! 14431: }
! 14432: /*
! 14433: * Inherit the attribute uses of the base type.
! 14434: */
! 14435: if (baseUses != NULL) {
! 14436: int i, j;
! 14437: xmlSchemaAttributeUseProhibPtr pro;
! 14438:
! 14439: if (WXS_IS_RESTRICTION(type)) {
! 14440: int usesCount;
! 14441: xmlSchemaAttributeUsePtr tmp;
! 14442:
! 14443: if (uses != NULL)
! 14444: usesCount = uses->nbItems;
! 14445: else
! 14446: usesCount = 0;
! 14447:
! 14448: /* Restriction. */
! 14449: for (i = 0; i < baseUses->nbItems; i++) {
! 14450: use = baseUses->items[i];
! 14451: if (prohibs) {
! 14452: /*
! 14453: * Filter out prohibited uses.
! 14454: */
! 14455: for (j = 0; j < prohibs->nbItems; j++) {
! 14456: pro = prohibs->items[j];
! 14457: if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
! 14458: (WXS_ATTRUSE_DECL_TNS(use) ==
! 14459: pro->targetNamespace))
! 14460: {
! 14461: goto inherit_next;
! 14462: }
! 14463: }
! 14464: }
! 14465: if (usesCount) {
! 14466: /*
! 14467: * Filter out existing uses.
! 14468: */
! 14469: for (j = 0; j < usesCount; j++) {
! 14470: tmp = uses->items[j];
! 14471: if ((WXS_ATTRUSE_DECL_NAME(use) ==
! 14472: WXS_ATTRUSE_DECL_NAME(tmp)) &&
! 14473: (WXS_ATTRUSE_DECL_TNS(use) ==
! 14474: WXS_ATTRUSE_DECL_TNS(tmp)))
! 14475: {
! 14476: goto inherit_next;
! 14477: }
! 14478: }
! 14479: }
! 14480: if (uses == NULL) {
! 14481: type->attrUses = xmlSchemaItemListCreate();
! 14482: if (type->attrUses == NULL)
! 14483: goto exit_failure;
! 14484: uses = type->attrUses;
! 14485: }
! 14486: xmlSchemaItemListAddSize(uses, 2, use);
! 14487: inherit_next: {}
! 14488: }
! 14489: } else {
! 14490: /* Extension. */
! 14491: for (i = 0; i < baseUses->nbItems; i++) {
! 14492: use = baseUses->items[i];
! 14493: if (uses == NULL) {
! 14494: type->attrUses = xmlSchemaItemListCreate();
! 14495: if (type->attrUses == NULL)
! 14496: goto exit_failure;
! 14497: uses = type->attrUses;
! 14498: }
! 14499: xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
! 14500: }
! 14501: }
! 14502: }
! 14503: /*
! 14504: * Shrink attr. uses.
! 14505: */
! 14506: if (uses) {
! 14507: if (uses->nbItems == 0) {
! 14508: xmlSchemaItemListFree(uses);
! 14509: type->attrUses = NULL;
! 14510: }
! 14511: /*
! 14512: * TODO: We could shrink the size of the array
! 14513: * to fit the actual number of items.
! 14514: */
! 14515: }
! 14516: /*
! 14517: * Compute the complete wildcard.
! 14518: */
! 14519: if (WXS_IS_EXTENSION(type)) {
! 14520: if (baseType->attributeWildcard != NULL) {
! 14521: /*
! 14522: * (3.2.2.1) "If the �base wildcard� is non-�absent�, then
! 14523: * the appropriate case among the following:"
! 14524: */
! 14525: if (type->attributeWildcard != NULL) {
! 14526: /*
! 14527: * Union the complete wildcard with the base wildcard.
! 14528: * SPEC {attribute wildcard}
! 14529: * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
! 14530: * and {annotation} are those of the �complete wildcard�,
! 14531: * and whose {namespace constraint} is the intensional union
! 14532: * of the {namespace constraint} of the �complete wildcard�
! 14533: * and of the �base wildcard�, as defined in Attribute
! 14534: * Wildcard Union (�3.10.6)."
! 14535: */
! 14536: if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
! 14537: baseType->attributeWildcard) == -1)
! 14538: goto exit_failure;
! 14539: } else {
! 14540: /*
! 14541: * (3.2.2.1.1) "If the �complete wildcard� is �absent�,
! 14542: * then the �base wildcard�."
! 14543: */
! 14544: type->attributeWildcard = baseType->attributeWildcard;
! 14545: }
! 14546: } else {
! 14547: /*
! 14548: * (3.2.2.2) "otherwise (the �base wildcard� is �absent�) the
! 14549: * �complete wildcard"
! 14550: * NOOP
! 14551: */
! 14552: }
! 14553: } else {
! 14554: /*
! 14555: * SPEC {attribute wildcard}
! 14556: * (3.1) "If the <restriction> alternative is chosen, then the
! 14557: * �complete wildcard�;"
! 14558: * NOOP
! 14559: */
! 14560: }
! 14561:
! 14562: return (0);
! 14563:
! 14564: exit_failure:
! 14565: return(-1);
! 14566: }
! 14567:
! 14568: /**
! 14569: * xmlSchemaTypeFinalContains:
! 14570: * @schema: the schema
! 14571: * @type: the type definition
! 14572: * @final: the final
! 14573: *
! 14574: * Evaluates if a type definition contains the given "final".
! 14575: * This does take "finalDefault" into account as well.
! 14576: *
! 14577: * Returns 1 if the type does containt the given "final",
! 14578: * 0 otherwise.
! 14579: */
! 14580: static int
! 14581: xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
! 14582: {
! 14583: if (type == NULL)
! 14584: return (0);
! 14585: if (type->flags & final)
! 14586: return (1);
! 14587: else
! 14588: return (0);
! 14589: }
! 14590:
! 14591: /**
! 14592: * xmlSchemaGetUnionSimpleTypeMemberTypes:
! 14593: * @type: the Union Simple Type
! 14594: *
! 14595: * Returns a list of member types of @type if existing,
! 14596: * returns NULL otherwise.
! 14597: */
! 14598: static xmlSchemaTypeLinkPtr
! 14599: xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
! 14600: {
! 14601: while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
! 14602: if (type->memberTypes != NULL)
! 14603: return (type->memberTypes);
! 14604: else
! 14605: type = type->baseType;
! 14606: }
! 14607: return (NULL);
! 14608: }
! 14609:
! 14610: /**
! 14611: * xmlSchemaGetParticleTotalRangeMin:
! 14612: * @particle: the particle
! 14613: *
! 14614: * Schema Component Constraint: Effective Total Range
! 14615: * (all and sequence) + (choice)
! 14616: *
! 14617: * Returns the minimun Effective Total Range.
! 14618: */
! 14619: static int
! 14620: xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
! 14621: {
! 14622: if ((particle->children == NULL) ||
! 14623: (particle->minOccurs == 0))
! 14624: return (0);
! 14625: if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
! 14626: int min = -1, cur;
! 14627: xmlSchemaParticlePtr part =
! 14628: (xmlSchemaParticlePtr) particle->children->children;
! 14629:
! 14630: if (part == NULL)
! 14631: return (0);
! 14632: while (part != NULL) {
! 14633: if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
! 14634: (part->children->type == XML_SCHEMA_TYPE_ANY))
! 14635: cur = part->minOccurs;
! 14636: else
! 14637: cur = xmlSchemaGetParticleTotalRangeMin(part);
! 14638: if (cur == 0)
! 14639: return (0);
! 14640: if ((min > cur) || (min == -1))
! 14641: min = cur;
! 14642: part = (xmlSchemaParticlePtr) part->next;
! 14643: }
! 14644: return (particle->minOccurs * min);
! 14645: } else {
! 14646: /* <all> and <sequence> */
! 14647: int sum = 0;
! 14648: xmlSchemaParticlePtr part =
! 14649: (xmlSchemaParticlePtr) particle->children->children;
! 14650:
! 14651: if (part == NULL)
! 14652: return (0);
! 14653: do {
! 14654: if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
! 14655: (part->children->type == XML_SCHEMA_TYPE_ANY))
! 14656: sum += part->minOccurs;
! 14657: else
! 14658: sum += xmlSchemaGetParticleTotalRangeMin(part);
! 14659: part = (xmlSchemaParticlePtr) part->next;
! 14660: } while (part != NULL);
! 14661: return (particle->minOccurs * sum);
! 14662: }
! 14663: }
! 14664:
! 14665: #if 0
! 14666: /**
! 14667: * xmlSchemaGetParticleTotalRangeMax:
! 14668: * @particle: the particle
! 14669: *
! 14670: * Schema Component Constraint: Effective Total Range
! 14671: * (all and sequence) + (choice)
! 14672: *
! 14673: * Returns the maximum Effective Total Range.
! 14674: */
! 14675: static int
! 14676: xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
! 14677: {
! 14678: if ((particle->children == NULL) ||
! 14679: (particle->children->children == NULL))
! 14680: return (0);
! 14681: if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
! 14682: int max = -1, cur;
! 14683: xmlSchemaParticlePtr part =
! 14684: (xmlSchemaParticlePtr) particle->children->children;
! 14685:
! 14686: for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
! 14687: if (part->children == NULL)
! 14688: continue;
! 14689: if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
! 14690: (part->children->type == XML_SCHEMA_TYPE_ANY))
! 14691: cur = part->maxOccurs;
! 14692: else
! 14693: cur = xmlSchemaGetParticleTotalRangeMax(part);
! 14694: if (cur == UNBOUNDED)
! 14695: return (UNBOUNDED);
! 14696: if ((max < cur) || (max == -1))
! 14697: max = cur;
! 14698: }
! 14699: /* TODO: Handle overflows? */
! 14700: return (particle->maxOccurs * max);
! 14701: } else {
! 14702: /* <all> and <sequence> */
! 14703: int sum = 0, cur;
! 14704: xmlSchemaParticlePtr part =
! 14705: (xmlSchemaParticlePtr) particle->children->children;
! 14706:
! 14707: for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
! 14708: if (part->children == NULL)
! 14709: continue;
! 14710: if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
! 14711: (part->children->type == XML_SCHEMA_TYPE_ANY))
! 14712: cur = part->maxOccurs;
! 14713: else
! 14714: cur = xmlSchemaGetParticleTotalRangeMax(part);
! 14715: if (cur == UNBOUNDED)
! 14716: return (UNBOUNDED);
! 14717: if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
! 14718: return (UNBOUNDED);
! 14719: sum += cur;
! 14720: }
! 14721: /* TODO: Handle overflows? */
! 14722: return (particle->maxOccurs * sum);
! 14723: }
! 14724: }
! 14725: #endif
! 14726:
! 14727: /**
! 14728: * xmlSchemaIsParticleEmptiable:
! 14729: * @particle: the particle
! 14730: *
! 14731: * Schema Component Constraint: Particle Emptiable
! 14732: * Checks whether the given particle is emptiable.
! 14733: *
! 14734: * Returns 1 if emptiable, 0 otherwise.
! 14735: */
! 14736: static int
! 14737: xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
! 14738: {
! 14739: /*
! 14740: * SPEC (1) "Its {min occurs} is 0."
! 14741: */
! 14742: if ((particle == NULL) || (particle->minOccurs == 0) ||
! 14743: (particle->children == NULL))
! 14744: return (1);
! 14745: /*
! 14746: * SPEC (2) "Its {term} is a group and the minimum part of the
! 14747: * effective total range of that group, [...] is 0."
! 14748: */
! 14749: if (WXS_IS_MODEL_GROUP(particle->children)) {
! 14750: if (xmlSchemaGetParticleTotalRangeMin(particle) == 0)
! 14751: return (1);
! 14752: }
! 14753: return (0);
! 14754: }
! 14755:
! 14756: /**
! 14757: * xmlSchemaCheckCOSSTDerivedOK:
! 14758: * @actxt: a context
! 14759: * @type: the derived simple type definition
! 14760: * @baseType: the base type definition
! 14761: * @subset: the subset of ('restriction', ect.)
! 14762: *
! 14763: * Schema Component Constraint:
! 14764: * Type Derivation OK (Simple) (cos-st-derived-OK)
! 14765: *
! 14766: * Checks wheter @type can be validly
! 14767: * derived from @baseType.
! 14768: *
! 14769: * Returns 0 on success, an positive error code otherwise.
! 14770: */
! 14771: static int
! 14772: xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
! 14773: xmlSchemaTypePtr type,
! 14774: xmlSchemaTypePtr baseType,
! 14775: int subset)
! 14776: {
! 14777: /*
! 14778: * 1 They are the same type definition.
! 14779: * TODO: The identy check might have to be more complex than this.
! 14780: */
! 14781: if (type == baseType)
! 14782: return (0);
! 14783: /*
! 14784: * 2.1 restriction is not in the subset, or in the {final}
! 14785: * of its own {base type definition};
! 14786: *
! 14787: * NOTE that this will be used also via "xsi:type".
! 14788: *
! 14789: * TODO: Revise this, it looks strange. How can the "type"
! 14790: * not be fixed or *in* fixing?
! 14791: */
! 14792: if (WXS_IS_TYPE_NOT_FIXED(type))
! 14793: if (xmlSchemaTypeFixup(type, actxt) == -1)
! 14794: return(-1);
! 14795: if (WXS_IS_TYPE_NOT_FIXED(baseType))
! 14796: if (xmlSchemaTypeFixup(baseType, actxt) == -1)
! 14797: return(-1);
! 14798: if ((subset & SUBSET_RESTRICTION) ||
! 14799: (xmlSchemaTypeFinalContains(type->baseType,
! 14800: XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
! 14801: return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
! 14802: }
! 14803: /* 2.2 */
! 14804: if (type->baseType == baseType) {
! 14805: /*
! 14806: * 2.2.1 D's �base type definition� is B.
! 14807: */
! 14808: return (0);
! 14809: }
! 14810: /*
! 14811: * 2.2.2 D's �base type definition� is not the �ur-type definition�
! 14812: * and is validly derived from B given the subset, as defined by this
! 14813: * constraint.
! 14814: */
! 14815: if ((! WXS_IS_ANYTYPE(type->baseType)) &&
! 14816: (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
! 14817: baseType, subset) == 0)) {
! 14818: return (0);
! 14819: }
! 14820: /*
! 14821: * 2.2.3 D's {variety} is list or union and B is the �simple ur-type
! 14822: * definition�.
! 14823: */
! 14824: if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
! 14825: (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
! 14826: return (0);
! 14827: }
! 14828: /*
! 14829: * 2.2.4 B's {variety} is union and D is validly derived from a type
! 14830: * definition in B's {member type definitions} given the subset, as
! 14831: * defined by this constraint.
! 14832: *
! 14833: * NOTE: This seems not to involve built-in types, since there is no
! 14834: * built-in Union Simple Type.
! 14835: */
! 14836: if (WXS_IS_UNION(baseType)) {
! 14837: xmlSchemaTypeLinkPtr cur;
! 14838:
! 14839: cur = baseType->memberTypes;
! 14840: while (cur != NULL) {
! 14841: if (WXS_IS_TYPE_NOT_FIXED(cur->type))
! 14842: if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
! 14843: return(-1);
! 14844: if (xmlSchemaCheckCOSSTDerivedOK(actxt,
! 14845: type, cur->type, subset) == 0)
! 14846: {
! 14847: /*
! 14848: * It just has to be validly derived from at least one
! 14849: * member-type.
! 14850: */
! 14851: return (0);
! 14852: }
! 14853: cur = cur->next;
! 14854: }
! 14855: }
! 14856: return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
! 14857: }
! 14858:
! 14859: /**
! 14860: * xmlSchemaCheckTypeDefCircularInternal:
! 14861: * @pctxt: the schema parser context
! 14862: * @ctxtType: the type definition
! 14863: * @ancestor: an ancestor of @ctxtType
! 14864: *
! 14865: * Checks st-props-correct (2) + ct-props-correct (3).
! 14866: * Circular type definitions are not allowed.
! 14867: *
! 14868: * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
! 14869: * circular, 0 otherwise.
! 14870: */
! 14871: static int
! 14872: xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
! 14873: xmlSchemaTypePtr ctxtType,
! 14874: xmlSchemaTypePtr ancestor)
! 14875: {
! 14876: int ret;
! 14877:
! 14878: if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
! 14879: return (0);
! 14880:
! 14881: if (ctxtType == ancestor) {
! 14882: xmlSchemaPCustomErr(pctxt,
! 14883: XML_SCHEMAP_ST_PROPS_CORRECT_2,
! 14884: WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
! 14885: "The definition is circular", NULL);
! 14886: return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
! 14887: }
! 14888: if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
! 14889: /*
! 14890: * Avoid inifinite recursion on circular types not yet checked.
! 14891: */
! 14892: return (0);
! 14893: }
! 14894: ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
! 14895: ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
! 14896: ancestor->baseType);
! 14897: ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
! 14898: return (ret);
! 14899: }
! 14900:
! 14901: /**
! 14902: * xmlSchemaCheckTypeDefCircular:
! 14903: * @item: the complex/simple type definition
! 14904: * @ctxt: the parser context
! 14905: * @name: the name
! 14906: *
! 14907: * Checks for circular type definitions.
! 14908: */
! 14909: static void
! 14910: xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
! 14911: xmlSchemaParserCtxtPtr ctxt)
! 14912: {
! 14913: if ((item == NULL) ||
! 14914: (item->type == XML_SCHEMA_TYPE_BASIC) ||
! 14915: (item->baseType == NULL))
! 14916: return;
! 14917: xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
! 14918: item->baseType);
! 14919: }
! 14920:
! 14921: /*
! 14922: * Simple Type Definition Representation OK (src-simple-type) 4
! 14923: *
! 14924: * "4 Circular union type definition is disallowed. That is, if the
! 14925: * <union> alternative is chosen, there must not be any entries in the
! 14926: * memberTypes [attribute] at any depth which resolve to the component
! 14927: * corresponding to the <simpleType>."
! 14928: *
! 14929: * Note that this should work on the *representation* of a component,
! 14930: * thus assumes any union types in the member types not being yet
! 14931: * substituted. At this stage we need the variety of the types
! 14932: * to be already computed.
! 14933: */
! 14934: static int
! 14935: xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
! 14936: xmlSchemaTypePtr ctxType,
! 14937: xmlSchemaTypeLinkPtr members)
! 14938: {
! 14939: xmlSchemaTypeLinkPtr member;
! 14940: xmlSchemaTypePtr memberType;
! 14941:
! 14942: member = members;
! 14943: while (member != NULL) {
! 14944: memberType = member->type;
! 14945: while ((memberType != NULL) &&
! 14946: (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
! 14947: if (memberType == ctxType) {
! 14948: xmlSchemaPCustomErr(pctxt,
! 14949: XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
! 14950: WXS_BASIC_CAST ctxType, NULL,
! 14951: "The union type definition is circular", NULL);
! 14952: return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
! 14953: }
! 14954: if ((WXS_IS_UNION(memberType)) &&
! 14955: ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
! 14956: {
! 14957: int res;
! 14958: memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
! 14959: res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
! 14960: ctxType,
! 14961: xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
! 14962: memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
! 14963: if (res != 0)
! 14964: return(res);
! 14965: }
! 14966: memberType = memberType->baseType;
! 14967: }
! 14968: member = member->next;
! 14969: }
! 14970: return(0);
! 14971: }
! 14972:
! 14973: static int
! 14974: xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
! 14975: xmlSchemaTypePtr type)
! 14976: {
! 14977: if (! WXS_IS_UNION(type))
! 14978: return(0);
! 14979: return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
! 14980: type->memberTypes));
! 14981: }
! 14982:
! 14983: /**
! 14984: * xmlSchemaResolveTypeReferences:
! 14985: * @item: the complex/simple type definition
! 14986: * @ctxt: the parser context
! 14987: * @name: the name
! 14988: *
! 14989: * Resolvese type definition references
! 14990: */
! 14991: static void
! 14992: xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
! 14993: xmlSchemaParserCtxtPtr ctxt)
! 14994: {
! 14995: if (typeDef == NULL)
! 14996: return;
! 14997:
! 14998: /*
! 14999: * Resolve the base type.
! 15000: */
! 15001: if (typeDef->baseType == NULL) {
! 15002: typeDef->baseType = xmlSchemaGetType(ctxt->schema,
! 15003: typeDef->base, typeDef->baseNs);
! 15004: if (typeDef->baseType == NULL) {
! 15005: xmlSchemaPResCompAttrErr(ctxt,
! 15006: XML_SCHEMAP_SRC_RESOLVE,
! 15007: WXS_BASIC_CAST typeDef, typeDef->node,
! 15008: "base", typeDef->base, typeDef->baseNs,
! 15009: XML_SCHEMA_TYPE_SIMPLE, NULL);
! 15010: return;
! 15011: }
! 15012: }
! 15013: if (WXS_IS_SIMPLE(typeDef)) {
! 15014: if (WXS_IS_UNION(typeDef)) {
! 15015: /*
! 15016: * Resolve the memberTypes.
! 15017: */
! 15018: xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
! 15019: return;
! 15020: } else if (WXS_IS_LIST(typeDef)) {
! 15021: /*
! 15022: * Resolve the itemType.
! 15023: */
! 15024: if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
! 15025:
! 15026: typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
! 15027: typeDef->base, typeDef->baseNs);
! 15028:
! 15029: if ((typeDef->subtypes == NULL) ||
! 15030: (! WXS_IS_SIMPLE(typeDef->subtypes)))
! 15031: {
! 15032: typeDef->subtypes = NULL;
! 15033: xmlSchemaPResCompAttrErr(ctxt,
! 15034: XML_SCHEMAP_SRC_RESOLVE,
! 15035: WXS_BASIC_CAST typeDef, typeDef->node,
! 15036: "itemType", typeDef->base, typeDef->baseNs,
! 15037: XML_SCHEMA_TYPE_SIMPLE, NULL);
! 15038: }
! 15039: }
! 15040: return;
! 15041: }
! 15042: }
! 15043: /*
! 15044: * The ball of letters below means, that if we have a particle
! 15045: * which has a QName-helper component as its {term}, we want
! 15046: * to resolve it...
! 15047: */
! 15048: else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
! 15049: ((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
! 15050: XML_SCHEMA_TYPE_PARTICLE) &&
! 15051: (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
! 15052: ((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
! 15053: XML_SCHEMA_EXTRA_QNAMEREF))
! 15054: {
! 15055: xmlSchemaQNameRefPtr ref =
! 15056: WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
! 15057: xmlSchemaModelGroupDefPtr groupDef;
! 15058:
! 15059: /*
! 15060: * URGENT TODO: Test this.
! 15061: */
! 15062: WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
! 15063: /*
! 15064: * Resolve the MG definition reference.
! 15065: */
! 15066: groupDef =
! 15067: WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
! 15068: ref->itemType, ref->name, ref->targetNamespace);
! 15069: if (groupDef == NULL) {
! 15070: xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
! 15071: NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
! 15072: "ref", ref->name, ref->targetNamespace, ref->itemType,
! 15073: NULL);
! 15074: /* Remove the particle. */
! 15075: WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
! 15076: } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
! 15077: /* Remove the particle. */
! 15078: WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
! 15079: else {
! 15080: /*
! 15081: * Assign the MG definition's {model group} to the
! 15082: * particle's {term}.
! 15083: */
! 15084: WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
! 15085:
! 15086: if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
! 15087: /*
! 15088: * SPEC cos-all-limited (1.2)
! 15089: * "1.2 the {term} property of a particle with
! 15090: * {max occurs}=1 which is part of a pair which constitutes
! 15091: * the {content type} of a complex type definition."
! 15092: */
! 15093: if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
! 15094: xmlSchemaCustomErr(ACTXT_CAST ctxt,
! 15095: /* TODO: error code */
! 15096: XML_SCHEMAP_COS_ALL_LIMITED,
! 15097: WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
! 15098: "The particle's {max occurs} must be 1, since the "
! 15099: "reference resolves to an 'all' model group",
! 15100: NULL, NULL);
! 15101: }
! 15102: }
! 15103: }
! 15104: }
! 15105: }
! 15106:
! 15107:
! 15108:
! 15109: /**
! 15110: * xmlSchemaCheckSTPropsCorrect:
! 15111: * @ctxt: the schema parser context
! 15112: * @type: the simple type definition
! 15113: *
! 15114: * Checks st-props-correct.
! 15115: *
! 15116: * Returns 0 if the properties are correct,
! 15117: * if not, a positive error code and -1 on internal
! 15118: * errors.
! 15119: */
! 15120: static int
! 15121: xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
! 15122: xmlSchemaTypePtr type)
! 15123: {
! 15124: xmlSchemaTypePtr baseType = type->baseType;
! 15125: xmlChar *str = NULL;
! 15126:
! 15127: /* STATE: error funcs converted. */
! 15128: /*
! 15129: * Schema Component Constraint: Simple Type Definition Properties Correct
! 15130: *
! 15131: * NOTE: This is somehow redundant, since we actually built a simple type
! 15132: * to have all the needed information; this acts as an self test.
! 15133: */
! 15134: /* Base type: If the datatype has been �derived� by �restriction�
! 15135: * then the Simple Type Definition component from which it is �derived�,
! 15136: * otherwise the Simple Type Definition for anySimpleType (�4.1.6).
! 15137: */
! 15138: if (baseType == NULL) {
! 15139: /*
! 15140: * TODO: Think about: "modulo the impact of Missing
! 15141: * Sub-components (�5.3)."
! 15142: */
! 15143: xmlSchemaPCustomErr(ctxt,
! 15144: XML_SCHEMAP_ST_PROPS_CORRECT_1,
! 15145: WXS_BASIC_CAST type, NULL,
! 15146: "No base type existent", NULL);
! 15147: return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
! 15148:
! 15149: }
! 15150: if (! WXS_IS_SIMPLE(baseType)) {
! 15151: xmlSchemaPCustomErr(ctxt,
! 15152: XML_SCHEMAP_ST_PROPS_CORRECT_1,
! 15153: WXS_BASIC_CAST type, NULL,
! 15154: "The base type '%s' is not a simple type",
! 15155: xmlSchemaGetComponentQName(&str, baseType));
! 15156: FREE_AND_NULL(str)
! 15157: return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
! 15158: }
! 15159: if ( (WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
! 15160: (WXS_IS_RESTRICTION(type) == 0) &&
! 15161: (! WXS_IS_ANY_SIMPLE_TYPE(baseType))) {
! 15162: xmlSchemaPCustomErr(ctxt,
! 15163: XML_SCHEMAP_ST_PROPS_CORRECT_1,
! 15164: WXS_BASIC_CAST type, NULL,
! 15165: "A type, derived by list or union, must have "
! 15166: "the simple ur-type definition as base type, not '%s'",
! 15167: xmlSchemaGetComponentQName(&str, baseType));
! 15168: FREE_AND_NULL(str)
! 15169: return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
! 15170: }
! 15171: /*
! 15172: * Variety: One of {atomic, list, union}.
! 15173: */
! 15174: if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
! 15175: (! WXS_IS_LIST(type))) {
! 15176: xmlSchemaPCustomErr(ctxt,
! 15177: XML_SCHEMAP_ST_PROPS_CORRECT_1,
! 15178: WXS_BASIC_CAST type, NULL,
! 15179: "The variety is absent", NULL);
! 15180: return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
! 15181: }
! 15182: /* TODO: Finish this. Hmm, is this finished? */
! 15183:
! 15184: /*
! 15185: * 3 The {final} of the {base type definition} must not contain restriction.
! 15186: */
! 15187: if (xmlSchemaTypeFinalContains(baseType,
! 15188: XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
! 15189: xmlSchemaPCustomErr(ctxt,
! 15190: XML_SCHEMAP_ST_PROPS_CORRECT_3,
! 15191: WXS_BASIC_CAST type, NULL,
! 15192: "The 'final' of its base type '%s' must not contain "
! 15193: "'restriction'",
! 15194: xmlSchemaGetComponentQName(&str, baseType));
! 15195: FREE_AND_NULL(str)
! 15196: return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
! 15197: }
! 15198:
! 15199: /*
! 15200: * 2 All simple type definitions must be derived ultimately from the �simple
! 15201: * ur-type definition (so� circular definitions are disallowed). That is, it
! 15202: * must be possible to reach a built-in primitive datatype or the �simple
! 15203: * ur-type definition� by repeatedly following the {base type definition}.
! 15204: *
! 15205: * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
! 15206: */
! 15207: return (0);
! 15208: }
! 15209:
! 15210: /**
! 15211: * xmlSchemaCheckCOSSTRestricts:
! 15212: * @ctxt: the schema parser context
! 15213: * @type: the simple type definition
! 15214: *
! 15215: * Schema Component Constraint:
! 15216: * Derivation Valid (Restriction, Simple) (cos-st-restricts)
! 15217:
! 15218: * Checks if the given @type (simpleType) is derived validly by restriction.
! 15219: * STATUS:
! 15220: *
! 15221: * Returns -1 on internal errors, 0 if the type is validly derived,
! 15222: * a positive error code otherwise.
! 15223: */
! 15224: static int
! 15225: xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
! 15226: xmlSchemaTypePtr type)
! 15227: {
! 15228: xmlChar *str = NULL;
! 15229:
! 15230: if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
! 15231: PERROR_INT("xmlSchemaCheckCOSSTRestricts",
! 15232: "given type is not a user-derived simpleType");
! 15233: return (-1);
! 15234: }
! 15235:
! 15236: if (WXS_IS_ATOMIC(type)) {
! 15237: xmlSchemaTypePtr primitive;
! 15238: /*
! 15239: * 1.1 The {base type definition} must be an atomic simple
! 15240: * type definition or a built-in primitive datatype.
! 15241: */
! 15242: if (! WXS_IS_ATOMIC(type->baseType)) {
! 15243: xmlSchemaPCustomErr(pctxt,
! 15244: XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
! 15245: WXS_BASIC_CAST type, NULL,
! 15246: "The base type '%s' is not an atomic simple type",
! 15247: xmlSchemaGetComponentQName(&str, type->baseType));
! 15248: FREE_AND_NULL(str)
! 15249: return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
! 15250: }
! 15251: /* 1.2 The {final} of the {base type definition} must not contain
! 15252: * restriction.
! 15253: */
! 15254: /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
! 15255: if (xmlSchemaTypeFinalContains(type->baseType,
! 15256: XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
! 15257: xmlSchemaPCustomErr(pctxt,
! 15258: XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
! 15259: WXS_BASIC_CAST type, NULL,
! 15260: "The final of its base type '%s' must not contain 'restriction'",
! 15261: xmlSchemaGetComponentQName(&str, type->baseType));
! 15262: FREE_AND_NULL(str)
! 15263: return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
! 15264: }
! 15265:
! 15266: /*
! 15267: * 1.3.1 DF must be an allowed constraining facet for the {primitive
! 15268: * type definition}, as specified in the appropriate subsection of 3.2
! 15269: * Primitive datatypes.
! 15270: */
! 15271: if (type->facets != NULL) {
! 15272: xmlSchemaFacetPtr facet;
! 15273: int ok = 1;
! 15274:
! 15275: primitive = xmlSchemaGetPrimitiveType(type);
! 15276: if (primitive == NULL) {
! 15277: PERROR_INT("xmlSchemaCheckCOSSTRestricts",
! 15278: "failed to get primitive type");
! 15279: return (-1);
! 15280: }
! 15281: facet = type->facets;
! 15282: do {
! 15283: if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
! 15284: ok = 0;
! 15285: xmlSchemaPIllegalFacetAtomicErr(pctxt,
! 15286: XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
! 15287: type, primitive, facet);
! 15288: }
! 15289: facet = facet->next;
! 15290: } while (facet != NULL);
! 15291: if (ok == 0)
! 15292: return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
! 15293: }
! 15294: /*
! 15295: * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
! 15296: * of the {base type definition} (call this BF),then the DF's {value}
! 15297: * must be a valid restriction of BF's {value} as defined in
! 15298: * [XML Schemas: Datatypes]."
! 15299: *
! 15300: * NOTE (1.3.2) Facet derivation constraints are currently handled in
! 15301: * xmlSchemaDeriveAndValidateFacets()
! 15302: */
! 15303: } else if (WXS_IS_LIST(type)) {
! 15304: xmlSchemaTypePtr itemType = NULL;
! 15305:
! 15306: itemType = type->subtypes;
! 15307: if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
! 15308: PERROR_INT("xmlSchemaCheckCOSSTRestricts",
! 15309: "failed to evaluate the item type");
! 15310: return (-1);
! 15311: }
! 15312: if (WXS_IS_TYPE_NOT_FIXED(itemType))
! 15313: xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
! 15314: /*
! 15315: * 2.1 The {item type definition} must have a {variety} of atomic or
! 15316: * union (in which case all the {member type definitions}
! 15317: * must be atomic).
! 15318: */
! 15319: if ((! WXS_IS_ATOMIC(itemType)) &&
! 15320: (! WXS_IS_UNION(itemType))) {
! 15321: xmlSchemaPCustomErr(pctxt,
! 15322: XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
! 15323: WXS_BASIC_CAST type, NULL,
! 15324: "The item type '%s' does not have a variety of atomic or union",
! 15325: xmlSchemaGetComponentQName(&str, itemType));
! 15326: FREE_AND_NULL(str)
! 15327: return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
! 15328: } else if (WXS_IS_UNION(itemType)) {
! 15329: xmlSchemaTypeLinkPtr member;
! 15330:
! 15331: member = itemType->memberTypes;
! 15332: while (member != NULL) {
! 15333: if (! WXS_IS_ATOMIC(member->type)) {
! 15334: xmlSchemaPCustomErr(pctxt,
! 15335: XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
! 15336: WXS_BASIC_CAST type, NULL,
! 15337: "The item type is a union type, but the "
! 15338: "member type '%s' of this item type is not atomic",
! 15339: xmlSchemaGetComponentQName(&str, member->type));
! 15340: FREE_AND_NULL(str)
! 15341: return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
! 15342: }
! 15343: member = member->next;
! 15344: }
! 15345: }
! 15346:
! 15347: if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
! 15348: xmlSchemaFacetPtr facet;
! 15349: /*
! 15350: * This is the case if we have: <simpleType><list ..
! 15351: */
! 15352: /*
! 15353: * 2.3.1
! 15354: * 2.3.1.1 The {final} of the {item type definition} must not
! 15355: * contain list.
! 15356: */
! 15357: if (xmlSchemaTypeFinalContains(itemType,
! 15358: XML_SCHEMAS_TYPE_FINAL_LIST)) {
! 15359: xmlSchemaPCustomErr(pctxt,
! 15360: XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
! 15361: WXS_BASIC_CAST type, NULL,
! 15362: "The final of its item type '%s' must not contain 'list'",
! 15363: xmlSchemaGetComponentQName(&str, itemType));
! 15364: FREE_AND_NULL(str)
! 15365: return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
! 15366: }
! 15367: /*
! 15368: * 2.3.1.2 The {facets} must only contain the whiteSpace
! 15369: * facet component.
! 15370: * OPTIMIZE TODO: the S4S already disallows any facet
! 15371: * to be specified.
! 15372: */
! 15373: if (type->facets != NULL) {
! 15374: facet = type->facets;
! 15375: do {
! 15376: if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
! 15377: xmlSchemaPIllegalFacetListUnionErr(pctxt,
! 15378: XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
! 15379: type, facet);
! 15380: return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
! 15381: }
! 15382: facet = facet->next;
! 15383: } while (facet != NULL);
! 15384: }
! 15385: /*
! 15386: * MAYBE TODO: (Hmm, not really) Datatypes states:
! 15387: * A �list� datatype can be �derived� from an �atomic� datatype
! 15388: * whose �lexical space� allows space (such as string or anyURI)or
! 15389: * a �union� datatype any of whose {member type definitions}'s
! 15390: * �lexical space� allows space.
! 15391: */
! 15392: } else {
! 15393: /*
! 15394: * This is the case if we have: <simpleType><restriction ...
! 15395: * I.e. the variety of "list" is inherited.
! 15396: */
! 15397: /*
! 15398: * 2.3.2
! 15399: * 2.3.2.1 The {base type definition} must have a {variety} of list.
! 15400: */
! 15401: if (! WXS_IS_LIST(type->baseType)) {
! 15402: xmlSchemaPCustomErr(pctxt,
! 15403: XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
! 15404: WXS_BASIC_CAST type, NULL,
! 15405: "The base type '%s' must be a list type",
! 15406: xmlSchemaGetComponentQName(&str, type->baseType));
! 15407: FREE_AND_NULL(str)
! 15408: return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
! 15409: }
! 15410: /*
! 15411: * 2.3.2.2 The {final} of the {base type definition} must not
! 15412: * contain restriction.
! 15413: */
! 15414: if (xmlSchemaTypeFinalContains(type->baseType,
! 15415: XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
! 15416: xmlSchemaPCustomErr(pctxt,
! 15417: XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
! 15418: WXS_BASIC_CAST type, NULL,
! 15419: "The 'final' of the base type '%s' must not contain 'restriction'",
! 15420: xmlSchemaGetComponentQName(&str, type->baseType));
! 15421: FREE_AND_NULL(str)
! 15422: return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
! 15423: }
! 15424: /*
! 15425: * 2.3.2.3 The {item type definition} must be validly derived
! 15426: * from the {base type definition}'s {item type definition} given
! 15427: * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6).
! 15428: */
! 15429: {
! 15430: xmlSchemaTypePtr baseItemType;
! 15431:
! 15432: baseItemType = type->baseType->subtypes;
! 15433: if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
! 15434: PERROR_INT("xmlSchemaCheckCOSSTRestricts",
! 15435: "failed to eval the item type of a base type");
! 15436: return (-1);
! 15437: }
! 15438: if ((itemType != baseItemType) &&
! 15439: (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
! 15440: baseItemType, 0) != 0)) {
! 15441: xmlChar *strBIT = NULL, *strBT = NULL;
! 15442: xmlSchemaPCustomErrExt(pctxt,
! 15443: XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
! 15444: WXS_BASIC_CAST type, NULL,
! 15445: "The item type '%s' is not validly derived from "
! 15446: "the item type '%s' of the base type '%s'",
! 15447: xmlSchemaGetComponentQName(&str, itemType),
! 15448: xmlSchemaGetComponentQName(&strBIT, baseItemType),
! 15449: xmlSchemaGetComponentQName(&strBT, type->baseType));
! 15450:
! 15451: FREE_AND_NULL(str)
! 15452: FREE_AND_NULL(strBIT)
! 15453: FREE_AND_NULL(strBT)
! 15454: return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
! 15455: }
! 15456: }
! 15457:
! 15458: if (type->facets != NULL) {
! 15459: xmlSchemaFacetPtr facet;
! 15460: int ok = 1;
! 15461: /*
! 15462: * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
! 15463: * and enumeration facet components are allowed among the {facets}.
! 15464: */
! 15465: facet = type->facets;
! 15466: do {
! 15467: switch (facet->type) {
! 15468: case XML_SCHEMA_FACET_LENGTH:
! 15469: case XML_SCHEMA_FACET_MINLENGTH:
! 15470: case XML_SCHEMA_FACET_MAXLENGTH:
! 15471: case XML_SCHEMA_FACET_WHITESPACE:
! 15472: /*
! 15473: * TODO: 2.5.1.2 List datatypes
! 15474: * The value of �whiteSpace� is fixed to the value collapse.
! 15475: */
! 15476: case XML_SCHEMA_FACET_PATTERN:
! 15477: case XML_SCHEMA_FACET_ENUMERATION:
! 15478: break;
! 15479: default: {
! 15480: xmlSchemaPIllegalFacetListUnionErr(pctxt,
! 15481: XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
! 15482: type, facet);
! 15483: /*
! 15484: * We could return, but it's nicer to report all
! 15485: * invalid facets.
! 15486: */
! 15487: ok = 0;
! 15488: }
! 15489: }
! 15490: facet = facet->next;
! 15491: } while (facet != NULL);
! 15492: if (ok == 0)
! 15493: return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
! 15494: /*
! 15495: * SPEC (2.3.2.5) (same as 1.3.2)
! 15496: *
! 15497: * NOTE (2.3.2.5) This is currently done in
! 15498: * xmlSchemaDeriveAndValidateFacets()
! 15499: */
! 15500: }
! 15501: }
! 15502: } else if (WXS_IS_UNION(type)) {
! 15503: /*
! 15504: * 3.1 The {member type definitions} must all have {variety} of
! 15505: * atomic or list.
! 15506: */
! 15507: xmlSchemaTypeLinkPtr member;
! 15508:
! 15509: member = type->memberTypes;
! 15510: while (member != NULL) {
! 15511: if (WXS_IS_TYPE_NOT_FIXED(member->type))
! 15512: xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
! 15513:
! 15514: if ((! WXS_IS_ATOMIC(member->type)) &&
! 15515: (! WXS_IS_LIST(member->type))) {
! 15516: xmlSchemaPCustomErr(pctxt,
! 15517: XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
! 15518: WXS_BASIC_CAST type, NULL,
! 15519: "The member type '%s' is neither an atomic, nor a list type",
! 15520: xmlSchemaGetComponentQName(&str, member->type));
! 15521: FREE_AND_NULL(str)
! 15522: return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
! 15523: }
! 15524: member = member->next;
! 15525: }
! 15526: /*
! 15527: * 3.3.1 If the {base type definition} is the �simple ur-type
! 15528: * definition�
! 15529: */
! 15530: if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
! 15531: /*
! 15532: * 3.3.1.1 All of the {member type definitions} must have a
! 15533: * {final} which does not contain union.
! 15534: */
! 15535: member = type->memberTypes;
! 15536: while (member != NULL) {
! 15537: if (xmlSchemaTypeFinalContains(member->type,
! 15538: XML_SCHEMAS_TYPE_FINAL_UNION)) {
! 15539: xmlSchemaPCustomErr(pctxt,
! 15540: XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
! 15541: WXS_BASIC_CAST type, NULL,
! 15542: "The 'final' of member type '%s' contains 'union'",
! 15543: xmlSchemaGetComponentQName(&str, member->type));
! 15544: FREE_AND_NULL(str)
! 15545: return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
! 15546: }
! 15547: member = member->next;
! 15548: }
! 15549: /*
! 15550: * 3.3.1.2 The {facets} must be empty.
! 15551: */
! 15552: if (type->facetSet != NULL) {
! 15553: xmlSchemaPCustomErr(pctxt,
! 15554: XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
! 15555: WXS_BASIC_CAST type, NULL,
! 15556: "No facets allowed", NULL);
! 15557: return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
! 15558: }
! 15559: } else {
! 15560: /*
! 15561: * 3.3.2.1 The {base type definition} must have a {variety} of union.
! 15562: * I.e. the variety of "list" is inherited.
! 15563: */
! 15564: if (! WXS_IS_UNION(type->baseType)) {
! 15565: xmlSchemaPCustomErr(pctxt,
! 15566: XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
! 15567: WXS_BASIC_CAST type, NULL,
! 15568: "The base type '%s' is not a union type",
! 15569: xmlSchemaGetComponentQName(&str, type->baseType));
! 15570: FREE_AND_NULL(str)
! 15571: return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
! 15572: }
! 15573: /*
! 15574: * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
! 15575: */
! 15576: if (xmlSchemaTypeFinalContains(type->baseType,
! 15577: XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
! 15578: xmlSchemaPCustomErr(pctxt,
! 15579: XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
! 15580: WXS_BASIC_CAST type, NULL,
! 15581: "The 'final' of its base type '%s' must not contain 'restriction'",
! 15582: xmlSchemaGetComponentQName(&str, type->baseType));
! 15583: FREE_AND_NULL(str)
! 15584: return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
! 15585: }
! 15586: /*
! 15587: * 3.3.2.3 The {member type definitions}, in order, must be validly
! 15588: * derived from the corresponding type definitions in the {base
! 15589: * type definition}'s {member type definitions} given the empty set,
! 15590: * as defined in Type Derivation OK (Simple) (�3.14.6).
! 15591: */
! 15592: {
! 15593: xmlSchemaTypeLinkPtr baseMember;
! 15594:
! 15595: /*
! 15596: * OPTIMIZE: if the type is restricting, it has no local defined
! 15597: * member types and inherits the member types of the base type;
! 15598: * thus a check for equality can be skipped.
! 15599: */
! 15600: /*
! 15601: * Even worse: I cannot see a scenario where a restricting
! 15602: * union simple type can have other member types as the member
! 15603: * types of it's base type. This check seems not necessary with
! 15604: * respect to the derivation process in libxml2.
! 15605: * But necessary if constructing types with an API.
! 15606: */
! 15607: if (type->memberTypes != NULL) {
! 15608: member = type->memberTypes;
! 15609: baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
! 15610: if ((member == NULL) && (baseMember != NULL)) {
! 15611: PERROR_INT("xmlSchemaCheckCOSSTRestricts",
! 15612: "different number of member types in base");
! 15613: }
! 15614: while (member != NULL) {
! 15615: if (baseMember == NULL) {
! 15616: PERROR_INT("xmlSchemaCheckCOSSTRestricts",
! 15617: "different number of member types in base");
! 15618: } else if ((member->type != baseMember->type) &&
! 15619: (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
! 15620: member->type, baseMember->type, 0) != 0)) {
! 15621: xmlChar *strBMT = NULL, *strBT = NULL;
! 15622:
! 15623: xmlSchemaPCustomErrExt(pctxt,
! 15624: XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
! 15625: WXS_BASIC_CAST type, NULL,
! 15626: "The member type %s is not validly "
! 15627: "derived from its corresponding member "
! 15628: "type %s of the base type %s",
! 15629: xmlSchemaGetComponentQName(&str, member->type),
! 15630: xmlSchemaGetComponentQName(&strBMT, baseMember->type),
! 15631: xmlSchemaGetComponentQName(&strBT, type->baseType));
! 15632: FREE_AND_NULL(str)
! 15633: FREE_AND_NULL(strBMT)
! 15634: FREE_AND_NULL(strBT)
! 15635: return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
! 15636: }
! 15637: member = member->next;
! 15638: if (baseMember != NULL)
! 15639: baseMember = baseMember->next;
! 15640: }
! 15641: }
! 15642: }
! 15643: /*
! 15644: * 3.3.2.4 Only pattern and enumeration facet components are
! 15645: * allowed among the {facets}.
! 15646: */
! 15647: if (type->facets != NULL) {
! 15648: xmlSchemaFacetPtr facet;
! 15649: int ok = 1;
! 15650:
! 15651: facet = type->facets;
! 15652: do {
! 15653: if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
! 15654: (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
! 15655: xmlSchemaPIllegalFacetListUnionErr(pctxt,
! 15656: XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
! 15657: type, facet);
! 15658: ok = 0;
! 15659: }
! 15660: facet = facet->next;
! 15661: } while (facet != NULL);
! 15662: if (ok == 0)
! 15663: return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
! 15664:
! 15665: }
! 15666: /*
! 15667: * SPEC (3.3.2.5) (same as 1.3.2)
! 15668: *
! 15669: * NOTE (3.3.2.5) This is currently done in
! 15670: * xmlSchemaDeriveAndValidateFacets()
! 15671: */
! 15672: }
! 15673: }
! 15674:
! 15675: return (0);
! 15676: }
! 15677:
! 15678: /**
! 15679: * xmlSchemaCheckSRCSimpleType:
! 15680: * @ctxt: the schema parser context
! 15681: * @type: the simple type definition
! 15682: *
! 15683: * Checks crc-simple-type constraints.
! 15684: *
! 15685: * Returns 0 if the constraints are satisfied,
! 15686: * if not a positive error code and -1 on internal
! 15687: * errors.
! 15688: */
! 15689: #if 0
! 15690: static int
! 15691: xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
! 15692: xmlSchemaTypePtr type)
! 15693: {
! 15694: /*
! 15695: * src-simple-type.1 The corresponding simple type definition, if any,
! 15696: * must satisfy the conditions set out in Constraints on Simple Type
! 15697: * Definition Schema Components (�3.14.6).
! 15698: */
! 15699: if (WXS_IS_RESTRICTION(type)) {
! 15700: /*
! 15701: * src-simple-type.2 "If the <restriction> alternative is chosen,
! 15702: * either it must have a base [attribute] or a <simpleType> among its
! 15703: * [children], but not both."
! 15704: * NOTE: This is checked in the parse function of <restriction>.
! 15705: */
! 15706: /*
! 15707: *
! 15708: */
! 15709: } else if (WXS_IS_LIST(type)) {
! 15710: /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
! 15711: * an itemType [attribute] or a <simpleType> among its [children],
! 15712: * but not both."
! 15713: *
! 15714: * NOTE: This is checked in the parse function of <list>.
! 15715: */
! 15716: } else if (WXS_IS_UNION(type)) {
! 15717: /*
! 15718: * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
! 15719: */
! 15720: }
! 15721: return (0);
! 15722: }
! 15723: #endif
! 15724:
! 15725: static int
! 15726: xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
! 15727: {
! 15728: if (ctxt->vctxt == NULL) {
! 15729: ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
! 15730: if (ctxt->vctxt == NULL) {
! 15731: xmlSchemaPErr(ctxt, NULL,
! 15732: XML_SCHEMAP_INTERNAL,
! 15733: "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
! 15734: "failed to create a temp. validation context.\n",
! 15735: NULL, NULL);
! 15736: return (-1);
! 15737: }
! 15738: /* TODO: Pass user data. */
! 15739: xmlSchemaSetValidErrors(ctxt->vctxt,
! 15740: ctxt->error, ctxt->warning, ctxt->errCtxt);
! 15741: xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
! 15742: ctxt->serror, ctxt->errCtxt);
! 15743: }
! 15744: return (0);
! 15745: }
! 15746:
! 15747: static int
! 15748: xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
! 15749: xmlNodePtr node,
! 15750: xmlSchemaTypePtr type,
! 15751: const xmlChar *value,
! 15752: xmlSchemaValPtr *retVal,
! 15753: int fireErrors,
! 15754: int normalize,
! 15755: int isNormalized);
! 15756:
! 15757: /**
! 15758: * xmlSchemaParseCheckCOSValidDefault:
! 15759: * @pctxt: the schema parser context
! 15760: * @type: the simple type definition
! 15761: * @value: the default value
! 15762: * @node: an optional node (the holder of the value)
! 15763: *
! 15764: * Schema Component Constraint: Element Default Valid (Immediate)
! 15765: * (cos-valid-default)
! 15766: * This will be used by the parser only. For the validator there's
! 15767: * an other version.
! 15768: *
! 15769: * Returns 0 if the constraints are satisfied,
! 15770: * if not, a positive error code and -1 on internal
! 15771: * errors.
! 15772: */
! 15773: static int
! 15774: xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
! 15775: xmlNodePtr node,
! 15776: xmlSchemaTypePtr type,
! 15777: const xmlChar *value,
! 15778: xmlSchemaValPtr *val)
! 15779: {
! 15780: int ret = 0;
! 15781:
! 15782: /*
! 15783: * cos-valid-default:
! 15784: * Schema Component Constraint: Element Default Valid (Immediate)
! 15785: * For a string to be a valid default with respect to a type
! 15786: * definition the appropriate case among the following must be true:
! 15787: */
! 15788: if WXS_IS_COMPLEX(type) {
! 15789: /*
! 15790: * Complex type.
! 15791: *
! 15792: * SPEC (2.1) "its {content type} must be a simple type definition
! 15793: * or mixed."
! 15794: * SPEC (2.2.2) "If the {content type} is mixed, then the {content
! 15795: * type}'s particle must be �emptiable� as defined by
! 15796: * Particle Emptiable (�3.9.6)."
! 15797: */
! 15798: if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
! 15799: ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
! 15800: /* NOTE that this covers (2.2.2) as well. */
! 15801: xmlSchemaPCustomErr(pctxt,
! 15802: XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
! 15803: WXS_BASIC_CAST type, type->node,
! 15804: "For a string to be a valid default, the type definition "
! 15805: "must be a simple type or a complex type with mixed content "
! 15806: "and a particle emptiable", NULL);
! 15807: return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
! 15808: }
! 15809: }
! 15810: /*
! 15811: * 1 If the type definition is a simple type definition, then the string
! 15812: * must be �valid� with respect to that definition as defined by String
! 15813: * Valid (�3.14.4).
! 15814: *
! 15815: * AND
! 15816: *
! 15817: * 2.2.1 If the {content type} is a simple type definition, then the
! 15818: * string must be �valid� with respect to that simple type definition
! 15819: * as defined by String Valid (�3.14.4).
! 15820: */
! 15821: if (WXS_IS_SIMPLE(type))
! 15822: ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
! 15823: type, value, val, 1, 1, 0);
! 15824: else if (WXS_HAS_SIMPLE_CONTENT(type))
! 15825: ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
! 15826: type->contentTypeDef, value, val, 1, 1, 0);
! 15827: else
! 15828: return (ret);
! 15829:
! 15830: if (ret < 0) {
! 15831: PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
! 15832: "calling xmlSchemaVCheckCVCSimpleType()");
! 15833: }
! 15834:
! 15835: return (ret);
! 15836: }
! 15837:
! 15838: /**
! 15839: * xmlSchemaCheckCTPropsCorrect:
! 15840: * @ctxt: the schema parser context
! 15841: * @type: the complex type definition
! 15842: *
! 15843: *.(4.6) Constraints on Complex Type Definition Schema Components
! 15844: * Schema Component Constraint:
! 15845: * Complex Type Definition Properties Correct (ct-props-correct)
! 15846: * STATUS: (seems) complete
! 15847: *
! 15848: * Returns 0 if the constraints are satisfied, a positive
! 15849: * error code if not and -1 if an internal error occured.
! 15850: */
! 15851: static int
! 15852: xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
! 15853: xmlSchemaTypePtr type)
! 15854: {
! 15855: /*
! 15856: * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
! 15857: *
! 15858: * SPEC (1) "The values of the properties of a complex type definition must
! 15859: * be as described in the property tableau in The Complex Type Definition
! 15860: * Schema Component (�3.4.1), modulo the impact of Missing
! 15861: * Sub-components (�5.3)."
! 15862: */
! 15863: if ((type->baseType != NULL) &&
! 15864: (WXS_IS_SIMPLE(type->baseType)) &&
! 15865: (WXS_IS_EXTENSION(type) == 0)) {
! 15866: /*
! 15867: * SPEC (2) "If the {base type definition} is a simple type definition,
! 15868: * the {derivation method} must be extension."
! 15869: */
! 15870: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 15871: XML_SCHEMAP_SRC_CT_1,
! 15872: NULL, WXS_BASIC_CAST type,
! 15873: "If the base type is a simple type, the derivation method must be "
! 15874: "'extension'", NULL, NULL);
! 15875: return (XML_SCHEMAP_SRC_CT_1);
! 15876: }
! 15877: /*
! 15878: * SPEC (3) "Circular definitions are disallowed, except for the �ur-type
! 15879: * definition�. That is, it must be possible to reach the �ur-type
! 15880: * definition by repeatedly following the {base type definition}."
! 15881: *
! 15882: * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
! 15883: */
! 15884: /*
! 15885: * NOTE that (4) and (5) need the following:
! 15886: * - attribute uses need to be already inherited (apply attr. prohibitions)
! 15887: * - attribute group references need to be expanded already
! 15888: * - simple types need to be typefixed already
! 15889: */
! 15890: if (type->attrUses &&
! 15891: (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
! 15892: {
! 15893: xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
! 15894: xmlSchemaAttributeUsePtr use, tmp;
! 15895: int i, j, hasId = 0;
! 15896:
! 15897: for (i = uses->nbItems -1; i >= 0; i--) {
! 15898: use = uses->items[i];
! 15899:
! 15900: /*
! 15901: * SPEC ct-props-correct
! 15902: * (4) "Two distinct attribute declarations in the
! 15903: * {attribute uses} must not have identical {name}s and
! 15904: * {target namespace}s."
! 15905: */
! 15906: if (i > 0) {
! 15907: for (j = i -1; j >= 0; j--) {
! 15908: tmp = uses->items[j];
! 15909: if ((WXS_ATTRUSE_DECL_NAME(use) ==
! 15910: WXS_ATTRUSE_DECL_NAME(tmp)) &&
! 15911: (WXS_ATTRUSE_DECL_TNS(use) ==
! 15912: WXS_ATTRUSE_DECL_TNS(tmp)))
! 15913: {
! 15914: xmlChar *str = NULL;
! 15915:
! 15916: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 15917: XML_SCHEMAP_AG_PROPS_CORRECT,
! 15918: NULL, WXS_BASIC_CAST type,
! 15919: "Duplicate %s",
! 15920: xmlSchemaGetComponentDesignation(&str, use),
! 15921: NULL);
! 15922: FREE_AND_NULL(str);
! 15923: /*
! 15924: * Remove the duplicate.
! 15925: */
! 15926: if (xmlSchemaItemListRemove(uses, i) == -1)
! 15927: goto exit_failure;
! 15928: goto next_use;
! 15929: }
! 15930: }
! 15931: }
! 15932: /*
! 15933: * SPEC ct-props-correct
! 15934: * (5) "Two distinct attribute declarations in the
! 15935: * {attribute uses} must not have {type definition}s which
! 15936: * are or are derived from ID."
! 15937: */
! 15938: if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
! 15939: if (xmlSchemaIsDerivedFromBuiltInType(
! 15940: WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
! 15941: {
! 15942: if (hasId) {
! 15943: xmlChar *str = NULL;
! 15944:
! 15945: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 15946: XML_SCHEMAP_AG_PROPS_CORRECT,
! 15947: NULL, WXS_BASIC_CAST type,
! 15948: "There must not exist more than one attribute "
! 15949: "declaration of type 'xs:ID' "
! 15950: "(or derived from 'xs:ID'). The %s violates this "
! 15951: "constraint",
! 15952: xmlSchemaGetComponentDesignation(&str, use),
! 15953: NULL);
! 15954: FREE_AND_NULL(str);
! 15955: if (xmlSchemaItemListRemove(uses, i) == -1)
! 15956: goto exit_failure;
! 15957: }
! 15958:
! 15959: hasId = 1;
! 15960: }
! 15961: }
! 15962: next_use: {}
! 15963: }
! 15964: }
! 15965: return (0);
! 15966: exit_failure:
! 15967: return(-1);
! 15968: }
! 15969:
! 15970: static int
! 15971: xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
! 15972: xmlSchemaTypePtr typeB)
! 15973: {
! 15974: /*
! 15975: * TODO: This should implement component-identity
! 15976: * in the future.
! 15977: */
! 15978: if ((typeA == NULL) || (typeB == NULL))
! 15979: return (0);
! 15980: return (typeA == typeB);
! 15981: }
! 15982:
! 15983: /**
! 15984: * xmlSchemaCheckCOSCTDerivedOK:
! 15985: * @ctxt: the schema parser context
! 15986: * @type: the to-be derived complex type definition
! 15987: * @baseType: the base complex type definition
! 15988: * @set: the given set
! 15989: *
! 15990: * Schema Component Constraint:
! 15991: * Type Derivation OK (Complex) (cos-ct-derived-ok)
! 15992: *
! 15993: * STATUS: completed
! 15994: *
! 15995: * Returns 0 if the constraints are satisfied, or 1
! 15996: * if not.
! 15997: */
! 15998: static int
! 15999: xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
! 16000: xmlSchemaTypePtr type,
! 16001: xmlSchemaTypePtr baseType,
! 16002: int set)
! 16003: {
! 16004: int equal = xmlSchemaAreEqualTypes(type, baseType);
! 16005: /* TODO: Error codes. */
! 16006: /*
! 16007: * SPEC "For a complex type definition (call it D, for derived)
! 16008: * to be validly derived from a type definition (call this
! 16009: * B, for base) given a subset of {extension, restriction}
! 16010: * all of the following must be true:"
! 16011: */
! 16012: if (! equal) {
! 16013: /*
! 16014: * SPEC (1) "If B and D are not the same type definition, then the
! 16015: * {derivation method} of D must not be in the subset."
! 16016: */
! 16017: if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
! 16018: ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
! 16019: return (1);
! 16020: } else {
! 16021: /*
! 16022: * SPEC (2.1) "B and D must be the same type definition."
! 16023: */
! 16024: return (0);
! 16025: }
! 16026: /*
! 16027: * SPEC (2.2) "B must be D's {base type definition}."
! 16028: */
! 16029: if (type->baseType == baseType)
! 16030: return (0);
! 16031: /*
! 16032: * SPEC (2.3.1) "D's {base type definition} must not be the �ur-type
! 16033: * definition�."
! 16034: */
! 16035: if (WXS_IS_ANYTYPE(type->baseType))
! 16036: return (1);
! 16037:
! 16038: if (WXS_IS_COMPLEX(type->baseType)) {
! 16039: /*
! 16040: * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
! 16041: * must be validly derived from B given the subset as defined by this
! 16042: * constraint."
! 16043: */
! 16044: return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
! 16045: baseType, set));
! 16046: } else {
! 16047: /*
! 16048: * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
! 16049: * must be validly derived from B given the subset as defined in Type
! 16050: * Derivation OK (Simple) (�3.14.6).
! 16051: */
! 16052: return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
! 16053: baseType, set));
! 16054: }
! 16055: }
! 16056:
! 16057: /**
! 16058: * xmlSchemaCheckCOSDerivedOK:
! 16059: * @type: the derived simple type definition
! 16060: * @baseType: the base type definition
! 16061: *
! 16062: * Calls:
! 16063: * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
! 16064: *
! 16065: * Checks wheter @type can be validly derived from @baseType.
! 16066: *
! 16067: * Returns 0 on success, an positive error code otherwise.
! 16068: */
! 16069: static int
! 16070: xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
! 16071: xmlSchemaTypePtr type,
! 16072: xmlSchemaTypePtr baseType,
! 16073: int set)
! 16074: {
! 16075: if (WXS_IS_SIMPLE(type))
! 16076: return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
! 16077: else
! 16078: return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
! 16079: }
! 16080:
! 16081: /**
! 16082: * xmlSchemaCheckCOSCTExtends:
! 16083: * @ctxt: the schema parser context
! 16084: * @type: the complex type definition
! 16085: *
! 16086: * (3.4.6) Constraints on Complex Type Definition Schema Components
! 16087: * Schema Component Constraint:
! 16088: * Derivation Valid (Extension) (cos-ct-extends)
! 16089: *
! 16090: * STATUS:
! 16091: * missing:
! 16092: * (1.5)
! 16093: * (1.4.3.2.2.2) "Particle Valid (Extension)"
! 16094: *
! 16095: * Returns 0 if the constraints are satisfied, a positive
! 16096: * error code if not and -1 if an internal error occured.
! 16097: */
! 16098: static int
! 16099: xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
! 16100: xmlSchemaTypePtr type)
! 16101: {
! 16102: xmlSchemaTypePtr base = type->baseType;
! 16103: /*
! 16104: * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
! 16105: * temporarily only.
! 16106: */
! 16107: /*
! 16108: * SPEC (1) "If the {base type definition} is a complex type definition,
! 16109: * then all of the following must be true:"
! 16110: */
! 16111: if (WXS_IS_COMPLEX(base)) {
! 16112: /*
! 16113: * SPEC (1.1) "The {final} of the {base type definition} must not
! 16114: * contain extension."
! 16115: */
! 16116: if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
! 16117: xmlSchemaPCustomErr(ctxt,
! 16118: XML_SCHEMAP_COS_CT_EXTENDS_1_1,
! 16119: WXS_BASIC_CAST type, NULL,
! 16120: "The 'final' of the base type definition "
! 16121: "contains 'extension'", NULL);
! 16122: return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
! 16123: }
! 16124:
! 16125: /*
! 16126: * ATTENTION: The constrains (1.2) and (1.3) are not applied,
! 16127: * since they are automatically satisfied through the
! 16128: * inheriting mechanism.
! 16129: * Note that even if redefining components, the inheriting mechanism
! 16130: * is used.
! 16131: */
! 16132: #if 0
! 16133: /*
! 16134: * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
! 16135: * uses}
! 16136: * of the complex type definition itself, that is, for every attribute
! 16137: * use in the {attribute uses} of the {base type definition}, there
! 16138: * must be an attribute use in the {attribute uses} of the complex
! 16139: * type definition itself whose {attribute declaration} has the same
! 16140: * {name}, {target namespace} and {type definition} as its attribute
! 16141: * declaration"
! 16142: */
! 16143: if (base->attrUses != NULL) {
! 16144: int i, j, found;
! 16145: xmlSchemaAttributeUsePtr use, buse;
! 16146:
! 16147: for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
! 16148: buse = (WXS_LIST_CAST base->attrUses)->items[i];
! 16149: found = 0;
! 16150: if (type->attrUses != NULL) {
! 16151: use = (WXS_LIST_CAST type->attrUses)->items[j];
! 16152: for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
! 16153: {
! 16154: if ((WXS_ATTRUSE_DECL_NAME(use) ==
! 16155: WXS_ATTRUSE_DECL_NAME(buse)) &&
! 16156: (WXS_ATTRUSE_DECL_TNS(use) ==
! 16157: WXS_ATTRUSE_DECL_TNS(buse)) &&
! 16158: (WXS_ATTRUSE_TYPEDEF(use) ==
! 16159: WXS_ATTRUSE_TYPEDEF(buse))
! 16160: {
! 16161: found = 1;
! 16162: break;
! 16163: }
! 16164: }
! 16165: }
! 16166: if (! found) {
! 16167: xmlChar *str = NULL;
! 16168:
! 16169: xmlSchemaCustomErr(ACTXT_CAST ctxt,
! 16170: XML_SCHEMAP_COS_CT_EXTENDS_1_2,
! 16171: NULL, WXS_BASIC_CAST type,
! 16172: /*
! 16173: * TODO: The report does not indicate that also the
! 16174: * type needs to be the same.
! 16175: */
! 16176: "This type is missing a matching correspondent "
! 16177: "for its {base type}'s %s in its {attribute uses}",
! 16178: xmlSchemaGetComponentDesignation(&str,
! 16179: buse->children),
! 16180: NULL);
! 16181: FREE_AND_NULL(str)
! 16182: }
! 16183: }
! 16184: }
! 16185: /*
! 16186: * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
! 16187: * definition must also have one, and the base type definition's
! 16188: * {attribute wildcard}'s {namespace constraint} must be a subset
! 16189: * of the complex type definition's {attribute wildcard}'s {namespace
! 16190: * constraint}, as defined by Wildcard Subset (�3.10.6)."
! 16191: */
! 16192:
! 16193: /*
! 16194: * MAYBE TODO: Enable if ever needed. But this will be needed only
! 16195: * if created the type via a schema construction API.
! 16196: */
! 16197: if (base->attributeWildcard != NULL) {
! 16198: if (type->attributeWilcard == NULL) {
! 16199: xmlChar *str = NULL;
! 16200:
! 16201: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 16202: XML_SCHEMAP_COS_CT_EXTENDS_1_3,
! 16203: NULL, type,
! 16204: "The base %s has an attribute wildcard, "
! 16205: "but this type is missing an attribute wildcard",
! 16206: xmlSchemaGetComponentDesignation(&str, base));
! 16207: FREE_AND_NULL(str)
! 16208:
! 16209: } else if (xmlSchemaCheckCOSNSSubset(
! 16210: base->attributeWildcard, type->attributeWildcard))
! 16211: {
! 16212: xmlChar *str = NULL;
! 16213:
! 16214: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 16215: XML_SCHEMAP_COS_CT_EXTENDS_1_3,
! 16216: NULL, type,
! 16217: "The attribute wildcard is not a valid "
! 16218: "superset of the one in the base %s",
! 16219: xmlSchemaGetComponentDesignation(&str, base));
! 16220: FREE_AND_NULL(str)
! 16221: }
! 16222: }
! 16223: #endif
! 16224: /*
! 16225: * SPEC (1.4) "One of the following must be true:"
! 16226: */
! 16227: if ((type->contentTypeDef != NULL) &&
! 16228: (type->contentTypeDef == base->contentTypeDef)) {
! 16229: /*
! 16230: * SPEC (1.4.1) "The {content type} of the {base type definition}
! 16231: * and the {content type} of the complex type definition itself
! 16232: * must be the same simple type definition"
! 16233: * PASS
! 16234: */
! 16235: } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
! 16236: (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
! 16237: /*
! 16238: * SPEC (1.4.2) "The {content type} of both the {base type
! 16239: * definition} and the complex type definition itself must
! 16240: * be empty."
! 16241: * PASS
! 16242: */
! 16243: } else {
! 16244: /*
! 16245: * SPEC (1.4.3) "All of the following must be true:"
! 16246: */
! 16247: if (type->subtypes == NULL) {
! 16248: /*
! 16249: * SPEC 1.4.3.1 The {content type} of the complex type
! 16250: * definition itself must specify a particle.
! 16251: */
! 16252: xmlSchemaPCustomErr(ctxt,
! 16253: XML_SCHEMAP_COS_CT_EXTENDS_1_1,
! 16254: WXS_BASIC_CAST type, NULL,
! 16255: "The content type must specify a particle", NULL);
! 16256: return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
! 16257: }
! 16258: /*
! 16259: * SPEC (1.4.3.2) "One of the following must be true:"
! 16260: */
! 16261: if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
! 16262: /*
! 16263: * SPEC (1.4.3.2.1) "The {content type} of the {base type
! 16264: * definition} must be empty.
! 16265: * PASS
! 16266: */
! 16267: } else {
! 16268: /*
! 16269: * SPEC (1.4.3.2.2) "All of the following must be true:"
! 16270: */
! 16271: if ((type->contentType != base->contentType) ||
! 16272: ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
! 16273: (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
! 16274: /*
! 16275: * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
! 16276: * or both must be element-only."
! 16277: */
! 16278: xmlSchemaPCustomErr(ctxt,
! 16279: XML_SCHEMAP_COS_CT_EXTENDS_1_1,
! 16280: WXS_BASIC_CAST type, NULL,
! 16281: "The content type of both, the type and its base "
! 16282: "type, must either 'mixed' or 'element-only'", NULL);
! 16283: return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
! 16284: }
! 16285: /*
! 16286: * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
! 16287: * complex type definition must be a �valid extension�
! 16288: * of the {base type definition}'s particle, as defined
! 16289: * in Particle Valid (Extension) (�3.9.6)."
! 16290: *
! 16291: * NOTE that we won't check "Particle Valid (Extension)",
! 16292: * since it is ensured by the derivation process in
! 16293: * xmlSchemaTypeFixup(). We need to implement this when heading
! 16294: * for a construction API
! 16295: * TODO: !! This is needed to be checked if redefining a type !!
! 16296: */
! 16297: }
! 16298: /*
! 16299: * URGENT TODO (1.5)
! 16300: */
! 16301: }
! 16302: } else {
! 16303: /*
! 16304: * SPEC (2) "If the {base type definition} is a simple type definition,
! 16305: * then all of the following must be true:"
! 16306: */
! 16307: if (type->contentTypeDef != base) {
! 16308: /*
! 16309: * SPEC (2.1) "The {content type} must be the same simple type
! 16310: * definition."
! 16311: */
! 16312: xmlSchemaPCustomErr(ctxt,
! 16313: XML_SCHEMAP_COS_CT_EXTENDS_1_1,
! 16314: WXS_BASIC_CAST type, NULL,
! 16315: "The content type must be the simple base type", NULL);
! 16316: return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
! 16317: }
! 16318: if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
! 16319: /*
! 16320: * SPEC (2.2) "The {final} of the {base type definition} must not
! 16321: * contain extension"
! 16322: * NOTE that this is the same as (1.1).
! 16323: */
! 16324: xmlSchemaPCustomErr(ctxt,
! 16325: XML_SCHEMAP_COS_CT_EXTENDS_1_1,
! 16326: WXS_BASIC_CAST type, NULL,
! 16327: "The 'final' of the base type definition "
! 16328: "contains 'extension'", NULL);
! 16329: return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
! 16330: }
! 16331: }
! 16332: return (0);
! 16333: }
! 16334:
! 16335: /**
! 16336: * xmlSchemaCheckDerivationOKRestriction:
! 16337: * @ctxt: the schema parser context
! 16338: * @type: the complex type definition
! 16339: *
! 16340: * (3.4.6) Constraints on Complex Type Definition Schema Components
! 16341: * Schema Component Constraint:
! 16342: * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
! 16343: *
! 16344: * STATUS:
! 16345: * missing:
! 16346: * (5.4.2) ???
! 16347: *
! 16348: * ATTENTION:
! 16349: * In XML Schema 1.1 this will be:
! 16350: * Validation Rule: Checking complex type subsumption
! 16351: *
! 16352: * Returns 0 if the constraints are satisfied, a positive
! 16353: * error code if not and -1 if an internal error occured.
! 16354: */
! 16355: static int
! 16356: xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
! 16357: xmlSchemaTypePtr type)
! 16358: {
! 16359: xmlSchemaTypePtr base;
! 16360:
! 16361: /*
! 16362: * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
! 16363: * temporarily only.
! 16364: */
! 16365: base = type->baseType;
! 16366: if (! WXS_IS_COMPLEX(base)) {
! 16367: xmlSchemaCustomErr(ACTXT_CAST ctxt,
! 16368: XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
! 16369: type->node, WXS_BASIC_CAST type,
! 16370: "The base type must be a complex type", NULL, NULL);
! 16371: return(ctxt->err);
! 16372: }
! 16373: if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
! 16374: /*
! 16375: * SPEC (1) "The {base type definition} must be a complex type
! 16376: * definition whose {final} does not contain restriction."
! 16377: */
! 16378: xmlSchemaCustomErr(ACTXT_CAST ctxt,
! 16379: XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
! 16380: type->node, WXS_BASIC_CAST type,
! 16381: "The 'final' of the base type definition "
! 16382: "contains 'restriction'", NULL, NULL);
! 16383: return (ctxt->err);
! 16384: }
! 16385: /*
! 16386: * SPEC (2), (3) and (4)
! 16387: * Those are handled in a separate function, since the
! 16388: * same constraints are needed for redefinition of
! 16389: * attribute groups as well.
! 16390: */
! 16391: if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
! 16392: XML_SCHEMA_ACTION_DERIVE,
! 16393: WXS_BASIC_CAST type, WXS_BASIC_CAST base,
! 16394: type->attrUses, base->attrUses,
! 16395: type->attributeWildcard,
! 16396: base->attributeWildcard) == -1)
! 16397: {
! 16398: return(-1);
! 16399: }
! 16400: /*
! 16401: * SPEC (5) "One of the following must be true:"
! 16402: */
! 16403: if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
! 16404: /*
! 16405: * SPEC (5.1) "The {base type definition} must be the
! 16406: * �ur-type definition�."
! 16407: * PASS
! 16408: */
! 16409: } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
! 16410: (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
! 16411: /*
! 16412: * SPEC (5.2.1) "The {content type} of the complex type definition
! 16413: * must be a simple type definition"
! 16414: *
! 16415: * SPEC (5.2.2) "One of the following must be true:"
! 16416: */
! 16417: if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
! 16418: (base->contentType == XML_SCHEMA_CONTENT_BASIC))
! 16419: {
! 16420: int err;
! 16421: /*
! 16422: * SPEC (5.2.2.1) "The {content type} of the {base type
! 16423: * definition} must be a simple type definition from which
! 16424: * the {content type} is validly derived given the empty
! 16425: * set as defined in Type Derivation OK (Simple) (�3.14.6)."
! 16426: *
! 16427: * ATTENTION TODO: This seems not needed if the type implicitely
! 16428: * derived from the base type.
! 16429: *
! 16430: */
! 16431: err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
! 16432: type->contentTypeDef, base->contentTypeDef, 0);
! 16433: if (err != 0) {
! 16434: xmlChar *strA = NULL, *strB = NULL;
! 16435:
! 16436: if (err == -1)
! 16437: return(-1);
! 16438: xmlSchemaCustomErr(ACTXT_CAST ctxt,
! 16439: XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
! 16440: NULL, WXS_BASIC_CAST type,
! 16441: "The {content type} %s is not validly derived from the "
! 16442: "base type's {content type} %s",
! 16443: xmlSchemaGetComponentDesignation(&strA,
! 16444: type->contentTypeDef),
! 16445: xmlSchemaGetComponentDesignation(&strB,
! 16446: base->contentTypeDef));
! 16447: FREE_AND_NULL(strA);
! 16448: FREE_AND_NULL(strB);
! 16449: return(ctxt->err);
! 16450: }
! 16451: } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
! 16452: (xmlSchemaIsParticleEmptiable(
! 16453: (xmlSchemaParticlePtr) base->subtypes))) {
! 16454: /*
! 16455: * SPEC (5.2.2.2) "The {base type definition} must be mixed
! 16456: * and have a particle which is �emptiable� as defined in
! 16457: * Particle Emptiable (�3.9.6)."
! 16458: * PASS
! 16459: */
! 16460: } else {
! 16461: xmlSchemaPCustomErr(ctxt,
! 16462: XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
! 16463: WXS_BASIC_CAST type, NULL,
! 16464: "The content type of the base type must be either "
! 16465: "a simple type or 'mixed' and an emptiable particle", NULL);
! 16466: return (ctxt->err);
! 16467: }
! 16468: } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
! 16469: /*
! 16470: * SPEC (5.3.1) "The {content type} of the complex type itself must
! 16471: * be empty"
! 16472: */
! 16473: if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
! 16474: /*
! 16475: * SPEC (5.3.2.1) "The {content type} of the {base type
! 16476: * definition} must also be empty."
! 16477: * PASS
! 16478: */
! 16479: } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
! 16480: (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
! 16481: xmlSchemaIsParticleEmptiable(
! 16482: (xmlSchemaParticlePtr) base->subtypes)) {
! 16483: /*
! 16484: * SPEC (5.3.2.2) "The {content type} of the {base type
! 16485: * definition} must be elementOnly or mixed and have a particle
! 16486: * which is �emptiable� as defined in Particle Emptiable (�3.9.6)."
! 16487: * PASS
! 16488: */
! 16489: } else {
! 16490: xmlSchemaPCustomErr(ctxt,
! 16491: XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
! 16492: WXS_BASIC_CAST type, NULL,
! 16493: "The content type of the base type must be either "
! 16494: "empty or 'mixed' (or 'elements-only') and an emptiable "
! 16495: "particle", NULL);
! 16496: return (ctxt->err);
! 16497: }
! 16498: } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
! 16499: WXS_HAS_MIXED_CONTENT(type)) {
! 16500: /*
! 16501: * SPEC (5.4.1.1) "The {content type} of the complex type definition
! 16502: * itself must be element-only"
! 16503: */
! 16504: if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
! 16505: /*
! 16506: * SPEC (5.4.1.2) "The {content type} of the complex type
! 16507: * definition itself and of the {base type definition} must be
! 16508: * mixed"
! 16509: */
! 16510: xmlSchemaPCustomErr(ctxt,
! 16511: XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
! 16512: WXS_BASIC_CAST type, NULL,
! 16513: "If the content type is 'mixed', then the content type of the "
! 16514: "base type must also be 'mixed'", NULL);
! 16515: return (ctxt->err);
! 16516: }
! 16517: /*
! 16518: * SPEC (5.4.2) "The particle of the complex type definition itself
! 16519: * must be a �valid restriction� of the particle of the {content
! 16520: * type} of the {base type definition} as defined in Particle Valid
! 16521: * (Restriction) (�3.9.6).
! 16522: *
! 16523: * URGENT TODO: (5.4.2)
! 16524: */
! 16525: } else {
! 16526: xmlSchemaPCustomErr(ctxt,
! 16527: XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
! 16528: WXS_BASIC_CAST type, NULL,
! 16529: "The type is not a valid restriction of its base type", NULL);
! 16530: return (ctxt->err);
! 16531: }
! 16532: return (0);
! 16533: }
! 16534:
! 16535: /**
! 16536: * xmlSchemaCheckCTComponent:
! 16537: * @ctxt: the schema parser context
! 16538: * @type: the complex type definition
! 16539: *
! 16540: * (3.4.6) Constraints on Complex Type Definition Schema Components
! 16541: *
! 16542: * Returns 0 if the constraints are satisfied, a positive
! 16543: * error code if not and -1 if an internal error occured.
! 16544: */
! 16545: static int
! 16546: xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
! 16547: xmlSchemaTypePtr type)
! 16548: {
! 16549: int ret;
! 16550: /*
! 16551: * Complex Type Definition Properties Correct
! 16552: */
! 16553: ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
! 16554: if (ret != 0)
! 16555: return (ret);
! 16556: if (WXS_IS_EXTENSION(type))
! 16557: ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
! 16558: else
! 16559: ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
! 16560: return (ret);
! 16561: }
! 16562:
! 16563: /**
! 16564: * xmlSchemaCheckSRCCT:
! 16565: * @ctxt: the schema parser context
! 16566: * @type: the complex type definition
! 16567: *
! 16568: * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
! 16569: * Schema Representation Constraint:
! 16570: * Complex Type Definition Representation OK (src-ct)
! 16571: *
! 16572: * Returns 0 if the constraints are satisfied, a positive
! 16573: * error code if not and -1 if an internal error occured.
! 16574: */
! 16575: static int
! 16576: xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
! 16577: xmlSchemaTypePtr type)
! 16578: {
! 16579: xmlSchemaTypePtr base;
! 16580: int ret = 0;
! 16581:
! 16582: /*
! 16583: * TODO: Adjust the error codes here, as I used
! 16584: * XML_SCHEMAP_SRC_CT_1 only yet.
! 16585: */
! 16586: base = type->baseType;
! 16587: if (! WXS_HAS_SIMPLE_CONTENT(type)) {
! 16588: /*
! 16589: * 1 If the <complexContent> alternative is chosen, the type definition
! 16590: * �resolved� to by the �actual value� of the base [attribute]
! 16591: * must be a complex type definition;
! 16592: */
! 16593: if (! WXS_IS_COMPLEX(base)) {
! 16594: xmlChar *str = NULL;
! 16595: xmlSchemaPCustomErr(ctxt,
! 16596: XML_SCHEMAP_SRC_CT_1,
! 16597: WXS_BASIC_CAST type, type->node,
! 16598: "If using <complexContent>, the base type is expected to be "
! 16599: "a complex type. The base type '%s' is a simple type",
! 16600: xmlSchemaFormatQName(&str, base->targetNamespace,
! 16601: base->name));
! 16602: FREE_AND_NULL(str)
! 16603: return (XML_SCHEMAP_SRC_CT_1);
! 16604: }
! 16605: } else {
! 16606: /*
! 16607: * SPEC
! 16608: * 2 If the <simpleContent> alternative is chosen, all of the
! 16609: * following must be true:
! 16610: * 2.1 The type definition �resolved� to by the �actual value� of the
! 16611: * base [attribute] must be one of the following:
! 16612: */
! 16613: if (WXS_IS_SIMPLE(base)) {
! 16614: if (WXS_IS_EXTENSION(type) == 0) {
! 16615: xmlChar *str = NULL;
! 16616: /*
! 16617: * 2.1.3 only if the <extension> alternative is also
! 16618: * chosen, a simple type definition.
! 16619: */
! 16620: /* TODO: Change error code to ..._SRC_CT_2_1_3. */
! 16621: xmlSchemaPCustomErr(ctxt,
! 16622: XML_SCHEMAP_SRC_CT_1,
! 16623: WXS_BASIC_CAST type, NULL,
! 16624: "If using <simpleContent> and <restriction>, the base "
! 16625: "type must be a complex type. The base type '%s' is "
! 16626: "a simple type",
! 16627: xmlSchemaFormatQName(&str, base->targetNamespace,
! 16628: base->name));
! 16629: FREE_AND_NULL(str)
! 16630: return (XML_SCHEMAP_SRC_CT_1);
! 16631: }
! 16632: } else {
! 16633: /* Base type is a complex type. */
! 16634: if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
! 16635: (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
! 16636: /*
! 16637: * 2.1.1 a complex type definition whose {content type} is a
! 16638: * simple type definition;
! 16639: * PASS
! 16640: */
! 16641: if (base->contentTypeDef == NULL) {
! 16642: xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
! 16643: WXS_BASIC_CAST type, NULL,
! 16644: "Internal error: xmlSchemaCheckSRCCT, "
! 16645: "'%s', base type has no content type",
! 16646: type->name);
! 16647: return (-1);
! 16648: }
! 16649: } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
! 16650: (WXS_IS_RESTRICTION(type))) {
! 16651:
! 16652: /*
! 16653: * 2.1.2 only if the <restriction> alternative is also
! 16654: * chosen, a complex type definition whose {content type}
! 16655: * is mixed and a particle emptiable.
! 16656: */
! 16657: if (! xmlSchemaIsParticleEmptiable(
! 16658: (xmlSchemaParticlePtr) base->subtypes)) {
! 16659: ret = XML_SCHEMAP_SRC_CT_1;
! 16660: } else
! 16661: /*
! 16662: * Attention: at this point the <simpleType> child is in
! 16663: * ->contentTypeDef (put there during parsing).
! 16664: */
! 16665: if (type->contentTypeDef == NULL) {
! 16666: xmlChar *str = NULL;
! 16667: /*
! 16668: * 2.2 If clause 2.1.2 above is satisfied, then there
! 16669: * must be a <simpleType> among the [children] of
! 16670: * <restriction>.
! 16671: */
! 16672: /* TODO: Change error code to ..._SRC_CT_2_2. */
! 16673: xmlSchemaPCustomErr(ctxt,
! 16674: XML_SCHEMAP_SRC_CT_1,
! 16675: WXS_BASIC_CAST type, NULL,
! 16676: "A <simpleType> is expected among the children "
! 16677: "of <restriction>, if <simpleContent> is used and "
! 16678: "the base type '%s' is a complex type",
! 16679: xmlSchemaFormatQName(&str, base->targetNamespace,
! 16680: base->name));
! 16681: FREE_AND_NULL(str)
! 16682: return (XML_SCHEMAP_SRC_CT_1);
! 16683: }
! 16684: } else {
! 16685: ret = XML_SCHEMAP_SRC_CT_1;
! 16686: }
! 16687: }
! 16688: if (ret > 0) {
! 16689: xmlChar *str = NULL;
! 16690: if (WXS_IS_RESTRICTION(type)) {
! 16691: xmlSchemaPCustomErr(ctxt,
! 16692: XML_SCHEMAP_SRC_CT_1,
! 16693: WXS_BASIC_CAST type, NULL,
! 16694: "If <simpleContent> and <restriction> is used, the "
! 16695: "base type must be a simple type or a complex type with "
! 16696: "mixed content and particle emptiable. The base type "
! 16697: "'%s' is none of those",
! 16698: xmlSchemaFormatQName(&str, base->targetNamespace,
! 16699: base->name));
! 16700: } else {
! 16701: xmlSchemaPCustomErr(ctxt,
! 16702: XML_SCHEMAP_SRC_CT_1,
! 16703: WXS_BASIC_CAST type, NULL,
! 16704: "If <simpleContent> and <extension> is used, the "
! 16705: "base type must be a simple type. The base type '%s' "
! 16706: "is a complex type",
! 16707: xmlSchemaFormatQName(&str, base->targetNamespace,
! 16708: base->name));
! 16709: }
! 16710: FREE_AND_NULL(str)
! 16711: }
! 16712: }
! 16713: /*
! 16714: * SPEC (3) "The corresponding complex type definition component must
! 16715: * satisfy the conditions set out in Constraints on Complex Type
! 16716: * Definition Schema Components (�3.4.6);"
! 16717: * NOTE (3) will be done in xmlSchemaTypeFixup().
! 16718: */
! 16719: /*
! 16720: * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
! 16721: * above for {attribute wildcard} is satisfied, the intensional
! 16722: * intersection must be expressible, as defined in Attribute Wildcard
! 16723: * Intersection (�3.10.6).
! 16724: * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
! 16725: */
! 16726: return (ret);
! 16727: }
! 16728:
! 16729: #ifdef ENABLE_PARTICLE_RESTRICTION
! 16730: /**
! 16731: * xmlSchemaCheckParticleRangeOK:
! 16732: * @ctxt: the schema parser context
! 16733: * @type: the complex type definition
! 16734: *
! 16735: * (3.9.6) Constraints on Particle Schema Components
! 16736: * Schema Component Constraint:
! 16737: * Occurrence Range OK (range-ok)
! 16738: *
! 16739: * STATUS: complete
! 16740: *
! 16741: * Returns 0 if the constraints are satisfied, a positive
! 16742: * error code if not and -1 if an internal error occured.
! 16743: */
! 16744: static int
! 16745: xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
! 16746: int bmin, int bmax)
! 16747: {
! 16748: if (rmin < bmin)
! 16749: return (1);
! 16750: if ((bmax != UNBOUNDED) &&
! 16751: (rmax > bmax))
! 16752: return (1);
! 16753: return (0);
! 16754: }
! 16755:
! 16756: /**
! 16757: * xmlSchemaCheckRCaseNameAndTypeOK:
! 16758: * @ctxt: the schema parser context
! 16759: * @r: the restricting element declaration particle
! 16760: * @b: the base element declaration particle
! 16761: *
! 16762: * (3.9.6) Constraints on Particle Schema Components
! 16763: * Schema Component Constraint:
! 16764: * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
! 16765: * (rcase-NameAndTypeOK)
! 16766: *
! 16767: * STATUS:
! 16768: * MISSING (3.2.3)
! 16769: * CLARIFY: (3.2.2)
! 16770: *
! 16771: * Returns 0 if the constraints are satisfied, a positive
! 16772: * error code if not and -1 if an internal error occured.
! 16773: */
! 16774: static int
! 16775: xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
! 16776: xmlSchemaParticlePtr r,
! 16777: xmlSchemaParticlePtr b)
! 16778: {
! 16779: xmlSchemaElementPtr elemR, elemB;
! 16780:
! 16781: /* TODO: Error codes (rcase-NameAndTypeOK). */
! 16782: elemR = (xmlSchemaElementPtr) r->children;
! 16783: elemB = (xmlSchemaElementPtr) b->children;
! 16784: /*
! 16785: * SPEC (1) "The declarations' {name}s and {target namespace}s are
! 16786: * the same."
! 16787: */
! 16788: if ((elemR != elemB) &&
! 16789: ((! xmlStrEqual(elemR->name, elemB->name)) ||
! 16790: (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
! 16791: return (1);
! 16792: /*
! 16793: * SPEC (2) "R's occurrence range is a valid restriction of B's
! 16794: * occurrence range as defined by Occurrence Range OK (�3.9.6)."
! 16795: */
! 16796: if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
! 16797: b->minOccurs, b->maxOccurs) != 0)
! 16798: return (1);
! 16799: /*
! 16800: * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
! 16801: * {scope} are global."
! 16802: */
! 16803: if (elemR == elemB)
! 16804: return (0);
! 16805: /*
! 16806: * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
! 16807: */
! 16808: if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
! 16809: (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
! 16810: return (1);
! 16811: /*
! 16812: * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
! 16813: * or is not fixed, or R's declaration's {value constraint} is fixed
! 16814: * with the same value."
! 16815: */
! 16816: if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
! 16817: ((elemR->value == NULL) ||
! 16818: ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
! 16819: /* TODO: Equality of the initial value or normalized or canonical? */
! 16820: (! xmlStrEqual(elemR->value, elemB->value))))
! 16821: return (1);
! 16822: /*
! 16823: * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
! 16824: * definitions} is a subset of B's declaration's {identity-constraint
! 16825: * definitions}, if any."
! 16826: */
! 16827: if (elemB->idcs != NULL) {
! 16828: /* TODO */
! 16829: }
! 16830: /*
! 16831: * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
! 16832: * superset of B's declaration's {disallowed substitutions}."
! 16833: */
! 16834: if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
! 16835: ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
! 16836: ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
! 16837: ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
! 16838: ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
! 16839: ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
! 16840: return (1);
! 16841: /*
! 16842: * SPEC (3.2.5) "R's {type definition} is validly derived given
! 16843: * {extension, list, union} from B's {type definition}"
! 16844: *
! 16845: * BADSPEC TODO: What's the point of adding "list" and "union" to the
! 16846: * set, if the corresponding constraints handle "restriction" and
! 16847: * "extension" only?
! 16848: *
! 16849: */
! 16850: {
! 16851: int set = 0;
! 16852:
! 16853: set |= SUBSET_EXTENSION;
! 16854: set |= SUBSET_LIST;
! 16855: set |= SUBSET_UNION;
! 16856: if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
! 16857: elemB->subtypes, set) != 0)
! 16858: return (1);
! 16859: }
! 16860: return (0);
! 16861: }
! 16862:
! 16863: /**
! 16864: * xmlSchemaCheckRCaseNSCompat:
! 16865: * @ctxt: the schema parser context
! 16866: * @r: the restricting element declaration particle
! 16867: * @b: the base wildcard particle
! 16868: *
! 16869: * (3.9.6) Constraints on Particle Schema Components
! 16870: * Schema Component Constraint:
! 16871: * Particle Derivation OK (Elt:Any -- NSCompat)
! 16872: * (rcase-NSCompat)
! 16873: *
! 16874: * STATUS: complete
! 16875: *
! 16876: * Returns 0 if the constraints are satisfied, a positive
! 16877: * error code if not and -1 if an internal error occured.
! 16878: */
! 16879: static int
! 16880: xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
! 16881: xmlSchemaParticlePtr r,
! 16882: xmlSchemaParticlePtr b)
! 16883: {
! 16884: /* TODO:Error codes (rcase-NSCompat). */
! 16885: /*
! 16886: * SPEC "For an element declaration particle to be a �valid restriction�
! 16887: * of a wildcard particle all of the following must be true:"
! 16888: *
! 16889: * SPEC (1) "The element declaration's {target namespace} is �valid�
! 16890: * with respect to the wildcard's {namespace constraint} as defined by
! 16891: * Wildcard allows Namespace Name (�3.10.4)."
! 16892: */
! 16893: if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
! 16894: ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
! 16895: return (1);
! 16896: /*
! 16897: * SPEC (2) "R's occurrence range is a valid restriction of B's
! 16898: * occurrence range as defined by Occurrence Range OK (�3.9.6)."
! 16899: */
! 16900: if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
! 16901: b->minOccurs, b->maxOccurs) != 0)
! 16902: return (1);
! 16903:
! 16904: return (0);
! 16905: }
! 16906:
! 16907: /**
! 16908: * xmlSchemaCheckRCaseRecurseAsIfGroup:
! 16909: * @ctxt: the schema parser context
! 16910: * @r: the restricting element declaration particle
! 16911: * @b: the base model group particle
! 16912: *
! 16913: * (3.9.6) Constraints on Particle Schema Components
! 16914: * Schema Component Constraint:
! 16915: * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
! 16916: * (rcase-RecurseAsIfGroup)
! 16917: *
! 16918: * STATUS: TODO
! 16919: *
! 16920: * Returns 0 if the constraints are satisfied, a positive
! 16921: * error code if not and -1 if an internal error occured.
! 16922: */
! 16923: static int
! 16924: xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
! 16925: xmlSchemaParticlePtr r,
! 16926: xmlSchemaParticlePtr b)
! 16927: {
! 16928: /* TODO: Error codes (rcase-RecurseAsIfGroup). */
! 16929: TODO
! 16930: return (0);
! 16931: }
! 16932:
! 16933: /**
! 16934: * xmlSchemaCheckRCaseNSSubset:
! 16935: * @ctxt: the schema parser context
! 16936: * @r: the restricting wildcard particle
! 16937: * @b: the base wildcard particle
! 16938: *
! 16939: * (3.9.6) Constraints on Particle Schema Components
! 16940: * Schema Component Constraint:
! 16941: * Particle Derivation OK (Any:Any -- NSSubset)
! 16942: * (rcase-NSSubset)
! 16943: *
! 16944: * STATUS: complete
! 16945: *
! 16946: * Returns 0 if the constraints are satisfied, a positive
! 16947: * error code if not and -1 if an internal error occured.
! 16948: */
! 16949: static int
! 16950: xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
! 16951: xmlSchemaParticlePtr r,
! 16952: xmlSchemaParticlePtr b,
! 16953: int isAnyTypeBase)
! 16954: {
! 16955: /* TODO: Error codes (rcase-NSSubset). */
! 16956: /*
! 16957: * SPEC (1) "R's occurrence range is a valid restriction of B's
! 16958: * occurrence range as defined by Occurrence Range OK (�3.9.6)."
! 16959: */
! 16960: if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
! 16961: b->minOccurs, b->maxOccurs))
! 16962: return (1);
! 16963: /*
! 16964: * SPEC (2) "R's {namespace constraint} must be an intensional subset
! 16965: * of B's {namespace constraint} as defined by Wildcard Subset (�3.10.6)."
! 16966: */
! 16967: if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
! 16968: (xmlSchemaWildcardPtr) b->children))
! 16969: return (1);
! 16970: /*
! 16971: * SPEC (3) "Unless B is the content model wildcard of the �ur-type
! 16972: * definition�, R's {process contents} must be identical to or stronger
! 16973: * than B's {process contents}, where strict is stronger than lax is
! 16974: * stronger than skip."
! 16975: */
! 16976: if (! isAnyTypeBase) {
! 16977: if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
! 16978: ((xmlSchemaWildcardPtr) b->children)->processContents)
! 16979: return (1);
! 16980: }
! 16981:
! 16982: return (0);
! 16983: }
! 16984:
! 16985: /**
! 16986: * xmlSchemaCheckCOSParticleRestrict:
! 16987: * @ctxt: the schema parser context
! 16988: * @type: the complex type definition
! 16989: *
! 16990: * (3.9.6) Constraints on Particle Schema Components
! 16991: * Schema Component Constraint:
! 16992: * Particle Valid (Restriction) (cos-particle-restrict)
! 16993: *
! 16994: * STATUS: TODO
! 16995: *
! 16996: * Returns 0 if the constraints are satisfied, a positive
! 16997: * error code if not and -1 if an internal error occured.
! 16998: */
! 16999: static int
! 17000: xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
! 17001: xmlSchemaParticlePtr r,
! 17002: xmlSchemaParticlePtr b)
! 17003: {
! 17004: int ret = 0;
! 17005:
! 17006: /*part = WXS_TYPE_PARTICLE(type);
! 17007: basePart = WXS_TYPE_PARTICLE(base);
! 17008: */
! 17009:
! 17010: TODO
! 17011:
! 17012: /*
! 17013: * SPEC (1) "They are the same particle."
! 17014: */
! 17015: if (r == b)
! 17016: return (0);
! 17017:
! 17018:
! 17019: return (0);
! 17020: }
! 17021:
! 17022: #if 0
! 17023: /**
! 17024: * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
! 17025: * @ctxt: the schema parser context
! 17026: * @r: the model group particle
! 17027: * @b: the base wildcard particle
! 17028: *
! 17029: * (3.9.6) Constraints on Particle Schema Components
! 17030: * Schema Component Constraint:
! 17031: * Particle Derivation OK (All/Choice/Sequence:Any --
! 17032: * NSRecurseCheckCardinality)
! 17033: * (rcase-NSRecurseCheckCardinality)
! 17034: *
! 17035: * STATUS: TODO: subst-groups
! 17036: *
! 17037: * Returns 0 if the constraints are satisfied, a positive
! 17038: * error code if not and -1 if an internal error occured.
! 17039: */
! 17040: static int
! 17041: xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
! 17042: xmlSchemaParticlePtr r,
! 17043: xmlSchemaParticlePtr b)
! 17044: {
! 17045: xmlSchemaParticlePtr part;
! 17046: /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
! 17047: if ((r->children == NULL) || (r->children->children == NULL))
! 17048: return (-1);
! 17049: /*
! 17050: * SPEC "For a group particle to be a �valid restriction� of a
! 17051: * wildcard particle..."
! 17052: *
! 17053: * SPEC (1) "Every member of the {particles} of the group is a �valid
! 17054: * restriction� of the wildcard as defined by
! 17055: * Particle Valid (Restriction) (�3.9.6)."
! 17056: */
! 17057: part = (xmlSchemaParticlePtr) r->children->children;
! 17058: do {
! 17059: if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
! 17060: return (1);
! 17061: part = (xmlSchemaParticlePtr) part->next;
! 17062: } while (part != NULL);
! 17063: /*
! 17064: * SPEC (2) "The effective total range of the group [...] is a
! 17065: * valid restriction of B's occurrence range as defined by
! 17066: * Occurrence Range OK (�3.9.6)."
! 17067: */
! 17068: if (xmlSchemaCheckParticleRangeOK(
! 17069: xmlSchemaGetParticleTotalRangeMin(r),
! 17070: xmlSchemaGetParticleTotalRangeMax(r),
! 17071: b->minOccurs, b->maxOccurs) != 0)
! 17072: return (1);
! 17073: return (0);
! 17074: }
! 17075: #endif
! 17076:
! 17077: /**
! 17078: * xmlSchemaCheckRCaseRecurse:
! 17079: * @ctxt: the schema parser context
! 17080: * @r: the <all> or <sequence> model group particle
! 17081: * @b: the base <all> or <sequence> model group particle
! 17082: *
! 17083: * (3.9.6) Constraints on Particle Schema Components
! 17084: * Schema Component Constraint:
! 17085: * Particle Derivation OK (All:All,Sequence:Sequence --
! 17086: Recurse)
! 17087: * (rcase-Recurse)
! 17088: *
! 17089: * STATUS: ?
! 17090: * TODO: subst-groups
! 17091: *
! 17092: * Returns 0 if the constraints are satisfied, a positive
! 17093: * error code if not and -1 if an internal error occured.
! 17094: */
! 17095: static int
! 17096: xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
! 17097: xmlSchemaParticlePtr r,
! 17098: xmlSchemaParticlePtr b)
! 17099: {
! 17100: /* xmlSchemaParticlePtr part; */
! 17101: /* TODO: Error codes (rcase-Recurse). */
! 17102: if ((r->children == NULL) || (b->children == NULL) ||
! 17103: (r->children->type != b->children->type))
! 17104: return (-1);
! 17105: /*
! 17106: * SPEC "For an all or sequence group particle to be a �valid
! 17107: * restriction� of another group particle with the same {compositor}..."
! 17108: *
! 17109: * SPEC (1) "R's occurrence range is a valid restriction of B's
! 17110: * occurrence range as defined by Occurrence Range OK (�3.9.6)."
! 17111: */
! 17112: if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
! 17113: b->minOccurs, b->maxOccurs))
! 17114: return (1);
! 17115:
! 17116:
! 17117: return (0);
! 17118: }
! 17119:
! 17120: #endif
! 17121:
! 17122: #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
! 17123: xmlSchemaPCustomErrExt(pctxt, \
! 17124: XML_SCHEMAP_INVALID_FACET_VALUE, \
! 17125: WXS_BASIC_CAST fac1, fac1->node, \
! 17126: "It is an error for both '%s' and '%s' to be specified on the "\
! 17127: "same type definition", \
! 17128: BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
! 17129: BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
! 17130:
! 17131: #define FACET_RESTR_ERR(fac1, msg) \
! 17132: xmlSchemaPCustomErr(pctxt, \
! 17133: XML_SCHEMAP_INVALID_FACET_VALUE, \
! 17134: WXS_BASIC_CAST fac1, fac1->node, \
! 17135: msg, NULL);
! 17136:
! 17137: #define FACET_RESTR_FIXED_ERR(fac) \
! 17138: xmlSchemaPCustomErr(pctxt, \
! 17139: XML_SCHEMAP_INVALID_FACET_VALUE, \
! 17140: WXS_BASIC_CAST fac, fac->node, \
! 17141: "The base type's facet is 'fixed', thus the value must not " \
! 17142: "differ", NULL);
! 17143:
! 17144: static void
! 17145: xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
! 17146: xmlSchemaFacetPtr facet1,
! 17147: xmlSchemaFacetPtr facet2,
! 17148: int lessGreater,
! 17149: int orEqual,
! 17150: int ofBase)
! 17151: {
! 17152: xmlChar *msg = NULL;
! 17153:
! 17154: msg = xmlStrdup(BAD_CAST "'");
! 17155: msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
! 17156: msg = xmlStrcat(msg, BAD_CAST "' has to be");
! 17157: if (lessGreater == 0)
! 17158: msg = xmlStrcat(msg, BAD_CAST " equal to");
! 17159: if (lessGreater == 1)
! 17160: msg = xmlStrcat(msg, BAD_CAST " greater than");
! 17161: else
! 17162: msg = xmlStrcat(msg, BAD_CAST " less than");
! 17163:
! 17164: if (orEqual)
! 17165: msg = xmlStrcat(msg, BAD_CAST " or equal to");
! 17166: msg = xmlStrcat(msg, BAD_CAST " '");
! 17167: msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
! 17168: if (ofBase)
! 17169: msg = xmlStrcat(msg, BAD_CAST "' of the base type");
! 17170: else
! 17171: msg = xmlStrcat(msg, BAD_CAST "'");
! 17172:
! 17173: xmlSchemaPCustomErr(pctxt,
! 17174: XML_SCHEMAP_INVALID_FACET_VALUE,
! 17175: WXS_BASIC_CAST facet1, NULL,
! 17176: (const char *) msg, NULL);
! 17177:
! 17178: if (msg != NULL)
! 17179: xmlFree(msg);
! 17180: }
! 17181:
! 17182: /*
! 17183: * xmlSchemaDeriveAndValidateFacets:
! 17184: *
! 17185: * Schema Component Constraint: Simple Type Restriction (Facets)
! 17186: * (st-restrict-facets)
! 17187: */
! 17188: static int
! 17189: xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
! 17190: xmlSchemaTypePtr type)
! 17191: {
! 17192: xmlSchemaTypePtr base = type->baseType;
! 17193: xmlSchemaFacetLinkPtr link, cur, last = NULL;
! 17194: xmlSchemaFacetPtr facet, bfacet,
! 17195: flength = NULL, ftotdig = NULL, ffracdig = NULL,
! 17196: fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
! 17197: fmininc = NULL, fmaxinc = NULL,
! 17198: fminexc = NULL, fmaxexc = NULL,
! 17199: bflength = NULL, bftotdig = NULL, bffracdig = NULL,
! 17200: bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
! 17201: bfmininc = NULL, bfmaxinc = NULL,
! 17202: bfminexc = NULL, bfmaxexc = NULL;
! 17203: int res; /* err = 0, fixedErr; */
! 17204:
! 17205: /*
! 17206: * SPEC st-restrict-facets 1:
! 17207: * "The {variety} of R is the same as that of B."
! 17208: */
! 17209: /*
! 17210: * SPEC st-restrict-facets 2:
! 17211: * "If {variety} is atomic, the {primitive type definition}
! 17212: * of R is the same as that of B."
! 17213: *
! 17214: * NOTE: we leave 1 & 2 out for now, since this will be
! 17215: * satisfied by the derivation process.
! 17216: * CONSTRUCTION TODO: Maybe needed if using a construction API.
! 17217: */
! 17218: /*
! 17219: * SPEC st-restrict-facets 3:
! 17220: * "The {facets} of R are the union of S and the {facets}
! 17221: * of B, eliminating duplicates. To eliminate duplicates,
! 17222: * when a facet of the same kind occurs in both S and the
! 17223: * {facets} of B, the one in the {facets} of B is not
! 17224: * included, with the exception of enumeration and pattern
! 17225: * facets, for which multiple occurrences with distinct values
! 17226: * are allowed."
! 17227: */
! 17228:
! 17229: if ((type->facetSet == NULL) && (base->facetSet == NULL))
! 17230: return (0);
! 17231:
! 17232: last = type->facetSet;
! 17233: if (last != NULL)
! 17234: while (last->next != NULL)
! 17235: last = last->next;
! 17236:
! 17237: for (cur = type->facetSet; cur != NULL; cur = cur->next) {
! 17238: facet = cur->facet;
! 17239: switch (facet->type) {
! 17240: case XML_SCHEMA_FACET_LENGTH:
! 17241: flength = facet; break;
! 17242: case XML_SCHEMA_FACET_MINLENGTH:
! 17243: fminlen = facet; break;
! 17244: case XML_SCHEMA_FACET_MININCLUSIVE:
! 17245: fmininc = facet; break;
! 17246: case XML_SCHEMA_FACET_MINEXCLUSIVE:
! 17247: fminexc = facet; break;
! 17248: case XML_SCHEMA_FACET_MAXLENGTH:
! 17249: fmaxlen = facet; break;
! 17250: case XML_SCHEMA_FACET_MAXINCLUSIVE:
! 17251: fmaxinc = facet; break;
! 17252: case XML_SCHEMA_FACET_MAXEXCLUSIVE:
! 17253: fmaxexc = facet; break;
! 17254: case XML_SCHEMA_FACET_TOTALDIGITS:
! 17255: ftotdig = facet; break;
! 17256: case XML_SCHEMA_FACET_FRACTIONDIGITS:
! 17257: ffracdig = facet; break;
! 17258: default:
! 17259: break;
! 17260: }
! 17261: }
! 17262: for (cur = base->facetSet; cur != NULL; cur = cur->next) {
! 17263: facet = cur->facet;
! 17264: switch (facet->type) {
! 17265: case XML_SCHEMA_FACET_LENGTH:
! 17266: bflength = facet; break;
! 17267: case XML_SCHEMA_FACET_MINLENGTH:
! 17268: bfminlen = facet; break;
! 17269: case XML_SCHEMA_FACET_MININCLUSIVE:
! 17270: bfmininc = facet; break;
! 17271: case XML_SCHEMA_FACET_MINEXCLUSIVE:
! 17272: bfminexc = facet; break;
! 17273: case XML_SCHEMA_FACET_MAXLENGTH:
! 17274: bfmaxlen = facet; break;
! 17275: case XML_SCHEMA_FACET_MAXINCLUSIVE:
! 17276: bfmaxinc = facet; break;
! 17277: case XML_SCHEMA_FACET_MAXEXCLUSIVE:
! 17278: bfmaxexc = facet; break;
! 17279: case XML_SCHEMA_FACET_TOTALDIGITS:
! 17280: bftotdig = facet; break;
! 17281: case XML_SCHEMA_FACET_FRACTIONDIGITS:
! 17282: bffracdig = facet; break;
! 17283: default:
! 17284: break;
! 17285: }
! 17286: }
! 17287: /*
! 17288: * length and minLength or maxLength (2.2) + (3.2)
! 17289: */
! 17290: if (flength && (fminlen || fmaxlen)) {
! 17291: FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
! 17292: "either of 'minLength' or 'maxLength' to be specified on "
! 17293: "the same type definition")
! 17294: }
! 17295: /*
! 17296: * Mutual exclusions in the same derivation step.
! 17297: */
! 17298: if ((fmaxinc) && (fmaxexc)) {
! 17299: /*
! 17300: * SCC "maxInclusive and maxExclusive"
! 17301: */
! 17302: FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
! 17303: }
! 17304: if ((fmininc) && (fminexc)) {
! 17305: /*
! 17306: * SCC "minInclusive and minExclusive"
! 17307: */
! 17308: FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
! 17309: }
! 17310:
! 17311: if (flength && bflength) {
! 17312: /*
! 17313: * SCC "length valid restriction"
! 17314: * The values have to be equal.
! 17315: */
! 17316: res = xmlSchemaCompareValues(flength->val, bflength->val);
! 17317: if (res == -2)
! 17318: goto internal_error;
! 17319: if (res != 0)
! 17320: xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
! 17321: if ((res != 0) && (bflength->fixed)) {
! 17322: FACET_RESTR_FIXED_ERR(flength)
! 17323: }
! 17324:
! 17325: }
! 17326: if (fminlen && bfminlen) {
! 17327: /*
! 17328: * SCC "minLength valid restriction"
! 17329: * minLength >= BASE minLength
! 17330: */
! 17331: res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
! 17332: if (res == -2)
! 17333: goto internal_error;
! 17334: if (res == -1)
! 17335: xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
! 17336: if ((res != 0) && (bfminlen->fixed)) {
! 17337: FACET_RESTR_FIXED_ERR(fminlen)
! 17338: }
! 17339: }
! 17340: if (fmaxlen && bfmaxlen) {
! 17341: /*
! 17342: * SCC "maxLength valid restriction"
! 17343: * maxLength <= BASE minLength
! 17344: */
! 17345: res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
! 17346: if (res == -2)
! 17347: goto internal_error;
! 17348: if (res == 1)
! 17349: xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
! 17350: if ((res != 0) && (bfmaxlen->fixed)) {
! 17351: FACET_RESTR_FIXED_ERR(fmaxlen)
! 17352: }
! 17353: }
! 17354: /*
! 17355: * SCC "length and minLength or maxLength"
! 17356: */
! 17357: if (! flength)
! 17358: flength = bflength;
! 17359: if (flength) {
! 17360: if (! fminlen)
! 17361: fminlen = bfminlen;
! 17362: if (fminlen) {
! 17363: /* (1.1) length >= minLength */
! 17364: res = xmlSchemaCompareValues(flength->val, fminlen->val);
! 17365: if (res == -2)
! 17366: goto internal_error;
! 17367: if (res == -1)
! 17368: xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
! 17369: }
! 17370: if (! fmaxlen)
! 17371: fmaxlen = bfmaxlen;
! 17372: if (fmaxlen) {
! 17373: /* (2.1) length <= maxLength */
! 17374: res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
! 17375: if (res == -2)
! 17376: goto internal_error;
! 17377: if (res == 1)
! 17378: xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
! 17379: }
! 17380: }
! 17381: if (fmaxinc) {
! 17382: /*
! 17383: * "maxInclusive"
! 17384: */
! 17385: if (fmininc) {
! 17386: /* SCC "maxInclusive >= minInclusive" */
! 17387: res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
! 17388: if (res == -2)
! 17389: goto internal_error;
! 17390: if (res == -1) {
! 17391: xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
! 17392: }
! 17393: }
! 17394: /*
! 17395: * SCC "maxInclusive valid restriction"
! 17396: */
! 17397: if (bfmaxinc) {
! 17398: /* maxInclusive <= BASE maxInclusive */
! 17399: res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
! 17400: if (res == -2)
! 17401: goto internal_error;
! 17402: if (res == 1)
! 17403: xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
! 17404: if ((res != 0) && (bfmaxinc->fixed)) {
! 17405: FACET_RESTR_FIXED_ERR(fmaxinc)
! 17406: }
! 17407: }
! 17408: if (bfmaxexc) {
! 17409: /* maxInclusive < BASE maxExclusive */
! 17410: res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
! 17411: if (res == -2)
! 17412: goto internal_error;
! 17413: if (res != -1) {
! 17414: xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
! 17415: }
! 17416: }
! 17417: if (bfmininc) {
! 17418: /* maxInclusive >= BASE minInclusive */
! 17419: res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
! 17420: if (res == -2)
! 17421: goto internal_error;
! 17422: if (res == -1) {
! 17423: xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
! 17424: }
! 17425: }
! 17426: if (bfminexc) {
! 17427: /* maxInclusive > BASE minExclusive */
! 17428: res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
! 17429: if (res == -2)
! 17430: goto internal_error;
! 17431: if (res != 1) {
! 17432: xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
! 17433: }
! 17434: }
! 17435: }
! 17436: if (fmaxexc) {
! 17437: /*
! 17438: * "maxExclusive >= minExclusive"
! 17439: */
! 17440: if (fminexc) {
! 17441: res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
! 17442: if (res == -2)
! 17443: goto internal_error;
! 17444: if (res == -1) {
! 17445: xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
! 17446: }
! 17447: }
! 17448: /*
! 17449: * "maxExclusive valid restriction"
! 17450: */
! 17451: if (bfmaxexc) {
! 17452: /* maxExclusive <= BASE maxExclusive */
! 17453: res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
! 17454: if (res == -2)
! 17455: goto internal_error;
! 17456: if (res == 1) {
! 17457: xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
! 17458: }
! 17459: if ((res != 0) && (bfmaxexc->fixed)) {
! 17460: FACET_RESTR_FIXED_ERR(fmaxexc)
! 17461: }
! 17462: }
! 17463: if (bfmaxinc) {
! 17464: /* maxExclusive <= BASE maxInclusive */
! 17465: res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
! 17466: if (res == -2)
! 17467: goto internal_error;
! 17468: if (res == 1) {
! 17469: xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
! 17470: }
! 17471: }
! 17472: if (bfmininc) {
! 17473: /* maxExclusive > BASE minInclusive */
! 17474: res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
! 17475: if (res == -2)
! 17476: goto internal_error;
! 17477: if (res != 1) {
! 17478: xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
! 17479: }
! 17480: }
! 17481: if (bfminexc) {
! 17482: /* maxExclusive > BASE minExclusive */
! 17483: res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
! 17484: if (res == -2)
! 17485: goto internal_error;
! 17486: if (res != 1) {
! 17487: xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
! 17488: }
! 17489: }
! 17490: }
! 17491: if (fminexc) {
! 17492: /*
! 17493: * "minExclusive < maxInclusive"
! 17494: */
! 17495: if (fmaxinc) {
! 17496: res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
! 17497: if (res == -2)
! 17498: goto internal_error;
! 17499: if (res != -1) {
! 17500: xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
! 17501: }
! 17502: }
! 17503: /*
! 17504: * "minExclusive valid restriction"
! 17505: */
! 17506: if (bfminexc) {
! 17507: /* minExclusive >= BASE minExclusive */
! 17508: res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
! 17509: if (res == -2)
! 17510: goto internal_error;
! 17511: if (res == -1) {
! 17512: xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
! 17513: }
! 17514: if ((res != 0) && (bfminexc->fixed)) {
! 17515: FACET_RESTR_FIXED_ERR(fminexc)
! 17516: }
! 17517: }
! 17518: if (bfmaxinc) {
! 17519: /* minExclusive <= BASE maxInclusive */
! 17520: res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
! 17521: if (res == -2)
! 17522: goto internal_error;
! 17523: if (res == 1) {
! 17524: xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
! 17525: }
! 17526: }
! 17527: if (bfmininc) {
! 17528: /* minExclusive >= BASE minInclusive */
! 17529: res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
! 17530: if (res == -2)
! 17531: goto internal_error;
! 17532: if (res == -1) {
! 17533: xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
! 17534: }
! 17535: }
! 17536: if (bfmaxexc) {
! 17537: /* minExclusive < BASE maxExclusive */
! 17538: res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
! 17539: if (res == -2)
! 17540: goto internal_error;
! 17541: if (res != -1) {
! 17542: xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
! 17543: }
! 17544: }
! 17545: }
! 17546: if (fmininc) {
! 17547: /*
! 17548: * "minInclusive < maxExclusive"
! 17549: */
! 17550: if (fmaxexc) {
! 17551: res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
! 17552: if (res == -2)
! 17553: goto internal_error;
! 17554: if (res != -1) {
! 17555: xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
! 17556: }
! 17557: }
! 17558: /*
! 17559: * "minExclusive valid restriction"
! 17560: */
! 17561: if (bfmininc) {
! 17562: /* minInclusive >= BASE minInclusive */
! 17563: res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
! 17564: if (res == -2)
! 17565: goto internal_error;
! 17566: if (res == -1) {
! 17567: xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
! 17568: }
! 17569: if ((res != 0) && (bfmininc->fixed)) {
! 17570: FACET_RESTR_FIXED_ERR(fmininc)
! 17571: }
! 17572: }
! 17573: if (bfmaxinc) {
! 17574: /* minInclusive <= BASE maxInclusive */
! 17575: res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
! 17576: if (res == -2)
! 17577: goto internal_error;
! 17578: if (res == 1) {
! 17579: xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
! 17580: }
! 17581: }
! 17582: if (bfminexc) {
! 17583: /* minInclusive > BASE minExclusive */
! 17584: res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
! 17585: if (res == -2)
! 17586: goto internal_error;
! 17587: if (res != 1)
! 17588: xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
! 17589: }
! 17590: if (bfmaxexc) {
! 17591: /* minInclusive < BASE maxExclusive */
! 17592: res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
! 17593: if (res == -2)
! 17594: goto internal_error;
! 17595: if (res != -1)
! 17596: xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
! 17597: }
! 17598: }
! 17599: if (ftotdig && bftotdig) {
! 17600: /*
! 17601: * SCC " totalDigits valid restriction"
! 17602: * totalDigits <= BASE totalDigits
! 17603: */
! 17604: res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
! 17605: if (res == -2)
! 17606: goto internal_error;
! 17607: if (res == 1)
! 17608: xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
! 17609: -1, 1, 1);
! 17610: if ((res != 0) && (bftotdig->fixed)) {
! 17611: FACET_RESTR_FIXED_ERR(ftotdig)
! 17612: }
! 17613: }
! 17614: if (ffracdig && bffracdig) {
! 17615: /*
! 17616: * SCC "fractionDigits valid restriction"
! 17617: * fractionDigits <= BASE fractionDigits
! 17618: */
! 17619: res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
! 17620: if (res == -2)
! 17621: goto internal_error;
! 17622: if (res == 1)
! 17623: xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
! 17624: -1, 1, 1);
! 17625: if ((res != 0) && (bffracdig->fixed)) {
! 17626: FACET_RESTR_FIXED_ERR(ffracdig)
! 17627: }
! 17628: }
! 17629: /*
! 17630: * SCC "fractionDigits less than or equal to totalDigits"
! 17631: */
! 17632: if (! ftotdig)
! 17633: ftotdig = bftotdig;
! 17634: if (! ffracdig)
! 17635: ffracdig = bffracdig;
! 17636: if (ftotdig && ffracdig) {
! 17637: res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
! 17638: if (res == -2)
! 17639: goto internal_error;
! 17640: if (res == 1)
! 17641: xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
! 17642: -1, 1, 0);
! 17643: }
! 17644: /*
! 17645: * *Enumerations* won' be added here, since only the first set
! 17646: * of enumerations in the ancestor-or-self axis is used
! 17647: * for validation, plus we need to use the base type of those
! 17648: * enumerations for whitespace.
! 17649: *
! 17650: * *Patterns*: won't be add here, since they are ORed at
! 17651: * type level and ANDed at ancestor level. This will
! 17652: * happed during validation by walking the base axis
! 17653: * of the type.
! 17654: */
! 17655: for (cur = base->facetSet; cur != NULL; cur = cur->next) {
! 17656: bfacet = cur->facet;
! 17657: /*
! 17658: * Special handling of enumerations and patterns.
! 17659: * TODO: hmm, they should not appear in the set, so remove this.
! 17660: */
! 17661: if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
! 17662: (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
! 17663: continue;
! 17664: /*
! 17665: * Search for a duplicate facet in the current type.
! 17666: */
! 17667: link = type->facetSet;
! 17668: /* err = 0; */
! 17669: /* fixedErr = 0; */
! 17670: while (link != NULL) {
! 17671: facet = link->facet;
! 17672: if (facet->type == bfacet->type) {
! 17673: switch (facet->type) {
! 17674: case XML_SCHEMA_FACET_WHITESPACE:
! 17675: /*
! 17676: * The whitespace must be stronger.
! 17677: */
! 17678: if (facet->whitespace < bfacet->whitespace) {
! 17679: FACET_RESTR_ERR(facet,
! 17680: "The 'whitespace' value has to be equal to "
! 17681: "or stronger than the 'whitespace' value of "
! 17682: "the base type")
! 17683: }
! 17684: if ((bfacet->fixed) &&
! 17685: (facet->whitespace != bfacet->whitespace)) {
! 17686: FACET_RESTR_FIXED_ERR(facet)
! 17687: }
! 17688: break;
! 17689: default:
! 17690: break;
! 17691: }
! 17692: /* Duplicate found. */
! 17693: break;
! 17694: }
! 17695: link = link->next;
! 17696: }
! 17697: /*
! 17698: * If no duplicate was found: add the base types's facet
! 17699: * to the set.
! 17700: */
! 17701: if (link == NULL) {
! 17702: link = (xmlSchemaFacetLinkPtr)
! 17703: xmlMalloc(sizeof(xmlSchemaFacetLink));
! 17704: if (link == NULL) {
! 17705: xmlSchemaPErrMemory(pctxt,
! 17706: "deriving facets, creating a facet link", NULL);
! 17707: return (-1);
! 17708: }
! 17709: link->facet = cur->facet;
! 17710: link->next = NULL;
! 17711: if (last == NULL)
! 17712: type->facetSet = link;
! 17713: else
! 17714: last->next = link;
! 17715: last = link;
! 17716: }
! 17717:
! 17718: }
! 17719:
! 17720: return (0);
! 17721: internal_error:
! 17722: PERROR_INT("xmlSchemaDeriveAndValidateFacets",
! 17723: "an error occured");
! 17724: return (-1);
! 17725: }
! 17726:
! 17727: static int
! 17728: xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
! 17729: xmlSchemaTypePtr type)
! 17730: {
! 17731: xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
! 17732: /*
! 17733: * The actual value is then formed by replacing any union type
! 17734: * definition in the �explicit members� with the members of their
! 17735: * {member type definitions}, in order.
! 17736: *
! 17737: * TODO: There's a bug entry at
! 17738: * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
! 17739: * which indicates that we'll keep the union types the future.
! 17740: */
! 17741: link = type->memberTypes;
! 17742: while (link != NULL) {
! 17743:
! 17744: if (WXS_IS_TYPE_NOT_FIXED(link->type))
! 17745: xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
! 17746:
! 17747: if (WXS_IS_UNION(link->type)) {
! 17748: subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
! 17749: if (subLink != NULL) {
! 17750: link->type = subLink->type;
! 17751: if (subLink->next != NULL) {
! 17752: lastLink = link->next;
! 17753: subLink = subLink->next;
! 17754: prevLink = link;
! 17755: while (subLink != NULL) {
! 17756: newLink = (xmlSchemaTypeLinkPtr)
! 17757: xmlMalloc(sizeof(xmlSchemaTypeLink));
! 17758: if (newLink == NULL) {
! 17759: xmlSchemaPErrMemory(pctxt, "allocating a type link",
! 17760: NULL);
! 17761: return (-1);
! 17762: }
! 17763: newLink->type = subLink->type;
! 17764: prevLink->next = newLink;
! 17765: prevLink = newLink;
! 17766: newLink->next = lastLink;
! 17767:
! 17768: subLink = subLink->next;
! 17769: }
! 17770: }
! 17771: }
! 17772: }
! 17773: link = link->next;
! 17774: }
! 17775: return (0);
! 17776: }
! 17777:
! 17778: static void
! 17779: xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
! 17780: {
! 17781: int has = 0, needVal = 0, normVal = 0;
! 17782:
! 17783: has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
! 17784: if (has) {
! 17785: needVal = (type->baseType->flags &
! 17786: XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
! 17787: normVal = (type->baseType->flags &
! 17788: XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
! 17789: }
! 17790: if (type->facets != NULL) {
! 17791: xmlSchemaFacetPtr fac;
! 17792:
! 17793: for (fac = type->facets; fac != NULL; fac = fac->next) {
! 17794: switch (fac->type) {
! 17795: case XML_SCHEMA_FACET_WHITESPACE:
! 17796: break;
! 17797: case XML_SCHEMA_FACET_PATTERN:
! 17798: normVal = 1;
! 17799: has = 1;
! 17800: break;
! 17801: case XML_SCHEMA_FACET_ENUMERATION:
! 17802: needVal = 1;
! 17803: normVal = 1;
! 17804: has = 1;
! 17805: break;
! 17806: default:
! 17807: has = 1;
! 17808: break;
! 17809: }
! 17810: }
! 17811: }
! 17812: if (normVal)
! 17813: type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
! 17814: if (needVal)
! 17815: type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
! 17816: if (has)
! 17817: type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
! 17818:
! 17819: if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
! 17820: xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
! 17821: /*
! 17822: * OPTIMIZE VAL TODO: Some facets need a computed value.
! 17823: */
! 17824: if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
! 17825: (prim->builtInType != XML_SCHEMAS_STRING)) {
! 17826: type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
! 17827: }
! 17828: }
! 17829: }
! 17830:
! 17831: static int
! 17832: xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
! 17833: {
! 17834:
! 17835:
! 17836: /*
! 17837: * Evaluate the whitespace-facet value.
! 17838: */
! 17839: if (WXS_IS_LIST(type)) {
! 17840: type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
! 17841: return (0);
! 17842: } else if (WXS_IS_UNION(type))
! 17843: return (0);
! 17844:
! 17845: if (type->facetSet != NULL) {
! 17846: xmlSchemaFacetLinkPtr lin;
! 17847:
! 17848: for (lin = type->facetSet; lin != NULL; lin = lin->next) {
! 17849: if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
! 17850: switch (lin->facet->whitespace) {
! 17851: case XML_SCHEMAS_FACET_PRESERVE:
! 17852: type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
! 17853: break;
! 17854: case XML_SCHEMAS_FACET_REPLACE:
! 17855: type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
! 17856: break;
! 17857: case XML_SCHEMAS_FACET_COLLAPSE:
! 17858: type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
! 17859: break;
! 17860: default:
! 17861: return (-1);
! 17862: }
! 17863: return (0);
! 17864: }
! 17865: }
! 17866: }
! 17867: /*
! 17868: * For all �atomic� datatypes other than string (and types �derived�
! 17869: * by �restriction� from it) the value of whiteSpace is fixed to
! 17870: * collapse
! 17871: */
! 17872: {
! 17873: xmlSchemaTypePtr anc;
! 17874:
! 17875: for (anc = type->baseType; anc != NULL &&
! 17876: anc->builtInType != XML_SCHEMAS_ANYTYPE;
! 17877: anc = anc->baseType) {
! 17878:
! 17879: if (anc->type == XML_SCHEMA_TYPE_BASIC) {
! 17880: if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
! 17881: type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
! 17882:
! 17883: } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
! 17884: (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
! 17885: type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
! 17886:
! 17887: } else
! 17888: type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
! 17889: break;
! 17890: }
! 17891: }
! 17892: }
! 17893: return (0);
! 17894: }
! 17895:
! 17896: static int
! 17897: xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
! 17898: xmlSchemaTypePtr type)
! 17899: {
! 17900: if (type->type != XML_SCHEMA_TYPE_SIMPLE)
! 17901: return(0);
! 17902: if (! WXS_IS_TYPE_NOT_FIXED_1(type))
! 17903: return(0);
! 17904: type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
! 17905:
! 17906: if (WXS_IS_LIST(type)) {
! 17907: /*
! 17908: * Corresponds to <simpleType><list>...
! 17909: */
! 17910: if (type->subtypes == NULL) {
! 17911: /*
! 17912: * This one is really needed, so get out.
! 17913: */
! 17914: PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
! 17915: "list type has no item-type assigned");
! 17916: return(-1);
! 17917: }
! 17918: } else if (WXS_IS_UNION(type)) {
! 17919: /*
! 17920: * Corresponds to <simpleType><union>...
! 17921: */
! 17922: if (type->memberTypes == NULL) {
! 17923: /*
! 17924: * This one is really needed, so get out.
! 17925: */
! 17926: PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
! 17927: "union type has no member-types assigned");
! 17928: return(-1);
! 17929: }
! 17930: } else {
! 17931: /*
! 17932: * Corresponds to <simpleType><restriction>...
! 17933: */
! 17934: if (type->baseType == NULL) {
! 17935: PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
! 17936: "type has no base-type assigned");
! 17937: return(-1);
! 17938: }
! 17939: if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
! 17940: if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
! 17941: return(-1);
! 17942: /*
! 17943: * Variety
! 17944: * If the <restriction> alternative is chosen, then the
! 17945: * {variety} of the {base type definition}.
! 17946: */
! 17947: if (WXS_IS_ATOMIC(type->baseType))
! 17948: type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
! 17949: else if (WXS_IS_LIST(type->baseType)) {
! 17950: type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
! 17951: /*
! 17952: * Inherit the itemType.
! 17953: */
! 17954: type->subtypes = type->baseType->subtypes;
! 17955: } else if (WXS_IS_UNION(type->baseType)) {
! 17956: type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
! 17957: /*
! 17958: * NOTE that we won't assign the memberTypes of the base,
! 17959: * since this will make trouble when freeing them; we will
! 17960: * use a lookup function to access them instead.
! 17961: */
! 17962: }
! 17963: }
! 17964: return(0);
! 17965: }
! 17966:
! 17967: #ifdef DEBUG_TYPE
! 17968: static void
! 17969: xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
! 17970: xmlSchemaTypePtr type)
! 17971: {
! 17972: if (type->node != NULL) {
! 17973: xmlGenericError(xmlGenericErrorContext,
! 17974: "Type of %s : %s:%d :", name,
! 17975: type->node->doc->URL,
! 17976: xmlGetLineNo(type->node));
! 17977: } else {
! 17978: xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
! 17979: }
! 17980: if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
! 17981: switch (type->contentType) {
! 17982: case XML_SCHEMA_CONTENT_SIMPLE:
! 17983: xmlGenericError(xmlGenericErrorContext, "simple\n");
! 17984: break;
! 17985: case XML_SCHEMA_CONTENT_ELEMENTS:
! 17986: xmlGenericError(xmlGenericErrorContext, "elements\n");
! 17987: break;
! 17988: case XML_SCHEMA_CONTENT_UNKNOWN:
! 17989: xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
! 17990: break;
! 17991: case XML_SCHEMA_CONTENT_EMPTY:
! 17992: xmlGenericError(xmlGenericErrorContext, "empty\n");
! 17993: break;
! 17994: case XML_SCHEMA_CONTENT_MIXED:
! 17995: if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
! 17996: type->subtypes))
! 17997: xmlGenericError(xmlGenericErrorContext,
! 17998: "mixed as emptiable particle\n");
! 17999: else
! 18000: xmlGenericError(xmlGenericErrorContext, "mixed\n");
! 18001: break;
! 18002: /* Removed, since not used. */
! 18003: /*
! 18004: case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
! 18005: xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
! 18006: break;
! 18007: */
! 18008: case XML_SCHEMA_CONTENT_BASIC:
! 18009: xmlGenericError(xmlGenericErrorContext, "basic\n");
! 18010: break;
! 18011: default:
! 18012: xmlGenericError(xmlGenericErrorContext,
! 18013: "not registered !!!\n");
! 18014: break;
! 18015: }
! 18016: }
! 18017: }
! 18018: #endif
! 18019:
! 18020: /*
! 18021: * 3.14.6 Constraints on Simple Type Definition Schema Components
! 18022: */
! 18023: static int
! 18024: xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
! 18025: xmlSchemaTypePtr type)
! 18026: {
! 18027: int res, olderrs = pctxt->nberrors;
! 18028:
! 18029: if (type->type != XML_SCHEMA_TYPE_SIMPLE)
! 18030: return(-1);
! 18031:
! 18032: if (! WXS_IS_TYPE_NOT_FIXED(type))
! 18033: return(0);
! 18034:
! 18035: type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
! 18036: type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
! 18037:
! 18038: if (type->baseType == NULL) {
! 18039: PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
! 18040: "missing baseType");
! 18041: goto exit_failure;
! 18042: }
! 18043: if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
! 18044: xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
! 18045: /*
! 18046: * If a member type of a union is a union itself, we need to substitute
! 18047: * that member type for its member types.
! 18048: * NOTE that this might change in WXS 1.1; i.e. we will keep the union
! 18049: * types in WXS 1.1.
! 18050: */
! 18051: if ((type->memberTypes != NULL) &&
! 18052: (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
! 18053: return(-1);
! 18054: /*
! 18055: * SPEC src-simple-type 1
! 18056: * "The corresponding simple type definition, if any, must satisfy
! 18057: * the conditions set out in Constraints on Simple Type Definition
! 18058: * Schema Components (�3.14.6)."
! 18059: */
! 18060: /*
! 18061: * Schema Component Constraint: Simple Type Definition Properties Correct
! 18062: * (st-props-correct)
! 18063: */
! 18064: res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
! 18065: HFAILURE HERROR
! 18066: /*
! 18067: * Schema Component Constraint: Derivation Valid (Restriction, Simple)
! 18068: * (cos-st-restricts)
! 18069: */
! 18070: res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
! 18071: HFAILURE HERROR
! 18072: /*
! 18073: * TODO: Removed the error report, since it got annoying to get an
! 18074: * extra error report, if anything failed until now.
! 18075: * Enable this if needed.
! 18076: *
! 18077: * xmlSchemaPErr(ctxt, type->node,
! 18078: * XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
! 18079: * "Simple type '%s' does not satisfy the constraints "
! 18080: * "on simple type definitions.\n",
! 18081: * type->name, NULL);
! 18082: */
! 18083: /*
! 18084: * Schema Component Constraint: Simple Type Restriction (Facets)
! 18085: * (st-restrict-facets)
! 18086: */
! 18087: res = xmlSchemaCheckFacetValues(type, pctxt);
! 18088: HFAILURE HERROR
! 18089: if ((type->facetSet != NULL) ||
! 18090: (type->baseType->facetSet != NULL)) {
! 18091: res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
! 18092: HFAILURE HERROR
! 18093: }
! 18094: /*
! 18095: * Whitespace value.
! 18096: */
! 18097: res = xmlSchemaTypeFixupWhitespace(type);
! 18098: HFAILURE HERROR
! 18099: xmlSchemaTypeFixupOptimFacets(type);
! 18100:
! 18101: exit_error:
! 18102: #ifdef DEBUG_TYPE
! 18103: xmlSchemaDebugFixedType(pctxt, type);
! 18104: #endif
! 18105: if (olderrs != pctxt->nberrors)
! 18106: return(pctxt->err);
! 18107: return(0);
! 18108:
! 18109: exit_failure:
! 18110: #ifdef DEBUG_TYPE
! 18111: xmlSchemaDebugFixedType(pctxt, type);
! 18112: #endif
! 18113: return(-1);
! 18114: }
! 18115:
! 18116: static int
! 18117: xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
! 18118: xmlSchemaTypePtr type)
! 18119: {
! 18120: int res = 0, olderrs = pctxt->nberrors;
! 18121: xmlSchemaTypePtr baseType = type->baseType;
! 18122:
! 18123: if (! WXS_IS_TYPE_NOT_FIXED(type))
! 18124: return(0);
! 18125: type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
! 18126: if (baseType == NULL) {
! 18127: PERROR_INT("xmlSchemaFixupComplexType",
! 18128: "missing baseType");
! 18129: goto exit_failure;
! 18130: }
! 18131: /*
! 18132: * Fixup the base type.
! 18133: */
! 18134: if (WXS_IS_TYPE_NOT_FIXED(baseType))
! 18135: xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
! 18136: if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
! 18137: /*
! 18138: * Skip fixup if the base type is invalid.
! 18139: * TODO: Generate a warning!
! 18140: */
! 18141: return(0);
! 18142: }
! 18143: /*
! 18144: * This basically checks if the base type can be derived.
! 18145: */
! 18146: res = xmlSchemaCheckSRCCT(pctxt, type);
! 18147: HFAILURE HERROR
! 18148: /*
! 18149: * Fixup the content type.
! 18150: */
! 18151: if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
! 18152: /*
! 18153: * Corresponds to <complexType><simpleContent>...
! 18154: */
! 18155: if ((WXS_IS_COMPLEX(baseType)) &&
! 18156: (baseType->contentTypeDef != NULL) &&
! 18157: (WXS_IS_RESTRICTION(type))) {
! 18158: xmlSchemaTypePtr contentBase, content;
! 18159: #ifdef ENABLE_NAMED_LOCALS
! 18160: char buf[30];
! 18161: const xmlChar *tmpname;
! 18162: #endif
! 18163: /*
! 18164: * SPEC (1) If <restriction> + base type is <complexType>,
! 18165: * "whose own {content type} is a simple type..."
! 18166: */
! 18167: if (type->contentTypeDef != NULL) {
! 18168: /*
! 18169: * SPEC (1.1) "the simple type definition corresponding to the
! 18170: * <simpleType> among the [children] of <restriction> if there
! 18171: * is one;"
! 18172: * Note that this "<simpleType> among the [children]" was put
! 18173: * into ->contentTypeDef during parsing.
! 18174: */
! 18175: contentBase = type->contentTypeDef;
! 18176: type->contentTypeDef = NULL;
! 18177: } else {
! 18178: /*
! 18179: * (1.2) "...otherwise (<restriction> has no <simpleType>
! 18180: * among its [children]), the simple type definition which
! 18181: * is the {content type} of the ... base type."
! 18182: */
! 18183: contentBase = baseType->contentTypeDef;
! 18184: }
! 18185: /*
! 18186: * SPEC
! 18187: * "... a simple type definition which restricts the simple
! 18188: * type definition identified in clause 1.1 or clause 1.2
! 18189: * with a set of facet components"
! 18190: *
! 18191: * Create the anonymous simple type, which will be the content
! 18192: * type of the complex type.
! 18193: */
! 18194: #ifdef ENABLE_NAMED_LOCALS
! 18195: snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
! 18196: tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
! 18197: content = xmlSchemaAddType(pctxt, pctxt->schema,
! 18198: XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
! 18199: type->node, 0);
! 18200: #else
! 18201: content = xmlSchemaAddType(pctxt, pctxt->schema,
! 18202: XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
! 18203: type->node, 0);
! 18204: #endif
! 18205: if (content == NULL)
! 18206: goto exit_failure;
! 18207: /*
! 18208: * We will use the same node as for the <complexType>
! 18209: * to have it somehow anchored in the schema doc.
! 18210: */
! 18211: content->type = XML_SCHEMA_TYPE_SIMPLE;
! 18212: content->baseType = contentBase;
! 18213: /*
! 18214: * Move the facets, previously anchored on the
! 18215: * complexType during parsing.
! 18216: */
! 18217: content->facets = type->facets;
! 18218: type->facets = NULL;
! 18219: content->facetSet = type->facetSet;
! 18220: type->facetSet = NULL;
! 18221:
! 18222: type->contentTypeDef = content;
! 18223: if (WXS_IS_TYPE_NOT_FIXED(contentBase))
! 18224: xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
! 18225: /*
! 18226: * Fixup the newly created type. We don't need to check
! 18227: * for circularity here.
! 18228: */
! 18229: res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
! 18230: HFAILURE HERROR
! 18231: res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
! 18232: HFAILURE HERROR
! 18233:
! 18234: } else if ((WXS_IS_COMPLEX(baseType)) &&
! 18235: (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
! 18236: (WXS_IS_RESTRICTION(type))) {
! 18237: /*
! 18238: * SPEC (2) If <restriction> + base is a mixed <complexType> with
! 18239: * an emptiable particle, then a simple type definition which
! 18240: * restricts the <restriction>'s <simpleType> child.
! 18241: */
! 18242: if ((type->contentTypeDef == NULL) ||
! 18243: (type->contentTypeDef->baseType == NULL)) {
! 18244: /*
! 18245: * TODO: Check if this ever happens.
! 18246: */
! 18247: xmlSchemaPCustomErr(pctxt,
! 18248: XML_SCHEMAP_INTERNAL,
! 18249: WXS_BASIC_CAST type, NULL,
! 18250: "Internal error: xmlSchemaTypeFixup, "
! 18251: "complex type '%s': the <simpleContent><restriction> "
! 18252: "is missing a <simpleType> child, but was not catched "
! 18253: "by xmlSchemaCheckSRCCT()", type->name);
! 18254: goto exit_failure;
! 18255: }
! 18256: } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
! 18257: /*
! 18258: * SPEC (3) If <extension> + base is <complexType> with
! 18259: * <simpleType> content, "...then the {content type} of that
! 18260: * complex type definition"
! 18261: */
! 18262: if (baseType->contentTypeDef == NULL) {
! 18263: /*
! 18264: * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
! 18265: * should have catched this already.
! 18266: */
! 18267: xmlSchemaPCustomErr(pctxt,
! 18268: XML_SCHEMAP_INTERNAL,
! 18269: WXS_BASIC_CAST type, NULL,
! 18270: "Internal error: xmlSchemaTypeFixup, "
! 18271: "complex type '%s': the <extension>ed base type is "
! 18272: "a complex type with no simple content type",
! 18273: type->name);
! 18274: goto exit_failure;
! 18275: }
! 18276: type->contentTypeDef = baseType->contentTypeDef;
! 18277: } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
! 18278: /*
! 18279: * SPEC (4) <extension> + base is <simpleType>
! 18280: * "... then that simple type definition"
! 18281: */
! 18282: type->contentTypeDef = baseType;
! 18283: } else {
! 18284: /*
! 18285: * TODO: Check if this ever happens.
! 18286: */
! 18287: xmlSchemaPCustomErr(pctxt,
! 18288: XML_SCHEMAP_INTERNAL,
! 18289: WXS_BASIC_CAST type, NULL,
! 18290: "Internal error: xmlSchemaTypeFixup, "
! 18291: "complex type '%s' with <simpleContent>: unhandled "
! 18292: "derivation case", type->name);
! 18293: goto exit_failure;
! 18294: }
! 18295: } else {
! 18296: int dummySequence = 0;
! 18297: xmlSchemaParticlePtr particle =
! 18298: (xmlSchemaParticlePtr) type->subtypes;
! 18299: /*
! 18300: * Corresponds to <complexType><complexContent>...
! 18301: *
! 18302: * NOTE that the effective mixed was already set during parsing of
! 18303: * <complexType> and <complexContent>; its flag value is
! 18304: * XML_SCHEMAS_TYPE_MIXED.
! 18305: *
! 18306: * Compute the "effective content":
! 18307: * (2.1.1) + (2.1.2) + (2.1.3)
! 18308: */
! 18309: if ((particle == NULL) ||
! 18310: ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
! 18311: ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
! 18312: (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
! 18313: ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
! 18314: (particle->minOccurs == 0))) &&
! 18315: ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
! 18316: if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
! 18317: /*
! 18318: * SPEC (2.1.4) "If the �effective mixed� is true, then
! 18319: * a particle whose properties are as follows:..."
! 18320: *
! 18321: * Empty sequence model group with
! 18322: * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
! 18323: * NOTE that we sill assign it the <complexType> node to
! 18324: * somehow anchor it in the doc.
! 18325: */
! 18326: if ((particle == NULL) ||
! 18327: (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
! 18328: /*
! 18329: * Create the particle.
! 18330: */
! 18331: particle = xmlSchemaAddParticle(pctxt,
! 18332: type->node, 1, 1);
! 18333: if (particle == NULL)
! 18334: goto exit_failure;
! 18335: /*
! 18336: * Create the model group.
! 18337: */ /* URGENT TODO: avoid adding to pending items. */
! 18338: particle->children = (xmlSchemaTreeItemPtr)
! 18339: xmlSchemaAddModelGroup(pctxt, pctxt->schema,
! 18340: XML_SCHEMA_TYPE_SEQUENCE, type->node);
! 18341: if (particle->children == NULL)
! 18342: goto exit_failure;
! 18343:
! 18344: type->subtypes = (xmlSchemaTypePtr) particle;
! 18345: }
! 18346: dummySequence = 1;
! 18347: type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
! 18348: } else {
! 18349: /*
! 18350: * SPEC (2.1.5) "otherwise empty"
! 18351: */
! 18352: type->contentType = XML_SCHEMA_CONTENT_EMPTY;
! 18353: }
! 18354: } else {
! 18355: /*
! 18356: * SPEC (2.2) "otherwise the particle corresponding to the
! 18357: * <all>, <choice>, <group> or <sequence> among the
! 18358: * [children]."
! 18359: */
! 18360: type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
! 18361: }
! 18362: /*
! 18363: * Compute the "content type".
! 18364: */
! 18365: if (WXS_IS_RESTRICTION(type)) {
! 18366: /*
! 18367: * SPEC (3.1) "If <restriction>..."
! 18368: * (3.1.1) + (3.1.2) */
! 18369: if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
! 18370: if (type->flags & XML_SCHEMAS_TYPE_MIXED)
! 18371: type->contentType = XML_SCHEMA_CONTENT_MIXED;
! 18372: }
! 18373: } else {
! 18374: /*
! 18375: * SPEC (3.2) "If <extension>..."
! 18376: */
! 18377: if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
! 18378: /*
! 18379: * SPEC (3.2.1)
! 18380: * "If the �effective content� is empty, then the
! 18381: * {content type} of the [...] base ..."
! 18382: */
! 18383: type->contentType = baseType->contentType;
! 18384: type->subtypes = baseType->subtypes;
! 18385: /*
! 18386: * Fixes bug #347316:
! 18387: * This is the case when the base type has a simple
! 18388: * type definition as content.
! 18389: */
! 18390: type->contentTypeDef = baseType->contentTypeDef;
! 18391: /*
! 18392: * NOTE that the effective mixed is ignored here.
! 18393: */
! 18394: } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
! 18395: /*
! 18396: * SPEC (3.2.2)
! 18397: */
! 18398: if (type->flags & XML_SCHEMAS_TYPE_MIXED)
! 18399: type->contentType = XML_SCHEMA_CONTENT_MIXED;
! 18400: } else {
! 18401: /*
! 18402: * SPEC (3.2.3)
! 18403: */
! 18404: if (type->flags & XML_SCHEMAS_TYPE_MIXED)
! 18405: type->contentType = XML_SCHEMA_CONTENT_MIXED;
! 18406: /*
! 18407: * "A model group whose {compositor} is sequence and whose
! 18408: * {particles} are..."
! 18409: */
! 18410: if ((WXS_TYPE_PARTICLE(type) != NULL) &&
! 18411: (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
! 18412: ((WXS_TYPE_PARTICLE_TERM(type))->type ==
! 18413: XML_SCHEMA_TYPE_ALL))
! 18414: {
! 18415: /*
! 18416: * SPEC cos-all-limited (1)
! 18417: */
! 18418: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 18419: /* TODO: error code */
! 18420: XML_SCHEMAP_COS_ALL_LIMITED,
! 18421: WXS_ITEM_NODE(type), NULL,
! 18422: "The type has an 'all' model group in its "
! 18423: "{content type} and thus cannot be derived from "
! 18424: "a non-empty type, since this would produce a "
! 18425: "'sequence' model group containing the 'all' "
! 18426: "model group; 'all' model groups are not "
! 18427: "allowed to appear inside other model groups",
! 18428: NULL, NULL);
! 18429:
! 18430: } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
! 18431: (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
! 18432: ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
! 18433: XML_SCHEMA_TYPE_ALL))
! 18434: {
! 18435: /*
! 18436: * SPEC cos-all-limited (1)
! 18437: */
! 18438: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 18439: /* TODO: error code */
! 18440: XML_SCHEMAP_COS_ALL_LIMITED,
! 18441: WXS_ITEM_NODE(type), NULL,
! 18442: "A type cannot be derived by extension from a type "
! 18443: "which has an 'all' model group in its "
! 18444: "{content type}, since this would produce a "
! 18445: "'sequence' model group containing the 'all' "
! 18446: "model group; 'all' model groups are not "
! 18447: "allowed to appear inside other model groups",
! 18448: NULL, NULL);
! 18449:
! 18450: } else if (! dummySequence) {
! 18451: xmlSchemaTreeItemPtr effectiveContent =
! 18452: (xmlSchemaTreeItemPtr) type->subtypes;
! 18453: /*
! 18454: * Create the particle.
! 18455: */
! 18456: particle = xmlSchemaAddParticle(pctxt,
! 18457: type->node, 1, 1);
! 18458: if (particle == NULL)
! 18459: goto exit_failure;
! 18460: /*
! 18461: * Create the "sequence" model group.
! 18462: */
! 18463: particle->children = (xmlSchemaTreeItemPtr)
! 18464: xmlSchemaAddModelGroup(pctxt, pctxt->schema,
! 18465: XML_SCHEMA_TYPE_SEQUENCE, type->node);
! 18466: if (particle->children == NULL)
! 18467: goto exit_failure;
! 18468: WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
! 18469: /*
! 18470: * SPEC "the particle of the {content type} of
! 18471: * the ... base ..."
! 18472: * Create a duplicate of the base type's particle
! 18473: * and assign its "term" to it.
! 18474: */
! 18475: particle->children->children =
! 18476: (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
! 18477: type->node,
! 18478: ((xmlSchemaParticlePtr) type->subtypes)->minOccurs,
! 18479: ((xmlSchemaParticlePtr) type->subtypes)->maxOccurs);
! 18480: if (particle->children->children == NULL)
! 18481: goto exit_failure;
! 18482: particle = (xmlSchemaParticlePtr)
! 18483: particle->children->children;
! 18484: particle->children =
! 18485: ((xmlSchemaParticlePtr) baseType->subtypes)->children;
! 18486: /*
! 18487: * SPEC "followed by the �effective content�."
! 18488: */
! 18489: particle->next = effectiveContent;
! 18490: /*
! 18491: * This all will result in:
! 18492: * new-particle
! 18493: * --> new-sequence(
! 18494: * new-particle
! 18495: * --> base-model,
! 18496: * this-particle
! 18497: * --> this-model
! 18498: * )
! 18499: */
! 18500: } else {
! 18501: /*
! 18502: * This is the case when there is already an empty
! 18503: * <sequence> with minOccurs==maxOccurs==1.
! 18504: * Just add the base types's content type.
! 18505: * NOTE that, although we miss to add an intermediate
! 18506: * <sequence>, this should produce no difference to
! 18507: * neither the regex compilation of the content model,
! 18508: * nor to the complex type contraints.
! 18509: */
! 18510: particle->children->children =
! 18511: (xmlSchemaTreeItemPtr) baseType->subtypes;
! 18512: }
! 18513: }
! 18514: }
! 18515: }
! 18516: /*
! 18517: * Now fixup attribute uses:
! 18518: * - expand attr. group references
! 18519: * - intersect attribute wildcards
! 18520: * - inherit attribute uses of the base type
! 18521: * - inherit or union attr. wildcards if extending
! 18522: * - apply attr. use prohibitions if restricting
! 18523: */
! 18524: res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
! 18525: HFAILURE HERROR
! 18526: /*
! 18527: * Apply the complex type component constraints; this will not
! 18528: * check attributes, since this is done in
! 18529: * xmlSchemaFixupTypeAttributeUses().
! 18530: */
! 18531: res = xmlSchemaCheckCTComponent(pctxt, type);
! 18532: HFAILURE HERROR
! 18533:
! 18534: #ifdef DEBUG_TYPE
! 18535: xmlSchemaDebugFixedType(pctxt, type);
! 18536: #endif
! 18537: if (olderrs != pctxt->nberrors)
! 18538: return(pctxt->err);
! 18539: else
! 18540: return(0);
! 18541:
! 18542: exit_error:
! 18543: type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
! 18544: #ifdef DEBUG_TYPE
! 18545: xmlSchemaDebugFixedType(pctxt, type);
! 18546: #endif
! 18547: return(pctxt->err);
! 18548:
! 18549: exit_failure:
! 18550: type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
! 18551: #ifdef DEBUG_TYPE
! 18552: xmlSchemaDebugFixedType(pctxt, type);
! 18553: #endif
! 18554: return(-1);
! 18555: }
! 18556:
! 18557:
! 18558: /**
! 18559: * xmlSchemaTypeFixup:
! 18560: * @typeDecl: the schema type definition
! 18561: * @ctxt: the schema parser context
! 18562: *
! 18563: * Fixes the content model of the type.
! 18564: * URGENT TODO: We need an int result!
! 18565: */
! 18566: static int
! 18567: xmlSchemaTypeFixup(xmlSchemaTypePtr type,
! 18568: xmlSchemaAbstractCtxtPtr actxt)
! 18569: {
! 18570: if (type == NULL)
! 18571: return(0);
! 18572: if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
! 18573: AERROR_INT("xmlSchemaTypeFixup",
! 18574: "this function needs a parser context");
! 18575: return(-1);
! 18576: }
! 18577: if (! WXS_IS_TYPE_NOT_FIXED(type))
! 18578: return(0);
! 18579: if (type->type == XML_SCHEMA_TYPE_COMPLEX)
! 18580: return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
! 18581: else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
! 18582: return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
! 18583: return(0);
! 18584: }
! 18585:
! 18586: /**
! 18587: * xmlSchemaCheckFacet:
! 18588: * @facet: the facet
! 18589: * @typeDecl: the schema type definition
! 18590: * @pctxt: the schema parser context or NULL
! 18591: * @name: the optional name of the type
! 18592: *
! 18593: * Checks and computes the values of facets.
! 18594: *
! 18595: * Returns 0 if valid, a positive error code if not valid and
! 18596: * -1 in case of an internal or API error.
! 18597: */
! 18598: int
! 18599: xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
! 18600: xmlSchemaTypePtr typeDecl,
! 18601: xmlSchemaParserCtxtPtr pctxt,
! 18602: const xmlChar * name ATTRIBUTE_UNUSED)
! 18603: {
! 18604: int ret = 0, ctxtGiven;
! 18605:
! 18606: if ((facet == NULL) || (typeDecl == NULL))
! 18607: return(-1);
! 18608: /*
! 18609: * TODO: will the parser context be given if used from
! 18610: * the relaxNG module?
! 18611: */
! 18612: if (pctxt == NULL)
! 18613: ctxtGiven = 0;
! 18614: else
! 18615: ctxtGiven = 1;
! 18616:
! 18617: switch (facet->type) {
! 18618: case XML_SCHEMA_FACET_MININCLUSIVE:
! 18619: case XML_SCHEMA_FACET_MINEXCLUSIVE:
! 18620: case XML_SCHEMA_FACET_MAXINCLUSIVE:
! 18621: case XML_SCHEMA_FACET_MAXEXCLUSIVE:
! 18622: case XML_SCHEMA_FACET_ENUMERATION: {
! 18623: /*
! 18624: * Okay we need to validate the value
! 18625: * at that point.
! 18626: */
! 18627: xmlSchemaTypePtr base;
! 18628:
! 18629: /* 4.3.5.5 Constraints on enumeration Schema Components
! 18630: * Schema Component Constraint: enumeration valid restriction
! 18631: * It is an �error� if any member of {value} is not in the
! 18632: * �value space� of {base type definition}.
! 18633: *
! 18634: * minInclusive, maxInclusive, minExclusive, maxExclusive:
! 18635: * The value �must� be in the
! 18636: * �value space� of the �base type�.
! 18637: */
! 18638: /*
! 18639: * This function is intended to deliver a compiled value
! 18640: * on the facet. In this implementation of XML Schemata the
! 18641: * type holding a facet, won't be a built-in type.
! 18642: * Thus to ensure that other API
! 18643: * calls (relaxng) do work, if the given type is a built-in
! 18644: * type, we will assume that the given built-in type *is
! 18645: * already* the base type.
! 18646: */
! 18647: if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
! 18648: base = typeDecl->baseType;
! 18649: if (base == NULL) {
! 18650: PERROR_INT("xmlSchemaCheckFacet",
! 18651: "a type user derived type has no base type");
! 18652: return (-1);
! 18653: }
! 18654: } else
! 18655: base = typeDecl;
! 18656:
! 18657: if (! ctxtGiven) {
! 18658: /*
! 18659: * A context is needed if called from RelaxNG.
! 18660: */
! 18661: pctxt = xmlSchemaNewParserCtxt("*");
! 18662: if (pctxt == NULL)
! 18663: return (-1);
! 18664: }
! 18665: /*
! 18666: * NOTE: This call does not check the content nodes,
! 18667: * since they are not available:
! 18668: * facet->node is just the node holding the facet
! 18669: * definition, *not* the attribute holding the *value*
! 18670: * of the facet.
! 18671: */
! 18672: ret = xmlSchemaVCheckCVCSimpleType(
! 18673: ACTXT_CAST pctxt, facet->node, base,
! 18674: facet->value, &(facet->val), 1, 1, 0);
! 18675: if (ret != 0) {
! 18676: if (ret < 0) {
! 18677: /* No error message for RelaxNG. */
! 18678: if (ctxtGiven) {
! 18679: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 18680: XML_SCHEMAP_INTERNAL, facet->node, NULL,
! 18681: "Internal error: xmlSchemaCheckFacet, "
! 18682: "failed to validate the value '%s' of the "
! 18683: "facet '%s' against the base type",
! 18684: facet->value, xmlSchemaFacetTypeToString(facet->type));
! 18685: }
! 18686: goto internal_error;
! 18687: }
! 18688: ret = XML_SCHEMAP_INVALID_FACET_VALUE;
! 18689: /* No error message for RelaxNG. */
! 18690: if (ctxtGiven) {
! 18691: xmlChar *str = NULL;
! 18692:
! 18693: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 18694: ret, facet->node, WXS_BASIC_CAST facet,
! 18695: "The value '%s' of the facet does not validate "
! 18696: "against the base type '%s'",
! 18697: facet->value,
! 18698: xmlSchemaFormatQName(&str,
! 18699: base->targetNamespace, base->name));
! 18700: FREE_AND_NULL(str);
! 18701: }
! 18702: goto exit;
! 18703: } else if (facet->val == NULL) {
! 18704: if (ctxtGiven) {
! 18705: PERROR_INT("xmlSchemaCheckFacet",
! 18706: "value was not computed");
! 18707: }
! 18708: TODO
! 18709: }
! 18710: break;
! 18711: }
! 18712: case XML_SCHEMA_FACET_PATTERN:
! 18713: facet->regexp = xmlRegexpCompile(facet->value);
! 18714: if (facet->regexp == NULL) {
! 18715: ret = XML_SCHEMAP_REGEXP_INVALID;
! 18716: /* No error message for RelaxNG. */
! 18717: if (ctxtGiven) {
! 18718: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 18719: ret, facet->node, WXS_BASIC_CAST typeDecl,
! 18720: "The value '%s' of the facet 'pattern' is not a "
! 18721: "valid regular expression",
! 18722: facet->value, NULL);
! 18723: }
! 18724: }
! 18725: break;
! 18726: case XML_SCHEMA_FACET_TOTALDIGITS:
! 18727: case XML_SCHEMA_FACET_FRACTIONDIGITS:
! 18728: case XML_SCHEMA_FACET_LENGTH:
! 18729: case XML_SCHEMA_FACET_MAXLENGTH:
! 18730: case XML_SCHEMA_FACET_MINLENGTH:
! 18731:
! 18732: if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
! 18733: ret = xmlSchemaValidatePredefinedType(
! 18734: xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
! 18735: facet->value, &(facet->val));
! 18736: } else {
! 18737: ret = xmlSchemaValidatePredefinedType(
! 18738: xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
! 18739: facet->value, &(facet->val));
! 18740: }
! 18741: if (ret != 0) {
! 18742: if (ret < 0) {
! 18743: /* No error message for RelaxNG. */
! 18744: if (ctxtGiven) {
! 18745: PERROR_INT("xmlSchemaCheckFacet",
! 18746: "validating facet value");
! 18747: }
! 18748: goto internal_error;
! 18749: }
! 18750: ret = XML_SCHEMAP_INVALID_FACET_VALUE;
! 18751: /* No error message for RelaxNG. */
! 18752: if (ctxtGiven) {
! 18753: /* error code */
! 18754: xmlSchemaCustomErr4(ACTXT_CAST pctxt,
! 18755: ret, facet->node, WXS_BASIC_CAST typeDecl,
! 18756: "The value '%s' of the facet '%s' is not a valid '%s'",
! 18757: facet->value,
! 18758: xmlSchemaFacetTypeToString(facet->type),
! 18759: (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
! 18760: BAD_CAST "nonNegativeInteger" :
! 18761: BAD_CAST "positiveInteger",
! 18762: NULL);
! 18763: }
! 18764: }
! 18765: break;
! 18766:
! 18767: case XML_SCHEMA_FACET_WHITESPACE:{
! 18768: if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
! 18769: facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
! 18770: } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
! 18771: facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
! 18772: } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
! 18773: facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
! 18774: } else {
! 18775: ret = XML_SCHEMAP_INVALID_FACET_VALUE;
! 18776: /* No error message for RelaxNG. */
! 18777: if (ctxtGiven) {
! 18778: /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
! 18779: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 18780: ret, facet->node, WXS_BASIC_CAST typeDecl,
! 18781: "The value '%s' of the facet 'whitespace' is not "
! 18782: "valid", facet->value, NULL);
! 18783: }
! 18784: }
! 18785: }
! 18786: default:
! 18787: break;
! 18788: }
! 18789: exit:
! 18790: if ((! ctxtGiven) && (pctxt != NULL))
! 18791: xmlSchemaFreeParserCtxt(pctxt);
! 18792: return (ret);
! 18793: internal_error:
! 18794: if ((! ctxtGiven) && (pctxt != NULL))
! 18795: xmlSchemaFreeParserCtxt(pctxt);
! 18796: return (-1);
! 18797: }
! 18798:
! 18799: /**
! 18800: * xmlSchemaCheckFacetValues:
! 18801: * @typeDecl: the schema type definition
! 18802: * @ctxt: the schema parser context
! 18803: *
! 18804: * Checks the default values types, especially for facets
! 18805: */
! 18806: static int
! 18807: xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
! 18808: xmlSchemaParserCtxtPtr pctxt)
! 18809: {
! 18810: int res, olderrs = pctxt->nberrors;
! 18811: const xmlChar *name = typeDecl->name;
! 18812: /*
! 18813: * NOTE: It is intended to use the facets list, instead
! 18814: * of facetSet.
! 18815: */
! 18816: if (typeDecl->facets != NULL) {
! 18817: xmlSchemaFacetPtr facet = typeDecl->facets;
! 18818:
! 18819: /*
! 18820: * Temporarily assign the "schema" to the validation context
! 18821: * of the parser context. This is needed for NOTATION validation.
! 18822: */
! 18823: if (pctxt->vctxt == NULL) {
! 18824: if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
! 18825: return(-1);
! 18826: }
! 18827: pctxt->vctxt->schema = pctxt->schema;
! 18828: while (facet != NULL) {
! 18829: res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
! 18830: HFAILURE
! 18831: facet = facet->next;
! 18832: }
! 18833: pctxt->vctxt->schema = NULL;
! 18834: }
! 18835: if (olderrs != pctxt->nberrors)
! 18836: return(pctxt->err);
! 18837: return(0);
! 18838: exit_failure:
! 18839: return(-1);
! 18840: }
! 18841:
! 18842: /**
! 18843: * xmlSchemaGetCircModelGrDefRef:
! 18844: * @ctxtMGroup: the searched model group
! 18845: * @selfMGroup: the second searched model group
! 18846: * @particle: the first particle
! 18847: *
! 18848: * This one is intended to be used by
! 18849: * xmlSchemaCheckGroupDefCircular only.
! 18850: *
! 18851: * Returns the particle with the circular model group definition reference,
! 18852: * otherwise NULL.
! 18853: */
! 18854: static xmlSchemaTreeItemPtr
! 18855: xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
! 18856: xmlSchemaTreeItemPtr particle)
! 18857: {
! 18858: xmlSchemaTreeItemPtr circ = NULL;
! 18859: xmlSchemaTreeItemPtr term;
! 18860: xmlSchemaModelGroupDefPtr gdef;
! 18861:
! 18862: for (; particle != NULL; particle = particle->next) {
! 18863: term = particle->children;
! 18864: if (term == NULL)
! 18865: continue;
! 18866: switch (term->type) {
! 18867: case XML_SCHEMA_TYPE_GROUP:
! 18868: gdef = (xmlSchemaModelGroupDefPtr) term;
! 18869: if (gdef == groupDef)
! 18870: return (particle);
! 18871: /*
! 18872: * Mark this model group definition to avoid infinite
! 18873: * recursion on circular references not yet examined.
! 18874: */
! 18875: if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
! 18876: continue;
! 18877: if (gdef->children != NULL) {
! 18878: gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
! 18879: circ = xmlSchemaGetCircModelGrDefRef(groupDef,
! 18880: gdef->children->children);
! 18881: gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
! 18882: if (circ != NULL)
! 18883: return (circ);
! 18884: }
! 18885: break;
! 18886: case XML_SCHEMA_TYPE_SEQUENCE:
! 18887: case XML_SCHEMA_TYPE_CHOICE:
! 18888: case XML_SCHEMA_TYPE_ALL:
! 18889: circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
! 18890: if (circ != NULL)
! 18891: return (circ);
! 18892: break;
! 18893: default:
! 18894: break;
! 18895: }
! 18896: }
! 18897: return (NULL);
! 18898: }
! 18899:
! 18900: /**
! 18901: * xmlSchemaCheckGroupDefCircular:
! 18902: * @item: the model group definition
! 18903: * @ctxt: the parser context
! 18904: * @name: the name
! 18905: *
! 18906: * Checks for circular references to model group definitions.
! 18907: */
! 18908: static void
! 18909: xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
! 18910: xmlSchemaParserCtxtPtr ctxt)
! 18911: {
! 18912: /*
! 18913: * Schema Component Constraint: Model Group Correct
! 18914: * 2 Circular groups are disallowed. That is, within the {particles}
! 18915: * of a group there must not be at any depth a particle whose {term}
! 18916: * is the group itself.
! 18917: */
! 18918: if ((item == NULL) ||
! 18919: (item->type != XML_SCHEMA_TYPE_GROUP) ||
! 18920: (item->children == NULL))
! 18921: return;
! 18922: {
! 18923: xmlSchemaTreeItemPtr circ;
! 18924:
! 18925: circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
! 18926: if (circ != NULL) {
! 18927: xmlChar *str = NULL;
! 18928: /*
! 18929: * TODO: The error report is not adequate: this constraint
! 18930: * is defined for model groups but not definitions, but since
! 18931: * there cannot be any circular model groups without a model group
! 18932: * definition (if not using a construction API), we check those
! 18933: * defintions only.
! 18934: */
! 18935: xmlSchemaPCustomErr(ctxt,
! 18936: XML_SCHEMAP_MG_PROPS_CORRECT_2,
! 18937: NULL, WXS_ITEM_NODE(circ),
! 18938: "Circular reference to the model group definition '%s' "
! 18939: "defined", xmlSchemaFormatQName(&str,
! 18940: item->targetNamespace, item->name));
! 18941: FREE_AND_NULL(str)
! 18942: /*
! 18943: * NOTE: We will cut the reference to avoid further
! 18944: * confusion of the processor. This is a fatal error.
! 18945: */
! 18946: circ->children = NULL;
! 18947: }
! 18948: }
! 18949: }
! 18950:
! 18951: /**
! 18952: * xmlSchemaModelGroupToModelGroupDefFixup:
! 18953: * @ctxt: the parser context
! 18954: * @mg: the model group
! 18955: *
! 18956: * Assigns the model group of model group definitions to the "term"
! 18957: * of the referencing particle.
! 18958: * In xmlSchemaResolveModelGroupParticleReferences the model group
! 18959: * definitions were assigned to the "term", since needed for the
! 18960: * circularity check.
! 18961: *
! 18962: * Schema Component Constraint:
! 18963: * All Group Limited (cos-all-limited) (1.2)
! 18964: */
! 18965: static void
! 18966: xmlSchemaModelGroupToModelGroupDefFixup(
! 18967: xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
! 18968: xmlSchemaModelGroupPtr mg)
! 18969: {
! 18970: xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
! 18971:
! 18972: while (particle != NULL) {
! 18973: if ((WXS_PARTICLE_TERM(particle) == NULL) ||
! 18974: ((WXS_PARTICLE_TERM(particle))->type !=
! 18975: XML_SCHEMA_TYPE_GROUP))
! 18976: {
! 18977: particle = WXS_PTC_CAST particle->next;
! 18978: continue;
! 18979: }
! 18980: if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
! 18981: /*
! 18982: * TODO: Remove the particle.
! 18983: */
! 18984: WXS_PARTICLE_TERM(particle) = NULL;
! 18985: particle = WXS_PTC_CAST particle->next;
! 18986: continue;
! 18987: }
! 18988: /*
! 18989: * Assign the model group to the {term} of the particle.
! 18990: */
! 18991: WXS_PARTICLE_TERM(particle) =
! 18992: WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
! 18993:
! 18994: particle = WXS_PTC_CAST particle->next;
! 18995: }
! 18996: }
! 18997:
! 18998: /**
! 18999: * xmlSchemaCheckAttrGroupCircularRecur:
! 19000: * @ctxtGr: the searched attribute group
! 19001: * @attr: the current attribute list to be processed
! 19002: *
! 19003: * This one is intended to be used by
! 19004: * xmlSchemaCheckAttrGroupCircular only.
! 19005: *
! 19006: * Returns the circular attribute grou reference, otherwise NULL.
! 19007: */
! 19008: static xmlSchemaQNameRefPtr
! 19009: xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
! 19010: xmlSchemaItemListPtr list)
! 19011: {
! 19012: xmlSchemaAttributeGroupPtr gr;
! 19013: xmlSchemaQNameRefPtr ref, circ;
! 19014: int i;
! 19015: /*
! 19016: * We will search for an attribute group reference which
! 19017: * references the context attribute group.
! 19018: */
! 19019: for (i = 0; i < list->nbItems; i++) {
! 19020: ref = list->items[i];
! 19021: if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
! 19022: (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
! 19023: (ref->item != NULL))
! 19024: {
! 19025: gr = WXS_ATTR_GROUP_CAST ref->item;
! 19026: if (gr == ctxtGr)
! 19027: return(ref);
! 19028: if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
! 19029: continue;
! 19030: /*
! 19031: * Mark as visited to avoid infinite recursion on
! 19032: * circular references not yet examined.
! 19033: */
! 19034: if ((gr->attrUses) &&
! 19035: (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
! 19036: {
! 19037: gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
! 19038: circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
! 19039: (xmlSchemaItemListPtr) gr->attrUses);
! 19040: gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
! 19041: if (circ != NULL)
! 19042: return (circ);
! 19043: }
! 19044:
! 19045: }
! 19046: }
! 19047: return (NULL);
! 19048: }
! 19049:
! 19050: /**
! 19051: * xmlSchemaCheckAttrGroupCircular:
! 19052: * attrGr: the attribute group definition
! 19053: * @ctxt: the parser context
! 19054: * @name: the name
! 19055: *
! 19056: * Checks for circular references of attribute groups.
! 19057: */
! 19058: static int
! 19059: xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
! 19060: xmlSchemaParserCtxtPtr ctxt)
! 19061: {
! 19062: /*
! 19063: * Schema Representation Constraint:
! 19064: * Attribute Group Definition Representation OK
! 19065: * 3 Circular group reference is disallowed outside <redefine>.
! 19066: * That is, unless this element information item's parent is
! 19067: * <redefine>, then among the [children], if any, there must
! 19068: * not be an <attributeGroup> with ref [attribute] which resolves
! 19069: * to the component corresponding to this <attributeGroup>. Indirect
! 19070: * circularity is also ruled out. That is, when QName resolution
! 19071: * (Schema Document) (�3.15.3) is applied to a �QName� arising from
! 19072: * any <attributeGroup>s with a ref [attribute] among the [children],
! 19073: * it must not be the case that a �QName� is encountered at any depth
! 19074: * which resolves to the component corresponding to this <attributeGroup>.
! 19075: */
! 19076: if (attrGr->attrUses == NULL)
! 19077: return(0);
! 19078: else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
! 19079: return(0);
! 19080: else {
! 19081: xmlSchemaQNameRefPtr circ;
! 19082:
! 19083: circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
! 19084: (xmlSchemaItemListPtr) attrGr->attrUses);
! 19085: if (circ != NULL) {
! 19086: xmlChar *str = NULL;
! 19087: /*
! 19088: * TODO: Report the referenced attr group as QName.
! 19089: */
! 19090: xmlSchemaPCustomErr(ctxt,
! 19091: XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
! 19092: NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
! 19093: "Circular reference to the attribute group '%s' "
! 19094: "defined", xmlSchemaGetComponentQName(&str, attrGr));
! 19095: FREE_AND_NULL(str);
! 19096: /*
! 19097: * NOTE: We will cut the reference to avoid further
! 19098: * confusion of the processor.
! 19099: * BADSPEC TODO: The spec should define how to process in this case.
! 19100: */
! 19101: circ->item = NULL;
! 19102: return(ctxt->err);
! 19103: }
! 19104: }
! 19105: return(0);
! 19106: }
! 19107:
! 19108: static int
! 19109: xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
! 19110: xmlSchemaAttributeGroupPtr attrGr);
! 19111:
! 19112: /**
! 19113: * xmlSchemaExpandAttributeGroupRefs:
! 19114: * @pctxt: the parser context
! 19115: * @node: the node of the component holding the attribute uses
! 19116: * @completeWild: the intersected wildcard to be returned
! 19117: * @list: the attribute uses
! 19118: *
! 19119: * Substitutes contained attribute group references
! 19120: * for their attribute uses. Wilcards are intersected.
! 19121: * Attribute use prohibitions are removed from the list
! 19122: * and returned via the @prohibs list.
! 19123: * Pointlessness of attr. prohibs, if a matching attr. decl
! 19124: * is existent a well, are checked.
! 19125: */
! 19126: static int
! 19127: xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
! 19128: xmlSchemaBasicItemPtr item,
! 19129: xmlSchemaWildcardPtr *completeWild,
! 19130: xmlSchemaItemListPtr list,
! 19131: xmlSchemaItemListPtr prohibs)
! 19132: {
! 19133: xmlSchemaAttributeGroupPtr gr;
! 19134: xmlSchemaAttributeUsePtr use;
! 19135: xmlSchemaItemListPtr sublist;
! 19136: int i, j;
! 19137: int created = (*completeWild == NULL) ? 0 : 1;
! 19138:
! 19139: if (prohibs)
! 19140: prohibs->nbItems = 0;
! 19141:
! 19142: for (i = 0; i < list->nbItems; i++) {
! 19143: use = list->items[i];
! 19144:
! 19145: if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
! 19146: if (prohibs == NULL) {
! 19147: PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
! 19148: "unexpected attr prohibition found");
! 19149: return(-1);
! 19150: }
! 19151: /*
! 19152: * Remove from attribute uses.
! 19153: */
! 19154: if (xmlSchemaItemListRemove(list, i) == -1)
! 19155: return(-1);
! 19156: i--;
! 19157: /*
! 19158: * Note that duplicate prohibitions were already
! 19159: * handled at parsing time.
! 19160: */
! 19161: /*
! 19162: * Add to list of prohibitions.
! 19163: */
! 19164: xmlSchemaItemListAddSize(prohibs, 2, use);
! 19165: continue;
! 19166: }
! 19167: if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
! 19168: ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
! 19169: {
! 19170: if ((WXS_QNAME_CAST use)->item == NULL)
! 19171: return(-1);
! 19172: gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
! 19173: /*
! 19174: * Expand the referenced attr. group.
! 19175: * TODO: remove this, this is done in a previous step, so
! 19176: * already done here.
! 19177: */
! 19178: if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
! 19179: if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
! 19180: return(-1);
! 19181: }
! 19182: /*
! 19183: * Build the 'complete' wildcard; i.e. intersect multiple
! 19184: * wildcards.
! 19185: */
! 19186: if (gr->attributeWildcard != NULL) {
! 19187: if (*completeWild == NULL) {
! 19188: *completeWild = gr->attributeWildcard;
! 19189: } else {
! 19190: if (! created) {
! 19191: xmlSchemaWildcardPtr tmpWild;
! 19192:
! 19193: /*
! 19194: * Copy the first encountered wildcard as context,
! 19195: * except for the annotation.
! 19196: *
! 19197: * Although the complete wildcard might not correspond
! 19198: * to any node in the schema, we will anchor it on
! 19199: * the node of the owner component.
! 19200: */
! 19201: tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema,
! 19202: XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
! 19203: WXS_ITEM_NODE(item));
! 19204: if (tmpWild == NULL)
! 19205: return(-1);
! 19206: if (xmlSchemaCloneWildcardNsConstraints(pctxt,
! 19207: tmpWild, *completeWild) == -1)
! 19208: return (-1);
! 19209: tmpWild->processContents = (*completeWild)->processContents;
! 19210: *completeWild = tmpWild;
! 19211: created = 1;
! 19212: }
! 19213:
! 19214: if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
! 19215: gr->attributeWildcard) == -1)
! 19216: return(-1);
! 19217: }
! 19218: }
! 19219: /*
! 19220: * Just remove the reference if the referenced group does not
! 19221: * contain any attribute uses.
! 19222: */
! 19223: sublist = ((xmlSchemaItemListPtr) gr->attrUses);
! 19224: if ((sublist == NULL) || sublist->nbItems == 0) {
! 19225: if (xmlSchemaItemListRemove(list, i) == -1)
! 19226: return(-1);
! 19227: i--;
! 19228: continue;
! 19229: }
! 19230: /*
! 19231: * Add the attribute uses.
! 19232: */
! 19233: list->items[i] = sublist->items[0];
! 19234: if (sublist->nbItems != 1) {
! 19235: for (j = 1; j < sublist->nbItems; j++) {
! 19236: i++;
! 19237: if (xmlSchemaItemListInsert(list,
! 19238: sublist->items[j], i) == -1)
! 19239: return(-1);
! 19240: }
! 19241: }
! 19242: }
! 19243:
! 19244: }
! 19245: /*
! 19246: * Handle pointless prohibitions of declared attributes.
! 19247: */
! 19248: if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
! 19249: xmlSchemaAttributeUseProhibPtr prohib;
! 19250:
! 19251: for (i = prohibs->nbItems -1; i >= 0; i--) {
! 19252: prohib = prohibs->items[i];
! 19253: for (j = 0; j < list->nbItems; j++) {
! 19254: use = list->items[j];
! 19255:
! 19256: if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
! 19257: (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
! 19258: {
! 19259: xmlChar *str = NULL;
! 19260:
! 19261: xmlSchemaCustomWarning(ACTXT_CAST pctxt,
! 19262: XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
! 19263: prohib->node, NULL,
! 19264: "Skipping pointless attribute use prohibition "
! 19265: "'%s', since a corresponding attribute use "
! 19266: "exists already in the type definition",
! 19267: xmlSchemaFormatQName(&str,
! 19268: prohib->targetNamespace, prohib->name),
! 19269: NULL, NULL);
! 19270: FREE_AND_NULL(str);
! 19271: /*
! 19272: * Remove the prohibition.
! 19273: */
! 19274: if (xmlSchemaItemListRemove(prohibs, i) == -1)
! 19275: return(-1);
! 19276: break;
! 19277: }
! 19278: }
! 19279: }
! 19280: }
! 19281: return(0);
! 19282: }
! 19283:
! 19284: /**
! 19285: * xmlSchemaAttributeGroupExpandRefs:
! 19286: * @pctxt: the parser context
! 19287: * @attrGr: the attribute group definition
! 19288: *
! 19289: * Computation of:
! 19290: * {attribute uses} property
! 19291: * {attribute wildcard} property
! 19292: *
! 19293: * Substitutes contained attribute group references
! 19294: * for their attribute uses. Wilcards are intersected.
! 19295: */
! 19296: static int
! 19297: xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
! 19298: xmlSchemaAttributeGroupPtr attrGr)
! 19299: {
! 19300: if ((attrGr->attrUses == NULL) ||
! 19301: (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
! 19302: return(0);
! 19303:
! 19304: attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
! 19305: if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
! 19306: &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
! 19307: return(-1);
! 19308: return(0);
! 19309: }
! 19310:
! 19311: /**
! 19312: * xmlSchemaAttributeGroupExpandRefs:
! 19313: * @pctxt: the parser context
! 19314: * @attrGr: the attribute group definition
! 19315: *
! 19316: * Substitutes contained attribute group references
! 19317: * for their attribute uses. Wilcards are intersected.
! 19318: *
! 19319: * Schema Component Constraint:
! 19320: * Attribute Group Definition Properties Correct (ag-props-correct)
! 19321: */
! 19322: static int
! 19323: xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
! 19324: xmlSchemaAttributeGroupPtr attrGr)
! 19325: {
! 19326: /*
! 19327: * SPEC ag-props-correct
! 19328: * (1) "The values of the properties of an attribute group definition
! 19329: * must be as described in the property tableau in The Attribute
! 19330: * Group Definition Schema Component (�3.6.1), modulo the impact of
! 19331: * Missing Sub-components (�5.3);"
! 19332: */
! 19333:
! 19334: if ((attrGr->attrUses != NULL) &&
! 19335: (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
! 19336: {
! 19337: xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
! 19338: xmlSchemaAttributeUsePtr use, tmp;
! 19339: int i, j, hasId = 0;
! 19340:
! 19341: for (i = uses->nbItems -1; i >= 0; i--) {
! 19342: use = uses->items[i];
! 19343: /*
! 19344: * SPEC ag-props-correct
! 19345: * (2) "Two distinct members of the {attribute uses} must not have
! 19346: * {attribute declaration}s both of whose {name}s match and whose
! 19347: * {target namespace}s are identical."
! 19348: */
! 19349: if (i > 0) {
! 19350: for (j = i -1; j >= 0; j--) {
! 19351: tmp = uses->items[j];
! 19352: if ((WXS_ATTRUSE_DECL_NAME(use) ==
! 19353: WXS_ATTRUSE_DECL_NAME(tmp)) &&
! 19354: (WXS_ATTRUSE_DECL_TNS(use) ==
! 19355: WXS_ATTRUSE_DECL_TNS(tmp)))
! 19356: {
! 19357: xmlChar *str = NULL;
! 19358:
! 19359: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 19360: XML_SCHEMAP_AG_PROPS_CORRECT,
! 19361: attrGr->node, WXS_BASIC_CAST attrGr,
! 19362: "Duplicate %s",
! 19363: xmlSchemaGetComponentDesignation(&str, use),
! 19364: NULL);
! 19365: FREE_AND_NULL(str);
! 19366: /*
! 19367: * Remove the duplicate.
! 19368: */
! 19369: if (xmlSchemaItemListRemove(uses, i) == -1)
! 19370: return(-1);
! 19371: goto next_use;
! 19372: }
! 19373: }
! 19374: }
! 19375: /*
! 19376: * SPEC ag-props-correct
! 19377: * (3) "Two distinct members of the {attribute uses} must not have
! 19378: * {attribute declaration}s both of whose {type definition}s are or
! 19379: * are derived from ID."
! 19380: * TODO: Does 'derived' include member-types of unions?
! 19381: */
! 19382: if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
! 19383: if (xmlSchemaIsDerivedFromBuiltInType(
! 19384: WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
! 19385: {
! 19386: if (hasId) {
! 19387: xmlChar *str = NULL;
! 19388:
! 19389: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 19390: XML_SCHEMAP_AG_PROPS_CORRECT,
! 19391: attrGr->node, WXS_BASIC_CAST attrGr,
! 19392: "There must not exist more than one attribute "
! 19393: "declaration of type 'xs:ID' "
! 19394: "(or derived from 'xs:ID'). The %s violates this "
! 19395: "constraint",
! 19396: xmlSchemaGetComponentDesignation(&str, use),
! 19397: NULL);
! 19398: FREE_AND_NULL(str);
! 19399: if (xmlSchemaItemListRemove(uses, i) == -1)
! 19400: return(-1);
! 19401: }
! 19402: hasId = 1;
! 19403: }
! 19404: }
! 19405: next_use: {}
! 19406: }
! 19407: }
! 19408: return(0);
! 19409: }
! 19410:
! 19411: /**
! 19412: * xmlSchemaResolveAttrGroupReferences:
! 19413: * @attrgrpDecl: the schema attribute definition
! 19414: * @ctxt: the schema parser context
! 19415: * @name: the attribute name
! 19416: *
! 19417: * Resolves references to attribute group definitions.
! 19418: */
! 19419: static int
! 19420: xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
! 19421: xmlSchemaParserCtxtPtr ctxt)
! 19422: {
! 19423: xmlSchemaAttributeGroupPtr group;
! 19424:
! 19425: if (ref->item != NULL)
! 19426: return(0);
! 19427: group = xmlSchemaGetAttributeGroup(ctxt->schema,
! 19428: ref->name,
! 19429: ref->targetNamespace);
! 19430: if (group == NULL) {
! 19431: xmlSchemaPResCompAttrErr(ctxt,
! 19432: XML_SCHEMAP_SRC_RESOLVE,
! 19433: NULL, ref->node,
! 19434: "ref", ref->name, ref->targetNamespace,
! 19435: ref->itemType, NULL);
! 19436: return(ctxt->err);
! 19437: }
! 19438: ref->item = WXS_BASIC_CAST group;
! 19439: return(0);
! 19440: }
! 19441:
! 19442: /**
! 19443: * xmlSchemaCheckAttrPropsCorrect:
! 19444: * @item: an schema attribute declaration/use
! 19445: * @ctxt: a schema parser context
! 19446: * @name: the name of the attribute
! 19447: *
! 19448: *
! 19449: * Schema Component Constraint:
! 19450: * Attribute Declaration Properties Correct (a-props-correct)
! 19451: *
! 19452: * Validates the value constraints of an attribute declaration/use.
! 19453: * NOTE that this needs the simle type definitions to be already
! 19454: * builded and checked.
! 19455: */
! 19456: static int
! 19457: xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
! 19458: xmlSchemaAttributePtr attr)
! 19459: {
! 19460:
! 19461: /*
! 19462: * SPEC a-props-correct (1)
! 19463: * "The values of the properties of an attribute declaration must
! 19464: * be as described in the property tableau in The Attribute
! 19465: * Declaration Schema Component (�3.2.1), modulo the impact of
! 19466: * Missing Sub-components (�5.3)."
! 19467: */
! 19468:
! 19469: if (WXS_ATTR_TYPEDEF(attr) == NULL)
! 19470: return(0);
! 19471:
! 19472: if (attr->defValue != NULL) {
! 19473: int ret;
! 19474:
! 19475: /*
! 19476: * SPEC a-props-correct (3)
! 19477: * "If the {type definition} is or is derived from ID then there
! 19478: * must not be a {value constraint}."
! 19479: */
! 19480: if (xmlSchemaIsDerivedFromBuiltInType(
! 19481: WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
! 19482: {
! 19483: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 19484: XML_SCHEMAP_A_PROPS_CORRECT_3,
! 19485: NULL, WXS_BASIC_CAST attr,
! 19486: "Value constraints are not allowed if the type definition "
! 19487: "is or is derived from xs:ID",
! 19488: NULL, NULL);
! 19489: return(pctxt->err);
! 19490: }
! 19491: /*
! 19492: * SPEC a-props-correct (2)
! 19493: * "if there is a {value constraint}, the canonical lexical
! 19494: * representation of its value must be �valid� with respect
! 19495: * to the {type definition} as defined in String Valid (�3.14.4)."
! 19496: * TODO: Don't care about the *cononical* stuff here, this requirement
! 19497: * will be removed in WXS 1.1 anyway.
! 19498: */
! 19499: ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
! 19500: attr->node, WXS_ATTR_TYPEDEF(attr),
! 19501: attr->defValue, &(attr->defVal),
! 19502: 1, 1, 0);
! 19503: if (ret != 0) {
! 19504: if (ret < 0) {
! 19505: PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
! 19506: "calling xmlSchemaVCheckCVCSimpleType()");
! 19507: return(-1);
! 19508: }
! 19509: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 19510: XML_SCHEMAP_A_PROPS_CORRECT_2,
! 19511: NULL, WXS_BASIC_CAST attr,
! 19512: "The value of the value constraint is not valid",
! 19513: NULL, NULL);
! 19514: return(pctxt->err);
! 19515: }
! 19516: }
! 19517:
! 19518: return(0);
! 19519: }
! 19520:
! 19521: static xmlSchemaElementPtr
! 19522: xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
! 19523: xmlSchemaElementPtr ancestor)
! 19524: {
! 19525: xmlSchemaElementPtr ret;
! 19526:
! 19527: if (WXS_SUBST_HEAD(ancestor) == NULL)
! 19528: return (NULL);
! 19529: if (WXS_SUBST_HEAD(ancestor) == elemDecl)
! 19530: return (ancestor);
! 19531:
! 19532: if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
! 19533: return (NULL);
! 19534: WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
! 19535: ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
! 19536: WXS_SUBST_HEAD(ancestor));
! 19537: WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
! 19538:
! 19539: return (ret);
! 19540: }
! 19541:
! 19542: /**
! 19543: * xmlSchemaCheckElemPropsCorrect:
! 19544: * @ctxt: a schema parser context
! 19545: * @decl: the element declaration
! 19546: * @name: the name of the attribute
! 19547: *
! 19548: * Schema Component Constraint:
! 19549: * Element Declaration Properties Correct (e-props-correct)
! 19550: *
! 19551: * STATUS:
! 19552: * missing: (6)
! 19553: */
! 19554: static int
! 19555: xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
! 19556: xmlSchemaElementPtr elemDecl)
! 19557: {
! 19558: int ret = 0;
! 19559: xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
! 19560: /*
! 19561: * SPEC (1) "The values of the properties of an element declaration
! 19562: * must be as described in the property tableau in The Element
! 19563: * Declaration Schema Component (�3.3.1), modulo the impact of Missing
! 19564: * Sub-components (�5.3)."
! 19565: */
! 19566: if (WXS_SUBST_HEAD(elemDecl) != NULL) {
! 19567: xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
! 19568:
! 19569: xmlSchemaCheckElementDeclComponent(head, pctxt);
! 19570: /*
! 19571: * SPEC (3) "If there is a non-�absent� {substitution group
! 19572: * affiliation}, then {scope} must be global."
! 19573: */
! 19574: if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
! 19575: xmlSchemaPCustomErr(pctxt,
! 19576: XML_SCHEMAP_E_PROPS_CORRECT_3,
! 19577: WXS_BASIC_CAST elemDecl, NULL,
! 19578: "Only global element declarations can have a "
! 19579: "substitution group affiliation", NULL);
! 19580: ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
! 19581: }
! 19582: /*
! 19583: * TODO: SPEC (6) "Circular substitution groups are disallowed.
! 19584: * That is, it must not be possible to return to an element declaration
! 19585: * by repeatedly following the {substitution group affiliation}
! 19586: * property."
! 19587: */
! 19588: if (head == elemDecl)
! 19589: circ = head;
! 19590: else if (WXS_SUBST_HEAD(head) != NULL)
! 19591: circ = xmlSchemaCheckSubstGroupCircular(head, head);
! 19592: else
! 19593: circ = NULL;
! 19594: if (circ != NULL) {
! 19595: xmlChar *strA = NULL, *strB = NULL;
! 19596:
! 19597: xmlSchemaPCustomErrExt(pctxt,
! 19598: XML_SCHEMAP_E_PROPS_CORRECT_6,
! 19599: WXS_BASIC_CAST circ, NULL,
! 19600: "The element declaration '%s' defines a circular "
! 19601: "substitution group to element declaration '%s'",
! 19602: xmlSchemaGetComponentQName(&strA, circ),
! 19603: xmlSchemaGetComponentQName(&strB, head),
! 19604: NULL);
! 19605: FREE_AND_NULL(strA)
! 19606: FREE_AND_NULL(strB)
! 19607: ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
! 19608: }
! 19609: /*
! 19610: * SPEC (4) "If there is a {substitution group affiliation},
! 19611: * the {type definition}
! 19612: * of the element declaration must be validly derived from the {type
! 19613: * definition} of the {substitution group affiliation}, given the value
! 19614: * of the {substitution group exclusions} of the {substitution group
! 19615: * affiliation}, as defined in Type Derivation OK (Complex) (�3.4.6)
! 19616: * (if the {type definition} is complex) or as defined in
! 19617: * Type Derivation OK (Simple) (�3.14.6) (if the {type definition} is
! 19618: * simple)."
! 19619: *
! 19620: * NOTE: {substitution group exclusions} means the values of the
! 19621: * attribute "final".
! 19622: */
! 19623:
! 19624: if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
! 19625: int set = 0;
! 19626:
! 19627: if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
! 19628: set |= SUBSET_EXTENSION;
! 19629: if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
! 19630: set |= SUBSET_RESTRICTION;
! 19631:
! 19632: if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
! 19633: WXS_ELEM_TYPEDEF(head), set) != 0) {
! 19634: xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
! 19635:
! 19636: ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
! 19637: xmlSchemaPCustomErrExt(pctxt,
! 19638: XML_SCHEMAP_E_PROPS_CORRECT_4,
! 19639: WXS_BASIC_CAST elemDecl, NULL,
! 19640: "The type definition '%s' was "
! 19641: "either rejected by the substitution group "
! 19642: "affiliation '%s', or not validly derived from its type "
! 19643: "definition '%s'",
! 19644: xmlSchemaGetComponentQName(&strA, typeDef),
! 19645: xmlSchemaGetComponentQName(&strB, head),
! 19646: xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
! 19647: FREE_AND_NULL(strA)
! 19648: FREE_AND_NULL(strB)
! 19649: FREE_AND_NULL(strC)
! 19650: }
! 19651: }
! 19652: }
! 19653: /*
! 19654: * SPEC (5) "If the {type definition} or {type definition}'s
! 19655: * {content type}
! 19656: * is or is derived from ID then there must not be a {value constraint}.
! 19657: * Note: The use of ID as a type definition for elements goes beyond
! 19658: * XML 1.0, and should be avoided if backwards compatibility is desired"
! 19659: */
! 19660: if ((elemDecl->value != NULL) &&
! 19661: ((WXS_IS_SIMPLE(typeDef) &&
! 19662: xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
! 19663: (WXS_IS_COMPLEX(typeDef) &&
! 19664: WXS_HAS_SIMPLE_CONTENT(typeDef) &&
! 19665: xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
! 19666: XML_SCHEMAS_ID)))) {
! 19667:
! 19668: ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
! 19669: xmlSchemaPCustomErr(pctxt,
! 19670: XML_SCHEMAP_E_PROPS_CORRECT_5,
! 19671: WXS_BASIC_CAST elemDecl, NULL,
! 19672: "The type definition (or type definition's content type) is or "
! 19673: "is derived from ID; value constraints are not allowed in "
! 19674: "conjunction with such a type definition", NULL);
! 19675: } else if (elemDecl->value != NULL) {
! 19676: int vcret;
! 19677: xmlNodePtr node = NULL;
! 19678:
! 19679: /*
! 19680: * SPEC (2) "If there is a {value constraint}, the canonical lexical
! 19681: * representation of its value must be �valid� with respect to the
! 19682: * {type definition} as defined in Element Default Valid (Immediate)
! 19683: * (�3.3.6)."
! 19684: */
! 19685: if (typeDef == NULL) {
! 19686: xmlSchemaPErr(pctxt, elemDecl->node,
! 19687: XML_SCHEMAP_INTERNAL,
! 19688: "Internal error: xmlSchemaCheckElemPropsCorrect, "
! 19689: "type is missing... skipping validation of "
! 19690: "the value constraint", NULL, NULL);
! 19691: return (-1);
! 19692: }
! 19693: if (elemDecl->node != NULL) {
! 19694: if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
! 19695: node = (xmlNodePtr) xmlHasProp(elemDecl->node,
! 19696: BAD_CAST "fixed");
! 19697: else
! 19698: node = (xmlNodePtr) xmlHasProp(elemDecl->node,
! 19699: BAD_CAST "default");
! 19700: }
! 19701: vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
! 19702: typeDef, elemDecl->value, &(elemDecl->defVal));
! 19703: if (vcret != 0) {
! 19704: if (vcret < 0) {
! 19705: PERROR_INT("xmlSchemaElemCheckValConstr",
! 19706: "failed to validate the value constraint of an "
! 19707: "element declaration");
! 19708: return (-1);
! 19709: }
! 19710: return (vcret);
! 19711: }
! 19712: }
! 19713:
! 19714: return (ret);
! 19715: }
! 19716:
! 19717: /**
! 19718: * xmlSchemaCheckElemSubstGroup:
! 19719: * @ctxt: a schema parser context
! 19720: * @decl: the element declaration
! 19721: * @name: the name of the attribute
! 19722: *
! 19723: * Schema Component Constraint:
! 19724: * Substitution Group (cos-equiv-class)
! 19725: *
! 19726: * In Libxml2 the subst. groups will be precomputed, in terms of that
! 19727: * a list will be built for each subst. group head, holding all direct
! 19728: * referents to this head.
! 19729: * NOTE that this function needs:
! 19730: * 1. circular subst. groups to be checked beforehand
! 19731: * 2. the declaration's type to be derived from the head's type
! 19732: *
! 19733: * STATUS:
! 19734: *
! 19735: */
! 19736: static void
! 19737: xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
! 19738: xmlSchemaElementPtr elemDecl)
! 19739: {
! 19740: if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
! 19741: /* SPEC (1) "Its {abstract} is false." */
! 19742: (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
! 19743: return;
! 19744: {
! 19745: xmlSchemaElementPtr head;
! 19746: xmlSchemaTypePtr headType, type;
! 19747: int set, methSet;
! 19748: /*
! 19749: * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
! 19750: * {disallowed substitutions} as the blocking constraint, as defined in
! 19751: * Substitution Group OK (Transitive) (�3.3.6)."
! 19752: */
! 19753: for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
! 19754: head = WXS_SUBST_HEAD(head)) {
! 19755: set = 0;
! 19756: methSet = 0;
! 19757: /*
! 19758: * The blocking constraints.
! 19759: */
! 19760: if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
! 19761: continue;
! 19762: headType = head->subtypes;
! 19763: type = elemDecl->subtypes;
! 19764: if (headType == type)
! 19765: goto add_member;
! 19766: if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
! 19767: set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
! 19768: if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
! 19769: set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
! 19770: /*
! 19771: * SPEC: Substitution Group OK (Transitive) (2.3)
! 19772: * "The set of all {derivation method}s involved in the
! 19773: * derivation of D's {type definition} from C's {type definition}
! 19774: * does not intersect with the union of the blocking constraint,
! 19775: * C's {prohibited substitutions} (if C is complex, otherwise the
! 19776: * empty set) and the {prohibited substitutions} (respectively the
! 19777: * empty set) of any intermediate {type definition}s in the
! 19778: * derivation of D's {type definition} from C's {type definition}."
! 19779: */
! 19780: /*
! 19781: * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
! 19782: * subst.head axis, the methSet does not need to be computed for
! 19783: * the full depth over and over.
! 19784: */
! 19785: /*
! 19786: * The set of all {derivation method}s involved in the derivation
! 19787: */
! 19788: while ((type != NULL) && (type != headType)) {
! 19789: if ((WXS_IS_EXTENSION(type)) &&
! 19790: ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
! 19791: methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
! 19792:
! 19793: if (WXS_IS_RESTRICTION(type) &&
! 19794: ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
! 19795: methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
! 19796:
! 19797: type = type->baseType;
! 19798: }
! 19799: /*
! 19800: * The {prohibited substitutions} of all intermediate types +
! 19801: * the head's type.
! 19802: */
! 19803: type = elemDecl->subtypes->baseType;
! 19804: while (type != NULL) {
! 19805: if (WXS_IS_COMPLEX(type)) {
! 19806: if ((type->flags &
! 19807: XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
! 19808: ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
! 19809: set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
! 19810: if ((type->flags &
! 19811: XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
! 19812: ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
! 19813: set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
! 19814: } else
! 19815: break;
! 19816: if (type == headType)
! 19817: break;
! 19818: type = type->baseType;
! 19819: }
! 19820: if ((set != 0) &&
! 19821: (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
! 19822: (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
! 19823: ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
! 19824: (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
! 19825: continue;
! 19826: }
! 19827: add_member:
! 19828: xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
! 19829: if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
! 19830: head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
! 19831: }
! 19832: }
! 19833: }
! 19834:
! 19835: #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
! 19836: /**
! 19837: * xmlSchemaCheckElementDeclComponent
! 19838: * @pctxt: the schema parser context
! 19839: * @ctxtComponent: the context component (an element declaration)
! 19840: * @ctxtParticle: the first particle of the context component
! 19841: * @searchParticle: the element declaration particle to be analysed
! 19842: *
! 19843: * Schema Component Constraint: Element Declarations Consistent
! 19844: */
! 19845: static int
! 19846: xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
! 19847: xmlSchemaBasicItemPtr ctxtComponent,
! 19848: xmlSchemaParticlePtr ctxtParticle,
! 19849: xmlSchemaParticlePtr searchParticle,
! 19850: xmlSchemaParticlePtr curParticle,
! 19851: int search)
! 19852: {
! 19853: return(0);
! 19854:
! 19855: int ret = 0;
! 19856: xmlSchemaParticlePtr cur = curParticle;
! 19857: if (curParticle == NULL) {
! 19858: return(0);
! 19859: }
! 19860: if (WXS_PARTICLE_TERM(curParticle) == NULL) {
! 19861: /*
! 19862: * Just return in this case. A missing "term" of the particle
! 19863: * might arise due to an invalid "term" component.
! 19864: */
! 19865: return(0);
! 19866: }
! 19867: while (cur != NULL) {
! 19868: switch (WXS_PARTICLE_TERM(cur)->type) {
! 19869: case XML_SCHEMA_TYPE_ANY:
! 19870: break;
! 19871: case XML_SCHEMA_TYPE_ELEMENT:
! 19872: if (search == 0) {
! 19873: ret = xmlSchemaCheckElementDeclConsistent(pctxt,
! 19874: ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
! 19875: if (ret != 0)
! 19876: return(ret);
! 19877: } else {
! 19878: xmlSchemaElementPtr elem =
! 19879: WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
! 19880: /*
! 19881: * SPEC Element Declarations Consistent:
! 19882: * "If the {particles} contains, either directly,
! 19883: * indirectly (that is, within the {particles} of a
! 19884: * contained model group, recursively) or �implicitly�
! 19885: * two or more element declaration particles with
! 19886: * the same {name} and {target namespace}, then
! 19887: * all their type definitions must be the same
! 19888: * top-level definition [...]"
! 19889: */
! 19890: if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
! 19891: WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
! 19892: xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
! 19893: WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
! 19894: {
! 19895: xmlChar *strA = NULL, *strB = NULL;
! 19896:
! 19897: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 19898: /* TODO: error code */
! 19899: XML_SCHEMAP_COS_NONAMBIG,
! 19900: WXS_ITEM_NODE(cur), NULL,
! 19901: "In the content model of %s, there are multiple "
! 19902: "element declarations for '%s' with different "
! 19903: "type definitions",
! 19904: xmlSchemaGetComponentDesignation(&strA,
! 19905: ctxtComponent),
! 19906: xmlSchemaFormatQName(&strB,
! 19907: WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
! 19908: WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
! 19909: FREE_AND_NULL(strA);
! 19910: FREE_AND_NULL(strB);
! 19911: return(XML_SCHEMAP_COS_NONAMBIG);
! 19912: }
! 19913: }
! 19914: break;
! 19915: case XML_SCHEMA_TYPE_SEQUENCE: {
! 19916: break;
! 19917: }
! 19918: case XML_SCHEMA_TYPE_CHOICE:{
! 19919: /*
! 19920: xmlSchemaTreeItemPtr sub;
! 19921:
! 19922: sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr)
! 19923: while (sub != NULL) {
! 19924: ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
! 19925: ctxtParticle, ctxtElem);
! 19926: if (ret != 0)
! 19927: return(ret);
! 19928: sub = sub->next;
! 19929: }
! 19930: */
! 19931: break;
! 19932: }
! 19933: case XML_SCHEMA_TYPE_ALL:
! 19934: break;
! 19935: case XML_SCHEMA_TYPE_GROUP:
! 19936: break;
! 19937: default:
! 19938: xmlSchemaInternalErr2(ACTXT_CAST pctxt,
! 19939: "xmlSchemaCheckElementDeclConsistent",
! 19940: "found unexpected term of type '%s' in content model",
! 19941: WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
! 19942: return(-1);
! 19943: }
! 19944: cur = (xmlSchemaParticlePtr) cur->next;
! 19945: }
! 19946:
! 19947: exit:
! 19948: return(ret);
! 19949: }
! 19950: #endif
! 19951:
! 19952: /**
! 19953: * xmlSchemaCheckElementDeclComponent
! 19954: * @item: an schema element declaration/particle
! 19955: * @ctxt: a schema parser context
! 19956: * @name: the name of the attribute
! 19957: *
! 19958: * Validates the value constraints of an element declaration.
! 19959: * Adds substitution group members.
! 19960: */
! 19961: static void
! 19962: xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
! 19963: xmlSchemaParserCtxtPtr ctxt)
! 19964: {
! 19965: if (elemDecl == NULL)
! 19966: return;
! 19967: if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
! 19968: return;
! 19969: elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
! 19970: if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
! 19971: /*
! 19972: * Adds substitution group members.
! 19973: */
! 19974: xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
! 19975: }
! 19976: }
! 19977:
! 19978: /**
! 19979: * xmlSchemaResolveModelGroupParticleReferences:
! 19980: * @particle: a particle component
! 19981: * @ctxt: a parser context
! 19982: *
! 19983: * Resolves references of a model group's {particles} to
! 19984: * model group definitions and to element declarations.
! 19985: */
! 19986: static void
! 19987: xmlSchemaResolveModelGroupParticleReferences(
! 19988: xmlSchemaParserCtxtPtr ctxt,
! 19989: xmlSchemaModelGroupPtr mg)
! 19990: {
! 19991: xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
! 19992: xmlSchemaQNameRefPtr ref;
! 19993: xmlSchemaBasicItemPtr refItem;
! 19994:
! 19995: /*
! 19996: * URGENT TODO: Test this.
! 19997: */
! 19998: while (particle != NULL) {
! 19999: if ((WXS_PARTICLE_TERM(particle) == NULL) ||
! 20000: ((WXS_PARTICLE_TERM(particle))->type !=
! 20001: XML_SCHEMA_EXTRA_QNAMEREF))
! 20002: {
! 20003: goto next_particle;
! 20004: }
! 20005: ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
! 20006: /*
! 20007: * Resolve the reference.
! 20008: * NULL the {term} by default.
! 20009: */
! 20010: particle->children = NULL;
! 20011:
! 20012: refItem = xmlSchemaGetNamedComponent(ctxt->schema,
! 20013: ref->itemType, ref->name, ref->targetNamespace);
! 20014: if (refItem == NULL) {
! 20015: xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
! 20016: NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
! 20017: ref->targetNamespace, ref->itemType, NULL);
! 20018: /* TODO: remove the particle. */
! 20019: goto next_particle;
! 20020: }
! 20021: if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
! 20022: if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
! 20023: /* TODO: remove the particle. */
! 20024: goto next_particle;
! 20025: /*
! 20026: * NOTE that we will assign the model group definition
! 20027: * itself to the "term" of the particle. This will ease
! 20028: * the check for circular model group definitions. After
! 20029: * that the "term" will be assigned the model group of the
! 20030: * model group definition.
! 20031: */
! 20032: if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
! 20033: XML_SCHEMA_TYPE_ALL) {
! 20034: /*
! 20035: * SPEC cos-all-limited (1)
! 20036: * SPEC cos-all-limited (1.2)
! 20037: * "It appears only as the value of one or both of the
! 20038: * following properties:"
! 20039: * (1.1) "the {model group} property of a model group
! 20040: * definition."
! 20041: * (1.2) "the {term} property of a particle [... of] the "
! 20042: * {content type} of a complex type definition."
! 20043: */
! 20044: xmlSchemaCustomErr(ACTXT_CAST ctxt,
! 20045: /* TODO: error code */
! 20046: XML_SCHEMAP_COS_ALL_LIMITED,
! 20047: WXS_ITEM_NODE(particle), NULL,
! 20048: "A model group definition is referenced, but "
! 20049: "it contains an 'all' model group, which "
! 20050: "cannot be contained by model groups",
! 20051: NULL, NULL);
! 20052: /* TODO: remove the particle. */
! 20053: goto next_particle;
! 20054: }
! 20055: particle->children = (xmlSchemaTreeItemPtr) refItem;
! 20056: } else {
! 20057: /*
! 20058: * TODO: Are referenced element declarations the only
! 20059: * other components we expect here?
! 20060: */
! 20061: particle->children = (xmlSchemaTreeItemPtr) refItem;
! 20062: }
! 20063: next_particle:
! 20064: particle = WXS_PTC_CAST particle->next;
! 20065: }
! 20066: }
! 20067:
! 20068: static int
! 20069: xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
! 20070: xmlSchemaValPtr y)
! 20071: {
! 20072: xmlSchemaTypePtr tx, ty, ptx, pty;
! 20073: int ret;
! 20074:
! 20075: while (x != NULL) {
! 20076: /* Same types. */
! 20077: tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
! 20078: ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
! 20079: ptx = xmlSchemaGetPrimitiveType(tx);
! 20080: pty = xmlSchemaGetPrimitiveType(ty);
! 20081: /*
! 20082: * (1) if a datatype T' is �derived� by �restriction� from an
! 20083: * atomic datatype T then the �value space� of T' is a subset of
! 20084: * the �value space� of T. */
! 20085: /*
! 20086: * (2) if datatypes T' and T'' are �derived� by �restriction�
! 20087: * from a common atomic ancestor T then the �value space�s of T'
! 20088: * and T'' may overlap.
! 20089: */
! 20090: if (ptx != pty)
! 20091: return(0);
! 20092: /*
! 20093: * We assume computed values to be normalized, so do a fast
! 20094: * string comparison for string based types.
! 20095: */
! 20096: if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
! 20097: WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
! 20098: if (! xmlStrEqual(
! 20099: xmlSchemaValueGetAsString(x),
! 20100: xmlSchemaValueGetAsString(y)))
! 20101: return (0);
! 20102: } else {
! 20103: ret = xmlSchemaCompareValuesWhtsp(
! 20104: x, XML_SCHEMA_WHITESPACE_PRESERVE,
! 20105: y, XML_SCHEMA_WHITESPACE_PRESERVE);
! 20106: if (ret == -2)
! 20107: return(-1);
! 20108: if (ret != 0)
! 20109: return(0);
! 20110: }
! 20111: /*
! 20112: * Lists.
! 20113: */
! 20114: x = xmlSchemaValueGetNext(x);
! 20115: if (x != NULL) {
! 20116: y = xmlSchemaValueGetNext(y);
! 20117: if (y == NULL)
! 20118: return (0);
! 20119: } else if (xmlSchemaValueGetNext(y) != NULL)
! 20120: return (0);
! 20121: else
! 20122: return (1);
! 20123: }
! 20124: return (0);
! 20125: }
! 20126:
! 20127: /**
! 20128: * xmlSchemaResolveAttrUseReferences:
! 20129: * @item: an attribute use
! 20130: * @ctxt: a parser context
! 20131: *
! 20132: * Resolves the referenced attribute declaration.
! 20133: */
! 20134: static int
! 20135: xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
! 20136: xmlSchemaParserCtxtPtr ctxt)
! 20137: {
! 20138: if ((ctxt == NULL) || (ause == NULL))
! 20139: return(-1);
! 20140: if ((ause->attrDecl == NULL) ||
! 20141: (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
! 20142: return(0);
! 20143:
! 20144: {
! 20145: xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
! 20146:
! 20147: /*
! 20148: * TODO: Evaluate, what errors could occur if the declaration is not
! 20149: * found.
! 20150: */
! 20151: ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
! 20152: ref->name, ref->targetNamespace);
! 20153: if (ause->attrDecl == NULL) {
! 20154: xmlSchemaPResCompAttrErr(ctxt,
! 20155: XML_SCHEMAP_SRC_RESOLVE,
! 20156: WXS_BASIC_CAST ause, ause->node,
! 20157: "ref", ref->name, ref->targetNamespace,
! 20158: XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
! 20159: return(ctxt->err);;
! 20160: }
! 20161: }
! 20162: return(0);
! 20163: }
! 20164:
! 20165: /**
! 20166: * xmlSchemaCheckAttrUsePropsCorrect:
! 20167: * @ctxt: a parser context
! 20168: * @use: an attribute use
! 20169: *
! 20170: * Schema Component Constraint:
! 20171: * Attribute Use Correct (au-props-correct)
! 20172: *
! 20173: */
! 20174: static int
! 20175: xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
! 20176: xmlSchemaAttributeUsePtr use)
! 20177: {
! 20178: if ((ctxt == NULL) || (use == NULL))
! 20179: return(-1);
! 20180: if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
! 20181: ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
! 20182: return(0);
! 20183:
! 20184: /*
! 20185: * SPEC au-props-correct (1)
! 20186: * "The values of the properties of an attribute use must be as
! 20187: * described in the property tableau in The Attribute Use Schema
! 20188: * Component (�3.5.1), modulo the impact of Missing
! 20189: * Sub-components (�5.3)."
! 20190: */
! 20191:
! 20192: if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
! 20193: ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
! 20194: ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
! 20195: {
! 20196: xmlSchemaPCustomErr(ctxt,
! 20197: XML_SCHEMAP_AU_PROPS_CORRECT_2,
! 20198: WXS_BASIC_CAST use, NULL,
! 20199: "The attribute declaration has a 'fixed' value constraint "
! 20200: ", thus the attribute use must also have a 'fixed' value "
! 20201: "constraint",
! 20202: NULL);
! 20203: return(ctxt->err);
! 20204: }
! 20205: /*
! 20206: * Compute and check the value constraint's value.
! 20207: */
! 20208: if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
! 20209: int ret;
! 20210: /*
! 20211: * TODO: The spec seems to be missing a check of the
! 20212: * value constraint of the attribute use. We will do it here.
! 20213: */
! 20214: /*
! 20215: * SPEC a-props-correct (3)
! 20216: */
! 20217: if (xmlSchemaIsDerivedFromBuiltInType(
! 20218: WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
! 20219: {
! 20220: xmlSchemaCustomErr(ACTXT_CAST ctxt,
! 20221: XML_SCHEMAP_AU_PROPS_CORRECT,
! 20222: NULL, WXS_BASIC_CAST use,
! 20223: "Value constraints are not allowed if the type definition "
! 20224: "is or is derived from xs:ID",
! 20225: NULL, NULL);
! 20226: return(ctxt->err);
! 20227: }
! 20228:
! 20229: ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
! 20230: use->node, WXS_ATTRUSE_TYPEDEF(use),
! 20231: use->defValue, &(use->defVal),
! 20232: 1, 1, 0);
! 20233: if (ret != 0) {
! 20234: if (ret < 0) {
! 20235: PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
! 20236: "calling xmlSchemaVCheckCVCSimpleType()");
! 20237: return(-1);
! 20238: }
! 20239: xmlSchemaCustomErr(ACTXT_CAST ctxt,
! 20240: XML_SCHEMAP_AU_PROPS_CORRECT,
! 20241: NULL, WXS_BASIC_CAST use,
! 20242: "The value of the value constraint is not valid",
! 20243: NULL, NULL);
! 20244: return(ctxt->err);
! 20245: }
! 20246: }
! 20247: /*
! 20248: * SPEC au-props-correct (2)
! 20249: * "If the {attribute declaration} has a fixed
! 20250: * {value constraint}, then if the attribute use itself has a
! 20251: * {value constraint}, it must also be fixed and its value must match
! 20252: * that of the {attribute declaration}'s {value constraint}."
! 20253: */
! 20254: if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
! 20255: (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
! 20256: {
! 20257: if (! xmlSchemaAreValuesEqual(use->defVal,
! 20258: (WXS_ATTRUSE_DECL(use))->defVal))
! 20259: {
! 20260: xmlSchemaPCustomErr(ctxt,
! 20261: XML_SCHEMAP_AU_PROPS_CORRECT_2,
! 20262: WXS_BASIC_CAST use, NULL,
! 20263: "The 'fixed' value constraint of the attribute use "
! 20264: "must match the attribute declaration's value "
! 20265: "constraint '%s'",
! 20266: (WXS_ATTRUSE_DECL(use))->defValue);
! 20267: }
! 20268: return(ctxt->err);
! 20269: }
! 20270: return(0);
! 20271: }
! 20272:
! 20273:
! 20274:
! 20275:
! 20276: /**
! 20277: * xmlSchemaResolveAttrTypeReferences:
! 20278: * @item: an attribute declaration
! 20279: * @ctxt: a parser context
! 20280: *
! 20281: * Resolves the referenced type definition component.
! 20282: */
! 20283: static int
! 20284: xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
! 20285: xmlSchemaParserCtxtPtr ctxt)
! 20286: {
! 20287: /*
! 20288: * The simple type definition corresponding to the <simpleType> element
! 20289: * information item in the [children], if present, otherwise the simple
! 20290: * type definition �resolved� to by the �actual value� of the type
! 20291: * [attribute], if present, otherwise the �simple ur-type definition�.
! 20292: */
! 20293: if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
! 20294: return(0);
! 20295: item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
! 20296: if (item->subtypes != NULL)
! 20297: return(0);
! 20298: if (item->typeName != NULL) {
! 20299: xmlSchemaTypePtr type;
! 20300:
! 20301: type = xmlSchemaGetType(ctxt->schema, item->typeName,
! 20302: item->typeNs);
! 20303: if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
! 20304: xmlSchemaPResCompAttrErr(ctxt,
! 20305: XML_SCHEMAP_SRC_RESOLVE,
! 20306: WXS_BASIC_CAST item, item->node,
! 20307: "type", item->typeName, item->typeNs,
! 20308: XML_SCHEMA_TYPE_SIMPLE, NULL);
! 20309: return(ctxt->err);
! 20310: } else
! 20311: item->subtypes = type;
! 20312:
! 20313: } else {
! 20314: /*
! 20315: * The type defaults to the xs:anySimpleType.
! 20316: */
! 20317: item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
! 20318: }
! 20319: return(0);
! 20320: }
! 20321:
! 20322: /**
! 20323: * xmlSchemaResolveIDCKeyReferences:
! 20324: * @idc: the identity-constraint definition
! 20325: * @ctxt: the schema parser context
! 20326: * @name: the attribute name
! 20327: *
! 20328: * Resolve keyRef references to key/unique IDCs.
! 20329: * Schema Component Constraint:
! 20330: * Identity-constraint Definition Properties Correct (c-props-correct)
! 20331: */
! 20332: static int
! 20333: xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
! 20334: xmlSchemaParserCtxtPtr pctxt)
! 20335: {
! 20336: if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
! 20337: return(0);
! 20338: if (idc->ref->name != NULL) {
! 20339: idc->ref->item = (xmlSchemaBasicItemPtr)
! 20340: xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
! 20341: idc->ref->targetNamespace);
! 20342: if (idc->ref->item == NULL) {
! 20343: /*
! 20344: * TODO: It is actually not an error to fail to resolve
! 20345: * at this stage. BUT we need to be that strict!
! 20346: */
! 20347: xmlSchemaPResCompAttrErr(pctxt,
! 20348: XML_SCHEMAP_SRC_RESOLVE,
! 20349: WXS_BASIC_CAST idc, idc->node,
! 20350: "refer", idc->ref->name,
! 20351: idc->ref->targetNamespace,
! 20352: XML_SCHEMA_TYPE_IDC_KEY, NULL);
! 20353: return(pctxt->err);
! 20354: } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
! 20355: /*
! 20356: * SPEC c-props-correct (1)
! 20357: */
! 20358: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 20359: XML_SCHEMAP_C_PROPS_CORRECT,
! 20360: NULL, WXS_BASIC_CAST idc,
! 20361: "The keyref references a keyref",
! 20362: NULL, NULL);
! 20363: idc->ref->item = NULL;
! 20364: return(pctxt->err);
! 20365: } else {
! 20366: if (idc->nbFields !=
! 20367: ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
! 20368: xmlChar *str = NULL;
! 20369: xmlSchemaIDCPtr refer;
! 20370:
! 20371: refer = (xmlSchemaIDCPtr) idc->ref->item;
! 20372: /*
! 20373: * SPEC c-props-correct(2)
! 20374: * "If the {identity-constraint category} is keyref,
! 20375: * the cardinality of the {fields} must equal that of
! 20376: * the {fields} of the {referenced key}.
! 20377: */
! 20378: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 20379: XML_SCHEMAP_C_PROPS_CORRECT,
! 20380: NULL, WXS_BASIC_CAST idc,
! 20381: "The cardinality of the keyref differs from the "
! 20382: "cardinality of the referenced key/unique '%s'",
! 20383: xmlSchemaFormatQName(&str, refer->targetNamespace,
! 20384: refer->name),
! 20385: NULL);
! 20386: FREE_AND_NULL(str)
! 20387: return(pctxt->err);
! 20388: }
! 20389: }
! 20390: }
! 20391: return(0);
! 20392: }
! 20393:
! 20394: static int
! 20395: xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
! 20396: xmlSchemaParserCtxtPtr pctxt)
! 20397: {
! 20398: if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
! 20399: prohib->targetNamespace) == NULL) {
! 20400:
! 20401: xmlSchemaPResCompAttrErr(pctxt,
! 20402: XML_SCHEMAP_SRC_RESOLVE,
! 20403: NULL, prohib->node,
! 20404: "ref", prohib->name, prohib->targetNamespace,
! 20405: XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
! 20406: return(XML_SCHEMAP_SRC_RESOLVE);
! 20407: }
! 20408: return(0);
! 20409: }
! 20410:
! 20411: #define WXS_REDEFINED_TYPE(c) \
! 20412: (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
! 20413:
! 20414: #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
! 20415: (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
! 20416:
! 20417: #define WXS_REDEFINED_ATTR_GROUP(c) \
! 20418: (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
! 20419:
! 20420: static int
! 20421: xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
! 20422: {
! 20423: int err = 0;
! 20424: xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
! 20425: xmlSchemaBasicItemPtr prev, item;
! 20426: int wasRedefined;
! 20427:
! 20428: if (redef == NULL)
! 20429: return(0);
! 20430:
! 20431: do {
! 20432: item = redef->item;
! 20433: /*
! 20434: * First try to locate the redefined component in the
! 20435: * schema graph starting with the redefined schema.
! 20436: * NOTE: According to this schema bug entry:
! 20437: * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
! 20438: * it's not clear if the referenced component needs to originate
! 20439: * from the <redefine>d schema _document_ or the schema; the latter
! 20440: * would include all imported and included sub-schemas of the
! 20441: * <redefine>d schema. Currenlty we latter approach is used.
! 20442: * SUPPLEMENT: It seems that the WG moves towards the latter
! 20443: * approach, so we are doing it right.
! 20444: *
! 20445: */
! 20446: prev = xmlSchemaFindRedefCompInGraph(
! 20447: redef->targetBucket, item->type,
! 20448: redef->refName, redef->refTargetNs);
! 20449: if (prev == NULL) {
! 20450: xmlChar *str = NULL;
! 20451: xmlNodePtr node;
! 20452:
! 20453: /*
! 20454: * SPEC src-redefine:
! 20455: * (6.2.1) "The �actual value� of its own name attribute plus
! 20456: * target namespace must successfully �resolve� to a model
! 20457: * group definition in I."
! 20458: * (7.2.1) "The �actual value� of its own name attribute plus
! 20459: * target namespace must successfully �resolve� to an attribute
! 20460: * group definition in I."
! 20461:
! 20462: *
! 20463: * Note that, if we are redefining with the use of references
! 20464: * to components, the spec assumes the src-resolve to be used;
! 20465: * but this won't assure that we search only *inside* the
! 20466: * redefined schema.
! 20467: */
! 20468: if (redef->reference)
! 20469: node = WXS_ITEM_NODE(redef->reference);
! 20470: else
! 20471: node = WXS_ITEM_NODE(item);
! 20472: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 20473: /*
! 20474: * TODO: error code.
! 20475: * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
! 20476: * reference kind.
! 20477: */
! 20478: XML_SCHEMAP_SRC_REDEFINE, node, NULL,
! 20479: "The %s '%s' to be redefined could not be found in "
! 20480: "the redefined schema",
! 20481: WXS_ITEM_TYPE_NAME(item),
! 20482: xmlSchemaFormatQName(&str, redef->refTargetNs,
! 20483: redef->refName));
! 20484: FREE_AND_NULL(str);
! 20485: err = pctxt->err;
! 20486: redef = redef->next;
! 20487: continue;
! 20488: }
! 20489: /*
! 20490: * TODO: Obtaining and setting the redefinition state is really
! 20491: * clumsy.
! 20492: */
! 20493: wasRedefined = 0;
! 20494: switch (item->type) {
! 20495: case XML_SCHEMA_TYPE_COMPLEX:
! 20496: case XML_SCHEMA_TYPE_SIMPLE:
! 20497: if ((WXS_TYPE_CAST prev)->flags &
! 20498: XML_SCHEMAS_TYPE_REDEFINED)
! 20499: {
! 20500: wasRedefined = 1;
! 20501: break;
! 20502: }
! 20503: /* Mark it as redefined. */
! 20504: (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
! 20505: /*
! 20506: * Assign the redefined type to the
! 20507: * base type of the redefining type.
! 20508: * TODO: How
! 20509: */
! 20510: ((xmlSchemaTypePtr) item)->baseType =
! 20511: (xmlSchemaTypePtr) prev;
! 20512: break;
! 20513: case XML_SCHEMA_TYPE_GROUP:
! 20514: if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
! 20515: XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
! 20516: {
! 20517: wasRedefined = 1;
! 20518: break;
! 20519: }
! 20520: /* Mark it as redefined. */
! 20521: (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
! 20522: XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
! 20523: if (redef->reference != NULL) {
! 20524: /*
! 20525: * Overwrite the QName-reference with the
! 20526: * referenced model group def.
! 20527: */
! 20528: (WXS_PTC_CAST redef->reference)->children =
! 20529: WXS_TREE_CAST prev;
! 20530: }
! 20531: redef->target = prev;
! 20532: break;
! 20533: case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
! 20534: if ((WXS_ATTR_GROUP_CAST prev)->flags &
! 20535: XML_SCHEMAS_ATTRGROUP_REDEFINED)
! 20536: {
! 20537: wasRedefined = 1;
! 20538: break;
! 20539: }
! 20540: (WXS_ATTR_GROUP_CAST prev)->flags |=
! 20541: XML_SCHEMAS_ATTRGROUP_REDEFINED;
! 20542: if (redef->reference != NULL) {
! 20543: /*
! 20544: * Assign the redefined attribute group to the
! 20545: * QName-reference component.
! 20546: * This is the easy case, since we will just
! 20547: * expand the redefined group.
! 20548: */
! 20549: (WXS_QNAME_CAST redef->reference)->item = prev;
! 20550: redef->target = NULL;
! 20551: } else {
! 20552: /*
! 20553: * This is the complicated case: we need
! 20554: * to apply src-redefine (7.2.2) at a later
! 20555: * stage, i.e. when attribute group references
! 20556: * have beed expanded and simple types have
! 20557: * beed fixed.
! 20558: */
! 20559: redef->target = prev;
! 20560: }
! 20561: break;
! 20562: default:
! 20563: PERROR_INT("xmlSchemaResolveRedefReferences",
! 20564: "Unexpected redefined component type");
! 20565: return(-1);
! 20566: }
! 20567: if (wasRedefined) {
! 20568: xmlChar *str = NULL;
! 20569: xmlNodePtr node;
! 20570:
! 20571: if (redef->reference)
! 20572: node = WXS_ITEM_NODE(redef->reference);
! 20573: else
! 20574: node = WXS_ITEM_NODE(redef->item);
! 20575:
! 20576: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 20577: /* TODO: error code. */
! 20578: XML_SCHEMAP_SRC_REDEFINE,
! 20579: node, NULL,
! 20580: "The referenced %s was already redefined. Multiple "
! 20581: "redefinition of the same component is not supported",
! 20582: xmlSchemaGetComponentDesignation(&str, prev),
! 20583: NULL);
! 20584: FREE_AND_NULL(str)
! 20585: err = pctxt->err;
! 20586: redef = redef->next;
! 20587: continue;
! 20588: }
! 20589: redef = redef->next;
! 20590: } while (redef != NULL);
! 20591:
! 20592: return(err);
! 20593: }
! 20594:
! 20595: static int
! 20596: xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
! 20597: {
! 20598: int err = 0;
! 20599: xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
! 20600: xmlSchemaBasicItemPtr item;
! 20601:
! 20602: if (redef == NULL)
! 20603: return(0);
! 20604:
! 20605: do {
! 20606: if (redef->target == NULL) {
! 20607: redef = redef->next;
! 20608: continue;
! 20609: }
! 20610: item = redef->item;
! 20611:
! 20612: switch (item->type) {
! 20613: case XML_SCHEMA_TYPE_SIMPLE:
! 20614: case XML_SCHEMA_TYPE_COMPLEX:
! 20615: /*
! 20616: * Since the spec wants the {name} of the redefined
! 20617: * type to be 'absent', we'll NULL it.
! 20618: */
! 20619: (WXS_TYPE_CAST redef->target)->name = NULL;
! 20620:
! 20621: /*
! 20622: * TODO: Seems like there's nothing more to do. The normal
! 20623: * inheritance mechanism is used. But not 100% sure.
! 20624: */
! 20625: break;
! 20626: case XML_SCHEMA_TYPE_GROUP:
! 20627: /*
! 20628: * URGENT TODO:
! 20629: * SPEC src-redefine:
! 20630: * (6.2.2) "The {model group} of the model group definition
! 20631: * which corresponds to it per XML Representation of Model
! 20632: * Group Definition Schema Components (�3.7.2) must be a
! 20633: * �valid restriction� of the {model group} of that model
! 20634: * group definition in I, as defined in Particle Valid
! 20635: * (Restriction) (�3.9.6)."
! 20636: */
! 20637: break;
! 20638: case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
! 20639: /*
! 20640: * SPEC src-redefine:
! 20641: * (7.2.2) "The {attribute uses} and {attribute wildcard} of
! 20642: * the attribute group definition which corresponds to it
! 20643: * per XML Representation of Attribute Group Definition Schema
! 20644: * Components (�3.6.2) must be �valid restrictions� of the
! 20645: * {attribute uses} and {attribute wildcard} of that attribute
! 20646: * group definition in I, as defined in clause 2, clause 3 and
! 20647: * clause 4 of Derivation Valid (Restriction, Complex)
! 20648: * (�3.4.6) (where references to the base type definition are
! 20649: * understood as references to the attribute group definition
! 20650: * in I)."
! 20651: */
! 20652: err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
! 20653: XML_SCHEMA_ACTION_REDEFINE,
! 20654: item, redef->target,
! 20655: (WXS_ATTR_GROUP_CAST item)->attrUses,
! 20656: (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
! 20657: (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
! 20658: (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
! 20659: if (err == -1)
! 20660: return(-1);
! 20661: break;
! 20662: default:
! 20663: break;
! 20664: }
! 20665: redef = redef->next;
! 20666: } while (redef != NULL);
! 20667: return(0);
! 20668: }
! 20669:
! 20670:
! 20671: static int
! 20672: xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
! 20673: xmlSchemaBucketPtr bucket)
! 20674: {
! 20675: xmlSchemaBasicItemPtr item;
! 20676: int err;
! 20677: xmlHashTablePtr *table;
! 20678: const xmlChar *name;
! 20679: int i;
! 20680:
! 20681: #define WXS_GET_GLOBAL_HASH(c, slot) { \
! 20682: if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
! 20683: table = &(WXS_IMPBUCKET((c))->schema->slot); \
! 20684: else \
! 20685: table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
! 20686:
! 20687: /*
! 20688: * Add global components to the schema's hash tables.
! 20689: * This is the place where duplicate components will be
! 20690: * detected.
! 20691: * TODO: I think normally we should support imports of the
! 20692: * same namespace from multiple locations. We don't do currently,
! 20693: * but if we do then according to:
! 20694: * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
! 20695: * we would need, if imported directly, to import redefined
! 20696: * components as well to be able to catch clashing components.
! 20697: * (I hope I'll still know what this means after some months :-()
! 20698: */
! 20699: if (bucket == NULL)
! 20700: return(-1);
! 20701: if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
! 20702: return(0);
! 20703: bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
! 20704:
! 20705: for (i = 0; i < bucket->globals->nbItems; i++) {
! 20706: item = bucket->globals->items[i];
! 20707: table = NULL;
! 20708: switch (item->type) {
! 20709: case XML_SCHEMA_TYPE_COMPLEX:
! 20710: case XML_SCHEMA_TYPE_SIMPLE:
! 20711: if (WXS_REDEFINED_TYPE(item))
! 20712: continue;
! 20713: name = (WXS_TYPE_CAST item)->name;
! 20714: WXS_GET_GLOBAL_HASH(bucket, typeDecl)
! 20715: break;
! 20716: case XML_SCHEMA_TYPE_ELEMENT:
! 20717: name = (WXS_ELEM_CAST item)->name;
! 20718: WXS_GET_GLOBAL_HASH(bucket, elemDecl)
! 20719: break;
! 20720: case XML_SCHEMA_TYPE_ATTRIBUTE:
! 20721: name = (WXS_ATTR_CAST item)->name;
! 20722: WXS_GET_GLOBAL_HASH(bucket, attrDecl)
! 20723: break;
! 20724: case XML_SCHEMA_TYPE_GROUP:
! 20725: if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
! 20726: continue;
! 20727: name = (WXS_MODEL_GROUPDEF_CAST item)->name;
! 20728: WXS_GET_GLOBAL_HASH(bucket, groupDecl)
! 20729: break;
! 20730: case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
! 20731: if (WXS_REDEFINED_ATTR_GROUP(item))
! 20732: continue;
! 20733: name = (WXS_ATTR_GROUP_CAST item)->name;
! 20734: WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
! 20735: break;
! 20736: case XML_SCHEMA_TYPE_IDC_KEY:
! 20737: case XML_SCHEMA_TYPE_IDC_UNIQUE:
! 20738: case XML_SCHEMA_TYPE_IDC_KEYREF:
! 20739: name = (WXS_IDC_CAST item)->name;
! 20740: WXS_GET_GLOBAL_HASH(bucket, idcDef)
! 20741: break;
! 20742: case XML_SCHEMA_TYPE_NOTATION:
! 20743: name = ((xmlSchemaNotationPtr) item)->name;
! 20744: WXS_GET_GLOBAL_HASH(bucket, notaDecl)
! 20745: break;
! 20746: default:
! 20747: PERROR_INT("xmlSchemaAddComponents",
! 20748: "Unexpected global component type");
! 20749: continue;
! 20750: }
! 20751: if (*table == NULL) {
! 20752: *table = xmlHashCreateDict(10, pctxt->dict);
! 20753: if (*table == NULL) {
! 20754: PERROR_INT("xmlSchemaAddComponents",
! 20755: "failed to create a component hash table");
! 20756: return(-1);
! 20757: }
! 20758: }
! 20759: err = xmlHashAddEntry(*table, name, item);
! 20760: if (err != 0) {
! 20761: xmlChar *str = NULL;
! 20762:
! 20763: xmlSchemaCustomErr(ACTXT_CAST pctxt,
! 20764: XML_SCHEMAP_REDEFINED_TYPE,
! 20765: WXS_ITEM_NODE(item),
! 20766: WXS_BASIC_CAST item,
! 20767: "A global %s '%s' does already exist",
! 20768: WXS_ITEM_TYPE_NAME(item),
! 20769: xmlSchemaGetComponentQName(&str, item));
! 20770: FREE_AND_NULL(str);
! 20771: }
! 20772: }
! 20773: /*
! 20774: * Process imported/included schemas.
! 20775: */
! 20776: if (bucket->relations != NULL) {
! 20777: xmlSchemaSchemaRelationPtr rel = bucket->relations;
! 20778: do {
! 20779: if ((rel->bucket != NULL) &&
! 20780: ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
! 20781: if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
! 20782: return(-1);
! 20783: }
! 20784: rel = rel->next;
! 20785: } while (rel != NULL);
! 20786: }
! 20787: return(0);
! 20788: }
! 20789:
! 20790: static int
! 20791: xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
! 20792: xmlSchemaBucketPtr rootBucket)
! 20793: {
! 20794: xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
! 20795: xmlSchemaTreeItemPtr item, *items;
! 20796: int nbItems, i, ret = 0;
! 20797: xmlSchemaBucketPtr oldbucket = con->bucket;
! 20798: xmlSchemaElementPtr elemDecl;
! 20799:
! 20800: #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
! 20801:
! 20802: if ((con->pending == NULL) ||
! 20803: (con->pending->nbItems == 0))
! 20804: return(0);
! 20805:
! 20806: /*
! 20807: * Since xmlSchemaFixupComplexType() will create new particles
! 20808: * (local components), and those particle components need a bucket
! 20809: * on the constructor, we'll assure here that the constructor has
! 20810: * a bucket.
! 20811: * TODO: Think about storing locals _only_ on the main bucket.
! 20812: */
! 20813: if (con->bucket == NULL)
! 20814: con->bucket = rootBucket;
! 20815:
! 20816: /* TODO:
! 20817: * SPEC (src-redefine):
! 20818: * (6.2) "If it has no such self-reference, then all of the
! 20819: * following must be true:"
! 20820:
! 20821: * (6.2.2) The {model group} of the model group definition which
! 20822: * corresponds to it per XML Representation of Model Group
! 20823: * Definition Schema Components (�3.7.2) must be a �valid
! 20824: * restriction� of the {model group} of that model group definition
! 20825: * in I, as defined in Particle Valid (Restriction) (�3.9.6)."
! 20826: */
! 20827: xmlSchemaCheckSRCRedefineFirst(pctxt);
! 20828:
! 20829: /*
! 20830: * Add global components to the schemata's hash tables.
! 20831: */
! 20832: xmlSchemaAddComponents(pctxt, rootBucket);
! 20833:
! 20834: pctxt->ctxtType = NULL;
! 20835: items = (xmlSchemaTreeItemPtr *) con->pending->items;
! 20836: nbItems = con->pending->nbItems;
! 20837: /*
! 20838: * Now that we have parsed *all* the schema document(s) and converted
! 20839: * them to schema components, we can resolve references, apply component
! 20840: * constraints, create the FSA from the content model, etc.
! 20841: */
! 20842: /*
! 20843: * Resolve references of..
! 20844: *
! 20845: * 1. element declarations:
! 20846: * - the type definition
! 20847: * - the substitution group affiliation
! 20848: * 2. simple/complex types:
! 20849: * - the base type definition
! 20850: * - the memberTypes of union types
! 20851: * - the itemType of list types
! 20852: * 3. attributes declarations and attribute uses:
! 20853: * - the type definition
! 20854: * - if an attribute use, then the attribute declaration
! 20855: * 4. attribute group references:
! 20856: * - the attribute group definition
! 20857: * 5. particles:
! 20858: * - the term of the particle (e.g. a model group)
! 20859: * 6. IDC key-references:
! 20860: * - the referenced IDC 'key' or 'unique' definition
! 20861: * 7. Attribute prohibitions which had a "ref" attribute.
! 20862: */
! 20863: for (i = 0; i < nbItems; i++) {
! 20864: item = items[i];
! 20865: switch (item->type) {
! 20866: case XML_SCHEMA_TYPE_ELEMENT:
! 20867: xmlSchemaResolveElementReferences(
! 20868: (xmlSchemaElementPtr) item, pctxt);
! 20869: FIXHFAILURE;
! 20870: break;
! 20871: case XML_SCHEMA_TYPE_COMPLEX:
! 20872: case XML_SCHEMA_TYPE_SIMPLE:
! 20873: xmlSchemaResolveTypeReferences(
! 20874: (xmlSchemaTypePtr) item, pctxt);
! 20875: FIXHFAILURE;
! 20876: break;
! 20877: case XML_SCHEMA_TYPE_ATTRIBUTE:
! 20878: xmlSchemaResolveAttrTypeReferences(
! 20879: (xmlSchemaAttributePtr) item, pctxt);
! 20880: FIXHFAILURE;
! 20881: break;
! 20882: case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
! 20883: xmlSchemaResolveAttrUseReferences(
! 20884: (xmlSchemaAttributeUsePtr) item, pctxt);
! 20885: FIXHFAILURE;
! 20886: break;
! 20887: case XML_SCHEMA_EXTRA_QNAMEREF:
! 20888: if ((WXS_QNAME_CAST item)->itemType ==
! 20889: XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
! 20890: {
! 20891: xmlSchemaResolveAttrGroupReferences(
! 20892: WXS_QNAME_CAST item, pctxt);
! 20893: }
! 20894: FIXHFAILURE;
! 20895: break;
! 20896: case XML_SCHEMA_TYPE_SEQUENCE:
! 20897: case XML_SCHEMA_TYPE_CHOICE:
! 20898: case XML_SCHEMA_TYPE_ALL:
! 20899: xmlSchemaResolveModelGroupParticleReferences(pctxt,
! 20900: WXS_MODEL_GROUP_CAST item);
! 20901: FIXHFAILURE;
! 20902: break;
! 20903: case XML_SCHEMA_TYPE_IDC_KEY:
! 20904: case XML_SCHEMA_TYPE_IDC_UNIQUE:
! 20905: case XML_SCHEMA_TYPE_IDC_KEYREF:
! 20906: xmlSchemaResolveIDCKeyReferences(
! 20907: (xmlSchemaIDCPtr) item, pctxt);
! 20908: FIXHFAILURE;
! 20909: break;
! 20910: case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
! 20911: /*
! 20912: * Handle attribue prohibition which had a
! 20913: * "ref" attribute.
! 20914: */
! 20915: xmlSchemaResolveAttrUseProhibReferences(
! 20916: WXS_ATTR_PROHIB_CAST item, pctxt);
! 20917: FIXHFAILURE;
! 20918: break;
! 20919: default:
! 20920: break;
! 20921: }
! 20922: }
! 20923: if (pctxt->nberrors != 0)
! 20924: goto exit_error;
! 20925:
! 20926: /*
! 20927: * Now that all references are resolved we
! 20928: * can check for circularity of...
! 20929: * 1. the base axis of type definitions
! 20930: * 2. nested model group definitions
! 20931: * 3. nested attribute group definitions
! 20932: * TODO: check for circual substitution groups.
! 20933: */
! 20934: for (i = 0; i < nbItems; i++) {
! 20935: item = items[i];
! 20936: /*
! 20937: * Let's better stop on the first error here.
! 20938: */
! 20939: switch (item->type) {
! 20940: case XML_SCHEMA_TYPE_COMPLEX:
! 20941: case XML_SCHEMA_TYPE_SIMPLE:
! 20942: xmlSchemaCheckTypeDefCircular(
! 20943: (xmlSchemaTypePtr) item, pctxt);
! 20944: FIXHFAILURE;
! 20945: if (pctxt->nberrors != 0)
! 20946: goto exit_error;
! 20947: break;
! 20948: case XML_SCHEMA_TYPE_GROUP:
! 20949: xmlSchemaCheckGroupDefCircular(
! 20950: (xmlSchemaModelGroupDefPtr) item, pctxt);
! 20951: FIXHFAILURE;
! 20952: if (pctxt->nberrors != 0)
! 20953: goto exit_error;
! 20954: break;
! 20955: case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
! 20956: xmlSchemaCheckAttrGroupCircular(
! 20957: (xmlSchemaAttributeGroupPtr) item, pctxt);
! 20958: FIXHFAILURE;
! 20959: if (pctxt->nberrors != 0)
! 20960: goto exit_error;
! 20961: break;
! 20962: default:
! 20963: break;
! 20964: }
! 20965: }
! 20966: if (pctxt->nberrors != 0)
! 20967: goto exit_error;
! 20968: /*
! 20969: * Model group definition references:
! 20970: * Such a reference is reflected by a particle at the component
! 20971: * level. Until now the 'term' of such particles pointed
! 20972: * to the model group definition; this was done, in order to
! 20973: * ease circularity checks. Now we need to set the 'term' of
! 20974: * such particles to the model group of the model group definition.
! 20975: */
! 20976: for (i = 0; i < nbItems; i++) {
! 20977: item = items[i];
! 20978: switch (item->type) {
! 20979: case XML_SCHEMA_TYPE_SEQUENCE:
! 20980: case XML_SCHEMA_TYPE_CHOICE:
! 20981: xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
! 20982: WXS_MODEL_GROUP_CAST item);
! 20983: break;
! 20984: default:
! 20985: break;
! 20986: }
! 20987: }
! 20988: if (pctxt->nberrors != 0)
! 20989: goto exit_error;
! 20990: /*
! 20991: * Expand attribute group references of attribute group definitions.
! 20992: */
! 20993: for (i = 0; i < nbItems; i++) {
! 20994: item = items[i];
! 20995: switch (item->type) {
! 20996: case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
! 20997: if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
! 20998: WXS_ATTR_GROUP_HAS_REFS(item))
! 20999: {
! 21000: xmlSchemaAttributeGroupExpandRefs(pctxt,
! 21001: WXS_ATTR_GROUP_CAST item);
! 21002: FIXHFAILURE;
! 21003: }
! 21004: break;
! 21005: default:
! 21006: break;
! 21007: }
! 21008: }
! 21009: if (pctxt->nberrors != 0)
! 21010: goto exit_error;
! 21011: /*
! 21012: * First compute the variety of simple types. This is needed as
! 21013: * a seperate step, since otherwise we won't be able to detect
! 21014: * circular union types in all cases.
! 21015: */
! 21016: for (i = 0; i < nbItems; i++) {
! 21017: item = items[i];
! 21018: switch (item->type) {
! 21019: case XML_SCHEMA_TYPE_SIMPLE:
! 21020: if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
! 21021: xmlSchemaFixupSimpleTypeStageOne(pctxt,
! 21022: (xmlSchemaTypePtr) item);
! 21023: FIXHFAILURE;
! 21024: }
! 21025: break;
! 21026: default:
! 21027: break;
! 21028: }
! 21029: }
! 21030: if (pctxt->nberrors != 0)
! 21031: goto exit_error;
! 21032: /*
! 21033: * Detect circular union types. Note that this needs the variety to
! 21034: * be already computed.
! 21035: */
! 21036: for (i = 0; i < nbItems; i++) {
! 21037: item = items[i];
! 21038: switch (item->type) {
! 21039: case XML_SCHEMA_TYPE_SIMPLE:
! 21040: if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
! 21041: xmlSchemaCheckUnionTypeDefCircular(pctxt,
! 21042: (xmlSchemaTypePtr) item);
! 21043: FIXHFAILURE;
! 21044: }
! 21045: break;
! 21046: default:
! 21047: break;
! 21048: }
! 21049: }
! 21050: if (pctxt->nberrors != 0)
! 21051: goto exit_error;
! 21052:
! 21053: /*
! 21054: * Do the complete type fixup for simple types.
! 21055: */
! 21056: for (i = 0; i < nbItems; i++) {
! 21057: item = items[i];
! 21058: switch (item->type) {
! 21059: case XML_SCHEMA_TYPE_SIMPLE:
! 21060: if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
! 21061: xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
! 21062: FIXHFAILURE;
! 21063: }
! 21064: break;
! 21065: default:
! 21066: break;
! 21067: }
! 21068: }
! 21069: if (pctxt->nberrors != 0)
! 21070: goto exit_error;
! 21071: /*
! 21072: * At this point we need build and check all simple types.
! 21073: */
! 21074: /*
! 21075: * Apply contraints for attribute declarations.
! 21076: */
! 21077: for (i = 0; i < nbItems; i++) {
! 21078: item = items[i];
! 21079: switch (item->type) {
! 21080: case XML_SCHEMA_TYPE_ATTRIBUTE:
! 21081: xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
! 21082: FIXHFAILURE;
! 21083: break;
! 21084: default:
! 21085: break;
! 21086: }
! 21087: }
! 21088: if (pctxt->nberrors != 0)
! 21089: goto exit_error;
! 21090: /*
! 21091: * Apply constraints for attribute uses.
! 21092: */
! 21093: for (i = 0; i < nbItems; i++) {
! 21094: item = items[i];
! 21095: switch (item->type) {
! 21096: case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
! 21097: if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
! 21098: xmlSchemaCheckAttrUsePropsCorrect(pctxt,
! 21099: WXS_ATTR_USE_CAST item);
! 21100: FIXHFAILURE;
! 21101: }
! 21102: break;
! 21103: default:
! 21104: break;
! 21105: }
! 21106: }
! 21107: if (pctxt->nberrors != 0)
! 21108: goto exit_error;
! 21109:
! 21110: /*
! 21111: * Apply constraints for attribute group definitions.
! 21112: */
! 21113: for (i = 0; i < nbItems; i++) {
! 21114: item = items[i];
! 21115: switch (item->type) {
! 21116: case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
! 21117: if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
! 21118: ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
! 21119: {
! 21120: xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
! 21121: FIXHFAILURE;
! 21122: }
! 21123: break;
! 21124: default:
! 21125: break;
! 21126: }
! 21127: }
! 21128: if (pctxt->nberrors != 0)
! 21129: goto exit_error;
! 21130:
! 21131: /*
! 21132: * Apply constraints for redefinitions.
! 21133: */
! 21134: if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
! 21135: xmlSchemaCheckSRCRedefineSecond(pctxt);
! 21136: if (pctxt->nberrors != 0)
! 21137: goto exit_error;
! 21138:
! 21139: /*
! 21140: * Complex types are builded and checked.
! 21141: */
! 21142: for (i = 0; i < nbItems; i++) {
! 21143: item = con->pending->items[i];
! 21144: switch (item->type) {
! 21145: case XML_SCHEMA_TYPE_COMPLEX:
! 21146: if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
! 21147: xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
! 21148: FIXHFAILURE;
! 21149: }
! 21150: break;
! 21151: default:
! 21152: break;
! 21153: }
! 21154: }
! 21155: if (pctxt->nberrors != 0)
! 21156: goto exit_error;
! 21157:
! 21158: /*
! 21159: * The list could have changed, since xmlSchemaFixupComplexType()
! 21160: * will create particles and model groups in some cases.
! 21161: */
! 21162: items = (xmlSchemaTreeItemPtr *) con->pending->items;
! 21163: nbItems = con->pending->nbItems;
! 21164:
! 21165: /*
! 21166: * Apply some constraints for element declarations.
! 21167: */
! 21168: for (i = 0; i < nbItems; i++) {
! 21169: item = items[i];
! 21170: switch (item->type) {
! 21171: case XML_SCHEMA_TYPE_ELEMENT:
! 21172: elemDecl = (xmlSchemaElementPtr) item;
! 21173:
! 21174: if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
! 21175: {
! 21176: xmlSchemaCheckElementDeclComponent(
! 21177: (xmlSchemaElementPtr) elemDecl, pctxt);
! 21178: FIXHFAILURE;
! 21179: }
! 21180:
! 21181: #ifdef WXS_ELEM_DECL_CONS_ENABLED
! 21182: /*
! 21183: * Schema Component Constraint: Element Declarations Consistent
! 21184: * Apply this constraint to local types of element declarations.
! 21185: */
! 21186: if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
! 21187: (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
! 21188: (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
! 21189: {
! 21190: xmlSchemaCheckElementDeclConsistent(pctxt,
! 21191: WXS_BASIC_CAST elemDecl,
! 21192: WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
! 21193: NULL, NULL, 0);
! 21194: }
! 21195: #endif
! 21196: break;
! 21197: default:
! 21198: break;
! 21199: }
! 21200: }
! 21201: if (pctxt->nberrors != 0)
! 21202: goto exit_error;
! 21203:
! 21204: /*
! 21205: * Finally we can build the automaton from the content model of
! 21206: * complex types.
! 21207: */
! 21208:
! 21209: for (i = 0; i < nbItems; i++) {
! 21210: item = items[i];
! 21211: switch (item->type) {
! 21212: case XML_SCHEMA_TYPE_COMPLEX:
! 21213: xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
! 21214: /* FIXHFAILURE; */
! 21215: break;
! 21216: default:
! 21217: break;
! 21218: }
! 21219: }
! 21220: if (pctxt->nberrors != 0)
! 21221: goto exit_error;
! 21222: /*
! 21223: * URGENT TODO: cos-element-consistent
! 21224: */
! 21225: goto exit;
! 21226:
! 21227: exit_error:
! 21228: ret = pctxt->err;
! 21229: goto exit;
! 21230:
! 21231: exit_failure:
! 21232: ret = -1;
! 21233:
! 21234: exit:
! 21235: /*
! 21236: * Reset the constructor. This is needed for XSI acquisition, since
! 21237: * those items will be processed over and over again for every XSI
! 21238: * if not cleared here.
! 21239: */
! 21240: con->bucket = oldbucket;
! 21241: con->pending->nbItems = 0;
! 21242: if (con->substGroups != NULL) {
! 21243: xmlHashFree(con->substGroups,
! 21244: (xmlHashDeallocator) xmlSchemaSubstGroupFree);
! 21245: con->substGroups = NULL;
! 21246: }
! 21247: if (con->redefs != NULL) {
! 21248: xmlSchemaRedefListFree(con->redefs);
! 21249: con->redefs = NULL;
! 21250: }
! 21251: return(ret);
! 21252: }
! 21253: /**
! 21254: * xmlSchemaParse:
! 21255: * @ctxt: a schema validation context
! 21256: *
! 21257: * parse a schema definition resource and build an internal
! 21258: * XML Shema struture which can be used to validate instances.
! 21259: *
! 21260: * Returns the internal XML Schema structure built from the resource or
! 21261: * NULL in case of error
! 21262: */
! 21263: xmlSchemaPtr
! 21264: xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
! 21265: {
! 21266: xmlSchemaPtr mainSchema = NULL;
! 21267: xmlSchemaBucketPtr bucket = NULL;
! 21268: int res;
! 21269:
! 21270: /*
! 21271: * This one is used if the schema to be parsed was specified via
! 21272: * the API; i.e. not automatically by the validated instance document.
! 21273: */
! 21274:
! 21275: xmlSchemaInitTypes();
! 21276:
! 21277: if (ctxt == NULL)
! 21278: return (NULL);
! 21279:
! 21280: /* TODO: Init the context. Is this all we need?*/
! 21281: ctxt->nberrors = 0;
! 21282: ctxt->err = 0;
! 21283: ctxt->counter = 0;
! 21284:
! 21285: /* Create the *main* schema. */
! 21286: mainSchema = xmlSchemaNewSchema(ctxt);
! 21287: if (mainSchema == NULL)
! 21288: goto exit_failure;
! 21289: /*
! 21290: * Create the schema constructor.
! 21291: */
! 21292: if (ctxt->constructor == NULL) {
! 21293: ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
! 21294: if (ctxt->constructor == NULL)
! 21295: return(NULL);
! 21296: /* Take ownership of the constructor to be able to free it. */
! 21297: ctxt->ownsConstructor = 1;
! 21298: }
! 21299: ctxt->constructor->mainSchema = mainSchema;
! 21300: /*
! 21301: * Locate and add the schema document.
! 21302: */
! 21303: res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
! 21304: ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
! 21305: NULL, NULL, &bucket);
! 21306: if (res == -1)
! 21307: goto exit_failure;
! 21308: if (res != 0)
! 21309: goto exit;
! 21310:
! 21311: if (bucket == NULL) {
! 21312: /* TODO: Error code, actually we failed to *locate* the schema. */
! 21313: if (ctxt->URL)
! 21314: xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
! 21315: NULL, NULL,
! 21316: "Failed to locate the main schema resource at '%s'",
! 21317: ctxt->URL, NULL);
! 21318: else
! 21319: xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
! 21320: NULL, NULL,
! 21321: "Failed to locate the main schema resource",
! 21322: NULL, NULL);
! 21323: goto exit;
! 21324: }
! 21325: /* Then do the parsing for good. */
! 21326: if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
! 21327: goto exit_failure;
! 21328: if (ctxt->nberrors != 0)
! 21329: goto exit;
! 21330:
! 21331: mainSchema->doc = bucket->doc;
! 21332: mainSchema->preserve = ctxt->preserve;
! 21333:
! 21334: ctxt->schema = mainSchema;
! 21335:
! 21336: if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
! 21337: goto exit_failure;
! 21338:
! 21339: /*
! 21340: * TODO: This is not nice, since we cannot distinguish from the
! 21341: * result if there was an internal error or not.
! 21342: */
! 21343: exit:
! 21344: if (ctxt->nberrors != 0) {
! 21345: if (mainSchema) {
! 21346: xmlSchemaFree(mainSchema);
! 21347: mainSchema = NULL;
! 21348: }
! 21349: if (ctxt->constructor) {
! 21350: xmlSchemaConstructionCtxtFree(ctxt->constructor);
! 21351: ctxt->constructor = NULL;
! 21352: ctxt->ownsConstructor = 0;
! 21353: }
! 21354: }
! 21355: ctxt->schema = NULL;
! 21356: return(mainSchema);
! 21357: exit_failure:
! 21358: /*
! 21359: * Quite verbose, but should catch internal errors, which were
! 21360: * not communitated.
! 21361: */
! 21362: if (mainSchema) {
! 21363: xmlSchemaFree(mainSchema);
! 21364: mainSchema = NULL;
! 21365: }
! 21366: if (ctxt->constructor) {
! 21367: xmlSchemaConstructionCtxtFree(ctxt->constructor);
! 21368: ctxt->constructor = NULL;
! 21369: ctxt->ownsConstructor = 0;
! 21370: }
! 21371: PERROR_INT2("xmlSchemaParse",
! 21372: "An internal error occured");
! 21373: ctxt->schema = NULL;
! 21374: return(NULL);
! 21375: }
! 21376:
! 21377: /**
! 21378: * xmlSchemaSetParserErrors:
! 21379: * @ctxt: a schema validation context
! 21380: * @err: the error callback
! 21381: * @warn: the warning callback
! 21382: * @ctx: contextual data for the callbacks
! 21383: *
! 21384: * Set the callback functions used to handle errors for a validation context
! 21385: */
! 21386: void
! 21387: xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
! 21388: xmlSchemaValidityErrorFunc err,
! 21389: xmlSchemaValidityWarningFunc warn, void *ctx)
! 21390: {
! 21391: if (ctxt == NULL)
! 21392: return;
! 21393: ctxt->error = err;
! 21394: ctxt->warning = warn;
! 21395: ctxt->errCtxt = ctx;
! 21396: if (ctxt->vctxt != NULL)
! 21397: xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
! 21398: }
! 21399:
! 21400: /**
! 21401: * xmlSchemaSetParserStructuredErrors:
! 21402: * @ctxt: a schema parser context
! 21403: * @serror: the structured error function
! 21404: * @ctx: the functions context
! 21405: *
! 21406: * Set the structured error callback
! 21407: */
! 21408: void
! 21409: xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
! 21410: xmlStructuredErrorFunc serror,
! 21411: void *ctx)
! 21412: {
! 21413: if (ctxt == NULL)
! 21414: return;
! 21415: ctxt->serror = serror;
! 21416: ctxt->errCtxt = ctx;
! 21417: if (ctxt->vctxt != NULL)
! 21418: xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
! 21419: }
! 21420:
! 21421: /**
! 21422: * xmlSchemaGetParserErrors:
! 21423: * @ctxt: a XMl-Schema parser context
! 21424: * @err: the error callback result
! 21425: * @warn: the warning callback result
! 21426: * @ctx: contextual data for the callbacks result
! 21427: *
! 21428: * Get the callback information used to handle errors for a parser context
! 21429: *
! 21430: * Returns -1 in case of failure, 0 otherwise
! 21431: */
! 21432: int
! 21433: xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
! 21434: xmlSchemaValidityErrorFunc * err,
! 21435: xmlSchemaValidityWarningFunc * warn, void **ctx)
! 21436: {
! 21437: if (ctxt == NULL)
! 21438: return(-1);
! 21439: if (err != NULL)
! 21440: *err = ctxt->error;
! 21441: if (warn != NULL)
! 21442: *warn = ctxt->warning;
! 21443: if (ctx != NULL)
! 21444: *ctx = ctxt->errCtxt;
! 21445: return(0);
! 21446: }
! 21447:
! 21448: /**
! 21449: * xmlSchemaFacetTypeToString:
! 21450: * @type: the facet type
! 21451: *
! 21452: * Convert the xmlSchemaTypeType to a char string.
! 21453: *
! 21454: * Returns the char string representation of the facet type if the
! 21455: * type is a facet and an "Internal Error" string otherwise.
! 21456: */
! 21457: static const xmlChar *
! 21458: xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
! 21459: {
! 21460: switch (type) {
! 21461: case XML_SCHEMA_FACET_PATTERN:
! 21462: return (BAD_CAST "pattern");
! 21463: case XML_SCHEMA_FACET_MAXEXCLUSIVE:
! 21464: return (BAD_CAST "maxExclusive");
! 21465: case XML_SCHEMA_FACET_MAXINCLUSIVE:
! 21466: return (BAD_CAST "maxInclusive");
! 21467: case XML_SCHEMA_FACET_MINEXCLUSIVE:
! 21468: return (BAD_CAST "minExclusive");
! 21469: case XML_SCHEMA_FACET_MININCLUSIVE:
! 21470: return (BAD_CAST "minInclusive");
! 21471: case XML_SCHEMA_FACET_WHITESPACE:
! 21472: return (BAD_CAST "whiteSpace");
! 21473: case XML_SCHEMA_FACET_ENUMERATION:
! 21474: return (BAD_CAST "enumeration");
! 21475: case XML_SCHEMA_FACET_LENGTH:
! 21476: return (BAD_CAST "length");
! 21477: case XML_SCHEMA_FACET_MAXLENGTH:
! 21478: return (BAD_CAST "maxLength");
! 21479: case XML_SCHEMA_FACET_MINLENGTH:
! 21480: return (BAD_CAST "minLength");
! 21481: case XML_SCHEMA_FACET_TOTALDIGITS:
! 21482: return (BAD_CAST "totalDigits");
! 21483: case XML_SCHEMA_FACET_FRACTIONDIGITS:
! 21484: return (BAD_CAST "fractionDigits");
! 21485: default:
! 21486: break;
! 21487: }
! 21488: return (BAD_CAST "Internal Error");
! 21489: }
! 21490:
! 21491: static xmlSchemaWhitespaceValueType
! 21492: xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
! 21493: {
! 21494: /*
! 21495: * The normalization type can be changed only for types which are derived
! 21496: * from xsd:string.
! 21497: */
! 21498: if (type->type == XML_SCHEMA_TYPE_BASIC) {
! 21499: /*
! 21500: * Note that we assume a whitespace of preserve for anySimpleType.
! 21501: */
! 21502: if ((type->builtInType == XML_SCHEMAS_STRING) ||
! 21503: (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
! 21504: return(XML_SCHEMA_WHITESPACE_PRESERVE);
! 21505: else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
! 21506: return(XML_SCHEMA_WHITESPACE_REPLACE);
! 21507: else {
! 21508: /*
! 21509: * For all �atomic� datatypes other than string (and types �derived�
! 21510: * by �restriction� from it) the value of whiteSpace is fixed to
! 21511: * collapse
! 21512: * Note that this includes built-in list datatypes.
! 21513: */
! 21514: return(XML_SCHEMA_WHITESPACE_COLLAPSE);
! 21515: }
! 21516: } else if (WXS_IS_LIST(type)) {
! 21517: /*
! 21518: * For list types the facet "whiteSpace" is fixed to "collapse".
! 21519: */
! 21520: return (XML_SCHEMA_WHITESPACE_COLLAPSE);
! 21521: } else if (WXS_IS_UNION(type)) {
! 21522: return (XML_SCHEMA_WHITESPACE_UNKNOWN);
! 21523: } else if (WXS_IS_ATOMIC(type)) {
! 21524: if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
! 21525: return (XML_SCHEMA_WHITESPACE_PRESERVE);
! 21526: else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
! 21527: return (XML_SCHEMA_WHITESPACE_REPLACE);
! 21528: else
! 21529: return (XML_SCHEMA_WHITESPACE_COLLAPSE);
! 21530: }
! 21531: return (-1);
! 21532: }
! 21533:
! 21534: /************************************************************************
! 21535: * *
! 21536: * Simple type validation *
! 21537: * *
! 21538: ************************************************************************/
! 21539:
! 21540:
! 21541: /************************************************************************
! 21542: * *
! 21543: * DOM Validation code *
! 21544: * *
! 21545: ************************************************************************/
! 21546:
! 21547: /**
! 21548: * xmlSchemaAssembleByLocation:
! 21549: * @pctxt: a schema parser context
! 21550: * @vctxt: a schema validation context
! 21551: * @schema: the existing schema
! 21552: * @node: the node that fired the assembling
! 21553: * @nsName: the namespace name of the new schema
! 21554: * @location: the location of the schema
! 21555: *
! 21556: * Expands an existing schema by an additional schema.
! 21557: *
! 21558: * Returns 0 if the new schema is correct, a positive error code
! 21559: * number otherwise and -1 in case of an internal or API error.
! 21560: */
! 21561: static int
! 21562: xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
! 21563: xmlSchemaPtr schema,
! 21564: xmlNodePtr node,
! 21565: const xmlChar *nsName,
! 21566: const xmlChar *location)
! 21567: {
! 21568: int ret = 0;
! 21569: xmlSchemaParserCtxtPtr pctxt;
! 21570: xmlSchemaBucketPtr bucket = NULL;
! 21571:
! 21572: if ((vctxt == NULL) || (schema == NULL))
! 21573: return (-1);
! 21574:
! 21575: if (vctxt->pctxt == NULL) {
! 21576: VERROR_INT("xmlSchemaAssembleByLocation",
! 21577: "no parser context available");
! 21578: return(-1);
! 21579: }
! 21580: pctxt = vctxt->pctxt;
! 21581: if (pctxt->constructor == NULL) {
! 21582: PERROR_INT("xmlSchemaAssembleByLocation",
! 21583: "no constructor");
! 21584: return(-1);
! 21585: }
! 21586: /*
! 21587: * Acquire the schema document.
! 21588: */
! 21589: location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
! 21590: location, node);
! 21591: /*
! 21592: * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
! 21593: * the process will automatically change this to
! 21594: * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
! 21595: */
! 21596: ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
! 21597: location, NULL, NULL, 0, node, NULL, nsName,
! 21598: &bucket);
! 21599: if (ret != 0)
! 21600: return(ret);
! 21601: if (bucket == NULL) {
! 21602: /*
! 21603: * Generate a warning that the document could not be located.
! 21604: */
! 21605: xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
! 21606: node, NULL,
! 21607: "The document at location '%s' could not be acquired",
! 21608: location, NULL, NULL);
! 21609: return(ret);
! 21610: }
! 21611: /*
! 21612: * The first located schema will be handled as if all other
! 21613: * schemas imported by XSI were imported by this first schema.
! 21614: */
! 21615: if ((bucket != NULL) &&
! 21616: (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
! 21617: WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
! 21618: /*
! 21619: * TODO: Is this handled like an import? I.e. is it not an error
! 21620: * if the schema cannot be located?
! 21621: */
! 21622: if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
! 21623: return(0);
! 21624: /*
! 21625: * We will reuse the parser context for every schema imported
! 21626: * directly via XSI. So reset the context.
! 21627: */
! 21628: pctxt->nberrors = 0;
! 21629: pctxt->err = 0;
! 21630: pctxt->doc = bucket->doc;
! 21631:
! 21632: ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
! 21633: if (ret == -1) {
! 21634: pctxt->doc = NULL;
! 21635: goto exit_failure;
! 21636: }
! 21637: /* Paranoid error channelling. */
! 21638: if ((ret == 0) && (pctxt->nberrors != 0))
! 21639: ret = pctxt->err;
! 21640: if (pctxt->nberrors == 0) {
! 21641: /*
! 21642: * Only bother to fixup pending components, if there was
! 21643: * no error yet.
! 21644: * For every XSI acquired schema (and its sub-schemata) we will
! 21645: * fixup the components.
! 21646: */
! 21647: xmlSchemaFixupComponents(pctxt, bucket);
! 21648: ret = pctxt->err;
! 21649: /*
! 21650: * Not nice, but we need somehow to channel the schema parser
! 21651: * error to the validation context.
! 21652: */
! 21653: if ((ret != 0) && (vctxt->err == 0))
! 21654: vctxt->err = ret;
! 21655: vctxt->nberrors += pctxt->nberrors;
! 21656: } else {
! 21657: /* Add to validation error sum. */
! 21658: vctxt->nberrors += pctxt->nberrors;
! 21659: }
! 21660: pctxt->doc = NULL;
! 21661: return(ret);
! 21662: exit_failure:
! 21663: pctxt->doc = NULL;
! 21664: return (-1);
! 21665: }
! 21666:
! 21667: static xmlSchemaAttrInfoPtr
! 21668: xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
! 21669: int metaType)
! 21670: {
! 21671: if (vctxt->nbAttrInfos == 0)
! 21672: return (NULL);
! 21673: {
! 21674: int i;
! 21675: xmlSchemaAttrInfoPtr iattr;
! 21676:
! 21677: for (i = 0; i < vctxt->nbAttrInfos; i++) {
! 21678: iattr = vctxt->attrInfos[i];
! 21679: if (iattr->metaType == metaType)
! 21680: return (iattr);
! 21681: }
! 21682:
! 21683: }
! 21684: return (NULL);
! 21685: }
! 21686:
! 21687: /**
! 21688: * xmlSchemaAssembleByXSI:
! 21689: * @vctxt: a schema validation context
! 21690: *
! 21691: * Expands an existing schema by an additional schema using
! 21692: * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
! 21693: * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
! 21694: * must be set to 1.
! 21695: *
! 21696: * Returns 0 if the new schema is correct, a positive error code
! 21697: * number otherwise and -1 in case of an internal or API error.
! 21698: */
! 21699: static int
! 21700: xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
! 21701: {
! 21702: const xmlChar *cur, *end;
! 21703: const xmlChar *nsname = NULL, *location;
! 21704: int count = 0;
! 21705: int ret = 0;
! 21706: xmlSchemaAttrInfoPtr iattr;
! 21707:
! 21708: /*
! 21709: * Parse the value; we will assume an even number of values
! 21710: * to be given (this is how Xerces and XSV work).
! 21711: *
! 21712: * URGENT TODO: !! This needs to work for both
! 21713: * @noNamespaceSchemaLocation AND @schemaLocation on the same
! 21714: * element !!
! 21715: */
! 21716: iattr = xmlSchemaGetMetaAttrInfo(vctxt,
! 21717: XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
! 21718: if (iattr == NULL)
! 21719: iattr = xmlSchemaGetMetaAttrInfo(vctxt,
! 21720: XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
! 21721: if (iattr == NULL)
! 21722: return (0);
! 21723: cur = iattr->value;
! 21724: do {
! 21725: /*
! 21726: * TODO: Move the string parsing mechanism away from here.
! 21727: */
! 21728: if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
! 21729: /*
! 21730: * Get the namespace name.
! 21731: */
! 21732: while (IS_BLANK_CH(*cur))
! 21733: cur++;
! 21734: end = cur;
! 21735: while ((*end != 0) && (!(IS_BLANK_CH(*end))))
! 21736: end++;
! 21737: if (end == cur)
! 21738: break;
! 21739: count++; /* TODO: Don't use the schema's dict. */
! 21740: nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
! 21741: cur = end;
! 21742: }
! 21743: /*
! 21744: * Get the URI.
! 21745: */
! 21746: while (IS_BLANK_CH(*cur))
! 21747: cur++;
! 21748: end = cur;
! 21749: while ((*end != 0) && (!(IS_BLANK_CH(*end))))
! 21750: end++;
! 21751: if (end == cur) {
! 21752: if (iattr->metaType ==
! 21753: XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
! 21754: {
! 21755: /*
! 21756: * If using @schemaLocation then tuples are expected.
! 21757: * I.e. the namespace name *and* the document's URI.
! 21758: */
! 21759: xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
! 21760: iattr->node, NULL,
! 21761: "The value must consist of tuples: the target namespace "
! 21762: "name and the document's URI", NULL, NULL, NULL);
! 21763: }
! 21764: break;
! 21765: }
! 21766: count++; /* TODO: Don't use the schema's dict. */
! 21767: location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
! 21768: cur = end;
! 21769: ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
! 21770: iattr->node, nsname, location);
! 21771: if (ret == -1) {
! 21772: VERROR_INT("xmlSchemaAssembleByXSI",
! 21773: "assembling schemata");
! 21774: return (-1);
! 21775: }
! 21776: } while (*cur != 0);
! 21777: return (ret);
! 21778: }
! 21779:
! 21780: static const xmlChar *
! 21781: xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
! 21782: const xmlChar *prefix)
! 21783: {
! 21784: if (vctxt->sax != NULL) {
! 21785: int i, j;
! 21786: xmlSchemaNodeInfoPtr inode;
! 21787:
! 21788: for (i = vctxt->depth; i >= 0; i--) {
! 21789: if (vctxt->elemInfos[i]->nbNsBindings != 0) {
! 21790: inode = vctxt->elemInfos[i];
! 21791: for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
! 21792: if (((prefix == NULL) &&
! 21793: (inode->nsBindings[j] == NULL)) ||
! 21794: ((prefix != NULL) && xmlStrEqual(prefix,
! 21795: inode->nsBindings[j]))) {
! 21796:
! 21797: /*
! 21798: * Note that the namespace bindings are already
! 21799: * in a string dict.
! 21800: */
! 21801: return (inode->nsBindings[j+1]);
! 21802: }
! 21803: }
! 21804: }
! 21805: }
! 21806: return (NULL);
! 21807: #ifdef LIBXML_READER_ENABLED
! 21808: } else if (vctxt->reader != NULL) {
! 21809: xmlChar *nsName;
! 21810:
! 21811: nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
! 21812: if (nsName != NULL) {
! 21813: const xmlChar *ret;
! 21814:
! 21815: ret = xmlDictLookup(vctxt->dict, nsName, -1);
! 21816: xmlFree(nsName);
! 21817: return (ret);
! 21818: } else
! 21819: return (NULL);
! 21820: #endif
! 21821: } else {
! 21822: xmlNsPtr ns;
! 21823:
! 21824: if ((vctxt->inode->node == NULL) ||
! 21825: (vctxt->inode->node->doc == NULL)) {
! 21826: VERROR_INT("xmlSchemaLookupNamespace",
! 21827: "no node or node's doc avaliable");
! 21828: return (NULL);
! 21829: }
! 21830: ns = xmlSearchNs(vctxt->inode->node->doc,
! 21831: vctxt->inode->node, prefix);
! 21832: if (ns != NULL)
! 21833: return (ns->href);
! 21834: return (NULL);
! 21835: }
! 21836: }
! 21837:
! 21838: /*
! 21839: * This one works on the schema of the validation context.
! 21840: */
! 21841: static int
! 21842: xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
! 21843: xmlSchemaPtr schema,
! 21844: xmlNodePtr node,
! 21845: const xmlChar *value,
! 21846: xmlSchemaValPtr *val,
! 21847: int valNeeded)
! 21848: {
! 21849: int ret;
! 21850:
! 21851: if (vctxt && (vctxt->schema == NULL)) {
! 21852: VERROR_INT("xmlSchemaValidateNotation",
! 21853: "a schema is needed on the validation context");
! 21854: return (-1);
! 21855: }
! 21856: ret = xmlValidateQName(value, 1);
! 21857: if (ret != 0)
! 21858: return (ret);
! 21859: {
! 21860: xmlChar *localName = NULL;
! 21861: xmlChar *prefix = NULL;
! 21862:
! 21863: localName = xmlSplitQName2(value, &prefix);
! 21864: if (prefix != NULL) {
! 21865: const xmlChar *nsName = NULL;
! 21866:
! 21867: if (vctxt != NULL)
! 21868: nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
! 21869: else if (node != NULL) {
! 21870: xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
! 21871: if (ns != NULL)
! 21872: nsName = ns->href;
! 21873: } else {
! 21874: xmlFree(prefix);
! 21875: xmlFree(localName);
! 21876: return (1);
! 21877: }
! 21878: if (nsName == NULL) {
! 21879: xmlFree(prefix);
! 21880: xmlFree(localName);
! 21881: return (1);
! 21882: }
! 21883: if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
! 21884: if ((valNeeded) && (val != NULL)) {
! 21885: (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
! 21886: xmlStrdup(nsName));
! 21887: if (*val == NULL)
! 21888: ret = -1;
! 21889: }
! 21890: } else
! 21891: ret = 1;
! 21892: xmlFree(prefix);
! 21893: xmlFree(localName);
! 21894: } else {
! 21895: if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
! 21896: if (valNeeded && (val != NULL)) {
! 21897: (*val) = xmlSchemaNewNOTATIONValue(
! 21898: BAD_CAST xmlStrdup(value), NULL);
! 21899: if (*val == NULL)
! 21900: ret = -1;
! 21901: }
! 21902: } else
! 21903: return (1);
! 21904: }
! 21905: }
! 21906: return (ret);
! 21907: }
! 21908:
! 21909: static int
! 21910: xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
! 21911: const xmlChar* lname,
! 21912: const xmlChar* nsname)
! 21913: {
! 21914: int i;
! 21915:
! 21916: lname = xmlDictLookup(vctxt->dict, lname, -1);
! 21917: if (lname == NULL)
! 21918: return(-1);
! 21919: if (nsname != NULL) {
! 21920: nsname = xmlDictLookup(vctxt->dict, nsname, -1);
! 21921: if (nsname == NULL)
! 21922: return(-1);
! 21923: }
! 21924: for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
! 21925: if ((vctxt->nodeQNames->items [i] == lname) &&
! 21926: (vctxt->nodeQNames->items[i +1] == nsname))
! 21927: /* Already there */
! 21928: return(i);
! 21929: }
! 21930: /* Add new entry. */
! 21931: i = vctxt->nodeQNames->nbItems;
! 21932: xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
! 21933: xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
! 21934: return(i);
! 21935: }
! 21936:
! 21937: /************************************************************************
! 21938: * *
! 21939: * Validation of identity-constraints (IDC) *
! 21940: * *
! 21941: ************************************************************************/
! 21942:
! 21943: /**
! 21944: * xmlSchemaAugmentIDC:
! 21945: * @idcDef: the IDC definition
! 21946: *
! 21947: * Creates an augmented IDC definition item.
! 21948: *
! 21949: * Returns the item, or NULL on internal errors.
! 21950: */
! 21951: static void
! 21952: xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef,
! 21953: xmlSchemaValidCtxtPtr vctxt)
! 21954: {
! 21955: xmlSchemaIDCAugPtr aidc;
! 21956:
! 21957: aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
! 21958: if (aidc == NULL) {
! 21959: xmlSchemaVErrMemory(vctxt,
! 21960: "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
! 21961: NULL);
! 21962: return;
! 21963: }
! 21964: aidc->keyrefDepth = -1;
! 21965: aidc->def = idcDef;
! 21966: aidc->next = NULL;
! 21967: if (vctxt->aidcs == NULL)
! 21968: vctxt->aidcs = aidc;
! 21969: else {
! 21970: aidc->next = vctxt->aidcs;
! 21971: vctxt->aidcs = aidc;
! 21972: }
! 21973: /*
! 21974: * Save if we have keyrefs at all.
! 21975: */
! 21976: if ((vctxt->hasKeyrefs == 0) &&
! 21977: (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
! 21978: vctxt->hasKeyrefs = 1;
! 21979: }
! 21980:
! 21981: /**
! 21982: * xmlSchemaAugmentImportedIDC:
! 21983: * @imported: the imported schema
! 21984: *
! 21985: * Creates an augmented IDC definition for the imported schema.
! 21986: */
! 21987: static void
! 21988: xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) {
! 21989: if (imported->schema->idcDef != NULL) {
! 21990: xmlHashScan(imported->schema->idcDef ,
! 21991: (xmlHashScanner) xmlSchemaAugmentIDC, vctxt);
! 21992: }
! 21993: }
! 21994:
! 21995: /**
! 21996: * xmlSchemaIDCNewBinding:
! 21997: * @idcDef: the IDC definition of this binding
! 21998: *
! 21999: * Creates a new IDC binding.
! 22000: *
! 22001: * Returns the new IDC binding, NULL on internal errors.
! 22002: */
! 22003: static xmlSchemaPSVIIDCBindingPtr
! 22004: xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
! 22005: {
! 22006: xmlSchemaPSVIIDCBindingPtr ret;
! 22007:
! 22008: ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
! 22009: sizeof(xmlSchemaPSVIIDCBinding));
! 22010: if (ret == NULL) {
! 22011: xmlSchemaVErrMemory(NULL,
! 22012: "allocating a PSVI IDC binding item", NULL);
! 22013: return (NULL);
! 22014: }
! 22015: memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
! 22016: ret->definition = idcDef;
! 22017: return (ret);
! 22018: }
! 22019:
! 22020: /**
! 22021: * xmlSchemaIDCStoreNodeTableItem:
! 22022: * @vctxt: the WXS validation context
! 22023: * @item: the IDC node table item
! 22024: *
! 22025: * The validation context is used to store IDC node table items.
! 22026: * They are stored to avoid copying them if IDC node-tables are merged
! 22027: * with corresponding parent IDC node-tables (bubbling).
! 22028: *
! 22029: * Returns 0 if succeeded, -1 on internal errors.
! 22030: */
! 22031: static int
! 22032: xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
! 22033: xmlSchemaPSVIIDCNodePtr item)
! 22034: {
! 22035: /*
! 22036: * Add to gobal list.
! 22037: */
! 22038: if (vctxt->idcNodes == NULL) {
! 22039: vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
! 22040: xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
! 22041: if (vctxt->idcNodes == NULL) {
! 22042: xmlSchemaVErrMemory(vctxt,
! 22043: "allocating the IDC node table item list", NULL);
! 22044: return (-1);
! 22045: }
! 22046: vctxt->sizeIdcNodes = 20;
! 22047: } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
! 22048: vctxt->sizeIdcNodes *= 2;
! 22049: vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
! 22050: xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
! 22051: sizeof(xmlSchemaPSVIIDCNodePtr));
! 22052: if (vctxt->idcNodes == NULL) {
! 22053: xmlSchemaVErrMemory(vctxt,
! 22054: "re-allocating the IDC node table item list", NULL);
! 22055: return (-1);
! 22056: }
! 22057: }
! 22058: vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
! 22059:
! 22060: return (0);
! 22061: }
! 22062:
! 22063: /**
! 22064: * xmlSchemaIDCStoreKey:
! 22065: * @vctxt: the WXS validation context
! 22066: * @item: the IDC key
! 22067: *
! 22068: * The validation context is used to store an IDC key.
! 22069: *
! 22070: * Returns 0 if succeeded, -1 on internal errors.
! 22071: */
! 22072: static int
! 22073: xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
! 22074: xmlSchemaPSVIIDCKeyPtr key)
! 22075: {
! 22076: /*
! 22077: * Add to gobal list.
! 22078: */
! 22079: if (vctxt->idcKeys == NULL) {
! 22080: vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
! 22081: xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
! 22082: if (vctxt->idcKeys == NULL) {
! 22083: xmlSchemaVErrMemory(vctxt,
! 22084: "allocating the IDC key storage list", NULL);
! 22085: return (-1);
! 22086: }
! 22087: vctxt->sizeIdcKeys = 40;
! 22088: } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
! 22089: vctxt->sizeIdcKeys *= 2;
! 22090: vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
! 22091: xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
! 22092: sizeof(xmlSchemaPSVIIDCKeyPtr));
! 22093: if (vctxt->idcKeys == NULL) {
! 22094: xmlSchemaVErrMemory(vctxt,
! 22095: "re-allocating the IDC key storage list", NULL);
! 22096: return (-1);
! 22097: }
! 22098: }
! 22099: vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
! 22100:
! 22101: return (0);
! 22102: }
! 22103:
! 22104: /**
! 22105: * xmlSchemaIDCAppendNodeTableItem:
! 22106: * @bind: the IDC binding
! 22107: * @ntItem: the node-table item
! 22108: *
! 22109: * Appends the IDC node-table item to the binding.
! 22110: *
! 22111: * Returns 0 on success and -1 on internal errors.
! 22112: */
! 22113: static int
! 22114: xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
! 22115: xmlSchemaPSVIIDCNodePtr ntItem)
! 22116: {
! 22117: if (bind->nodeTable == NULL) {
! 22118: bind->sizeNodes = 10;
! 22119: bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
! 22120: xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
! 22121: if (bind->nodeTable == NULL) {
! 22122: xmlSchemaVErrMemory(NULL,
! 22123: "allocating an array of IDC node-table items", NULL);
! 22124: return(-1);
! 22125: }
! 22126: } else if (bind->sizeNodes <= bind->nbNodes) {
! 22127: bind->sizeNodes *= 2;
! 22128: bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
! 22129: xmlRealloc(bind->nodeTable, bind->sizeNodes *
! 22130: sizeof(xmlSchemaPSVIIDCNodePtr));
! 22131: if (bind->nodeTable == NULL) {
! 22132: xmlSchemaVErrMemory(NULL,
! 22133: "re-allocating an array of IDC node-table items", NULL);
! 22134: return(-1);
! 22135: }
! 22136: }
! 22137: bind->nodeTable[bind->nbNodes++] = ntItem;
! 22138: return(0);
! 22139: }
! 22140:
! 22141: /**
! 22142: * xmlSchemaIDCAcquireBinding:
! 22143: * @vctxt: the WXS validation context
! 22144: * @matcher: the IDC matcher
! 22145: *
! 22146: * Looks up an PSVI IDC binding, for the IDC definition and
! 22147: * of the given matcher. If none found, a new one is created
! 22148: * and added to the IDC table.
! 22149: *
! 22150: * Returns an IDC binding or NULL on internal errors.
! 22151: */
! 22152: static xmlSchemaPSVIIDCBindingPtr
! 22153: xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
! 22154: xmlSchemaIDCMatcherPtr matcher)
! 22155: {
! 22156: xmlSchemaNodeInfoPtr ielem;
! 22157:
! 22158: ielem = vctxt->elemInfos[matcher->depth];
! 22159:
! 22160: if (ielem->idcTable == NULL) {
! 22161: ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
! 22162: if (ielem->idcTable == NULL)
! 22163: return (NULL);
! 22164: return(ielem->idcTable);
! 22165: } else {
! 22166: xmlSchemaPSVIIDCBindingPtr bind = NULL;
! 22167:
! 22168: bind = ielem->idcTable;
! 22169: do {
! 22170: if (bind->definition == matcher->aidc->def)
! 22171: return(bind);
! 22172: if (bind->next == NULL) {
! 22173: bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
! 22174: if (bind->next == NULL)
! 22175: return (NULL);
! 22176: return(bind->next);
! 22177: }
! 22178: bind = bind->next;
! 22179: } while (bind != NULL);
! 22180: }
! 22181: return (NULL);
! 22182: }
! 22183:
! 22184: static xmlSchemaItemListPtr
! 22185: xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
! 22186: xmlSchemaIDCMatcherPtr matcher)
! 22187: {
! 22188: if (matcher->targets == NULL)
! 22189: matcher->targets = xmlSchemaItemListCreate();
! 22190: return(matcher->targets);
! 22191: }
! 22192:
! 22193: /**
! 22194: * xmlSchemaIDCFreeKey:
! 22195: * @key: the IDC key
! 22196: *
! 22197: * Frees an IDC key together with its compiled value.
! 22198: */
! 22199: static void
! 22200: xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
! 22201: {
! 22202: if (key->val != NULL)
! 22203: xmlSchemaFreeValue(key->val);
! 22204: xmlFree(key);
! 22205: }
! 22206:
! 22207: /**
! 22208: * xmlSchemaIDCFreeBinding:
! 22209: *
! 22210: * Frees an IDC binding. Note that the node table-items
! 22211: * are not freed.
! 22212: */
! 22213: static void
! 22214: xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
! 22215: {
! 22216: if (bind->nodeTable != NULL)
! 22217: xmlFree(bind->nodeTable);
! 22218: if (bind->dupls != NULL)
! 22219: xmlSchemaItemListFree(bind->dupls);
! 22220: xmlFree(bind);
! 22221: }
! 22222:
! 22223: /**
! 22224: * xmlSchemaIDCFreeIDCTable:
! 22225: * @bind: the first IDC binding in the list
! 22226: *
! 22227: * Frees an IDC table, i.e. all the IDC bindings in the list.
! 22228: */
! 22229: static void
! 22230: xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
! 22231: {
! 22232: xmlSchemaPSVIIDCBindingPtr prev;
! 22233:
! 22234: while (bind != NULL) {
! 22235: prev = bind;
! 22236: bind = bind->next;
! 22237: xmlSchemaIDCFreeBinding(prev);
! 22238: }
! 22239: }
! 22240:
! 22241: /**
! 22242: * xmlSchemaIDCFreeMatcherList:
! 22243: * @matcher: the first IDC matcher in the list
! 22244: *
! 22245: * Frees a list of IDC matchers.
! 22246: */
! 22247: static void
! 22248: xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
! 22249: {
! 22250: xmlSchemaIDCMatcherPtr next;
! 22251:
! 22252: while (matcher != NULL) {
! 22253: next = matcher->next;
! 22254: if (matcher->keySeqs != NULL) {
! 22255: int i;
! 22256: for (i = 0; i < matcher->sizeKeySeqs; i++)
! 22257: if (matcher->keySeqs[i] != NULL)
! 22258: xmlFree(matcher->keySeqs[i]);
! 22259: xmlFree(matcher->keySeqs);
! 22260: }
! 22261: if (matcher->targets != NULL) {
! 22262: if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
! 22263: int i;
! 22264: xmlSchemaPSVIIDCNodePtr idcNode;
! 22265: /*
! 22266: * Node-table items for keyrefs are not stored globally
! 22267: * to the validation context, since they are not bubbled.
! 22268: * We need to free them here.
! 22269: */
! 22270: for (i = 0; i < matcher->targets->nbItems; i++) {
! 22271: idcNode =
! 22272: (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
! 22273: xmlFree(idcNode->keys);
! 22274: xmlFree(idcNode);
! 22275: }
! 22276: }
! 22277: xmlSchemaItemListFree(matcher->targets);
! 22278: }
! 22279: xmlFree(matcher);
! 22280: matcher = next;
! 22281: }
! 22282: }
! 22283:
! 22284: /**
! 22285: * xmlSchemaIDCReleaseMatcherList:
! 22286: * @vctxt: the WXS validation context
! 22287: * @matcher: the first IDC matcher in the list
! 22288: *
! 22289: * Caches a list of IDC matchers for reuse.
! 22290: */
! 22291: static void
! 22292: xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
! 22293: xmlSchemaIDCMatcherPtr matcher)
! 22294: {
! 22295: xmlSchemaIDCMatcherPtr next;
! 22296:
! 22297: while (matcher != NULL) {
! 22298: next = matcher->next;
! 22299: if (matcher->keySeqs != NULL) {
! 22300: int i;
! 22301: /*
! 22302: * Don't free the array, but only the content.
! 22303: */
! 22304: for (i = 0; i < matcher->sizeKeySeqs; i++)
! 22305: if (matcher->keySeqs[i] != NULL) {
! 22306: xmlFree(matcher->keySeqs[i]);
! 22307: matcher->keySeqs[i] = NULL;
! 22308: }
! 22309: }
! 22310: if (matcher->targets) {
! 22311: if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
! 22312: int i;
! 22313: xmlSchemaPSVIIDCNodePtr idcNode;
! 22314: /*
! 22315: * Node-table items for keyrefs are not stored globally
! 22316: * to the validation context, since they are not bubbled.
! 22317: * We need to free them here.
! 22318: */
! 22319: for (i = 0; i < matcher->targets->nbItems; i++) {
! 22320: idcNode =
! 22321: (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
! 22322: xmlFree(idcNode->keys);
! 22323: xmlFree(idcNode);
! 22324: }
! 22325: }
! 22326: xmlSchemaItemListFree(matcher->targets);
! 22327: matcher->targets = NULL;
! 22328: }
! 22329: matcher->next = NULL;
! 22330: /*
! 22331: * Cache the matcher.
! 22332: */
! 22333: if (vctxt->idcMatcherCache != NULL)
! 22334: matcher->nextCached = vctxt->idcMatcherCache;
! 22335: vctxt->idcMatcherCache = matcher;
! 22336:
! 22337: matcher = next;
! 22338: }
! 22339: }
! 22340:
! 22341: /**
! 22342: * xmlSchemaIDCAddStateObject:
! 22343: * @vctxt: the WXS validation context
! 22344: * @matcher: the IDC matcher
! 22345: * @sel: the XPath information
! 22346: * @parent: the parent "selector" state object if any
! 22347: * @type: "selector" or "field"
! 22348: *
! 22349: * Creates/reuses and activates state objects for the given
! 22350: * XPath information; if the XPath expression consists of unions,
! 22351: * multiple state objects are created for every unioned expression.
! 22352: *
! 22353: * Returns 0 on success and -1 on internal errors.
! 22354: */
! 22355: static int
! 22356: xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
! 22357: xmlSchemaIDCMatcherPtr matcher,
! 22358: xmlSchemaIDCSelectPtr sel,
! 22359: int type)
! 22360: {
! 22361: xmlSchemaIDCStateObjPtr sto;
! 22362:
! 22363: /*
! 22364: * Reuse the state objects from the pool.
! 22365: */
! 22366: if (vctxt->xpathStatePool != NULL) {
! 22367: sto = vctxt->xpathStatePool;
! 22368: vctxt->xpathStatePool = sto->next;
! 22369: sto->next = NULL;
! 22370: } else {
! 22371: /*
! 22372: * Create a new state object.
! 22373: */
! 22374: sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
! 22375: if (sto == NULL) {
! 22376: xmlSchemaVErrMemory(NULL,
! 22377: "allocating an IDC state object", NULL);
! 22378: return (-1);
! 22379: }
! 22380: memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
! 22381: }
! 22382: /*
! 22383: * Add to global list.
! 22384: */
! 22385: if (vctxt->xpathStates != NULL)
! 22386: sto->next = vctxt->xpathStates;
! 22387: vctxt->xpathStates = sto;
! 22388:
! 22389: /*
! 22390: * Free the old xpath validation context.
! 22391: */
! 22392: if (sto->xpathCtxt != NULL)
! 22393: xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
! 22394:
! 22395: /*
! 22396: * Create a new XPath (pattern) validation context.
! 22397: */
! 22398: sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
! 22399: (xmlPatternPtr) sel->xpathComp);
! 22400: if (sto->xpathCtxt == NULL) {
! 22401: VERROR_INT("xmlSchemaIDCAddStateObject",
! 22402: "failed to create an XPath validation context");
! 22403: return (-1);
! 22404: }
! 22405: sto->type = type;
! 22406: sto->depth = vctxt->depth;
! 22407: sto->matcher = matcher;
! 22408: sto->sel = sel;
! 22409: sto->nbHistory = 0;
! 22410:
! 22411: #ifdef DEBUG_IDC
! 22412: xmlGenericError(xmlGenericErrorContext, "IDC: STO push '%s'\n",
! 22413: sto->sel->xpath);
! 22414: #endif
! 22415: return (0);
! 22416: }
! 22417:
! 22418: /**
! 22419: * xmlSchemaXPathEvaluate:
! 22420: * @vctxt: the WXS validation context
! 22421: * @nodeType: the nodeType of the current node
! 22422: *
! 22423: * Evaluates all active XPath state objects.
! 22424: *
! 22425: * Returns the number of IC "field" state objects which resolved to
! 22426: * this node, 0 if none resolved and -1 on internal errors.
! 22427: */
! 22428: static int
! 22429: xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
! 22430: xmlElementType nodeType)
! 22431: {
! 22432: xmlSchemaIDCStateObjPtr sto, head = NULL, first;
! 22433: int res, resolved = 0, depth = vctxt->depth;
! 22434:
! 22435: if (vctxt->xpathStates == NULL)
! 22436: return (0);
! 22437:
! 22438: if (nodeType == XML_ATTRIBUTE_NODE)
! 22439: depth++;
! 22440: #ifdef DEBUG_IDC
! 22441: {
! 22442: xmlChar *str = NULL;
! 22443: xmlGenericError(xmlGenericErrorContext,
! 22444: "IDC: EVAL on %s, depth %d, type %d\n",
! 22445: xmlSchemaFormatQName(&str, vctxt->inode->nsName,
! 22446: vctxt->inode->localName), depth, nodeType);
! 22447: FREE_AND_NULL(str)
! 22448: }
! 22449: #endif
! 22450: /*
! 22451: * Process all active XPath state objects.
! 22452: */
! 22453: first = vctxt->xpathStates;
! 22454: sto = first;
! 22455: while (sto != head) {
! 22456: #ifdef DEBUG_IDC
! 22457: if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
! 22458: xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] selector '%s'\n",
! 22459: sto->matcher->aidc->def->name, sto->sel->xpath);
! 22460: else
! 22461: xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] field '%s'\n",
! 22462: sto->matcher->aidc->def->name, sto->sel->xpath);
! 22463: #endif
! 22464: if (nodeType == XML_ELEMENT_NODE)
! 22465: res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
! 22466: vctxt->inode->localName, vctxt->inode->nsName);
! 22467: else
! 22468: res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
! 22469: vctxt->inode->localName, vctxt->inode->nsName);
! 22470:
! 22471: if (res == -1) {
! 22472: VERROR_INT("xmlSchemaXPathEvaluate",
! 22473: "calling xmlStreamPush()");
! 22474: return (-1);
! 22475: }
! 22476: if (res == 0)
! 22477: goto next_sto;
! 22478: /*
! 22479: * Full match.
! 22480: */
! 22481: #ifdef DEBUG_IDC
! 22482: xmlGenericError(xmlGenericErrorContext, "IDC: "
! 22483: "MATCH\n");
! 22484: #endif
! 22485: /*
! 22486: * Register a match in the state object history.
! 22487: */
! 22488: if (sto->history == NULL) {
! 22489: sto->history = (int *) xmlMalloc(5 * sizeof(int));
! 22490: if (sto->history == NULL) {
! 22491: xmlSchemaVErrMemory(NULL,
! 22492: "allocating the state object history", NULL);
! 22493: return(-1);
! 22494: }
! 22495: sto->sizeHistory = 5;
! 22496: } else if (sto->sizeHistory <= sto->nbHistory) {
! 22497: sto->sizeHistory *= 2;
! 22498: sto->history = (int *) xmlRealloc(sto->history,
! 22499: sto->sizeHistory * sizeof(int));
! 22500: if (sto->history == NULL) {
! 22501: xmlSchemaVErrMemory(NULL,
! 22502: "re-allocating the state object history", NULL);
! 22503: return(-1);
! 22504: }
! 22505: }
! 22506: sto->history[sto->nbHistory++] = depth;
! 22507:
! 22508: #ifdef DEBUG_IDC
! 22509: xmlGenericError(xmlGenericErrorContext, "IDC: push match '%d'\n",
! 22510: vctxt->depth);
! 22511: #endif
! 22512:
! 22513: if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
! 22514: xmlSchemaIDCSelectPtr sel;
! 22515: /*
! 22516: * Activate state objects for the IDC fields of
! 22517: * the IDC selector.
! 22518: */
! 22519: #ifdef DEBUG_IDC
! 22520: xmlGenericError(xmlGenericErrorContext, "IDC: "
! 22521: "activating field states\n");
! 22522: #endif
! 22523: sel = sto->matcher->aidc->def->fields;
! 22524: while (sel != NULL) {
! 22525: if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
! 22526: sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
! 22527: return (-1);
! 22528: sel = sel->next;
! 22529: }
! 22530: } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
! 22531: /*
! 22532: * An IDC key node was found by the IDC field.
! 22533: */
! 22534: #ifdef DEBUG_IDC
! 22535: xmlGenericError(xmlGenericErrorContext,
! 22536: "IDC: key found\n");
! 22537: #endif
! 22538: /*
! 22539: * Notify that the character value of this node is
! 22540: * needed.
! 22541: */
! 22542: if (resolved == 0) {
! 22543: if ((vctxt->inode->flags &
! 22544: XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
! 22545: vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
! 22546: }
! 22547: resolved++;
! 22548: }
! 22549: next_sto:
! 22550: if (sto->next == NULL) {
! 22551: /*
! 22552: * Evaluate field state objects created on this node as well.
! 22553: */
! 22554: head = first;
! 22555: sto = vctxt->xpathStates;
! 22556: } else
! 22557: sto = sto->next;
! 22558: }
! 22559: return (resolved);
! 22560: }
! 22561:
! 22562: static const xmlChar *
! 22563: xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
! 22564: xmlChar **buf,
! 22565: xmlSchemaPSVIIDCKeyPtr *seq,
! 22566: int count)
! 22567: {
! 22568: int i, res;
! 22569: xmlChar *value = NULL;
! 22570:
! 22571: *buf = xmlStrdup(BAD_CAST "[");
! 22572: for (i = 0; i < count; i++) {
! 22573: *buf = xmlStrcat(*buf, BAD_CAST "'");
! 22574: res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
! 22575: xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
! 22576: &value);
! 22577: if (res == 0)
! 22578: *buf = xmlStrcat(*buf, BAD_CAST value);
! 22579: else {
! 22580: VERROR_INT("xmlSchemaFormatIDCKeySequence",
! 22581: "failed to compute a canonical value");
! 22582: *buf = xmlStrcat(*buf, BAD_CAST "???");
! 22583: }
! 22584: if (i < count -1)
! 22585: *buf = xmlStrcat(*buf, BAD_CAST "', ");
! 22586: else
! 22587: *buf = xmlStrcat(*buf, BAD_CAST "'");
! 22588: if (value != NULL) {
! 22589: xmlFree(value);
! 22590: value = NULL;
! 22591: }
! 22592: }
! 22593: *buf = xmlStrcat(*buf, BAD_CAST "]");
! 22594:
! 22595: return (BAD_CAST *buf);
! 22596: }
! 22597:
! 22598: /**
! 22599: * xmlSchemaXPathPop:
! 22600: * @vctxt: the WXS validation context
! 22601: *
! 22602: * Pops all XPath states.
! 22603: *
! 22604: * Returns 0 on success and -1 on internal errors.
! 22605: */
! 22606: static int
! 22607: xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
! 22608: {
! 22609: xmlSchemaIDCStateObjPtr sto;
! 22610: int res;
! 22611:
! 22612: if (vctxt->xpathStates == NULL)
! 22613: return(0);
! 22614: sto = vctxt->xpathStates;
! 22615: do {
! 22616: res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
! 22617: if (res == -1)
! 22618: return (-1);
! 22619: sto = sto->next;
! 22620: } while (sto != NULL);
! 22621: return(0);
! 22622: }
! 22623:
! 22624: /**
! 22625: * xmlSchemaXPathProcessHistory:
! 22626: * @vctxt: the WXS validation context
! 22627: * @type: the simple/complex type of the current node if any at all
! 22628: * @val: the precompiled value
! 22629: *
! 22630: * Processes and pops the history items of the IDC state objects.
! 22631: * IDC key-sequences are validated/created on IDC bindings.
! 22632: *
! 22633: * Returns 0 on success and -1 on internal errors.
! 22634: */
! 22635: static int
! 22636: xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
! 22637: int depth)
! 22638: {
! 22639: xmlSchemaIDCStateObjPtr sto, nextsto;
! 22640: int res, matchDepth;
! 22641: xmlSchemaPSVIIDCKeyPtr key = NULL;
! 22642: xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
! 22643:
! 22644: if (vctxt->xpathStates == NULL)
! 22645: return (0);
! 22646: sto = vctxt->xpathStates;
! 22647:
! 22648: #ifdef DEBUG_IDC
! 22649: {
! 22650: xmlChar *str = NULL;
! 22651: xmlGenericError(xmlGenericErrorContext,
! 22652: "IDC: BACK on %s, depth %d\n",
! 22653: xmlSchemaFormatQName(&str, vctxt->inode->nsName,
! 22654: vctxt->inode->localName), vctxt->depth);
! 22655: FREE_AND_NULL(str)
! 22656: }
! 22657: #endif
! 22658: /*
! 22659: * Evaluate the state objects.
! 22660: */
! 22661: while (sto != NULL) {
! 22662: res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
! 22663: if (res == -1) {
! 22664: VERROR_INT("xmlSchemaXPathProcessHistory",
! 22665: "calling xmlStreamPop()");
! 22666: return (-1);
! 22667: }
! 22668: #ifdef DEBUG_IDC
! 22669: xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n",
! 22670: sto->sel->xpath);
! 22671: #endif
! 22672: if (sto->nbHistory == 0)
! 22673: goto deregister_check;
! 22674:
! 22675: matchDepth = sto->history[sto->nbHistory -1];
! 22676:
! 22677: /*
! 22678: * Only matches at the current depth are of interest.
! 22679: */
! 22680: if (matchDepth != depth) {
! 22681: sto = sto->next;
! 22682: continue;
! 22683: }
! 22684: if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
! 22685: /*
! 22686: * NOTE: According to
! 22687: * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
! 22688: * ... the simple-content of complex types is also allowed.
! 22689: */
! 22690:
! 22691: if (WXS_IS_COMPLEX(type)) {
! 22692: if (WXS_HAS_SIMPLE_CONTENT(type)) {
! 22693: /*
! 22694: * Sanity check for complex types with simple content.
! 22695: */
! 22696: simpleType = type->contentTypeDef;
! 22697: if (simpleType == NULL) {
! 22698: VERROR_INT("xmlSchemaXPathProcessHistory",
! 22699: "field resolves to a CT with simple content "
! 22700: "but the CT is missing the ST definition");
! 22701: return (-1);
! 22702: }
! 22703: } else
! 22704: simpleType = NULL;
! 22705: } else
! 22706: simpleType = type;
! 22707: if (simpleType == NULL) {
! 22708: xmlChar *str = NULL;
! 22709:
! 22710: /*
! 22711: * Not qualified if the field resolves to a node of non
! 22712: * simple type.
! 22713: */
! 22714: xmlSchemaCustomErr(ACTXT_CAST vctxt,
! 22715: XML_SCHEMAV_CVC_IDC, NULL,
! 22716: WXS_BASIC_CAST sto->matcher->aidc->def,
! 22717: "The XPath '%s' of a field of %s does evaluate to a node of "
! 22718: "non-simple type",
! 22719: sto->sel->xpath,
! 22720: xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
! 22721: FREE_AND_NULL(str);
! 22722: sto->nbHistory--;
! 22723: goto deregister_check;
! 22724: }
! 22725:
! 22726: if ((key == NULL) && (vctxt->inode->val == NULL)) {
! 22727: /*
! 22728: * Failed to provide the normalized value; maybe
! 22729: * the value was invalid.
! 22730: */
! 22731: VERROR(XML_SCHEMAV_CVC_IDC,
! 22732: WXS_BASIC_CAST sto->matcher->aidc->def,
! 22733: "Warning: No precomputed value available, the value "
! 22734: "was either invalid or something strange happend");
! 22735: sto->nbHistory--;
! 22736: goto deregister_check;
! 22737: } else {
! 22738: xmlSchemaIDCMatcherPtr matcher = sto->matcher;
! 22739: xmlSchemaPSVIIDCKeyPtr *keySeq;
! 22740: int pos, idx;
! 22741:
! 22742: /*
! 22743: * The key will be anchored on the matcher's list of
! 22744: * key-sequences. The position in this list is determined
! 22745: * by the target node's depth relative to the matcher's
! 22746: * depth of creation (i.e. the depth of the scope element).
! 22747: *
! 22748: * Element Depth Pos List-entries
! 22749: * <scope> 0 NULL
! 22750: * <bar> 1 NULL
! 22751: * <target/> 2 2 target
! 22752: * <bar>
! 22753: * </scope>
! 22754: *
! 22755: * The size of the list is only dependant on the depth of
! 22756: * the tree.
! 22757: * An entry will be NULLed in selector_leave, i.e. when
! 22758: * we hit the target's
! 22759: */
! 22760: pos = sto->depth - matcher->depth;
! 22761: idx = sto->sel->index;
! 22762:
! 22763: /*
! 22764: * Create/grow the array of key-sequences.
! 22765: */
! 22766: if (matcher->keySeqs == NULL) {
! 22767: if (pos > 9)
! 22768: matcher->sizeKeySeqs = pos * 2;
! 22769: else
! 22770: matcher->sizeKeySeqs = 10;
! 22771: matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
! 22772: xmlMalloc(matcher->sizeKeySeqs *
! 22773: sizeof(xmlSchemaPSVIIDCKeyPtr *));
! 22774: if (matcher->keySeqs == NULL) {
! 22775: xmlSchemaVErrMemory(NULL,
! 22776: "allocating an array of key-sequences",
! 22777: NULL);
! 22778: return(-1);
! 22779: }
! 22780: memset(matcher->keySeqs, 0,
! 22781: matcher->sizeKeySeqs *
! 22782: sizeof(xmlSchemaPSVIIDCKeyPtr *));
! 22783: } else if (pos >= matcher->sizeKeySeqs) {
! 22784: int i = matcher->sizeKeySeqs;
! 22785:
! 22786: matcher->sizeKeySeqs *= 2;
! 22787: matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
! 22788: xmlRealloc(matcher->keySeqs,
! 22789: matcher->sizeKeySeqs *
! 22790: sizeof(xmlSchemaPSVIIDCKeyPtr *));
! 22791: if (matcher->keySeqs == NULL) {
! 22792: xmlSchemaVErrMemory(NULL,
! 22793: "reallocating an array of key-sequences",
! 22794: NULL);
! 22795: return (-1);
! 22796: }
! 22797: /*
! 22798: * The array needs to be NULLed.
! 22799: * TODO: Use memset?
! 22800: */
! 22801: for (; i < matcher->sizeKeySeqs; i++)
! 22802: matcher->keySeqs[i] = NULL;
! 22803: }
! 22804:
! 22805: /*
! 22806: * Get/create the key-sequence.
! 22807: */
! 22808: keySeq = matcher->keySeqs[pos];
! 22809: if (keySeq == NULL) {
! 22810: goto create_sequence;
! 22811: } else if (keySeq[idx] != NULL) {
! 22812: xmlChar *str = NULL;
! 22813: /*
! 22814: * cvc-identity-constraint:
! 22815: * 3 For each node in the �target node set� all
! 22816: * of the {fields}, with that node as the context
! 22817: * node, evaluate to either an empty node-set or
! 22818: * a node-set with exactly one member, which must
! 22819: * have a simple type.
! 22820: *
! 22821: * The key was already set; report an error.
! 22822: */
! 22823: xmlSchemaCustomErr(ACTXT_CAST vctxt,
! 22824: XML_SCHEMAV_CVC_IDC, NULL,
! 22825: WXS_BASIC_CAST matcher->aidc->def,
! 22826: "The XPath '%s' of a field of %s evaluates to a "
! 22827: "node-set with more than one member",
! 22828: sto->sel->xpath,
! 22829: xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
! 22830: FREE_AND_NULL(str);
! 22831: sto->nbHistory--;
! 22832: goto deregister_check;
! 22833: } else
! 22834: goto create_key;
! 22835:
! 22836: create_sequence:
! 22837: /*
! 22838: * Create a key-sequence.
! 22839: */
! 22840: keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
! 22841: matcher->aidc->def->nbFields *
! 22842: sizeof(xmlSchemaPSVIIDCKeyPtr));
! 22843: if (keySeq == NULL) {
! 22844: xmlSchemaVErrMemory(NULL,
! 22845: "allocating an IDC key-sequence", NULL);
! 22846: return(-1);
! 22847: }
! 22848: memset(keySeq, 0, matcher->aidc->def->nbFields *
! 22849: sizeof(xmlSchemaPSVIIDCKeyPtr));
! 22850: matcher->keySeqs[pos] = keySeq;
! 22851: create_key:
! 22852: /*
! 22853: * Create a key once per node only.
! 22854: */
! 22855: if (key == NULL) {
! 22856: key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
! 22857: sizeof(xmlSchemaPSVIIDCKey));
! 22858: if (key == NULL) {
! 22859: xmlSchemaVErrMemory(NULL,
! 22860: "allocating a IDC key", NULL);
! 22861: xmlFree(keySeq);
! 22862: matcher->keySeqs[pos] = NULL;
! 22863: return(-1);
! 22864: }
! 22865: /*
! 22866: * Consume the compiled value.
! 22867: */
! 22868: key->type = simpleType;
! 22869: key->val = vctxt->inode->val;
! 22870: vctxt->inode->val = NULL;
! 22871: /*
! 22872: * Store the key in a global list.
! 22873: */
! 22874: if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
! 22875: xmlSchemaIDCFreeKey(key);
! 22876: return (-1);
! 22877: }
! 22878: }
! 22879: keySeq[idx] = key;
! 22880: }
! 22881: } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
! 22882:
! 22883: xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
! 22884: /* xmlSchemaPSVIIDCBindingPtr bind; */
! 22885: xmlSchemaPSVIIDCNodePtr ntItem;
! 22886: xmlSchemaIDCMatcherPtr matcher;
! 22887: xmlSchemaIDCPtr idc;
! 22888: xmlSchemaItemListPtr targets;
! 22889: int pos, i, j, nbKeys;
! 22890: /*
! 22891: * Here we have the following scenario:
! 22892: * An IDC 'selector' state object resolved to a target node,
! 22893: * during the time this target node was in the
! 22894: * ancestor-or-self axis, the 'field' state object(s) looked
! 22895: * out for matching nodes to create a key-sequence for this
! 22896: * target node. Now we are back to this target node and need
! 22897: * to put the key-sequence, together with the target node
! 22898: * itself, into the node-table of the corresponding IDC
! 22899: * binding.
! 22900: */
! 22901: matcher = sto->matcher;
! 22902: idc = matcher->aidc->def;
! 22903: nbKeys = idc->nbFields;
! 22904: pos = depth - matcher->depth;
! 22905: /*
! 22906: * Check if the matcher has any key-sequences at all, plus
! 22907: * if it has a key-sequence for the current target node.
! 22908: */
! 22909: if ((matcher->keySeqs == NULL) ||
! 22910: (matcher->sizeKeySeqs <= pos)) {
! 22911: if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
! 22912: goto selector_key_error;
! 22913: else
! 22914: goto selector_leave;
! 22915: }
! 22916:
! 22917: keySeq = &(matcher->keySeqs[pos]);
! 22918: if (*keySeq == NULL) {
! 22919: if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
! 22920: goto selector_key_error;
! 22921: else
! 22922: goto selector_leave;
! 22923: }
! 22924:
! 22925: for (i = 0; i < nbKeys; i++) {
! 22926: if ((*keySeq)[i] == NULL) {
! 22927: /*
! 22928: * Not qualified, if not all fields did resolve.
! 22929: */
! 22930: if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
! 22931: /*
! 22932: * All fields of a "key" IDC must resolve.
! 22933: */
! 22934: goto selector_key_error;
! 22935: }
! 22936: goto selector_leave;
! 22937: }
! 22938: }
! 22939: /*
! 22940: * All fields did resolve.
! 22941: */
! 22942:
! 22943: /*
! 22944: * 4.1 If the {identity-constraint category} is unique(/key),
! 22945: * then no two members of the �qualified node set� have
! 22946: * �key-sequences� whose members are pairwise equal, as
! 22947: * defined by Equal in [XML Schemas: Datatypes].
! 22948: *
! 22949: * Get the IDC binding from the matcher and check for
! 22950: * duplicate key-sequences.
! 22951: */
! 22952: #if 0
! 22953: bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
! 22954: #endif
! 22955: targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
! 22956: if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
! 22957: (targets->nbItems != 0)) {
! 22958: xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
! 22959:
! 22960: i = 0;
! 22961: res = 0;
! 22962: /*
! 22963: * Compare the key-sequences, key by key.
! 22964: */
! 22965: do {
! 22966: bkeySeq =
! 22967: ((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys;
! 22968: for (j = 0; j < nbKeys; j++) {
! 22969: ckey = (*keySeq)[j];
! 22970: bkey = bkeySeq[j];
! 22971: res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
! 22972: if (res == -1) {
! 22973: return (-1);
! 22974: } else if (res == 0) {
! 22975: /*
! 22976: * One of the keys differs, so the key-sequence
! 22977: * won't be equal; get out.
! 22978: */
! 22979: break;
! 22980: }
! 22981: }
! 22982: if (res == 1) {
! 22983: /*
! 22984: * Duplicate key-sequence found.
! 22985: */
! 22986: break;
! 22987: }
! 22988: i++;
! 22989: } while (i < targets->nbItems);
! 22990: if (i != targets->nbItems) {
! 22991: xmlChar *str = NULL, *strB = NULL;
! 22992: /*
! 22993: * TODO: Try to report the key-sequence.
! 22994: */
! 22995: xmlSchemaCustomErr(ACTXT_CAST vctxt,
! 22996: XML_SCHEMAV_CVC_IDC, NULL,
! 22997: WXS_BASIC_CAST idc,
! 22998: "Duplicate key-sequence %s in %s",
! 22999: xmlSchemaFormatIDCKeySequence(vctxt, &str,
! 23000: (*keySeq), nbKeys),
! 23001: xmlSchemaGetIDCDesignation(&strB, idc));
! 23002: FREE_AND_NULL(str);
! 23003: FREE_AND_NULL(strB);
! 23004: goto selector_leave;
! 23005: }
! 23006: }
! 23007: /*
! 23008: * Add a node-table item to the IDC binding.
! 23009: */
! 23010: ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
! 23011: sizeof(xmlSchemaPSVIIDCNode));
! 23012: if (ntItem == NULL) {
! 23013: xmlSchemaVErrMemory(NULL,
! 23014: "allocating an IDC node-table item", NULL);
! 23015: xmlFree(*keySeq);
! 23016: *keySeq = NULL;
! 23017: return(-1);
! 23018: }
! 23019: memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
! 23020:
! 23021: /*
! 23022: * Store the node-table item in a global list.
! 23023: */
! 23024: if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
! 23025: if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
! 23026: xmlFree(ntItem);
! 23027: xmlFree(*keySeq);
! 23028: *keySeq = NULL;
! 23029: return (-1);
! 23030: }
! 23031: ntItem->nodeQNameID = -1;
! 23032: } else {
! 23033: /*
! 23034: * Save a cached QName for this node on the IDC node, to be
! 23035: * able to report it, even if the node is not saved.
! 23036: */
! 23037: ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
! 23038: vctxt->inode->localName, vctxt->inode->nsName);
! 23039: if (ntItem->nodeQNameID == -1) {
! 23040: xmlFree(ntItem);
! 23041: xmlFree(*keySeq);
! 23042: *keySeq = NULL;
! 23043: return (-1);
! 23044: }
! 23045: }
! 23046: /*
! 23047: * Init the node-table item: Save the node, position and
! 23048: * consume the key-sequence.
! 23049: */
! 23050: ntItem->node = vctxt->node;
! 23051: ntItem->nodeLine = vctxt->inode->nodeLine;
! 23052: ntItem->keys = *keySeq;
! 23053: *keySeq = NULL;
! 23054: #if 0
! 23055: if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
! 23056: #endif
! 23057: if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
! 23058: if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
! 23059: /*
! 23060: * Free the item, since keyref items won't be
! 23061: * put on a global list.
! 23062: */
! 23063: xmlFree(ntItem->keys);
! 23064: xmlFree(ntItem);
! 23065: }
! 23066: return (-1);
! 23067: }
! 23068:
! 23069: goto selector_leave;
! 23070: selector_key_error:
! 23071: {
! 23072: xmlChar *str = NULL;
! 23073: /*
! 23074: * 4.2.1 (KEY) The �target node set� and the
! 23075: * �qualified node set� are equal, that is, every
! 23076: * member of the �target node set� is also a member
! 23077: * of the �qualified node set� and vice versa.
! 23078: */
! 23079: xmlSchemaCustomErr(ACTXT_CAST vctxt,
! 23080: XML_SCHEMAV_CVC_IDC, NULL,
! 23081: WXS_BASIC_CAST idc,
! 23082: "Not all fields of %s evaluate to a node",
! 23083: xmlSchemaGetIDCDesignation(&str, idc), NULL);
! 23084: FREE_AND_NULL(str);
! 23085: }
! 23086: selector_leave:
! 23087: /*
! 23088: * Free the key-sequence if not added to the IDC table.
! 23089: */
! 23090: if ((keySeq != NULL) && (*keySeq != NULL)) {
! 23091: xmlFree(*keySeq);
! 23092: *keySeq = NULL;
! 23093: }
! 23094: } /* if selector */
! 23095:
! 23096: sto->nbHistory--;
! 23097:
! 23098: deregister_check:
! 23099: /*
! 23100: * Deregister state objects if they reach the depth of creation.
! 23101: */
! 23102: if ((sto->nbHistory == 0) && (sto->depth == depth)) {
! 23103: #ifdef DEBUG_IDC
! 23104: xmlGenericError(xmlGenericErrorContext, "IDC: STO pop '%s'\n",
! 23105: sto->sel->xpath);
! 23106: #endif
! 23107: if (vctxt->xpathStates != sto) {
! 23108: VERROR_INT("xmlSchemaXPathProcessHistory",
! 23109: "The state object to be removed is not the first "
! 23110: "in the list");
! 23111: }
! 23112: nextsto = sto->next;
! 23113: /*
! 23114: * Unlink from the list of active XPath state objects.
! 23115: */
! 23116: vctxt->xpathStates = sto->next;
! 23117: sto->next = vctxt->xpathStatePool;
! 23118: /*
! 23119: * Link it to the pool of reusable state objects.
! 23120: */
! 23121: vctxt->xpathStatePool = sto;
! 23122: sto = nextsto;
! 23123: } else
! 23124: sto = sto->next;
! 23125: } /* while (sto != NULL) */
! 23126: return (0);
! 23127: }
! 23128:
! 23129: /**
! 23130: * xmlSchemaIDCRegisterMatchers:
! 23131: * @vctxt: the WXS validation context
! 23132: * @elemDecl: the element declaration
! 23133: *
! 23134: * Creates helper objects to evaluate IDC selectors/fields
! 23135: * successively.
! 23136: *
! 23137: * Returns 0 if OK and -1 on internal errors.
! 23138: */
! 23139: static int
! 23140: xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
! 23141: xmlSchemaElementPtr elemDecl)
! 23142: {
! 23143: xmlSchemaIDCMatcherPtr matcher, last = NULL;
! 23144: xmlSchemaIDCPtr idc, refIdc;
! 23145: xmlSchemaIDCAugPtr aidc;
! 23146:
! 23147: idc = (xmlSchemaIDCPtr) elemDecl->idcs;
! 23148: if (idc == NULL)
! 23149: return (0);
! 23150:
! 23151: #ifdef DEBUG_IDC
! 23152: {
! 23153: xmlChar *str = NULL;
! 23154: xmlGenericError(xmlGenericErrorContext,
! 23155: "IDC: REGISTER on %s, depth %d\n",
! 23156: (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
! 23157: vctxt->inode->localName), vctxt->depth);
! 23158: FREE_AND_NULL(str)
! 23159: }
! 23160: #endif
! 23161: if (vctxt->inode->idcMatchers != NULL) {
! 23162: VERROR_INT("xmlSchemaIDCRegisterMatchers",
! 23163: "The chain of IDC matchers is expected to be empty");
! 23164: return (-1);
! 23165: }
! 23166: do {
! 23167: if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
! 23168: /*
! 23169: * Since IDCs bubbles are expensive we need to know the
! 23170: * depth at which the bubbles should stop; this will be
! 23171: * the depth of the top-most keyref IDC. If no keyref
! 23172: * references a key/unique IDC, the keyrefDepth will
! 23173: * be -1, indicating that no bubbles are needed.
! 23174: */
! 23175: refIdc = (xmlSchemaIDCPtr) idc->ref->item;
! 23176: if (refIdc != NULL) {
! 23177: /*
! 23178: * Remember that we have keyrefs on this node.
! 23179: */
! 23180: vctxt->inode->hasKeyrefs = 1;
! 23181: /*
! 23182: * Lookup the referenced augmented IDC info.
! 23183: */
! 23184: aidc = vctxt->aidcs;
! 23185: while (aidc != NULL) {
! 23186: if (aidc->def == refIdc)
! 23187: break;
! 23188: aidc = aidc->next;
! 23189: }
! 23190: if (aidc == NULL) {
! 23191: VERROR_INT("xmlSchemaIDCRegisterMatchers",
! 23192: "Could not find an augmented IDC item for an IDC "
! 23193: "definition");
! 23194: return (-1);
! 23195: }
! 23196: if ((aidc->keyrefDepth == -1) ||
! 23197: (vctxt->depth < aidc->keyrefDepth))
! 23198: aidc->keyrefDepth = vctxt->depth;
! 23199: }
! 23200: }
! 23201: /*
! 23202: * Lookup the augmented IDC item for the IDC definition.
! 23203: */
! 23204: aidc = vctxt->aidcs;
! 23205: while (aidc != NULL) {
! 23206: if (aidc->def == idc)
! 23207: break;
! 23208: aidc = aidc->next;
! 23209: }
! 23210: if (aidc == NULL) {
! 23211: VERROR_INT("xmlSchemaIDCRegisterMatchers",
! 23212: "Could not find an augmented IDC item for an IDC definition");
! 23213: return (-1);
! 23214: }
! 23215: /*
! 23216: * Create an IDC matcher for every IDC definition.
! 23217: */
! 23218: if (vctxt->idcMatcherCache != NULL) {
! 23219: /*
! 23220: * Reuse a cached matcher.
! 23221: */
! 23222: matcher = vctxt->idcMatcherCache;
! 23223: vctxt->idcMatcherCache = matcher->nextCached;
! 23224: matcher->nextCached = NULL;
! 23225: } else {
! 23226: matcher = (xmlSchemaIDCMatcherPtr)
! 23227: xmlMalloc(sizeof(xmlSchemaIDCMatcher));
! 23228: if (matcher == NULL) {
! 23229: xmlSchemaVErrMemory(vctxt,
! 23230: "allocating an IDC matcher", NULL);
! 23231: return (-1);
! 23232: }
! 23233: memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
! 23234: }
! 23235: if (last == NULL)
! 23236: vctxt->inode->idcMatchers = matcher;
! 23237: else
! 23238: last->next = matcher;
! 23239: last = matcher;
! 23240:
! 23241: matcher->type = IDC_MATCHER;
! 23242: matcher->depth = vctxt->depth;
! 23243: matcher->aidc = aidc;
! 23244: matcher->idcType = aidc->def->type;
! 23245: #ifdef DEBUG_IDC
! 23246: xmlGenericError(xmlGenericErrorContext, "IDC: register matcher\n");
! 23247: #endif
! 23248: /*
! 23249: * Init the automaton state object.
! 23250: */
! 23251: if (xmlSchemaIDCAddStateObject(vctxt, matcher,
! 23252: idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
! 23253: return (-1);
! 23254:
! 23255: idc = idc->next;
! 23256: } while (idc != NULL);
! 23257: return (0);
! 23258: }
! 23259:
! 23260: static int
! 23261: xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
! 23262: xmlSchemaNodeInfoPtr ielem)
! 23263: {
! 23264: xmlSchemaPSVIIDCBindingPtr bind;
! 23265: int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
! 23266: xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
! 23267: xmlSchemaPSVIIDCNodePtr *targets, *dupls;
! 23268:
! 23269: xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
! 23270: /* vctxt->createIDCNodeTables */
! 23271: while (matcher != NULL) {
! 23272: /*
! 23273: * Skip keyref IDCs and empty IDC target-lists.
! 23274: */
! 23275: if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
! 23276: WXS_ILIST_IS_EMPTY(matcher->targets))
! 23277: {
! 23278: matcher = matcher->next;
! 23279: continue;
! 23280: }
! 23281: /*
! 23282: * If we _want_ the IDC node-table to be created in any case
! 23283: * then do so. Otherwise create them only if keyrefs need them.
! 23284: */
! 23285: if ((! vctxt->createIDCNodeTables) &&
! 23286: ((matcher->aidc->keyrefDepth == -1) ||
! 23287: (matcher->aidc->keyrefDepth > vctxt->depth)))
! 23288: {
! 23289: matcher = matcher->next;
! 23290: continue;
! 23291: }
! 23292: /*
! 23293: * Get/create the IDC binding on this element for the IDC definition.
! 23294: */
! 23295: bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
! 23296:
! 23297: if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
! 23298: dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
! 23299: nbDupls = bind->dupls->nbItems;
! 23300: } else {
! 23301: dupls = NULL;
! 23302: nbDupls = 0;
! 23303: }
! 23304: if (bind->nodeTable != NULL) {
! 23305: nbNodeTable = bind->nbNodes;
! 23306: } else {
! 23307: nbNodeTable = 0;
! 23308: }
! 23309:
! 23310: if ((nbNodeTable == 0) && (nbDupls == 0)) {
! 23311: /*
! 23312: * Transfer all IDC target-nodes to the IDC node-table.
! 23313: */
! 23314: bind->nodeTable =
! 23315: (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
! 23316: bind->sizeNodes = matcher->targets->sizeItems;
! 23317: bind->nbNodes = matcher->targets->nbItems;
! 23318:
! 23319: matcher->targets->items = NULL;
! 23320: matcher->targets->sizeItems = 0;
! 23321: matcher->targets->nbItems = 0;
! 23322: } else {
! 23323: /*
! 23324: * Compare the key-sequences and add to the IDC node-table.
! 23325: */
! 23326: nbTargets = matcher->targets->nbItems;
! 23327: targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
! 23328: nbFields = matcher->aidc->def->nbFields;
! 23329: i = 0;
! 23330: do {
! 23331: keys = targets[i]->keys;
! 23332: if (nbDupls) {
! 23333: /*
! 23334: * Search in already found duplicates first.
! 23335: */
! 23336: j = 0;
! 23337: do {
! 23338: if (nbFields == 1) {
! 23339: res = xmlSchemaAreValuesEqual(keys[0]->val,
! 23340: dupls[j]->keys[0]->val);
! 23341: if (res == -1)
! 23342: goto internal_error;
! 23343: if (res == 1) {
! 23344: /*
! 23345: * Equal key-sequence.
! 23346: */
! 23347: goto next_target;
! 23348: }
! 23349: } else {
! 23350: res = 0;
! 23351: ntkeys = dupls[j]->keys;
! 23352: for (k = 0; k < nbFields; k++) {
! 23353: res = xmlSchemaAreValuesEqual(keys[k]->val,
! 23354: ntkeys[k]->val);
! 23355: if (res == -1)
! 23356: goto internal_error;
! 23357: if (res == 0) {
! 23358: /*
! 23359: * One of the keys differs.
! 23360: */
! 23361: break;
! 23362: }
! 23363: }
! 23364: if (res == 1) {
! 23365: /*
! 23366: * Equal key-sequence found.
! 23367: */
! 23368: goto next_target;
! 23369: }
! 23370: }
! 23371: j++;
! 23372: } while (j < nbDupls);
! 23373: }
! 23374: if (nbNodeTable) {
! 23375: j = 0;
! 23376: do {
! 23377: if (nbFields == 1) {
! 23378: res = xmlSchemaAreValuesEqual(keys[0]->val,
! 23379: bind->nodeTable[j]->keys[0]->val);
! 23380: if (res == -1)
! 23381: goto internal_error;
! 23382: if (res == 0) {
! 23383: /*
! 23384: * The key-sequence differs.
! 23385: */
! 23386: goto next_node_table_entry;
! 23387: }
! 23388: } else {
! 23389: res = 0;
! 23390: ntkeys = bind->nodeTable[j]->keys;
! 23391: for (k = 0; k < nbFields; k++) {
! 23392: res = xmlSchemaAreValuesEqual(keys[k]->val,
! 23393: ntkeys[k]->val);
! 23394: if (res == -1)
! 23395: goto internal_error;
! 23396: if (res == 0) {
! 23397: /*
! 23398: * One of the keys differs.
! 23399: */
! 23400: goto next_node_table_entry;
! 23401: }
! 23402: }
! 23403: }
! 23404: /*
! 23405: * Add the duplicate to the list of duplicates.
! 23406: */
! 23407: if (bind->dupls == NULL) {
! 23408: bind->dupls = xmlSchemaItemListCreate();
! 23409: if (bind->dupls == NULL)
! 23410: goto internal_error;
! 23411: }
! 23412: if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
! 23413: goto internal_error;
! 23414: /*
! 23415: * Remove the duplicate entry from the IDC node-table.
! 23416: */
! 23417: bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
! 23418: bind->nbNodes--;
! 23419:
! 23420: goto next_target;
! 23421:
! 23422: next_node_table_entry:
! 23423: j++;
! 23424: } while (j < nbNodeTable);
! 23425: }
! 23426: /*
! 23427: * If everything is fine, then add the IDC target-node to
! 23428: * the IDC node-table.
! 23429: */
! 23430: if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
! 23431: goto internal_error;
! 23432:
! 23433: next_target:
! 23434: i++;
! 23435: } while (i < nbTargets);
! 23436: }
! 23437: matcher = matcher->next;
! 23438: }
! 23439: return(0);
! 23440:
! 23441: internal_error:
! 23442: return(-1);
! 23443: }
! 23444:
! 23445: /**
! 23446: * xmlSchemaBubbleIDCNodeTables:
! 23447: * @depth: the current tree depth
! 23448: *
! 23449: * Merges IDC bindings of an element at @depth into the corresponding IDC
! 23450: * bindings of its parent element. If a duplicate note-table entry is found,
! 23451: * both, the parent node-table entry and child entry are discarded from the
! 23452: * node-table of the parent.
! 23453: *
! 23454: * Returns 0 if OK and -1 on internal errors.
! 23455: */
! 23456: static int
! 23457: xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
! 23458: {
! 23459: xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
! 23460: xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
! 23461: xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
! 23462: xmlSchemaIDCAugPtr aidc;
! 23463: int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
! 23464:
! 23465: bind = vctxt->inode->idcTable;
! 23466: if (bind == NULL) {
! 23467: /* Fine, no table, no bubbles. */
! 23468: return (0);
! 23469: }
! 23470:
! 23471: parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
! 23472: /*
! 23473: * Walk all bindings; create new or add to existing bindings.
! 23474: * Remove duplicate key-sequences.
! 23475: */
! 23476: while (bind != NULL) {
! 23477:
! 23478: if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
! 23479: goto next_binding;
! 23480: /*
! 23481: * Check if the key/unique IDC table needs to be bubbled.
! 23482: */
! 23483: if (! vctxt->createIDCNodeTables) {
! 23484: aidc = vctxt->aidcs;
! 23485: do {
! 23486: if (aidc->def == bind->definition) {
! 23487: if ((aidc->keyrefDepth == -1) ||
! 23488: (aidc->keyrefDepth >= vctxt->depth)) {
! 23489: goto next_binding;
! 23490: }
! 23491: break;
! 23492: }
! 23493: aidc = aidc->next;
! 23494: } while (aidc != NULL);
! 23495: }
! 23496:
! 23497: if (parTable != NULL)
! 23498: parBind = *parTable;
! 23499: /*
! 23500: * Search a matching parent binding for the
! 23501: * IDC definition.
! 23502: */
! 23503: while (parBind != NULL) {
! 23504: if (parBind->definition == bind->definition)
! 23505: break;
! 23506: parBind = parBind->next;
! 23507: }
! 23508:
! 23509: if (parBind != NULL) {
! 23510: /*
! 23511: * Compare every node-table entry of the child node,
! 23512: * i.e. the key-sequence within, ...
! 23513: */
! 23514: oldNum = parBind->nbNodes; /* Skip newly added items. */
! 23515:
! 23516: if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
! 23517: oldDupls = parBind->dupls->nbItems;
! 23518: dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
! 23519: } else {
! 23520: dupls = NULL;
! 23521: oldDupls = 0;
! 23522: }
! 23523:
! 23524: parNodes = parBind->nodeTable;
! 23525: nbFields = bind->definition->nbFields;
! 23526:
! 23527: for (i = 0; i < bind->nbNodes; i++) {
! 23528: node = bind->nodeTable[i];
! 23529: if (node == NULL)
! 23530: continue;
! 23531: /*
! 23532: * ...with every key-sequence of the parent node, already
! 23533: * evaluated to be a duplicate key-sequence.
! 23534: */
! 23535: if (oldDupls) {
! 23536: j = 0;
! 23537: while (j < oldDupls) {
! 23538: if (nbFields == 1) {
! 23539: ret = xmlSchemaAreValuesEqual(
! 23540: node->keys[0]->val,
! 23541: dupls[j]->keys[0]->val);
! 23542: if (ret == -1)
! 23543: goto internal_error;
! 23544: if (ret == 0) {
! 23545: j++;
! 23546: continue;
! 23547: }
! 23548: } else {
! 23549: parNode = dupls[j];
! 23550: for (k = 0; k < nbFields; k++) {
! 23551: ret = xmlSchemaAreValuesEqual(
! 23552: node->keys[k]->val,
! 23553: parNode->keys[k]->val);
! 23554: if (ret == -1)
! 23555: goto internal_error;
! 23556: if (ret == 0)
! 23557: break;
! 23558: }
! 23559: }
! 23560: if (ret == 1)
! 23561: /* Duplicate found. */
! 23562: break;
! 23563: j++;
! 23564: }
! 23565: if (j != oldDupls) {
! 23566: /* Duplicate found. Skip this entry. */
! 23567: continue;
! 23568: }
! 23569: }
! 23570: /*
! 23571: * ... and with every key-sequence of the parent node.
! 23572: */
! 23573: if (oldNum) {
! 23574: j = 0;
! 23575: while (j < oldNum) {
! 23576: parNode = parNodes[j];
! 23577: if (nbFields == 1) {
! 23578: ret = xmlSchemaAreValuesEqual(
! 23579: node->keys[0]->val,
! 23580: parNode->keys[0]->val);
! 23581: if (ret == -1)
! 23582: goto internal_error;
! 23583: if (ret == 0) {
! 23584: j++;
! 23585: continue;
! 23586: }
! 23587: } else {
! 23588: for (k = 0; k < nbFields; k++) {
! 23589: ret = xmlSchemaAreValuesEqual(
! 23590: node->keys[k]->val,
! 23591: parNode->keys[k]->val);
! 23592: if (ret == -1)
! 23593: goto internal_error;
! 23594: if (ret == 0)
! 23595: break;
! 23596: }
! 23597: }
! 23598: if (ret == 1)
! 23599: /* Duplicate found. */
! 23600: break;
! 23601: j++;
! 23602: }
! 23603: if (j != oldNum) {
! 23604: /*
! 23605: * Handle duplicates. Move the duplicate in
! 23606: * the parent's node-table to the list of
! 23607: * duplicates.
! 23608: */
! 23609: oldNum--;
! 23610: parBind->nbNodes--;
! 23611: /*
! 23612: * Move last old item to pos of duplicate.
! 23613: */
! 23614: parNodes[j] = parNodes[oldNum];
! 23615:
! 23616: if (parBind->nbNodes != oldNum) {
! 23617: /*
! 23618: * If new items exist, move last new item to
! 23619: * last of old items.
! 23620: */
! 23621: parNodes[oldNum] =
! 23622: parNodes[parBind->nbNodes];
! 23623: }
! 23624: if (parBind->dupls == NULL) {
! 23625: parBind->dupls = xmlSchemaItemListCreate();
! 23626: if (parBind->dupls == NULL)
! 23627: goto internal_error;
! 23628: }
! 23629: xmlSchemaItemListAdd(parBind->dupls, parNode);
! 23630: } else {
! 23631: /*
! 23632: * Add the node-table entry (node and key-sequence) of
! 23633: * the child node to the node table of the parent node.
! 23634: */
! 23635: if (parBind->nodeTable == NULL) {
! 23636: parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
! 23637: xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
! 23638: if (parBind->nodeTable == NULL) {
! 23639: xmlSchemaVErrMemory(NULL,
! 23640: "allocating IDC list of node-table items", NULL);
! 23641: goto internal_error;
! 23642: }
! 23643: parBind->sizeNodes = 1;
! 23644: } else if (parBind->nbNodes >= parBind->sizeNodes) {
! 23645: parBind->sizeNodes *= 2;
! 23646: parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
! 23647: xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
! 23648: sizeof(xmlSchemaPSVIIDCNodePtr));
! 23649: if (parBind->nodeTable == NULL) {
! 23650: xmlSchemaVErrMemory(NULL,
! 23651: "re-allocating IDC list of node-table items", NULL);
! 23652: goto internal_error;
! 23653: }
! 23654: }
! 23655: parNodes = parBind->nodeTable;
! 23656: /*
! 23657: * Append the new node-table entry to the 'new node-table
! 23658: * entries' section.
! 23659: */
! 23660: parNodes[parBind->nbNodes++] = node;
! 23661: }
! 23662:
! 23663: }
! 23664:
! 23665: }
! 23666: } else {
! 23667: /*
! 23668: * No binding for the IDC was found: create a new one and
! 23669: * copy all node-tables.
! 23670: */
! 23671: parBind = xmlSchemaIDCNewBinding(bind->definition);
! 23672: if (parBind == NULL)
! 23673: goto internal_error;
! 23674:
! 23675: /*
! 23676: * TODO: Hmm, how to optimize the initial number of
! 23677: * allocated entries?
! 23678: */
! 23679: if (bind->nbNodes != 0) {
! 23680: /*
! 23681: * Add all IDC node-table entries.
! 23682: */
! 23683: if (! vctxt->psviExposeIDCNodeTables) {
! 23684: /*
! 23685: * Just move the entries.
! 23686: * NOTE: this is quite save here, since
! 23687: * all the keyref lookups have already been
! 23688: * performed.
! 23689: */
! 23690: parBind->nodeTable = bind->nodeTable;
! 23691: bind->nodeTable = NULL;
! 23692: parBind->sizeNodes = bind->sizeNodes;
! 23693: bind->sizeNodes = 0;
! 23694: parBind->nbNodes = bind->nbNodes;
! 23695: bind->nbNodes = 0;
! 23696: } else {
! 23697: /*
! 23698: * Copy the entries.
! 23699: */
! 23700: parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
! 23701: xmlMalloc(bind->nbNodes *
! 23702: sizeof(xmlSchemaPSVIIDCNodePtr));
! 23703: if (parBind->nodeTable == NULL) {
! 23704: xmlSchemaVErrMemory(NULL,
! 23705: "allocating an array of IDC node-table "
! 23706: "items", NULL);
! 23707: xmlSchemaIDCFreeBinding(parBind);
! 23708: goto internal_error;
! 23709: }
! 23710: parBind->sizeNodes = bind->nbNodes;
! 23711: parBind->nbNodes = bind->nbNodes;
! 23712: memcpy(parBind->nodeTable, bind->nodeTable,
! 23713: bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
! 23714: }
! 23715: }
! 23716: if (bind->dupls) {
! 23717: /*
! 23718: * Move the duplicates.
! 23719: */
! 23720: if (parBind->dupls != NULL)
! 23721: xmlSchemaItemListFree(parBind->dupls);
! 23722: parBind->dupls = bind->dupls;
! 23723: bind->dupls = NULL;
! 23724: }
! 23725: if (parTable != NULL) {
! 23726: if (*parTable == NULL)
! 23727: *parTable = parBind;
! 23728: else {
! 23729: parBind->next = *parTable;
! 23730: *parTable = parBind;
! 23731: }
! 23732: }
! 23733: }
! 23734:
! 23735: next_binding:
! 23736: bind = bind->next;
! 23737: }
! 23738: return (0);
! 23739:
! 23740: internal_error:
! 23741: return(-1);
! 23742: }
! 23743:
! 23744: /**
! 23745: * xmlSchemaCheckCVCIDCKeyRef:
! 23746: * @vctxt: the WXS validation context
! 23747: * @elemDecl: the element declaration
! 23748: *
! 23749: * Check the cvc-idc-keyref constraints.
! 23750: */
! 23751: static int
! 23752: xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
! 23753: {
! 23754: xmlSchemaIDCMatcherPtr matcher;
! 23755: xmlSchemaPSVIIDCBindingPtr bind;
! 23756:
! 23757: matcher = vctxt->inode->idcMatchers;
! 23758: /*
! 23759: * Find a keyref.
! 23760: */
! 23761: while (matcher != NULL) {
! 23762: if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
! 23763: matcher->targets &&
! 23764: matcher->targets->nbItems)
! 23765: {
! 23766: int i, j, k, res, nbFields, hasDupls;
! 23767: xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
! 23768: xmlSchemaPSVIIDCNodePtr refNode = NULL;
! 23769:
! 23770: nbFields = matcher->aidc->def->nbFields;
! 23771:
! 23772: /*
! 23773: * Find the IDC node-table for the referenced IDC key/unique.
! 23774: */
! 23775: bind = vctxt->inode->idcTable;
! 23776: while (bind != NULL) {
! 23777: if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
! 23778: bind->definition)
! 23779: break;
! 23780: bind = bind->next;
! 23781: }
! 23782: hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
! 23783: /*
! 23784: * Search for a matching key-sequences.
! 23785: */
! 23786: for (i = 0; i < matcher->targets->nbItems; i++) {
! 23787: res = 0;
! 23788: refNode = matcher->targets->items[i];
! 23789: if (bind != NULL) {
! 23790: refKeys = refNode->keys;
! 23791: for (j = 0; j < bind->nbNodes; j++) {
! 23792: keys = bind->nodeTable[j]->keys;
! 23793: for (k = 0; k < nbFields; k++) {
! 23794: res = xmlSchemaAreValuesEqual(keys[k]->val,
! 23795: refKeys[k]->val);
! 23796: if (res == 0)
! 23797: break;
! 23798: else if (res == -1) {
! 23799: return (-1);
! 23800: }
! 23801: }
! 23802: if (res == 1) {
! 23803: /*
! 23804: * Match found.
! 23805: */
! 23806: break;
! 23807: }
! 23808: }
! 23809: if ((res == 0) && hasDupls) {
! 23810: /*
! 23811: * Search in duplicates
! 23812: */
! 23813: for (j = 0; j < bind->dupls->nbItems; j++) {
! 23814: keys = ((xmlSchemaPSVIIDCNodePtr)
! 23815: bind->dupls->items[j])->keys;
! 23816: for (k = 0; k < nbFields; k++) {
! 23817: res = xmlSchemaAreValuesEqual(keys[k]->val,
! 23818: refKeys[k]->val);
! 23819: if (res == 0)
! 23820: break;
! 23821: else if (res == -1) {
! 23822: return (-1);
! 23823: }
! 23824: }
! 23825: if (res == 1) {
! 23826: /*
! 23827: * Match in duplicates found.
! 23828: */
! 23829: xmlChar *str = NULL, *strB = NULL;
! 23830: xmlSchemaKeyrefErr(vctxt,
! 23831: XML_SCHEMAV_CVC_IDC, refNode,
! 23832: (xmlSchemaTypePtr) matcher->aidc->def,
! 23833: "More than one match found for "
! 23834: "key-sequence %s of keyref '%s'",
! 23835: xmlSchemaFormatIDCKeySequence(vctxt, &str,
! 23836: refNode->keys, nbFields),
! 23837: xmlSchemaGetComponentQName(&strB,
! 23838: matcher->aidc->def));
! 23839: FREE_AND_NULL(str);
! 23840: FREE_AND_NULL(strB);
! 23841: break;
! 23842: }
! 23843: }
! 23844: }
! 23845: }
! 23846:
! 23847: if (res == 0) {
! 23848: xmlChar *str = NULL, *strB = NULL;
! 23849: xmlSchemaKeyrefErr(vctxt,
! 23850: XML_SCHEMAV_CVC_IDC, refNode,
! 23851: (xmlSchemaTypePtr) matcher->aidc->def,
! 23852: "No match found for key-sequence %s of keyref '%s'",
! 23853: xmlSchemaFormatIDCKeySequence(vctxt, &str,
! 23854: refNode->keys, nbFields),
! 23855: xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
! 23856: FREE_AND_NULL(str);
! 23857: FREE_AND_NULL(strB);
! 23858: }
! 23859: }
! 23860: }
! 23861: matcher = matcher->next;
! 23862: }
! 23863: /* TODO: Return an error if any error encountered. */
! 23864: return (0);
! 23865: }
! 23866:
! 23867: /************************************************************************
! 23868: * *
! 23869: * XML Reader validation code *
! 23870: * *
! 23871: ************************************************************************/
! 23872:
! 23873: static xmlSchemaAttrInfoPtr
! 23874: xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
! 23875: {
! 23876: xmlSchemaAttrInfoPtr iattr;
! 23877: /*
! 23878: * Grow/create list of attribute infos.
! 23879: */
! 23880: if (vctxt->attrInfos == NULL) {
! 23881: vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
! 23882: xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
! 23883: vctxt->sizeAttrInfos = 1;
! 23884: if (vctxt->attrInfos == NULL) {
! 23885: xmlSchemaVErrMemory(vctxt,
! 23886: "allocating attribute info list", NULL);
! 23887: return (NULL);
! 23888: }
! 23889: } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
! 23890: vctxt->sizeAttrInfos++;
! 23891: vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
! 23892: xmlRealloc(vctxt->attrInfos,
! 23893: vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
! 23894: if (vctxt->attrInfos == NULL) {
! 23895: xmlSchemaVErrMemory(vctxt,
! 23896: "re-allocating attribute info list", NULL);
! 23897: return (NULL);
! 23898: }
! 23899: } else {
! 23900: iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
! 23901: if (iattr->localName != NULL) {
! 23902: VERROR_INT("xmlSchemaGetFreshAttrInfo",
! 23903: "attr info not cleared");
! 23904: return (NULL);
! 23905: }
! 23906: iattr->nodeType = XML_ATTRIBUTE_NODE;
! 23907: return (iattr);
! 23908: }
! 23909: /*
! 23910: * Create an attribute info.
! 23911: */
! 23912: iattr = (xmlSchemaAttrInfoPtr)
! 23913: xmlMalloc(sizeof(xmlSchemaAttrInfo));
! 23914: if (iattr == NULL) {
! 23915: xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
! 23916: return (NULL);
! 23917: }
! 23918: memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
! 23919: iattr->nodeType = XML_ATTRIBUTE_NODE;
! 23920: vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
! 23921:
! 23922: return (iattr);
! 23923: }
! 23924:
! 23925: static int
! 23926: xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
! 23927: xmlNodePtr attrNode,
! 23928: int nodeLine,
! 23929: const xmlChar *localName,
! 23930: const xmlChar *nsName,
! 23931: int ownedNames,
! 23932: xmlChar *value,
! 23933: int ownedValue)
! 23934: {
! 23935: xmlSchemaAttrInfoPtr attr;
! 23936:
! 23937: attr = xmlSchemaGetFreshAttrInfo(vctxt);
! 23938: if (attr == NULL) {
! 23939: VERROR_INT("xmlSchemaPushAttribute",
! 23940: "calling xmlSchemaGetFreshAttrInfo()");
! 23941: return (-1);
! 23942: }
! 23943: attr->node = attrNode;
! 23944: attr->nodeLine = nodeLine;
! 23945: attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
! 23946: attr->localName = localName;
! 23947: attr->nsName = nsName;
! 23948: if (ownedNames)
! 23949: attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
! 23950: /*
! 23951: * Evaluate if it's an XSI attribute.
! 23952: */
! 23953: if (nsName != NULL) {
! 23954: if (xmlStrEqual(localName, BAD_CAST "nil")) {
! 23955: if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
! 23956: attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
! 23957: }
! 23958: } else if (xmlStrEqual(localName, BAD_CAST "type")) {
! 23959: if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
! 23960: attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
! 23961: }
! 23962: } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
! 23963: if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
! 23964: attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
! 23965: }
! 23966: } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
! 23967: if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
! 23968: attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
! 23969: }
! 23970: } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
! 23971: attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
! 23972: }
! 23973: }
! 23974: attr->value = value;
! 23975: if (ownedValue)
! 23976: attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
! 23977: if (attr->metaType != 0)
! 23978: attr->state = XML_SCHEMAS_ATTR_META;
! 23979: return (0);
! 23980: }
! 23981:
! 23982: /**
! 23983: * xmlSchemaClearElemInfo:
! 23984: * @vctxt: the WXS validation context
! 23985: * @ielem: the element information item
! 23986: */
! 23987: static void
! 23988: xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
! 23989: xmlSchemaNodeInfoPtr ielem)
! 23990: {
! 23991: ielem->hasKeyrefs = 0;
! 23992: ielem->appliedXPath = 0;
! 23993: if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
! 23994: FREE_AND_NULL(ielem->localName);
! 23995: FREE_AND_NULL(ielem->nsName);
! 23996: } else {
! 23997: ielem->localName = NULL;
! 23998: ielem->nsName = NULL;
! 23999: }
! 24000: if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
! 24001: FREE_AND_NULL(ielem->value);
! 24002: } else {
! 24003: ielem->value = NULL;
! 24004: }
! 24005: if (ielem->val != NULL) {
! 24006: /*
! 24007: * PSVI TODO: Be careful not to free it when the value is
! 24008: * exposed via PSVI.
! 24009: */
! 24010: xmlSchemaFreeValue(ielem->val);
! 24011: ielem->val = NULL;
! 24012: }
! 24013: if (ielem->idcMatchers != NULL) {
! 24014: /*
! 24015: * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
! 24016: * Does it work?
! 24017: */
! 24018: xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
! 24019: #if 0
! 24020: xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
! 24021: #endif
! 24022: ielem->idcMatchers = NULL;
! 24023: }
! 24024: if (ielem->idcTable != NULL) {
! 24025: /*
! 24026: * OPTIMIZE TODO: Use a pool of IDC tables??.
! 24027: */
! 24028: xmlSchemaIDCFreeIDCTable(ielem->idcTable);
! 24029: ielem->idcTable = NULL;
! 24030: }
! 24031: if (ielem->regexCtxt != NULL) {
! 24032: xmlRegFreeExecCtxt(ielem->regexCtxt);
! 24033: ielem->regexCtxt = NULL;
! 24034: }
! 24035: if (ielem->nsBindings != NULL) {
! 24036: xmlFree((xmlChar **)ielem->nsBindings);
! 24037: ielem->nsBindings = NULL;
! 24038: ielem->nbNsBindings = 0;
! 24039: ielem->sizeNsBindings = 0;
! 24040: }
! 24041: }
! 24042:
! 24043: /**
! 24044: * xmlSchemaGetFreshElemInfo:
! 24045: * @vctxt: the schema validation context
! 24046: *
! 24047: * Creates/reuses and initializes the element info item for
! 24048: * the currect tree depth.
! 24049: *
! 24050: * Returns the element info item or NULL on API or internal errors.
! 24051: */
! 24052: static xmlSchemaNodeInfoPtr
! 24053: xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
! 24054: {
! 24055: xmlSchemaNodeInfoPtr info = NULL;
! 24056:
! 24057: if (vctxt->depth > vctxt->sizeElemInfos) {
! 24058: VERROR_INT("xmlSchemaGetFreshElemInfo",
! 24059: "inconsistent depth encountered");
! 24060: return (NULL);
! 24061: }
! 24062: if (vctxt->elemInfos == NULL) {
! 24063: vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
! 24064: xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
! 24065: if (vctxt->elemInfos == NULL) {
! 24066: xmlSchemaVErrMemory(vctxt,
! 24067: "allocating the element info array", NULL);
! 24068: return (NULL);
! 24069: }
! 24070: memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
! 24071: vctxt->sizeElemInfos = 10;
! 24072: } else if (vctxt->sizeElemInfos <= vctxt->depth) {
! 24073: int i = vctxt->sizeElemInfos;
! 24074:
! 24075: vctxt->sizeElemInfos *= 2;
! 24076: vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
! 24077: xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
! 24078: sizeof(xmlSchemaNodeInfoPtr));
! 24079: if (vctxt->elemInfos == NULL) {
! 24080: xmlSchemaVErrMemory(vctxt,
! 24081: "re-allocating the element info array", NULL);
! 24082: return (NULL);
! 24083: }
! 24084: /*
! 24085: * We need the new memory to be NULLed.
! 24086: * TODO: Use memset instead?
! 24087: */
! 24088: for (; i < vctxt->sizeElemInfos; i++)
! 24089: vctxt->elemInfos[i] = NULL;
! 24090: } else
! 24091: info = vctxt->elemInfos[vctxt->depth];
! 24092:
! 24093: if (info == NULL) {
! 24094: info = (xmlSchemaNodeInfoPtr)
! 24095: xmlMalloc(sizeof(xmlSchemaNodeInfo));
! 24096: if (info == NULL) {
! 24097: xmlSchemaVErrMemory(vctxt,
! 24098: "allocating an element info", NULL);
! 24099: return (NULL);
! 24100: }
! 24101: vctxt->elemInfos[vctxt->depth] = info;
! 24102: } else {
! 24103: if (info->localName != NULL) {
! 24104: VERROR_INT("xmlSchemaGetFreshElemInfo",
! 24105: "elem info has not been cleared");
! 24106: return (NULL);
! 24107: }
! 24108: }
! 24109: memset(info, 0, sizeof(xmlSchemaNodeInfo));
! 24110: info->nodeType = XML_ELEMENT_NODE;
! 24111: info->depth = vctxt->depth;
! 24112:
! 24113: return (info);
! 24114: }
! 24115:
! 24116: #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
! 24117: #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
! 24118: #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
! 24119:
! 24120: static int
! 24121: xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
! 24122: xmlNodePtr node,
! 24123: xmlSchemaTypePtr type,
! 24124: xmlSchemaValType valType,
! 24125: const xmlChar * value,
! 24126: xmlSchemaValPtr val,
! 24127: unsigned long length,
! 24128: int fireErrors)
! 24129: {
! 24130: int ret, error = 0;
! 24131:
! 24132: xmlSchemaTypePtr tmpType;
! 24133: xmlSchemaFacetLinkPtr facetLink;
! 24134: xmlSchemaFacetPtr facet;
! 24135: unsigned long len = 0;
! 24136: xmlSchemaWhitespaceValueType ws;
! 24137:
! 24138: /*
! 24139: * In Libxml2, derived built-in types have currently no explicit facets.
! 24140: */
! 24141: if (type->type == XML_SCHEMA_TYPE_BASIC)
! 24142: return (0);
! 24143:
! 24144: /*
! 24145: * NOTE: Do not jump away, if the facetSet of the given type is
! 24146: * empty: until now, "pattern" and "enumeration" facets of the
! 24147: * *base types* need to be checked as well.
! 24148: */
! 24149: if (type->facetSet == NULL)
! 24150: goto pattern_and_enum;
! 24151:
! 24152: if (! WXS_IS_ATOMIC(type)) {
! 24153: if (WXS_IS_LIST(type))
! 24154: goto WXS_IS_LIST;
! 24155: else
! 24156: goto pattern_and_enum;
! 24157: }
! 24158: /*
! 24159: * Whitespace handling is only of importance for string-based
! 24160: * types.
! 24161: */
! 24162: tmpType = xmlSchemaGetPrimitiveType(type);
! 24163: if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
! 24164: WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
! 24165: ws = xmlSchemaGetWhiteSpaceFacetValue(type);
! 24166: } else
! 24167: ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
! 24168: /*
! 24169: * If the value was not computed (for string or
! 24170: * anySimpleType based types), then use the provided
! 24171: * type.
! 24172: */
! 24173: if (val == NULL)
! 24174: valType = valType;
! 24175: else
! 24176: valType = xmlSchemaGetValType(val);
! 24177:
! 24178: ret = 0;
! 24179: for (facetLink = type->facetSet; facetLink != NULL;
! 24180: facetLink = facetLink->next) {
! 24181: /*
! 24182: * Skip the pattern "whiteSpace": it is used to
! 24183: * format the character content beforehand.
! 24184: */
! 24185: switch (facetLink->facet->type) {
! 24186: case XML_SCHEMA_FACET_WHITESPACE:
! 24187: case XML_SCHEMA_FACET_PATTERN:
! 24188: case XML_SCHEMA_FACET_ENUMERATION:
! 24189: continue;
! 24190: case XML_SCHEMA_FACET_LENGTH:
! 24191: case XML_SCHEMA_FACET_MINLENGTH:
! 24192: case XML_SCHEMA_FACET_MAXLENGTH:
! 24193: ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
! 24194: valType, value, val, &len, ws);
! 24195: break;
! 24196: default:
! 24197: ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
! 24198: valType, value, val, ws);
! 24199: break;
! 24200: }
! 24201: if (ret < 0) {
! 24202: AERROR_INT("xmlSchemaValidateFacets",
! 24203: "validating against a atomic type facet");
! 24204: return (-1);
! 24205: } else if (ret > 0) {
! 24206: if (fireErrors)
! 24207: xmlSchemaFacetErr(actxt, ret, node,
! 24208: value, len, type, facetLink->facet, NULL, NULL, NULL);
! 24209: else
! 24210: return (ret);
! 24211: if (error == 0)
! 24212: error = ret;
! 24213: }
! 24214: ret = 0;
! 24215: }
! 24216:
! 24217: WXS_IS_LIST:
! 24218: if (! WXS_IS_LIST(type))
! 24219: goto pattern_and_enum;
! 24220: /*
! 24221: * "length", "minLength" and "maxLength" of list types.
! 24222: */
! 24223: ret = 0;
! 24224: for (facetLink = type->facetSet; facetLink != NULL;
! 24225: facetLink = facetLink->next) {
! 24226:
! 24227: switch (facetLink->facet->type) {
! 24228: case XML_SCHEMA_FACET_LENGTH:
! 24229: case XML_SCHEMA_FACET_MINLENGTH:
! 24230: case XML_SCHEMA_FACET_MAXLENGTH:
! 24231: ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
! 24232: value, length, NULL);
! 24233: break;
! 24234: default:
! 24235: continue;
! 24236: }
! 24237: if (ret < 0) {
! 24238: AERROR_INT("xmlSchemaValidateFacets",
! 24239: "validating against a list type facet");
! 24240: return (-1);
! 24241: } else if (ret > 0) {
! 24242: if (fireErrors)
! 24243: xmlSchemaFacetErr(actxt, ret, node,
! 24244: value, length, type, facetLink->facet, NULL, NULL, NULL);
! 24245: else
! 24246: return (ret);
! 24247: if (error == 0)
! 24248: error = ret;
! 24249: }
! 24250: ret = 0;
! 24251: }
! 24252:
! 24253: pattern_and_enum:
! 24254: if (error >= 0) {
! 24255: int found = 0;
! 24256: /*
! 24257: * Process enumerations. Facet values are in the value space
! 24258: * of the defining type's base type. This seems to be a bug in the
! 24259: * XML Schema 1.0 spec. Use the whitespace type of the base type.
! 24260: * Only the first set of enumerations in the ancestor-or-self axis
! 24261: * is used for validation.
! 24262: */
! 24263: ret = 0;
! 24264: tmpType = type;
! 24265: do {
! 24266: for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
! 24267: if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
! 24268: continue;
! 24269: found = 1;
! 24270: ret = xmlSchemaAreValuesEqual(facet->val, val);
! 24271: if (ret == 1)
! 24272: break;
! 24273: else if (ret < 0) {
! 24274: AERROR_INT("xmlSchemaValidateFacets",
! 24275: "validating against an enumeration facet");
! 24276: return (-1);
! 24277: }
! 24278: }
! 24279: if (ret != 0)
! 24280: break;
! 24281: /*
! 24282: * Break on the first set of enumerations. Any additional
! 24283: * enumerations which might be existent on the ancestors
! 24284: * of the current type are restricted by this set; thus
! 24285: * *must* *not* be taken into account.
! 24286: */
! 24287: if (found)
! 24288: break;
! 24289: tmpType = tmpType->baseType;
! 24290: } while ((tmpType != NULL) &&
! 24291: (tmpType->type != XML_SCHEMA_TYPE_BASIC));
! 24292: if (found && (ret == 0)) {
! 24293: ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
! 24294: if (fireErrors) {
! 24295: xmlSchemaFacetErr(actxt, ret, node,
! 24296: value, 0, type, NULL, NULL, NULL, NULL);
! 24297: } else
! 24298: return (ret);
! 24299: if (error == 0)
! 24300: error = ret;
! 24301: }
! 24302: }
! 24303:
! 24304: if (error >= 0) {
! 24305: int found;
! 24306: /*
! 24307: * Process patters. Pattern facets are ORed at type level
! 24308: * and ANDed if derived. Walk the base type axis.
! 24309: */
! 24310: tmpType = type;
! 24311: facet = NULL;
! 24312: do {
! 24313: found = 0;
! 24314: for (facetLink = tmpType->facetSet; facetLink != NULL;
! 24315: facetLink = facetLink->next) {
! 24316: if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
! 24317: continue;
! 24318: found = 1;
! 24319: /*
! 24320: * NOTE that for patterns, @value needs to be the
! 24321: * normalized vaule.
! 24322: */
! 24323: ret = xmlRegexpExec(facetLink->facet->regexp, value);
! 24324: if (ret == 1)
! 24325: break;
! 24326: else if (ret < 0) {
! 24327: AERROR_INT("xmlSchemaValidateFacets",
! 24328: "validating against a pattern facet");
! 24329: return (-1);
! 24330: } else {
! 24331: /*
! 24332: * Save the last non-validating facet.
! 24333: */
! 24334: facet = facetLink->facet;
! 24335: }
! 24336: }
! 24337: if (found && (ret != 1)) {
! 24338: ret = XML_SCHEMAV_CVC_PATTERN_VALID;
! 24339: if (fireErrors) {
! 24340: xmlSchemaFacetErr(actxt, ret, node,
! 24341: value, 0, type, facet, NULL, NULL, NULL);
! 24342: } else
! 24343: return (ret);
! 24344: if (error == 0)
! 24345: error = ret;
! 24346: break;
! 24347: }
! 24348: tmpType = tmpType->baseType;
! 24349: } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
! 24350: }
! 24351:
! 24352: return (error);
! 24353: }
! 24354:
! 24355: static xmlChar *
! 24356: xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
! 24357: const xmlChar *value)
! 24358: {
! 24359: switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
! 24360: case XML_SCHEMA_WHITESPACE_COLLAPSE:
! 24361: return (xmlSchemaCollapseString(value));
! 24362: case XML_SCHEMA_WHITESPACE_REPLACE:
! 24363: return (xmlSchemaWhiteSpaceReplace(value));
! 24364: default:
! 24365: return (NULL);
! 24366: }
! 24367: }
! 24368:
! 24369: static int
! 24370: xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
! 24371: const xmlChar *value,
! 24372: xmlSchemaValPtr *val,
! 24373: int valNeeded)
! 24374: {
! 24375: int ret;
! 24376: const xmlChar *nsName;
! 24377: xmlChar *local, *prefix = NULL;
! 24378:
! 24379: ret = xmlValidateQName(value, 1);
! 24380: if (ret != 0) {
! 24381: if (ret == -1) {
! 24382: VERROR_INT("xmlSchemaValidateQName",
! 24383: "calling xmlValidateQName()");
! 24384: return (-1);
! 24385: }
! 24386: return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
! 24387: }
! 24388: /*
! 24389: * NOTE: xmlSplitQName2 will always return a duplicated
! 24390: * strings.
! 24391: */
! 24392: local = xmlSplitQName2(value, &prefix);
! 24393: if (local == NULL)
! 24394: local = xmlStrdup(value);
! 24395: /*
! 24396: * OPTIMIZE TODO: Use flags for:
! 24397: * - is there any namespace binding?
! 24398: * - is there a default namespace?
! 24399: */
! 24400: nsName = xmlSchemaLookupNamespace(vctxt, prefix);
! 24401:
! 24402: if (prefix != NULL) {
! 24403: xmlFree(prefix);
! 24404: /*
! 24405: * A namespace must be found if the prefix is
! 24406: * NOT NULL.
! 24407: */
! 24408: if (nsName == NULL) {
! 24409: ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
! 24410: xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
! 24411: WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
! 24412: "The QName value '%s' has no "
! 24413: "corresponding namespace declaration in "
! 24414: "scope", value, NULL);
! 24415: if (local != NULL)
! 24416: xmlFree(local);
! 24417: return (ret);
! 24418: }
! 24419: }
! 24420: if (valNeeded && val) {
! 24421: if (nsName != NULL)
! 24422: *val = xmlSchemaNewQNameValue(
! 24423: BAD_CAST xmlStrdup(nsName), BAD_CAST local);
! 24424: else
! 24425: *val = xmlSchemaNewQNameValue(NULL,
! 24426: BAD_CAST local);
! 24427: } else
! 24428: xmlFree(local);
! 24429: return (0);
! 24430: }
! 24431:
! 24432: /*
! 24433: * cvc-simple-type
! 24434: */
! 24435: static int
! 24436: xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
! 24437: xmlNodePtr node,
! 24438: xmlSchemaTypePtr type,
! 24439: const xmlChar *value,
! 24440: xmlSchemaValPtr *retVal,
! 24441: int fireErrors,
! 24442: int normalize,
! 24443: int isNormalized)
! 24444: {
! 24445: int ret = 0, valNeeded = (retVal) ? 1 : 0;
! 24446: xmlSchemaValPtr val = NULL;
! 24447: /* xmlSchemaWhitespaceValueType ws; */
! 24448: xmlChar *normValue = NULL;
! 24449:
! 24450: #define NORMALIZE(atype) \
! 24451: if ((! isNormalized) && \
! 24452: (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
! 24453: normValue = xmlSchemaNormalizeValue(atype, value); \
! 24454: if (normValue != NULL) \
! 24455: value = normValue; \
! 24456: isNormalized = 1; \
! 24457: }
! 24458:
! 24459: if ((retVal != NULL) && (*retVal != NULL)) {
! 24460: xmlSchemaFreeValue(*retVal);
! 24461: *retVal = NULL;
! 24462: }
! 24463: /*
! 24464: * 3.14.4 Simple Type Definition Validation Rules
! 24465: * Validation Rule: String Valid
! 24466: */
! 24467: /*
! 24468: * 1 It is schema-valid with respect to that definition as defined
! 24469: * by Datatype Valid in [XML Schemas: Datatypes].
! 24470: */
! 24471: /*
! 24472: * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
! 24473: * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6), then
! 24474: * the string must be a �declared entity name�.
! 24475: */
! 24476: /*
! 24477: * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
! 24478: * given the empty set, as defined in Type Derivation OK (Simple) (�3.14.6),
! 24479: * then every whitespace-delimited substring of the string must be a �declared
! 24480: * entity name�.
! 24481: */
! 24482: /*
! 24483: * 2.3 otherwise no further condition applies.
! 24484: */
! 24485: if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
! 24486: valNeeded = 1;
! 24487: if (value == NULL)
! 24488: value = BAD_CAST "";
! 24489: if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
! 24490: xmlSchemaTypePtr biType; /* The built-in type. */
! 24491: /*
! 24492: * SPEC (1.2.1) "if {variety} is �atomic� then the string must �match�
! 24493: * a literal in the �lexical space� of {base type definition}"
! 24494: */
! 24495: /*
! 24496: * Whitespace-normalize.
! 24497: */
! 24498: NORMALIZE(type);
! 24499: if (type->type != XML_SCHEMA_TYPE_BASIC) {
! 24500: /*
! 24501: * Get the built-in type.
! 24502: */
! 24503: biType = type->baseType;
! 24504: while ((biType != NULL) &&
! 24505: (biType->type != XML_SCHEMA_TYPE_BASIC))
! 24506: biType = biType->baseType;
! 24507:
! 24508: if (biType == NULL) {
! 24509: AERROR_INT("xmlSchemaVCheckCVCSimpleType",
! 24510: "could not get the built-in type");
! 24511: goto internal_error;
! 24512: }
! 24513: } else
! 24514: biType = type;
! 24515: /*
! 24516: * NOTATIONs need to be processed here, since they need
! 24517: * to lookup in the hashtable of NOTATION declarations of the schema.
! 24518: */
! 24519: if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
! 24520: switch (biType->builtInType) {
! 24521: case XML_SCHEMAS_NOTATION:
! 24522: ret = xmlSchemaValidateNotation(
! 24523: (xmlSchemaValidCtxtPtr) actxt,
! 24524: ((xmlSchemaValidCtxtPtr) actxt)->schema,
! 24525: NULL, value, &val, valNeeded);
! 24526: break;
! 24527: case XML_SCHEMAS_QNAME:
! 24528: ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
! 24529: value, &val, valNeeded);
! 24530: break;
! 24531: default:
! 24532: /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
! 24533: if (valNeeded)
! 24534: ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
! 24535: value, &val, node);
! 24536: else
! 24537: ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
! 24538: value, NULL, node);
! 24539: break;
! 24540: }
! 24541: } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
! 24542: switch (biType->builtInType) {
! 24543: case XML_SCHEMAS_NOTATION:
! 24544: ret = xmlSchemaValidateNotation(NULL,
! 24545: ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
! 24546: value, &val, valNeeded);
! 24547: break;
! 24548: default:
! 24549: /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
! 24550: if (valNeeded)
! 24551: ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
! 24552: value, &val, node);
! 24553: else
! 24554: ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
! 24555: value, NULL, node);
! 24556: break;
! 24557: }
! 24558: } else {
! 24559: /*
! 24560: * Validation via a public API is not implemented yet.
! 24561: */
! 24562: TODO
! 24563: goto internal_error;
! 24564: }
! 24565: if (ret != 0) {
! 24566: if (ret < 0) {
! 24567: AERROR_INT("xmlSchemaVCheckCVCSimpleType",
! 24568: "validating against a built-in type");
! 24569: goto internal_error;
! 24570: }
! 24571: if (WXS_IS_LIST(type))
! 24572: ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
! 24573: else
! 24574: ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
! 24575: }
! 24576: if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
! 24577: /*
! 24578: * Check facets.
! 24579: */
! 24580: ret = xmlSchemaValidateFacets(actxt, node, type,
! 24581: (xmlSchemaValType) biType->builtInType, value, val,
! 24582: 0, fireErrors);
! 24583: if (ret != 0) {
! 24584: if (ret < 0) {
! 24585: AERROR_INT("xmlSchemaVCheckCVCSimpleType",
! 24586: "validating facets of atomic simple type");
! 24587: goto internal_error;
! 24588: }
! 24589: if (WXS_IS_LIST(type))
! 24590: ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
! 24591: else
! 24592: ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
! 24593: }
! 24594: }
! 24595: if (fireErrors && (ret > 0))
! 24596: xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
! 24597: } else if (WXS_IS_LIST(type)) {
! 24598:
! 24599: xmlSchemaTypePtr itemType;
! 24600: const xmlChar *cur, *end;
! 24601: xmlChar *tmpValue = NULL;
! 24602: unsigned long len = 0;
! 24603: xmlSchemaValPtr prevVal = NULL, curVal = NULL;
! 24604: /* 1.2.2 if {variety} is �list� then the string must be a sequence
! 24605: * of white space separated tokens, each of which �match�es a literal
! 24606: * in the �lexical space� of {item type definition}
! 24607: */
! 24608: /*
! 24609: * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
! 24610: * the list type has an enum or pattern facet.
! 24611: */
! 24612: NORMALIZE(type);
! 24613: /*
! 24614: * VAL TODO: Optimize validation of empty values.
! 24615: * VAL TODO: We do not have computed values for lists.
! 24616: */
! 24617: itemType = WXS_LIST_ITEMTYPE(type);
! 24618: cur = value;
! 24619: do {
! 24620: while (IS_BLANK_CH(*cur))
! 24621: cur++;
! 24622: end = cur;
! 24623: while ((*end != 0) && (!(IS_BLANK_CH(*end))))
! 24624: end++;
! 24625: if (end == cur)
! 24626: break;
! 24627: tmpValue = xmlStrndup(cur, end - cur);
! 24628: len++;
! 24629:
! 24630: if (valNeeded)
! 24631: ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
! 24632: tmpValue, &curVal, fireErrors, 0, 1);
! 24633: else
! 24634: ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
! 24635: tmpValue, NULL, fireErrors, 0, 1);
! 24636: FREE_AND_NULL(tmpValue);
! 24637: if (curVal != NULL) {
! 24638: /*
! 24639: * Add to list of computed values.
! 24640: */
! 24641: if (val == NULL)
! 24642: val = curVal;
! 24643: else
! 24644: xmlSchemaValueAppend(prevVal, curVal);
! 24645: prevVal = curVal;
! 24646: curVal = NULL;
! 24647: }
! 24648: if (ret != 0) {
! 24649: if (ret < 0) {
! 24650: AERROR_INT("xmlSchemaVCheckCVCSimpleType",
! 24651: "validating an item of list simple type");
! 24652: goto internal_error;
! 24653: }
! 24654: ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
! 24655: break;
! 24656: }
! 24657: cur = end;
! 24658: } while (*cur != 0);
! 24659: FREE_AND_NULL(tmpValue);
! 24660: if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
! 24661: /*
! 24662: * Apply facets (pattern, enumeration).
! 24663: */
! 24664: ret = xmlSchemaValidateFacets(actxt, node, type,
! 24665: XML_SCHEMAS_UNKNOWN, value, val,
! 24666: len, fireErrors);
! 24667: if (ret != 0) {
! 24668: if (ret < 0) {
! 24669: AERROR_INT("xmlSchemaVCheckCVCSimpleType",
! 24670: "validating facets of list simple type");
! 24671: goto internal_error;
! 24672: }
! 24673: ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
! 24674: }
! 24675: }
! 24676: if (fireErrors && (ret > 0)) {
! 24677: /*
! 24678: * Report the normalized value.
! 24679: */
! 24680: normalize = 1;
! 24681: NORMALIZE(type);
! 24682: xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
! 24683: }
! 24684: } else if (WXS_IS_UNION(type)) {
! 24685: xmlSchemaTypeLinkPtr memberLink;
! 24686: /*
! 24687: * TODO: For all datatypes �derived� by �union� whiteSpace does
! 24688: * not apply directly; however, the normalization behavior of �union�
! 24689: * types is controlled by the value of whiteSpace on that one of the
! 24690: * �memberTypes� against which the �union� is successfully validated.
! 24691: *
! 24692: * This means that the value is normalized by the first validating
! 24693: * member type, then the facets of the union type are applied. This
! 24694: * needs changing of the value!
! 24695: */
! 24696:
! 24697: /*
! 24698: * 1.2.3 if {variety} is �union� then the string must �match� a
! 24699: * literal in the �lexical space� of at least one member of
! 24700: * {member type definitions}
! 24701: */
! 24702: memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
! 24703: if (memberLink == NULL) {
! 24704: AERROR_INT("xmlSchemaVCheckCVCSimpleType",
! 24705: "union simple type has no member types");
! 24706: goto internal_error;
! 24707: }
! 24708: /*
! 24709: * Always normalize union type values, since we currently
! 24710: * cannot store the whitespace information with the value
! 24711: * itself; otherwise a later value-comparison would be
! 24712: * not possible.
! 24713: */
! 24714: while (memberLink != NULL) {
! 24715: if (valNeeded)
! 24716: ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
! 24717: memberLink->type, value, &val, 0, 1, 0);
! 24718: else
! 24719: ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
! 24720: memberLink->type, value, NULL, 0, 1, 0);
! 24721: if (ret <= 0)
! 24722: break;
! 24723: memberLink = memberLink->next;
! 24724: }
! 24725: if (ret != 0) {
! 24726: if (ret < 0) {
! 24727: AERROR_INT("xmlSchemaVCheckCVCSimpleType",
! 24728: "validating members of union simple type");
! 24729: goto internal_error;
! 24730: }
! 24731: ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
! 24732: }
! 24733: /*
! 24734: * Apply facets (pattern, enumeration).
! 24735: */
! 24736: if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
! 24737: /*
! 24738: * The normalization behavior of �union� types is controlled by
! 24739: * the value of whiteSpace on that one of the �memberTypes�
! 24740: * against which the �union� is successfully validated.
! 24741: */
! 24742: NORMALIZE(memberLink->type);
! 24743: ret = xmlSchemaValidateFacets(actxt, node, type,
! 24744: XML_SCHEMAS_UNKNOWN, value, val,
! 24745: 0, fireErrors);
! 24746: if (ret != 0) {
! 24747: if (ret < 0) {
! 24748: AERROR_INT("xmlSchemaVCheckCVCSimpleType",
! 24749: "validating facets of union simple type");
! 24750: goto internal_error;
! 24751: }
! 24752: ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
! 24753: }
! 24754: }
! 24755: if (fireErrors && (ret > 0))
! 24756: xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
! 24757: }
! 24758:
! 24759: if (normValue != NULL)
! 24760: xmlFree(normValue);
! 24761: if (ret == 0) {
! 24762: if (retVal != NULL)
! 24763: *retVal = val;
! 24764: else if (val != NULL)
! 24765: xmlSchemaFreeValue(val);
! 24766: } else if (val != NULL)
! 24767: xmlSchemaFreeValue(val);
! 24768: return (ret);
! 24769: internal_error:
! 24770: if (normValue != NULL)
! 24771: xmlFree(normValue);
! 24772: if (val != NULL)
! 24773: xmlSchemaFreeValue(val);
! 24774: return (-1);
! 24775: }
! 24776:
! 24777: static int
! 24778: xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
! 24779: const xmlChar *value,
! 24780: const xmlChar **nsName,
! 24781: const xmlChar **localName)
! 24782: {
! 24783: int ret = 0;
! 24784:
! 24785: if ((nsName == NULL) || (localName == NULL))
! 24786: return (-1);
! 24787: *nsName = NULL;
! 24788: *localName = NULL;
! 24789:
! 24790: ret = xmlValidateQName(value, 1);
! 24791: if (ret == -1)
! 24792: return (-1);
! 24793: if (ret > 0) {
! 24794: xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
! 24795: XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
! 24796: value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
! 24797: return (1);
! 24798: }
! 24799: {
! 24800: xmlChar *local = NULL;
! 24801: xmlChar *prefix;
! 24802:
! 24803: /*
! 24804: * NOTE: xmlSplitQName2 will return a duplicated
! 24805: * string.
! 24806: */
! 24807: local = xmlSplitQName2(value, &prefix);
! 24808: if (local == NULL)
! 24809: *localName = xmlDictLookup(vctxt->dict, value, -1);
! 24810: else {
! 24811: *localName = xmlDictLookup(vctxt->dict, local, -1);
! 24812: xmlFree(local);
! 24813: }
! 24814:
! 24815: *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
! 24816:
! 24817: if (prefix != NULL) {
! 24818: xmlFree(prefix);
! 24819: /*
! 24820: * A namespace must be found if the prefix is NOT NULL.
! 24821: */
! 24822: if (*nsName == NULL) {
! 24823: xmlSchemaCustomErr(ACTXT_CAST vctxt,
! 24824: XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
! 24825: WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
! 24826: "The QName value '%s' has no "
! 24827: "corresponding namespace declaration in scope",
! 24828: value, NULL);
! 24829: return (2);
! 24830: }
! 24831: }
! 24832: }
! 24833: return (0);
! 24834: }
! 24835:
! 24836: static int
! 24837: xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
! 24838: xmlSchemaAttrInfoPtr iattr,
! 24839: xmlSchemaTypePtr *localType,
! 24840: xmlSchemaElementPtr elemDecl)
! 24841: {
! 24842: int ret = 0;
! 24843: /*
! 24844: * cvc-elt (3.3.4) : (4)
! 24845: * AND
! 24846: * Schema-Validity Assessment (Element) (cvc-assess-elt)
! 24847: * (1.2.1.2.1) - (1.2.1.2.4)
! 24848: * Handle 'xsi:type'.
! 24849: */
! 24850: if (localType == NULL)
! 24851: return (-1);
! 24852: *localType = NULL;
! 24853: if (iattr == NULL)
! 24854: return (0);
! 24855: else {
! 24856: const xmlChar *nsName = NULL, *local = NULL;
! 24857: /*
! 24858: * TODO: We should report a *warning* that the type was overriden
! 24859: * by the instance.
! 24860: */
! 24861: ACTIVATE_ATTRIBUTE(iattr);
! 24862: /*
! 24863: * (cvc-elt) (3.3.4) : (4.1)
! 24864: * (cvc-assess-elt) (1.2.1.2.2)
! 24865: */
! 24866: ret = xmlSchemaVExpandQName(vctxt, iattr->value,
! 24867: &nsName, &local);
! 24868: if (ret != 0) {
! 24869: if (ret < 0) {
! 24870: VERROR_INT("xmlSchemaValidateElementByDeclaration",
! 24871: "calling xmlSchemaQNameExpand() to validate the "
! 24872: "attribute 'xsi:type'");
! 24873: goto internal_error;
! 24874: }
! 24875: goto exit;
! 24876: }
! 24877: /*
! 24878: * (cvc-elt) (3.3.4) : (4.2)
! 24879: * (cvc-assess-elt) (1.2.1.2.3)
! 24880: */
! 24881: *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
! 24882: if (*localType == NULL) {
! 24883: xmlChar *str = NULL;
! 24884:
! 24885: xmlSchemaCustomErr(ACTXT_CAST vctxt,
! 24886: XML_SCHEMAV_CVC_ELT_4_2, NULL,
! 24887: WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
! 24888: "The QName value '%s' of the xsi:type attribute does not "
! 24889: "resolve to a type definition",
! 24890: xmlSchemaFormatQName(&str, nsName, local), NULL);
! 24891: FREE_AND_NULL(str);
! 24892: ret = vctxt->err;
! 24893: goto exit;
! 24894: }
! 24895: if (elemDecl != NULL) {
! 24896: int set = 0;
! 24897:
! 24898: /*
! 24899: * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
! 24900: * "The �local type definition� must be validly
! 24901: * derived from the {type definition} given the union of
! 24902: * the {disallowed substitutions} and the {type definition}'s
! 24903: * {prohibited substitutions}, as defined in
! 24904: * Type Derivation OK (Complex) (�3.4.6)
! 24905: * (if it is a complex type definition),
! 24906: * or given {disallowed substitutions} as defined in Type
! 24907: * Derivation OK (Simple) (�3.14.6) (if it is a simple type
! 24908: * definition)."
! 24909: *
! 24910: * {disallowed substitutions}: the "block" on the element decl.
! 24911: * {prohibited substitutions}: the "block" on the type def.
! 24912: */
! 24913: /*
! 24914: * OPTIMIZE TODO: We could map types already evaluated
! 24915: * to be validly derived from other types to avoid checking
! 24916: * this over and over for the same types.
! 24917: */
! 24918: if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
! 24919: (elemDecl->subtypes->flags &
! 24920: XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
! 24921: set |= SUBSET_EXTENSION;
! 24922:
! 24923: if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
! 24924: (elemDecl->subtypes->flags &
! 24925: XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
! 24926: set |= SUBSET_RESTRICTION;
! 24927:
! 24928: /*
! 24929: * REMOVED and CHANGED since this produced a parser context
! 24930: * which adds to the string dict of the schema. So this would
! 24931: * change the schema and we don't want this. We don't need
! 24932: * the parser context anymore.
! 24933: *
! 24934: * if ((vctxt->pctxt == NULL) &&
! 24935: * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
! 24936: * return (-1);
! 24937: */
! 24938:
! 24939: if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
! 24940: elemDecl->subtypes, set) != 0) {
! 24941: xmlChar *str = NULL;
! 24942:
! 24943: xmlSchemaCustomErr(ACTXT_CAST vctxt,
! 24944: XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
! 24945: "The type definition '%s', specified by xsi:type, is "
! 24946: "blocked or not validly derived from the type definition "
! 24947: "of the element declaration",
! 24948: xmlSchemaFormatQName(&str,
! 24949: (*localType)->targetNamespace,
! 24950: (*localType)->name),
! 24951: NULL);
! 24952: FREE_AND_NULL(str);
! 24953: ret = vctxt->err;
! 24954: *localType = NULL;
! 24955: }
! 24956: }
! 24957: }
! 24958: exit:
! 24959: ACTIVATE_ELEM;
! 24960: return (ret);
! 24961: internal_error:
! 24962: ACTIVATE_ELEM;
! 24963: return (-1);
! 24964: }
! 24965:
! 24966: static int
! 24967: xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
! 24968: {
! 24969: xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
! 24970: xmlSchemaTypePtr actualType;
! 24971:
! 24972: /*
! 24973: * cvc-elt (3.3.4) : 1
! 24974: */
! 24975: if (elemDecl == NULL) {
! 24976: VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
! 24977: "No matching declaration available");
! 24978: return (vctxt->err);
! 24979: }
! 24980: actualType = WXS_ELEM_TYPEDEF(elemDecl);
! 24981: /*
! 24982: * cvc-elt (3.3.4) : 2
! 24983: */
! 24984: if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
! 24985: VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
! 24986: "The element declaration is abstract");
! 24987: return (vctxt->err);
! 24988: }
! 24989: if (actualType == NULL) {
! 24990: VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
! 24991: "The type definition is absent");
! 24992: return (XML_SCHEMAV_CVC_TYPE_1);
! 24993: }
! 24994: if (vctxt->nbAttrInfos != 0) {
! 24995: int ret;
! 24996: xmlSchemaAttrInfoPtr iattr;
! 24997: /*
! 24998: * cvc-elt (3.3.4) : 3
! 24999: * Handle 'xsi:nil'.
! 25000: */
! 25001: iattr = xmlSchemaGetMetaAttrInfo(vctxt,
! 25002: XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
! 25003: if (iattr) {
! 25004: ACTIVATE_ATTRIBUTE(iattr);
! 25005: /*
! 25006: * Validate the value.
! 25007: */
! 25008: ret = xmlSchemaVCheckCVCSimpleType(
! 25009: ACTXT_CAST vctxt, NULL,
! 25010: xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
! 25011: iattr->value, &(iattr->val), 1, 0, 0);
! 25012: ACTIVATE_ELEM;
! 25013: if (ret < 0) {
! 25014: VERROR_INT("xmlSchemaValidateElemDecl",
! 25015: "calling xmlSchemaVCheckCVCSimpleType() to "
! 25016: "validate the attribute 'xsi:nil'");
! 25017: return (-1);
! 25018: }
! 25019: if (ret == 0) {
! 25020: if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
! 25021: /*
! 25022: * cvc-elt (3.3.4) : 3.1
! 25023: */
! 25024: VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
! 25025: "The element is not 'nillable'");
! 25026: /* Does not return an error on purpose. */
! 25027: } else {
! 25028: if (xmlSchemaValueGetAsBoolean(iattr->val)) {
! 25029: /*
! 25030: * cvc-elt (3.3.4) : 3.2.2
! 25031: */
! 25032: if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
! 25033: (elemDecl->value != NULL)) {
! 25034: VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
! 25035: "The element cannot be 'nilled' because "
! 25036: "there is a fixed value constraint defined "
! 25037: "for it");
! 25038: /* Does not return an error on purpose. */
! 25039: } else
! 25040: vctxt->inode->flags |=
! 25041: XML_SCHEMA_ELEM_INFO_NILLED;
! 25042: }
! 25043: }
! 25044: }
! 25045: }
! 25046: /*
! 25047: * cvc-elt (3.3.4) : 4
! 25048: * Handle 'xsi:type'.
! 25049: */
! 25050: iattr = xmlSchemaGetMetaAttrInfo(vctxt,
! 25051: XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
! 25052: if (iattr) {
! 25053: xmlSchemaTypePtr localType = NULL;
! 25054:
! 25055: ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
! 25056: elemDecl);
! 25057: if (ret != 0) {
! 25058: if (ret == -1) {
! 25059: VERROR_INT("xmlSchemaValidateElemDecl",
! 25060: "calling xmlSchemaProcessXSIType() to "
! 25061: "process the attribute 'xsi:type'");
! 25062: return (-1);
! 25063: }
! 25064: /* Does not return an error on purpose. */
! 25065: }
! 25066: if (localType != NULL) {
! 25067: vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
! 25068: actualType = localType;
! 25069: }
! 25070: }
! 25071: }
! 25072: /*
! 25073: * IDC: Register identity-constraint XPath matchers.
! 25074: */
! 25075: if ((elemDecl->idcs != NULL) &&
! 25076: (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
! 25077: return (-1);
! 25078: /*
! 25079: * No actual type definition.
! 25080: */
! 25081: if (actualType == NULL) {
! 25082: VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
! 25083: "The type definition is absent");
! 25084: return (XML_SCHEMAV_CVC_TYPE_1);
! 25085: }
! 25086: /*
! 25087: * Remember the actual type definition.
! 25088: */
! 25089: vctxt->inode->typeDef = actualType;
! 25090:
! 25091: return (0);
! 25092: }
! 25093:
! 25094: static int
! 25095: xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
! 25096: {
! 25097: xmlSchemaAttrInfoPtr iattr;
! 25098: int ret = 0, i;
! 25099:
! 25100: /*
! 25101: * SPEC cvc-type (3.1.1)
! 25102: * "The attributes of must be empty, excepting those whose namespace
! 25103: * name is identical to http://www.w3.org/2001/XMLSchema-instance and
! 25104: * whose local name is one of type, nil, schemaLocation or
! 25105: * noNamespaceSchemaLocation."
! 25106: */
! 25107: if (vctxt->nbAttrInfos == 0)
! 25108: return (0);
! 25109: for (i = 0; i < vctxt->nbAttrInfos; i++) {
! 25110: iattr = vctxt->attrInfos[i];
! 25111: if (! iattr->metaType) {
! 25112: ACTIVATE_ATTRIBUTE(iattr)
! 25113: xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
! 25114: XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
! 25115: ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
! 25116: }
! 25117: }
! 25118: ACTIVATE_ELEM
! 25119: return (ret);
! 25120: }
! 25121:
! 25122: /*
! 25123: * Cleanup currently used attribute infos.
! 25124: */
! 25125: static void
! 25126: xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
! 25127: {
! 25128: int i;
! 25129: xmlSchemaAttrInfoPtr attr;
! 25130:
! 25131: if (vctxt->nbAttrInfos == 0)
! 25132: return;
! 25133: for (i = 0; i < vctxt->nbAttrInfos; i++) {
! 25134: attr = vctxt->attrInfos[i];
! 25135: if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
! 25136: if (attr->localName != NULL)
! 25137: xmlFree((xmlChar *) attr->localName);
! 25138: if (attr->nsName != NULL)
! 25139: xmlFree((xmlChar *) attr->nsName);
! 25140: }
! 25141: if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
! 25142: if (attr->value != NULL)
! 25143: xmlFree((xmlChar *) attr->value);
! 25144: }
! 25145: if (attr->val != NULL) {
! 25146: xmlSchemaFreeValue(attr->val);
! 25147: attr->val = NULL;
! 25148: }
! 25149: memset(attr, 0, sizeof(xmlSchemaAttrInfo));
! 25150: }
! 25151: vctxt->nbAttrInfos = 0;
! 25152: }
! 25153:
! 25154: /*
! 25155: * 3.4.4 Complex Type Definition Validation Rules
! 25156: * Element Locally Valid (Complex Type) (cvc-complex-type)
! 25157: * 3.2.4 Attribute Declaration Validation Rules
! 25158: * Validation Rule: Attribute Locally Valid (cvc-attribute)
! 25159: * Attribute Locally Valid (Use) (cvc-au)
! 25160: *
! 25161: * Only "assessed" attribute information items will be visible to
! 25162: * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
! 25163: */
! 25164: static int
! 25165: xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
! 25166: {
! 25167: xmlSchemaTypePtr type = vctxt->inode->typeDef;
! 25168: xmlSchemaItemListPtr attrUseList;
! 25169: xmlSchemaAttributeUsePtr attrUse = NULL;
! 25170: xmlSchemaAttributePtr attrDecl = NULL;
! 25171: xmlSchemaAttrInfoPtr iattr, tmpiattr;
! 25172: int i, j, found, nbAttrs, nbUses;
! 25173: int xpathRes = 0, res, wildIDs = 0, fixed;
! 25174: xmlNodePtr defAttrOwnerElem = NULL;
! 25175:
! 25176: /*
! 25177: * SPEC (cvc-attribute)
! 25178: * (1) "The declaration must not be �absent� (see Missing
! 25179: * Sub-components (�5.3) for how this can fail to be
! 25180: * the case)."
! 25181: * (2) "Its {type definition} must not be absent."
! 25182: *
! 25183: * NOTE (1) + (2): This is not handled here, since we currently do not
! 25184: * allow validation against schemas which have missing sub-components.
! 25185: *
! 25186: * SPEC (cvc-complex-type)
! 25187: * (3) "For each attribute information item in the element information
! 25188: * item's [attributes] excepting those whose [namespace name] is
! 25189: * identical to http://www.w3.org/2001/XMLSchema-instance and whose
! 25190: * [local name] is one of type, nil, schemaLocation or
! 25191: * noNamespaceSchemaLocation, the appropriate case among the following
! 25192: * must be true:
! 25193: *
! 25194: */
! 25195: attrUseList = (xmlSchemaItemListPtr) type->attrUses;
! 25196: /*
! 25197: * @nbAttrs is the number of attributes present in the instance.
! 25198: */
! 25199: nbAttrs = vctxt->nbAttrInfos;
! 25200: if (attrUseList != NULL)
! 25201: nbUses = attrUseList->nbItems;
! 25202: else
! 25203: nbUses = 0;
! 25204: for (i = 0; i < nbUses; i++) {
! 25205: found = 0;
! 25206: attrUse = attrUseList->items[i];
! 25207: attrDecl = WXS_ATTRUSE_DECL(attrUse);
! 25208: for (j = 0; j < nbAttrs; j++) {
! 25209: iattr = vctxt->attrInfos[j];
! 25210: /*
! 25211: * SPEC (cvc-complex-type) (3)
! 25212: * Skip meta attributes.
! 25213: */
! 25214: if (iattr->metaType)
! 25215: continue;
! 25216: if (iattr->localName[0] != attrDecl->name[0])
! 25217: continue;
! 25218: if (!xmlStrEqual(iattr->localName, attrDecl->name))
! 25219: continue;
! 25220: if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
! 25221: continue;
! 25222: found = 1;
! 25223: /*
! 25224: * SPEC (cvc-complex-type)
! 25225: * (3.1) "If there is among the {attribute uses} an attribute
! 25226: * use with an {attribute declaration} whose {name} matches
! 25227: * the attribute information item's [local name] and whose
! 25228: * {target namespace} is identical to the attribute information
! 25229: * item's [namespace name] (where an �absent� {target namespace}
! 25230: * is taken to be identical to a [namespace name] with no value),
! 25231: * then the attribute information must be �valid� with respect
! 25232: * to that attribute use as per Attribute Locally Valid (Use)
! 25233: * (�3.5.4). In this case the {attribute declaration} of that
! 25234: * attribute use is the �context-determined declaration� for the
! 25235: * attribute information item with respect to Schema-Validity
! 25236: * Assessment (Attribute) (�3.2.4) and
! 25237: * Assessment Outcome (Attribute) (�3.2.5).
! 25238: */
! 25239: iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
! 25240: iattr->use = attrUse;
! 25241: /*
! 25242: * Context-determined declaration.
! 25243: */
! 25244: iattr->decl = attrDecl;
! 25245: iattr->typeDef = attrDecl->subtypes;
! 25246: break;
! 25247: }
! 25248:
! 25249: if (found)
! 25250: continue;
! 25251:
! 25252: if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
! 25253: /*
! 25254: * Handle non-existent, required attributes.
! 25255: *
! 25256: * SPEC (cvc-complex-type)
! 25257: * (4) "The {attribute declaration} of each attribute use in
! 25258: * the {attribute uses} whose {required} is true matches one
! 25259: * of the attribute information items in the element information
! 25260: * item's [attributes] as per clause 3.1 above."
! 25261: */
! 25262: tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
! 25263: if (tmpiattr == NULL) {
! 25264: VERROR_INT(
! 25265: "xmlSchemaVAttributesComplex",
! 25266: "calling xmlSchemaGetFreshAttrInfo()");
! 25267: return (-1);
! 25268: }
! 25269: tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
! 25270: tmpiattr->use = attrUse;
! 25271: tmpiattr->decl = attrDecl;
! 25272: } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
! 25273: ((attrUse->defValue != NULL) ||
! 25274: (attrDecl->defValue != NULL))) {
! 25275: /*
! 25276: * Handle non-existent, optional, default/fixed attributes.
! 25277: */
! 25278: tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
! 25279: if (tmpiattr == NULL) {
! 25280: VERROR_INT(
! 25281: "xmlSchemaVAttributesComplex",
! 25282: "calling xmlSchemaGetFreshAttrInfo()");
! 25283: return (-1);
! 25284: }
! 25285: tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
! 25286: tmpiattr->use = attrUse;
! 25287: tmpiattr->decl = attrDecl;
! 25288: tmpiattr->typeDef = attrDecl->subtypes;
! 25289: tmpiattr->localName = attrDecl->name;
! 25290: tmpiattr->nsName = attrDecl->targetNamespace;
! 25291: }
! 25292: }
! 25293:
! 25294: if (vctxt->nbAttrInfos == 0)
! 25295: return (0);
! 25296: /*
! 25297: * Validate against the wildcard.
! 25298: */
! 25299: if (type->attributeWildcard != NULL) {
! 25300: /*
! 25301: * SPEC (cvc-complex-type)
! 25302: * (3.2.1) "There must be an {attribute wildcard}."
! 25303: */
! 25304: for (i = 0; i < nbAttrs; i++) {
! 25305: iattr = vctxt->attrInfos[i];
! 25306: /*
! 25307: * SPEC (cvc-complex-type) (3)
! 25308: * Skip meta attributes.
! 25309: */
! 25310: if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
! 25311: continue;
! 25312: /*
! 25313: * SPEC (cvc-complex-type)
! 25314: * (3.2.2) "The attribute information item must be �valid� with
! 25315: * respect to it as defined in Item Valid (Wildcard) (�3.10.4)."
! 25316: *
! 25317: * SPEC Item Valid (Wildcard) (cvc-wildcard)
! 25318: * "... its [namespace name] must be �valid� with respect to
! 25319: * the wildcard constraint, as defined in Wildcard allows
! 25320: * Namespace Name (�3.10.4)."
! 25321: */
! 25322: if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
! 25323: iattr->nsName) == 0) {
! 25324: /*
! 25325: * Handle processContents.
! 25326: *
! 25327: * SPEC (cvc-wildcard):
! 25328: * processContents | context-determined declaration:
! 25329: * "strict" "mustFind"
! 25330: * "lax" "none"
! 25331: * "skip" "skip"
! 25332: */
! 25333: if (type->attributeWildcard->processContents ==
! 25334: XML_SCHEMAS_ANY_SKIP) {
! 25335: /*
! 25336: * context-determined declaration = "skip"
! 25337: *
! 25338: * SPEC PSVI Assessment Outcome (Attribute)
! 25339: * [validity] = "notKnown"
! 25340: * [validation attempted] = "none"
! 25341: */
! 25342: iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
! 25343: continue;
! 25344: }
! 25345: /*
! 25346: * Find an attribute declaration.
! 25347: */
! 25348: iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
! 25349: iattr->localName, iattr->nsName);
! 25350: if (iattr->decl != NULL) {
! 25351: iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
! 25352: /*
! 25353: * SPEC (cvc-complex-type)
! 25354: * (5) "Let [Definition:] the wild IDs be the set of
! 25355: * all attribute information item to which clause 3.2
! 25356: * applied and whose �validation� resulted in a
! 25357: * �context-determined declaration� of mustFind or no
! 25358: * �context-determined declaration� at all, and whose
! 25359: * [local name] and [namespace name] resolve (as
! 25360: * defined by QName resolution (Instance) (�3.15.4)) to
! 25361: * an attribute declaration whose {type definition} is
! 25362: * or is derived from ID. Then all of the following
! 25363: * must be true:"
! 25364: */
! 25365: iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
! 25366: if (xmlSchemaIsDerivedFromBuiltInType(
! 25367: iattr->typeDef, XML_SCHEMAS_ID)) {
! 25368: /*
! 25369: * SPEC (5.1) "There must be no more than one
! 25370: * item in �wild IDs�."
! 25371: */
! 25372: if (wildIDs != 0) {
! 25373: /* VAL TODO */
! 25374: iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
! 25375: TODO
! 25376: continue;
! 25377: }
! 25378: wildIDs++;
! 25379: /*
! 25380: * SPEC (cvc-complex-type)
! 25381: * (5.2) "If �wild IDs� is non-empty, there must not
! 25382: * be any attribute uses among the {attribute uses}
! 25383: * whose {attribute declaration}'s {type definition}
! 25384: * is or is derived from ID."
! 25385: */
! 25386: if (attrUseList != NULL) {
! 25387: for (j = 0; j < attrUseList->nbItems; j++) {
! 25388: if (xmlSchemaIsDerivedFromBuiltInType(
! 25389: WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
! 25390: XML_SCHEMAS_ID)) {
! 25391: /* URGENT VAL TODO: implement */
! 25392: iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
! 25393: TODO
! 25394: break;
! 25395: }
! 25396: }
! 25397: }
! 25398: }
! 25399: } else if (type->attributeWildcard->processContents ==
! 25400: XML_SCHEMAS_ANY_LAX) {
! 25401: iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
! 25402: /*
! 25403: * SPEC PSVI Assessment Outcome (Attribute)
! 25404: * [validity] = "notKnown"
! 25405: * [validation attempted] = "none"
! 25406: */
! 25407: } else {
! 25408: iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
! 25409: }
! 25410: }
! 25411: }
! 25412: }
! 25413:
! 25414: if (vctxt->nbAttrInfos == 0)
! 25415: return (0);
! 25416:
! 25417: /*
! 25418: * Get the owner element; needed for creation of default attributes.
! 25419: * This fixes bug #341337, reported by David Grohmann.
! 25420: */
! 25421: if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
! 25422: xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
! 25423: if (ielem && ielem->node && ielem->node->doc)
! 25424: defAttrOwnerElem = ielem->node;
! 25425: }
! 25426: /*
! 25427: * Validate values, create default attributes, evaluate IDCs.
! 25428: */
! 25429: for (i = 0; i < vctxt->nbAttrInfos; i++) {
! 25430: iattr = vctxt->attrInfos[i];
! 25431: /*
! 25432: * VAL TODO: Note that we won't try to resolve IDCs to
! 25433: * "lax" and "skip" validated attributes. Check what to
! 25434: * do in this case.
! 25435: */
! 25436: if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
! 25437: (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
! 25438: continue;
! 25439: /*
! 25440: * VAL TODO: What to do if the type definition is missing?
! 25441: */
! 25442: if (iattr->typeDef == NULL) {
! 25443: iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
! 25444: continue;
! 25445: }
! 25446:
! 25447: ACTIVATE_ATTRIBUTE(iattr);
! 25448: fixed = 0;
! 25449: xpathRes = 0;
! 25450:
! 25451: if (vctxt->xpathStates != NULL) {
! 25452: /*
! 25453: * Evaluate IDCs.
! 25454: */
! 25455: xpathRes = xmlSchemaXPathEvaluate(vctxt,
! 25456: XML_ATTRIBUTE_NODE);
! 25457: if (xpathRes == -1) {
! 25458: VERROR_INT("xmlSchemaVAttributesComplex",
! 25459: "calling xmlSchemaXPathEvaluate()");
! 25460: goto internal_error;
! 25461: }
! 25462: }
! 25463:
! 25464: if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
! 25465: /*
! 25466: * Default/fixed attributes.
! 25467: * We need the value only if we need to resolve IDCs or
! 25468: * will create default attributes.
! 25469: */
! 25470: if ((xpathRes) || (defAttrOwnerElem)) {
! 25471: if (iattr->use->defValue != NULL) {
! 25472: iattr->value = (xmlChar *) iattr->use->defValue;
! 25473: iattr->val = iattr->use->defVal;
! 25474: } else {
! 25475: iattr->value = (xmlChar *) iattr->decl->defValue;
! 25476: iattr->val = iattr->decl->defVal;
! 25477: }
! 25478: /*
! 25479: * IDCs will consume the precomputed default value,
! 25480: * so we need to clone it.
! 25481: */
! 25482: if (iattr->val == NULL) {
! 25483: VERROR_INT("xmlSchemaVAttributesComplex",
! 25484: "default/fixed value on an attribute use was "
! 25485: "not precomputed");
! 25486: goto internal_error;
! 25487: }
! 25488: iattr->val = xmlSchemaCopyValue(iattr->val);
! 25489: if (iattr->val == NULL) {
! 25490: VERROR_INT("xmlSchemaVAttributesComplex",
! 25491: "calling xmlSchemaCopyValue()");
! 25492: goto internal_error;
! 25493: }
! 25494: }
! 25495: /*
! 25496: * PSVI: Add the default attribute to the current element.
! 25497: * VAL TODO: Should we use the *normalized* value? This currently
! 25498: * uses the *initial* value.
! 25499: */
! 25500:
! 25501: if (defAttrOwnerElem) {
! 25502: xmlChar *normValue;
! 25503: const xmlChar *value;
! 25504:
! 25505: value = iattr->value;
! 25506: /*
! 25507: * Normalize the value.
! 25508: */
! 25509: normValue = xmlSchemaNormalizeValue(iattr->typeDef,
! 25510: iattr->value);
! 25511: if (normValue != NULL)
! 25512: value = BAD_CAST normValue;
! 25513:
! 25514: if (iattr->nsName == NULL) {
! 25515: if (xmlNewProp(defAttrOwnerElem,
! 25516: iattr->localName, value) == NULL) {
! 25517: VERROR_INT("xmlSchemaVAttributesComplex",
! 25518: "callling xmlNewProp()");
! 25519: if (normValue != NULL)
! 25520: xmlFree(normValue);
! 25521: goto internal_error;
! 25522: }
! 25523: } else {
! 25524: xmlNsPtr ns;
! 25525:
! 25526: ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
! 25527: defAttrOwnerElem, iattr->nsName);
! 25528: if (ns == NULL) {
! 25529: xmlChar prefix[12];
! 25530: int counter = 0;
! 25531:
! 25532: /*
! 25533: * Create a namespace declaration on the validation
! 25534: * root node if no namespace declaration is in scope.
! 25535: */
! 25536: do {
! 25537: snprintf((char *) prefix, 12, "p%d", counter++);
! 25538: ns = xmlSearchNs(defAttrOwnerElem->doc,
! 25539: defAttrOwnerElem, BAD_CAST prefix);
! 25540: if (counter > 1000) {
! 25541: VERROR_INT(
! 25542: "xmlSchemaVAttributesComplex",
! 25543: "could not compute a ns prefix for a "
! 25544: "default/fixed attribute");
! 25545: if (normValue != NULL)
! 25546: xmlFree(normValue);
! 25547: goto internal_error;
! 25548: }
! 25549: } while (ns != NULL);
! 25550: ns = xmlNewNs(vctxt->validationRoot,
! 25551: iattr->nsName, BAD_CAST prefix);
! 25552: }
! 25553: /*
! 25554: * TODO:
! 25555: * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
! 25556: * If we have QNames: do we need to ensure there's a
! 25557: * prefix defined for the QName?
! 25558: */
! 25559: xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
! 25560: }
! 25561: if (normValue != NULL)
! 25562: xmlFree(normValue);
! 25563: }
! 25564: /*
! 25565: * Go directly to IDC evaluation.
! 25566: */
! 25567: goto eval_idcs;
! 25568: }
! 25569: /*
! 25570: * Validate the value.
! 25571: */
! 25572: if (vctxt->value != NULL) {
! 25573: /*
! 25574: * Free last computed value; just for safety reasons.
! 25575: */
! 25576: xmlSchemaFreeValue(vctxt->value);
! 25577: vctxt->value = NULL;
! 25578: }
! 25579: /*
! 25580: * Note that the attribute *use* can be unavailable, if
! 25581: * the attribute was a wild attribute.
! 25582: */
! 25583: if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
! 25584: ((iattr->use != NULL) &&
! 25585: (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
! 25586: fixed = 1;
! 25587: else
! 25588: fixed = 0;
! 25589: /*
! 25590: * SPEC (cvc-attribute)
! 25591: * (3) "The item's �normalized value� must be locally �valid�
! 25592: * with respect to that {type definition} as per
! 25593: * String Valid (�3.14.4)."
! 25594: *
! 25595: * VAL TODO: Do we already have the
! 25596: * "normalized attribute value" here?
! 25597: */
! 25598: if (xpathRes || fixed) {
! 25599: iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
! 25600: /*
! 25601: * Request a computed value.
! 25602: */
! 25603: res = xmlSchemaVCheckCVCSimpleType(
! 25604: ACTXT_CAST vctxt,
! 25605: iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
! 25606: 1, 1, 0);
! 25607: } else {
! 25608: res = xmlSchemaVCheckCVCSimpleType(
! 25609: ACTXT_CAST vctxt,
! 25610: iattr->node, iattr->typeDef, iattr->value, NULL,
! 25611: 1, 0, 0);
! 25612: }
! 25613:
! 25614: if (res != 0) {
! 25615: if (res == -1) {
! 25616: VERROR_INT("xmlSchemaVAttributesComplex",
! 25617: "calling xmlSchemaStreamValidateSimpleTypeValue()");
! 25618: goto internal_error;
! 25619: }
! 25620: iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
! 25621: /*
! 25622: * SPEC PSVI Assessment Outcome (Attribute)
! 25623: * [validity] = "invalid"
! 25624: */
! 25625: goto eval_idcs;
! 25626: }
! 25627:
! 25628: if (fixed) {
! 25629: /*
! 25630: * SPEC Attribute Locally Valid (Use) (cvc-au)
! 25631: * "For an attribute information item to be�valid�
! 25632: * with respect to an attribute use its *normalized*
! 25633: * value� must match the *canonical* lexical
! 25634: * representation of the attribute use's {value
! 25635: * constraint}value, if it is present and fixed."
! 25636: *
! 25637: * VAL TODO: The requirement for the *canonical* value
! 25638: * will be removed in XML Schema 1.1.
! 25639: */
! 25640: /*
! 25641: * SPEC Attribute Locally Valid (cvc-attribute)
! 25642: * (4) "The item's *actual* value� must match the *value* of
! 25643: * the {value constraint}, if it is present and fixed."
! 25644: */
! 25645: if (iattr->val == NULL) {
! 25646: /* VAL TODO: A value was not precomputed. */
! 25647: TODO
! 25648: goto eval_idcs;
! 25649: }
! 25650: if ((iattr->use != NULL) &&
! 25651: (iattr->use->defValue != NULL)) {
! 25652: if (iattr->use->defVal == NULL) {
! 25653: /* VAL TODO: A default value was not precomputed. */
! 25654: TODO
! 25655: goto eval_idcs;
! 25656: }
! 25657: iattr->vcValue = iattr->use->defValue;
! 25658: /*
! 25659: if (xmlSchemaCompareValuesWhtsp(attr->val,
! 25660: (xmlSchemaWhitespaceValueType) ws,
! 25661: attr->use->defVal,
! 25662: (xmlSchemaWhitespaceValueType) ws) != 0) {
! 25663: */
! 25664: if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
! 25665: iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
! 25666: } else {
! 25667: if (iattr->decl->defVal == NULL) {
! 25668: /* VAL TODO: A default value was not precomputed. */
! 25669: TODO
! 25670: goto eval_idcs;
! 25671: }
! 25672: iattr->vcValue = iattr->decl->defValue;
! 25673: /*
! 25674: if (xmlSchemaCompareValuesWhtsp(attr->val,
! 25675: (xmlSchemaWhitespaceValueType) ws,
! 25676: attrDecl->defVal,
! 25677: (xmlSchemaWhitespaceValueType) ws) != 0) {
! 25678: */
! 25679: if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
! 25680: iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
! 25681: }
! 25682: /*
! 25683: * [validity] = "valid"
! 25684: */
! 25685: }
! 25686: eval_idcs:
! 25687: /*
! 25688: * Evaluate IDCs.
! 25689: */
! 25690: if (xpathRes) {
! 25691: if (xmlSchemaXPathProcessHistory(vctxt,
! 25692: vctxt->depth +1) == -1) {
! 25693: VERROR_INT("xmlSchemaVAttributesComplex",
! 25694: "calling xmlSchemaXPathEvaluate()");
! 25695: goto internal_error;
! 25696: }
! 25697: } else if (vctxt->xpathStates != NULL)
! 25698: xmlSchemaXPathPop(vctxt);
! 25699: }
! 25700:
! 25701: /*
! 25702: * Report errors.
! 25703: */
! 25704: for (i = 0; i < vctxt->nbAttrInfos; i++) {
! 25705: iattr = vctxt->attrInfos[i];
! 25706: if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
! 25707: (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
! 25708: (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
! 25709: (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
! 25710: continue;
! 25711: ACTIVATE_ATTRIBUTE(iattr);
! 25712: switch (iattr->state) {
! 25713: case XML_SCHEMAS_ATTR_ERR_MISSING: {
! 25714: xmlChar *str = NULL;
! 25715: ACTIVATE_ELEM;
! 25716: xmlSchemaCustomErr(ACTXT_CAST vctxt,
! 25717: XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
! 25718: "The attribute '%s' is required but missing",
! 25719: xmlSchemaFormatQName(&str,
! 25720: iattr->decl->targetNamespace,
! 25721: iattr->decl->name),
! 25722: NULL);
! 25723: FREE_AND_NULL(str)
! 25724: break;
! 25725: }
! 25726: case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
! 25727: VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
! 25728: "The type definition is absent");
! 25729: break;
! 25730: case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
! 25731: xmlSchemaCustomErr(ACTXT_CAST vctxt,
! 25732: XML_SCHEMAV_CVC_AU, NULL, NULL,
! 25733: "The value '%s' does not match the fixed "
! 25734: "value constraint '%s'",
! 25735: iattr->value, iattr->vcValue);
! 25736: break;
! 25737: case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
! 25738: VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
! 25739: "No matching global attribute declaration available, but "
! 25740: "demanded by the strict wildcard");
! 25741: break;
! 25742: case XML_SCHEMAS_ATTR_UNKNOWN:
! 25743: if (iattr->metaType)
! 25744: break;
! 25745: /*
! 25746: * MAYBE VAL TODO: One might report different error messages
! 25747: * for the following errors.
! 25748: */
! 25749: if (type->attributeWildcard == NULL) {
! 25750: xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
! 25751: XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
! 25752: } else {
! 25753: xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
! 25754: XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
! 25755: }
! 25756: break;
! 25757: default:
! 25758: break;
! 25759: }
! 25760: }
! 25761:
! 25762: ACTIVATE_ELEM;
! 25763: return (0);
! 25764: internal_error:
! 25765: ACTIVATE_ELEM;
! 25766: return (-1);
! 25767: }
! 25768:
! 25769: static int
! 25770: xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
! 25771: int *skip)
! 25772: {
! 25773: xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
! 25774: /*
! 25775: * The namespace of the element was already identified to be
! 25776: * matching the wildcard.
! 25777: */
! 25778: if ((skip == NULL) || (wild == NULL) ||
! 25779: (wild->type != XML_SCHEMA_TYPE_ANY)) {
! 25780: VERROR_INT("xmlSchemaValidateElemWildcard",
! 25781: "bad arguments");
! 25782: return (-1);
! 25783: }
! 25784: *skip = 0;
! 25785: if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
! 25786: /*
! 25787: * URGENT VAL TODO: Either we need to position the stream to the
! 25788: * next sibling, or walk the whole subtree.
! 25789: */
! 25790: *skip = 1;
! 25791: return (0);
! 25792: }
! 25793: {
! 25794: xmlSchemaElementPtr decl = NULL;
! 25795:
! 25796: decl = xmlSchemaGetElem(vctxt->schema,
! 25797: vctxt->inode->localName, vctxt->inode->nsName);
! 25798: if (decl != NULL) {
! 25799: vctxt->inode->decl = decl;
! 25800: return (0);
! 25801: }
! 25802: }
! 25803: if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
! 25804: /* VAL TODO: Change to proper error code. */
! 25805: VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
! 25806: "No matching global element declaration available, but "
! 25807: "demanded by the strict wildcard");
! 25808: return (vctxt->err);
! 25809: }
! 25810: if (vctxt->nbAttrInfos != 0) {
! 25811: xmlSchemaAttrInfoPtr iattr;
! 25812: /*
! 25813: * SPEC Validation Rule: Schema-Validity Assessment (Element)
! 25814: * (1.2.1.2.1) - (1.2.1.2.3 )
! 25815: *
! 25816: * Use the xsi:type attribute for the type definition.
! 25817: */
! 25818: iattr = xmlSchemaGetMetaAttrInfo(vctxt,
! 25819: XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
! 25820: if (iattr != NULL) {
! 25821: if (xmlSchemaProcessXSIType(vctxt, iattr,
! 25822: &(vctxt->inode->typeDef), NULL) == -1) {
! 25823: VERROR_INT("xmlSchemaValidateElemWildcard",
! 25824: "calling xmlSchemaProcessXSIType() to "
! 25825: "process the attribute 'xsi:nil'");
! 25826: return (-1);
! 25827: }
! 25828: /*
! 25829: * Don't return an error on purpose.
! 25830: */
! 25831: return (0);
! 25832: }
! 25833: }
! 25834: /*
! 25835: * SPEC Validation Rule: Schema-Validity Assessment (Element)
! 25836: *
! 25837: * Fallback to "anyType".
! 25838: */
! 25839: vctxt->inode->typeDef =
! 25840: xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
! 25841: return (0);
! 25842: }
! 25843:
! 25844: /*
! 25845: * xmlSchemaCheckCOSValidDefault:
! 25846: *
! 25847: * This will be called if: not nilled, no content and a default/fixed
! 25848: * value is provided.
! 25849: */
! 25850:
! 25851: static int
! 25852: xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
! 25853: const xmlChar *value,
! 25854: xmlSchemaValPtr *val)
! 25855: {
! 25856: int ret = 0;
! 25857: xmlSchemaNodeInfoPtr inode = vctxt->inode;
! 25858:
! 25859: /*
! 25860: * cos-valid-default:
! 25861: * Schema Component Constraint: Element Default Valid (Immediate)
! 25862: * For a string to be a valid default with respect to a type
! 25863: * definition the appropriate case among the following must be true:
! 25864: */
! 25865: if WXS_IS_COMPLEX(inode->typeDef) {
! 25866: /*
! 25867: * Complex type.
! 25868: *
! 25869: * SPEC (2.1) "its {content type} must be a simple type definition
! 25870: * or mixed."
! 25871: * SPEC (2.2.2) "If the {content type} is mixed, then the {content
! 25872: * type}'s particle must be �emptiable� as defined by
! 25873: * Particle Emptiable (�3.9.6)."
! 25874: */
! 25875: if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
! 25876: ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
! 25877: (! WXS_EMPTIABLE(inode->typeDef)))) {
! 25878: ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
! 25879: /* NOTE that this covers (2.2.2) as well. */
! 25880: VERROR(ret, NULL,
! 25881: "For a string to be a valid default, the type definition "
! 25882: "must be a simple type or a complex type with simple content "
! 25883: "or mixed content and a particle emptiable");
! 25884: return(ret);
! 25885: }
! 25886: }
! 25887: /*
! 25888: * 1 If the type definition is a simple type definition, then the string
! 25889: * must be �valid� with respect to that definition as defined by String
! 25890: * Valid (�3.14.4).
! 25891: *
! 25892: * AND
! 25893: *
! 25894: * 2.2.1 If the {content type} is a simple type definition, then the
! 25895: * string must be �valid� with respect to that simple type definition
! 25896: * as defined by String Valid (�3.14.4).
! 25897: */
! 25898: if (WXS_IS_SIMPLE(inode->typeDef)) {
! 25899:
! 25900: ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
! 25901: NULL, inode->typeDef, value, val, 1, 1, 0);
! 25902:
! 25903: } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
! 25904:
! 25905: ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
! 25906: NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
! 25907: }
! 25908: if (ret < 0) {
! 25909: VERROR_INT("xmlSchemaCheckCOSValidDefault",
! 25910: "calling xmlSchemaVCheckCVCSimpleType()");
! 25911: }
! 25912: return (ret);
! 25913: }
! 25914:
! 25915: static void
! 25916: xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
! 25917: const xmlChar * name ATTRIBUTE_UNUSED,
! 25918: xmlSchemaElementPtr item,
! 25919: xmlSchemaNodeInfoPtr inode)
! 25920: {
! 25921: inode->decl = item;
! 25922: #ifdef DEBUG_CONTENT
! 25923: {
! 25924: xmlChar *str = NULL;
! 25925:
! 25926: if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
! 25927: xmlGenericError(xmlGenericErrorContext,
! 25928: "AUTOMATON callback for '%s' [declaration]\n",
! 25929: xmlSchemaFormatQName(&str,
! 25930: inode->localName, inode->nsName));
! 25931: } else {
! 25932: xmlGenericError(xmlGenericErrorContext,
! 25933: "AUTOMATON callback for '%s' [wildcard]\n",
! 25934: xmlSchemaFormatQName(&str,
! 25935: inode->localName, inode->nsName));
! 25936:
! 25937: }
! 25938: FREE_AND_NULL(str)
! 25939: }
! 25940: #endif
! 25941: }
! 25942:
! 25943: static int
! 25944: xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
! 25945: {
! 25946: vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
! 25947: if (vctxt->inode == NULL) {
! 25948: VERROR_INT("xmlSchemaValidatorPushElem",
! 25949: "calling xmlSchemaGetFreshElemInfo()");
! 25950: return (-1);
! 25951: }
! 25952: vctxt->nbAttrInfos = 0;
! 25953: return (0);
! 25954: }
! 25955:
! 25956: static int
! 25957: xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
! 25958: xmlSchemaNodeInfoPtr inode,
! 25959: xmlSchemaTypePtr type,
! 25960: const xmlChar *value)
! 25961: {
! 25962: if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
! 25963: return (xmlSchemaVCheckCVCSimpleType(
! 25964: ACTXT_CAST vctxt, NULL,
! 25965: type, value, &(inode->val), 1, 1, 0));
! 25966: else
! 25967: return (xmlSchemaVCheckCVCSimpleType(
! 25968: ACTXT_CAST vctxt, NULL,
! 25969: type, value, NULL, 1, 0, 0));
! 25970: }
! 25971:
! 25972:
! 25973:
! 25974: /*
! 25975: * Process END of element.
! 25976: */
! 25977: static int
! 25978: xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
! 25979: {
! 25980: int ret = 0;
! 25981: xmlSchemaNodeInfoPtr inode = vctxt->inode;
! 25982:
! 25983: if (vctxt->nbAttrInfos != 0)
! 25984: xmlSchemaClearAttrInfos(vctxt);
! 25985: if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
! 25986: /*
! 25987: * This element was not expected;
! 25988: * we will not validate child elements of broken parents.
! 25989: * Skip validation of all content of the parent.
! 25990: */
! 25991: vctxt->skipDepth = vctxt->depth -1;
! 25992: goto end_elem;
! 25993: }
! 25994: if ((inode->typeDef == NULL) ||
! 25995: (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
! 25996: /*
! 25997: * 1. the type definition might be missing if the element was
! 25998: * error prone
! 25999: * 2. it might be abstract.
! 26000: */
! 26001: goto end_elem;
! 26002: }
! 26003: /*
! 26004: * Check the content model.
! 26005: */
! 26006: if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
! 26007: (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
! 26008:
! 26009: /*
! 26010: * Workaround for "anyType".
! 26011: */
! 26012: if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
! 26013: goto character_content;
! 26014:
! 26015: if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
! 26016: xmlChar *values[10];
! 26017: int terminal, nbval = 10, nbneg;
! 26018:
! 26019: if (inode->regexCtxt == NULL) {
! 26020: /*
! 26021: * Create the regex context.
! 26022: */
! 26023: inode->regexCtxt =
! 26024: xmlRegNewExecCtxt(inode->typeDef->contModel,
! 26025: (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
! 26026: vctxt);
! 26027: if (inode->regexCtxt == NULL) {
! 26028: VERROR_INT("xmlSchemaValidatorPopElem",
! 26029: "failed to create a regex context");
! 26030: goto internal_error;
! 26031: }
! 26032: #ifdef DEBUG_AUTOMATA
! 26033: xmlGenericError(xmlGenericErrorContext,
! 26034: "AUTOMATON create on '%s'\n", inode->localName);
! 26035: #endif
! 26036: }
! 26037: /*
! 26038: * Get hold of the still expected content, since a further
! 26039: * call to xmlRegExecPushString() will loose this information.
! 26040: */
! 26041: xmlRegExecNextValues(inode->regexCtxt,
! 26042: &nbval, &nbneg, &values[0], &terminal);
! 26043: ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
! 26044: if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
! 26045: /*
! 26046: * Still missing something.
! 26047: */
! 26048: ret = 1;
! 26049: inode->flags |=
! 26050: XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
! 26051: xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
! 26052: XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
! 26053: "Missing child element(s)",
! 26054: nbval, nbneg, values);
! 26055: #ifdef DEBUG_AUTOMATA
! 26056: xmlGenericError(xmlGenericErrorContext,
! 26057: "AUTOMATON missing ERROR on '%s'\n",
! 26058: inode->localName);
! 26059: #endif
! 26060: } else {
! 26061: /*
! 26062: * Content model is satisfied.
! 26063: */
! 26064: ret = 0;
! 26065: #ifdef DEBUG_AUTOMATA
! 26066: xmlGenericError(xmlGenericErrorContext,
! 26067: "AUTOMATON succeeded on '%s'\n",
! 26068: inode->localName);
! 26069: #endif
! 26070: }
! 26071:
! 26072: }
! 26073: }
! 26074: if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
! 26075: goto end_elem;
! 26076:
! 26077: character_content:
! 26078:
! 26079: if (vctxt->value != NULL) {
! 26080: xmlSchemaFreeValue(vctxt->value);
! 26081: vctxt->value = NULL;
! 26082: }
! 26083: /*
! 26084: * Check character content.
! 26085: */
! 26086: if (inode->decl == NULL) {
! 26087: /*
! 26088: * Speedup if no declaration exists.
! 26089: */
! 26090: if (WXS_IS_SIMPLE(inode->typeDef)) {
! 26091: ret = xmlSchemaVCheckINodeDataType(vctxt,
! 26092: inode, inode->typeDef, inode->value);
! 26093: } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
! 26094: ret = xmlSchemaVCheckINodeDataType(vctxt,
! 26095: inode, inode->typeDef->contentTypeDef,
! 26096: inode->value);
! 26097: }
! 26098: if (ret < 0) {
! 26099: VERROR_INT("xmlSchemaValidatorPopElem",
! 26100: "calling xmlSchemaVCheckCVCSimpleType()");
! 26101: goto internal_error;
! 26102: }
! 26103: goto end_elem;
! 26104: }
! 26105: /*
! 26106: * cvc-elt (3.3.4) : 5
! 26107: * The appropriate case among the following must be true:
! 26108: */
! 26109: /*
! 26110: * cvc-elt (3.3.4) : 5.1
! 26111: * If the declaration has a {value constraint},
! 26112: * the item has neither element nor character [children] and
! 26113: * clause 3.2 has not applied, then all of the following must be true:
! 26114: */
! 26115: if ((inode->decl->value != NULL) &&
! 26116: (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
! 26117: (! INODE_NILLED(inode))) {
! 26118: /*
! 26119: * cvc-elt (3.3.4) : 5.1.1
! 26120: * If the �actual type definition� is a �local type definition�
! 26121: * then the canonical lexical representation of the {value constraint}
! 26122: * value must be a valid default for the �actual type definition� as
! 26123: * defined in Element Default Valid (Immediate) (�3.3.6).
! 26124: */
! 26125: /*
! 26126: * NOTE: 'local' above means types acquired by xsi:type.
! 26127: * NOTE: Although the *canonical* value is stated, it is not
! 26128: * relevant if canonical or not. Additionally XML Schema 1.1
! 26129: * will removed this requirement as well.
! 26130: */
! 26131: if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
! 26132:
! 26133: ret = xmlSchemaCheckCOSValidDefault(vctxt,
! 26134: inode->decl->value, &(inode->val));
! 26135: if (ret != 0) {
! 26136: if (ret < 0) {
! 26137: VERROR_INT("xmlSchemaValidatorPopElem",
! 26138: "calling xmlSchemaCheckCOSValidDefault()");
! 26139: goto internal_error;
! 26140: }
! 26141: goto end_elem;
! 26142: }
! 26143: /*
! 26144: * Stop here, to avoid redundant validation of the value
! 26145: * (see following).
! 26146: */
! 26147: goto default_psvi;
! 26148: }
! 26149: /*
! 26150: * cvc-elt (3.3.4) : 5.1.2
! 26151: * The element information item with the canonical lexical
! 26152: * representation of the {value constraint} value used as its
! 26153: * �normalized value� must be �valid� with respect to the
! 26154: * �actual type definition� as defined by Element Locally Valid (Type)
! 26155: * (�3.3.4).
! 26156: */
! 26157: if (WXS_IS_SIMPLE(inode->typeDef)) {
! 26158: ret = xmlSchemaVCheckINodeDataType(vctxt,
! 26159: inode, inode->typeDef, inode->decl->value);
! 26160: } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
! 26161: ret = xmlSchemaVCheckINodeDataType(vctxt,
! 26162: inode, inode->typeDef->contentTypeDef,
! 26163: inode->decl->value);
! 26164: }
! 26165: if (ret != 0) {
! 26166: if (ret < 0) {
! 26167: VERROR_INT("xmlSchemaValidatorPopElem",
! 26168: "calling xmlSchemaVCheckCVCSimpleType()");
! 26169: goto internal_error;
! 26170: }
! 26171: goto end_elem;
! 26172: }
! 26173:
! 26174: default_psvi:
! 26175: /*
! 26176: * PSVI: Create a text node on the instance element.
! 26177: */
! 26178: if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
! 26179: (inode->node != NULL)) {
! 26180: xmlNodePtr textChild;
! 26181: xmlChar *normValue;
! 26182: /*
! 26183: * VAL TODO: Normalize the value.
! 26184: */
! 26185: normValue = xmlSchemaNormalizeValue(inode->typeDef,
! 26186: inode->decl->value);
! 26187: if (normValue != NULL) {
! 26188: textChild = xmlNewText(BAD_CAST normValue);
! 26189: xmlFree(normValue);
! 26190: } else
! 26191: textChild = xmlNewText(inode->decl->value);
! 26192: if (textChild == NULL) {
! 26193: VERROR_INT("xmlSchemaValidatorPopElem",
! 26194: "calling xmlNewText()");
! 26195: goto internal_error;
! 26196: } else
! 26197: xmlAddChild(inode->node, textChild);
! 26198: }
! 26199:
! 26200: } else if (! INODE_NILLED(inode)) {
! 26201: /*
! 26202: * 5.2.1 The element information item must be �valid� with respect
! 26203: * to the �actual type definition� as defined by Element Locally
! 26204: * Valid (Type) (�3.3.4).
! 26205: */
! 26206: if (WXS_IS_SIMPLE(inode->typeDef)) {
! 26207: /*
! 26208: * SPEC (cvc-type) (3.1)
! 26209: * "If the type definition is a simple type definition, ..."
! 26210: * (3.1.3) "If clause 3.2 of Element Locally Valid
! 26211: * (Element) (�3.3.4) did not apply, then the �normalized value�
! 26212: * must be �valid� with respect to the type definition as defined
! 26213: * by String Valid (�3.14.4).
! 26214: */
! 26215: ret = xmlSchemaVCheckINodeDataType(vctxt,
! 26216: inode, inode->typeDef, inode->value);
! 26217: } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
! 26218: /*
! 26219: * SPEC (cvc-type) (3.2) "If the type definition is a complex type
! 26220: * definition, then the element information item must be
! 26221: * �valid� with respect to the type definition as per
! 26222: * Element Locally Valid (Complex Type) (�3.4.4);"
! 26223: *
! 26224: * SPEC (cvc-complex-type) (2.2)
! 26225: * "If the {content type} is a simple type definition, ...
! 26226: * the �normalized value� of the element information item is
! 26227: * �valid� with respect to that simple type definition as
! 26228: * defined by String Valid (�3.14.4)."
! 26229: */
! 26230: ret = xmlSchemaVCheckINodeDataType(vctxt,
! 26231: inode, inode->typeDef->contentTypeDef, inode->value);
! 26232: }
! 26233: if (ret != 0) {
! 26234: if (ret < 0) {
! 26235: VERROR_INT("xmlSchemaValidatorPopElem",
! 26236: "calling xmlSchemaVCheckCVCSimpleType()");
! 26237: goto internal_error;
! 26238: }
! 26239: goto end_elem;
! 26240: }
! 26241: /*
! 26242: * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
! 26243: * not applied, all of the following must be true:
! 26244: */
! 26245: if ((inode->decl->value != NULL) &&
! 26246: (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
! 26247:
! 26248: /*
! 26249: * TODO: We will need a computed value, when comparison is
! 26250: * done on computed values.
! 26251: */
! 26252: /*
! 26253: * 5.2.2.1 The element information item must have no element
! 26254: * information item [children].
! 26255: */
! 26256: if (inode->flags &
! 26257: XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
! 26258: ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
! 26259: VERROR(ret, NULL,
! 26260: "The content must not containt element nodes since "
! 26261: "there is a fixed value constraint");
! 26262: goto end_elem;
! 26263: } else {
! 26264: /*
! 26265: * 5.2.2.2 The appropriate case among the following must
! 26266: * be true:
! 26267: */
! 26268: if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
! 26269: /*
! 26270: * 5.2.2.2.1 If the {content type} of the �actual type
! 26271: * definition� is mixed, then the *initial value* of the
! 26272: * item must match the canonical lexical representation
! 26273: * of the {value constraint} value.
! 26274: *
! 26275: * ... the *initial value* of an element information
! 26276: * item is the string composed of, in order, the
! 26277: * [character code] of each character information item in
! 26278: * the [children] of that element information item.
! 26279: */
! 26280: if (! xmlStrEqual(inode->value, inode->decl->value)){
! 26281: /*
! 26282: * VAL TODO: Report invalid & expected values as well.
! 26283: * VAL TODO: Implement the canonical stuff.
! 26284: */
! 26285: ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
! 26286: xmlSchemaCustomErr(ACTXT_CAST vctxt,
! 26287: ret, NULL, NULL,
! 26288: "The initial value '%s' does not match the fixed "
! 26289: "value constraint '%s'",
! 26290: inode->value, inode->decl->value);
! 26291: goto end_elem;
! 26292: }
! 26293: } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
! 26294: /*
! 26295: * 5.2.2.2.2 If the {content type} of the �actual type
! 26296: * definition� is a simple type definition, then the
! 26297: * *actual value* of the item must match the canonical
! 26298: * lexical representation of the {value constraint} value.
! 26299: */
! 26300: /*
! 26301: * VAL TODO: *actual value* is the normalized value, impl.
! 26302: * this.
! 26303: * VAL TODO: Report invalid & expected values as well.
! 26304: * VAL TODO: Implement a comparison with the computed values.
! 26305: */
! 26306: if (! xmlStrEqual(inode->value,
! 26307: inode->decl->value)) {
! 26308: ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
! 26309: xmlSchemaCustomErr(ACTXT_CAST vctxt,
! 26310: ret, NULL, NULL,
! 26311: "The actual value '%s' does not match the fixed "
! 26312: "value constraint '%s'",
! 26313: inode->value,
! 26314: inode->decl->value);
! 26315: goto end_elem;
! 26316: }
! 26317: }
! 26318: }
! 26319: }
! 26320: }
! 26321:
! 26322: end_elem:
! 26323: if (vctxt->depth < 0) {
! 26324: /* TODO: raise error? */
! 26325: return (0);
! 26326: }
! 26327: if (vctxt->depth == vctxt->skipDepth)
! 26328: vctxt->skipDepth = -1;
! 26329: /*
! 26330: * Evaluate the history of XPath state objects.
! 26331: */
! 26332: if (inode->appliedXPath &&
! 26333: (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
! 26334: goto internal_error;
! 26335: /*
! 26336: * MAYBE TODO:
! 26337: * SPEC (6) "The element information item must be �valid� with
! 26338: * respect to each of the {identity-constraint definitions} as per
! 26339: * Identity-constraint Satisfied (�3.11.4)."
! 26340: */
! 26341: /*
! 26342: * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
! 26343: * need to be built in any case.
! 26344: * We will currently build IDC node-tables and bubble them only if
! 26345: * keyrefs do exist.
! 26346: */
! 26347:
! 26348: /*
! 26349: * Add the current IDC target-nodes to the IDC node-tables.
! 26350: */
! 26351: if ((inode->idcMatchers != NULL) &&
! 26352: (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
! 26353: {
! 26354: if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
! 26355: goto internal_error;
! 26356: }
! 26357: /*
! 26358: * Validate IDC keyrefs.
! 26359: */
! 26360: if (vctxt->inode->hasKeyrefs)
! 26361: if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
! 26362: goto internal_error;
! 26363: /*
! 26364: * Merge/free the IDC table.
! 26365: */
! 26366: if (inode->idcTable != NULL) {
! 26367: #ifdef DEBUG_IDC_NODE_TABLE
! 26368: xmlSchemaDebugDumpIDCTable(stdout,
! 26369: inode->nsName,
! 26370: inode->localName,
! 26371: inode->idcTable);
! 26372: #endif
! 26373: if ((vctxt->depth > 0) &&
! 26374: (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
! 26375: {
! 26376: /*
! 26377: * Merge the IDC node table with the table of the parent node.
! 26378: */
! 26379: if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
! 26380: goto internal_error;
! 26381: }
! 26382: }
! 26383: /*
! 26384: * Clear the current ielem.
! 26385: * VAL TODO: Don't free the PSVI IDC tables if they are
! 26386: * requested for the PSVI.
! 26387: */
! 26388: xmlSchemaClearElemInfo(vctxt, inode);
! 26389: /*
! 26390: * Skip further processing if we are on the validation root.
! 26391: */
! 26392: if (vctxt->depth == 0) {
! 26393: vctxt->depth--;
! 26394: vctxt->inode = NULL;
! 26395: return (0);
! 26396: }
! 26397: /*
! 26398: * Reset the keyrefDepth if needed.
! 26399: */
! 26400: if (vctxt->aidcs != NULL) {
! 26401: xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
! 26402: do {
! 26403: if (aidc->keyrefDepth == vctxt->depth) {
! 26404: /*
! 26405: * A 'keyrefDepth' of a key/unique IDC matches the current
! 26406: * depth, this means that we are leaving the scope of the
! 26407: * top-most keyref IDC which refers to this IDC.
! 26408: */
! 26409: aidc->keyrefDepth = -1;
! 26410: }
! 26411: aidc = aidc->next;
! 26412: } while (aidc != NULL);
! 26413: }
! 26414: vctxt->depth--;
! 26415: vctxt->inode = vctxt->elemInfos[vctxt->depth];
! 26416: /*
! 26417: * VAL TODO: 7 If the element information item is the �validation root�, it must be
! 26418: * �valid� per Validation Root Valid (ID/IDREF) (�3.3.4).
! 26419: */
! 26420: return (ret);
! 26421:
! 26422: internal_error:
! 26423: vctxt->err = -1;
! 26424: return (-1);
! 26425: }
! 26426:
! 26427: /*
! 26428: * 3.4.4 Complex Type Definition Validation Rules
! 26429: * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
! 26430: */
! 26431: static int
! 26432: xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
! 26433: {
! 26434: xmlSchemaNodeInfoPtr pielem;
! 26435: xmlSchemaTypePtr ptype;
! 26436: int ret = 0;
! 26437:
! 26438: if (vctxt->depth <= 0) {
! 26439: VERROR_INT("xmlSchemaValidateChildElem",
! 26440: "not intended for the validation root");
! 26441: return (-1);
! 26442: }
! 26443: pielem = vctxt->elemInfos[vctxt->depth -1];
! 26444: if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
! 26445: pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
! 26446: /*
! 26447: * Handle 'nilled' elements.
! 26448: */
! 26449: if (INODE_NILLED(pielem)) {
! 26450: /*
! 26451: * SPEC (cvc-elt) (3.3.4) : (3.2.1)
! 26452: */
! 26453: ACTIVATE_PARENT_ELEM;
! 26454: ret = XML_SCHEMAV_CVC_ELT_3_2_1;
! 26455: VERROR(ret, NULL,
! 26456: "Neither character nor element content is allowed, "
! 26457: "because the element was 'nilled'");
! 26458: ACTIVATE_ELEM;
! 26459: goto unexpected_elem;
! 26460: }
! 26461:
! 26462: ptype = pielem->typeDef;
! 26463:
! 26464: if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
! 26465: /*
! 26466: * Workaround for "anyType": we have currently no content model
! 26467: * assigned for "anyType", so handle it explicitely.
! 26468: * "anyType" has an unbounded, lax "any" wildcard.
! 26469: */
! 26470: vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
! 26471: vctxt->inode->localName,
! 26472: vctxt->inode->nsName);
! 26473:
! 26474: if (vctxt->inode->decl == NULL) {
! 26475: xmlSchemaAttrInfoPtr iattr;
! 26476: /*
! 26477: * Process "xsi:type".
! 26478: * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
! 26479: */
! 26480: iattr = xmlSchemaGetMetaAttrInfo(vctxt,
! 26481: XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
! 26482: if (iattr != NULL) {
! 26483: ret = xmlSchemaProcessXSIType(vctxt, iattr,
! 26484: &(vctxt->inode->typeDef), NULL);
! 26485: if (ret != 0) {
! 26486: if (ret == -1) {
! 26487: VERROR_INT("xmlSchemaValidateChildElem",
! 26488: "calling xmlSchemaProcessXSIType() to "
! 26489: "process the attribute 'xsi:nil'");
! 26490: return (-1);
! 26491: }
! 26492: return (ret);
! 26493: }
! 26494: } else {
! 26495: /*
! 26496: * Fallback to "anyType".
! 26497: *
! 26498: * SPEC (cvc-assess-elt)
! 26499: * "If the item cannot be �strictly assessed�, [...]
! 26500: * an element information item's schema validity may be laxly
! 26501: * assessed if its �context-determined declaration� is not
! 26502: * skip by �validating� with respect to the �ur-type
! 26503: * definition� as per Element Locally Valid (Type) (�3.3.4)."
! 26504: */
! 26505: vctxt->inode->typeDef =
! 26506: xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
! 26507: }
! 26508: }
! 26509: return (0);
! 26510: }
! 26511:
! 26512: switch (ptype->contentType) {
! 26513: case XML_SCHEMA_CONTENT_EMPTY:
! 26514: /*
! 26515: * SPEC (2.1) "If the {content type} is empty, then the
! 26516: * element information item has no character or element
! 26517: * information item [children]."
! 26518: */
! 26519: ACTIVATE_PARENT_ELEM
! 26520: ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
! 26521: VERROR(ret, NULL,
! 26522: "Element content is not allowed, "
! 26523: "because the content type is empty");
! 26524: ACTIVATE_ELEM
! 26525: goto unexpected_elem;
! 26526: break;
! 26527:
! 26528: case XML_SCHEMA_CONTENT_MIXED:
! 26529: case XML_SCHEMA_CONTENT_ELEMENTS: {
! 26530: xmlRegExecCtxtPtr regexCtxt;
! 26531: xmlChar *values[10];
! 26532: int terminal, nbval = 10, nbneg;
! 26533:
! 26534: /* VAL TODO: Optimized "anyType" validation.*/
! 26535:
! 26536: if (ptype->contModel == NULL) {
! 26537: VERROR_INT("xmlSchemaValidateChildElem",
! 26538: "type has elem content but no content model");
! 26539: return (-1);
! 26540: }
! 26541: /*
! 26542: * Safety belf for evaluation if the cont. model was already
! 26543: * examined to be invalid.
! 26544: */
! 26545: if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
! 26546: VERROR_INT("xmlSchemaValidateChildElem",
! 26547: "validating elem, but elem content is already invalid");
! 26548: return (-1);
! 26549: }
! 26550:
! 26551: regexCtxt = pielem->regexCtxt;
! 26552: if (regexCtxt == NULL) {
! 26553: /*
! 26554: * Create the regex context.
! 26555: */
! 26556: regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
! 26557: (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
! 26558: vctxt);
! 26559: if (regexCtxt == NULL) {
! 26560: VERROR_INT("xmlSchemaValidateChildElem",
! 26561: "failed to create a regex context");
! 26562: return (-1);
! 26563: }
! 26564: pielem->regexCtxt = regexCtxt;
! 26565: #ifdef DEBUG_AUTOMATA
! 26566: xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
! 26567: pielem->localName);
! 26568: #endif
! 26569: }
! 26570:
! 26571: /*
! 26572: * SPEC (2.4) "If the {content type} is element-only or mixed,
! 26573: * then the sequence of the element information item's
! 26574: * element information item [children], if any, taken in
! 26575: * order, is �valid� with respect to the {content type}'s
! 26576: * particle, as defined in Element Sequence Locally Valid
! 26577: * (Particle) (�3.9.4)."
! 26578: */
! 26579: ret = xmlRegExecPushString2(regexCtxt,
! 26580: vctxt->inode->localName,
! 26581: vctxt->inode->nsName,
! 26582: vctxt->inode);
! 26583: #ifdef DEBUG_AUTOMATA
! 26584: if (ret < 0)
! 26585: xmlGenericError(xmlGenericErrorContext,
! 26586: "AUTOMATON push ERROR for '%s' on '%s'\n",
! 26587: vctxt->inode->localName, pielem->localName);
! 26588: else
! 26589: xmlGenericError(xmlGenericErrorContext,
! 26590: "AUTOMATON push OK for '%s' on '%s'\n",
! 26591: vctxt->inode->localName, pielem->localName);
! 26592: #endif
! 26593: if (vctxt->err == XML_SCHEMAV_INTERNAL) {
! 26594: VERROR_INT("xmlSchemaValidateChildElem",
! 26595: "calling xmlRegExecPushString2()");
! 26596: return (-1);
! 26597: }
! 26598: if (ret < 0) {
! 26599: xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
! 26600: &values[0], &terminal);
! 26601: xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
! 26602: XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
! 26603: "This element is not expected",
! 26604: nbval, nbneg, values);
! 26605: ret = vctxt->err;
! 26606: goto unexpected_elem;
! 26607: } else
! 26608: ret = 0;
! 26609: }
! 26610: break;
! 26611: case XML_SCHEMA_CONTENT_SIMPLE:
! 26612: case XML_SCHEMA_CONTENT_BASIC:
! 26613: ACTIVATE_PARENT_ELEM
! 26614: if (WXS_IS_COMPLEX(ptype)) {
! 26615: /*
! 26616: * SPEC (cvc-complex-type) (2.2)
! 26617: * "If the {content type} is a simple type definition, then
! 26618: * the element information item has no element information
! 26619: * item [children], ..."
! 26620: */
! 26621: ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
! 26622: VERROR(ret, NULL, "Element content is not allowed, "
! 26623: "because the content type is a simple type definition");
! 26624: } else {
! 26625: /*
! 26626: * SPEC (cvc-type) (3.1.2) "The element information item must
! 26627: * have no element information item [children]."
! 26628: */
! 26629: ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
! 26630: VERROR(ret, NULL, "Element content is not allowed, "
! 26631: "because the type definition is simple");
! 26632: }
! 26633: ACTIVATE_ELEM
! 26634: ret = vctxt->err;
! 26635: goto unexpected_elem;
! 26636: break;
! 26637:
! 26638: default:
! 26639: break;
! 26640: }
! 26641: return (ret);
! 26642: unexpected_elem:
! 26643: /*
! 26644: * Pop this element and set the skipDepth to skip
! 26645: * all further content of the parent element.
! 26646: */
! 26647: vctxt->skipDepth = vctxt->depth;
! 26648: vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
! 26649: pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
! 26650: return (ret);
! 26651: }
! 26652:
! 26653: #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
! 26654: #define XML_SCHEMA_PUSH_TEXT_CREATED 2
! 26655: #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
! 26656:
! 26657: static int
! 26658: xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
! 26659: int nodeType, const xmlChar *value, int len,
! 26660: int mode, int *consumed)
! 26661: {
! 26662: /*
! 26663: * Unfortunately we have to duplicate the text sometimes.
! 26664: * OPTIMIZE: Maybe we could skip it, if:
! 26665: * 1. content type is simple
! 26666: * 2. whitespace is "collapse"
! 26667: * 3. it consists of whitespace only
! 26668: *
! 26669: * Process character content.
! 26670: */
! 26671: if (consumed != NULL)
! 26672: *consumed = 0;
! 26673: if (INODE_NILLED(vctxt->inode)) {
! 26674: /*
! 26675: * SPEC cvc-elt (3.3.4 - 3.2.1)
! 26676: * "The element information item must have no character or
! 26677: * element information item [children]."
! 26678: */
! 26679: VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
! 26680: "Neither character nor element content is allowed "
! 26681: "because the element is 'nilled'");
! 26682: return (vctxt->err);
! 26683: }
! 26684: /*
! 26685: * SPEC (2.1) "If the {content type} is empty, then the
! 26686: * element information item has no character or element
! 26687: * information item [children]."
! 26688: */
! 26689: if (vctxt->inode->typeDef->contentType ==
! 26690: XML_SCHEMA_CONTENT_EMPTY) {
! 26691: VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
! 26692: "Character content is not allowed, "
! 26693: "because the content type is empty");
! 26694: return (vctxt->err);
! 26695: }
! 26696:
! 26697: if (vctxt->inode->typeDef->contentType ==
! 26698: XML_SCHEMA_CONTENT_ELEMENTS) {
! 26699: if ((nodeType != XML_TEXT_NODE) ||
! 26700: (! xmlSchemaIsBlank((xmlChar *) value, len))) {
! 26701: /*
! 26702: * SPEC cvc-complex-type (2.3)
! 26703: * "If the {content type} is element-only, then the
! 26704: * element information item has no character information
! 26705: * item [children] other than those whose [character
! 26706: * code] is defined as a white space in [XML 1.0 (Second
! 26707: * Edition)]."
! 26708: */
! 26709: VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
! 26710: "Character content other than whitespace is not allowed "
! 26711: "because the content type is 'element-only'");
! 26712: return (vctxt->err);
! 26713: }
! 26714: return (0);
! 26715: }
! 26716:
! 26717: if ((value == NULL) || (value[0] == 0))
! 26718: return (0);
! 26719: /*
! 26720: * Save the value.
! 26721: * NOTE that even if the content type is *mixed*, we need the
! 26722: * *initial value* for default/fixed value constraints.
! 26723: */
! 26724: if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
! 26725: ((vctxt->inode->decl == NULL) ||
! 26726: (vctxt->inode->decl->value == NULL)))
! 26727: return (0);
! 26728:
! 26729: if (vctxt->inode->value == NULL) {
! 26730: /*
! 26731: * Set the value.
! 26732: */
! 26733: switch (mode) {
! 26734: case XML_SCHEMA_PUSH_TEXT_PERSIST:
! 26735: /*
! 26736: * When working on a tree.
! 26737: */
! 26738: vctxt->inode->value = value;
! 26739: break;
! 26740: case XML_SCHEMA_PUSH_TEXT_CREATED:
! 26741: /*
! 26742: * When working with the reader.
! 26743: * The value will be freed by the element info.
! 26744: */
! 26745: vctxt->inode->value = value;
! 26746: if (consumed != NULL)
! 26747: *consumed = 1;
! 26748: vctxt->inode->flags |=
! 26749: XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
! 26750: break;
! 26751: case XML_SCHEMA_PUSH_TEXT_VOLATILE:
! 26752: /*
! 26753: * When working with SAX.
! 26754: * The value will be freed by the element info.
! 26755: */
! 26756: if (len != -1)
! 26757: vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
! 26758: else
! 26759: vctxt->inode->value = BAD_CAST xmlStrdup(value);
! 26760: vctxt->inode->flags |=
! 26761: XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
! 26762: break;
! 26763: default:
! 26764: break;
! 26765: }
! 26766: } else {
! 26767: if (len < 0)
! 26768: len = xmlStrlen(value);
! 26769: /*
! 26770: * Concat the value.
! 26771: */
! 26772: if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
! 26773: vctxt->inode->value = BAD_CAST xmlStrncat(
! 26774: (xmlChar *) vctxt->inode->value, value, len);
! 26775: } else {
! 26776: vctxt->inode->value =
! 26777: BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
! 26778: vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
! 26779: }
! 26780: }
! 26781:
! 26782: return (0);
! 26783: }
! 26784:
! 26785: static int
! 26786: xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
! 26787: {
! 26788: int ret = 0;
! 26789:
! 26790: if ((vctxt->skipDepth != -1) &&
! 26791: (vctxt->depth >= vctxt->skipDepth)) {
! 26792: VERROR_INT("xmlSchemaValidateElem",
! 26793: "in skip-state");
! 26794: goto internal_error;
! 26795: }
! 26796: if (vctxt->xsiAssemble) {
! 26797: /*
! 26798: * We will stop validation if there was an error during
! 26799: * dynamic schema construction.
! 26800: * Note that we simply set @skipDepth to 0, this could
! 26801: * mean that a streaming document via SAX would be
! 26802: * still read to the end but it won't be validated any more.
! 26803: * TODO: If we are sure how to stop the validation at once
! 26804: * for all input scenarios, then this should be changed to
! 26805: * instantly stop the validation.
! 26806: */
! 26807: ret = xmlSchemaAssembleByXSI(vctxt);
! 26808: if (ret != 0) {
! 26809: if (ret == -1)
! 26810: goto internal_error;
! 26811: vctxt->skipDepth = 0;
! 26812: return(ret);
! 26813: }
! 26814: /*
! 26815: * Augment the IDC definitions for the main schema and all imported ones
! 26816: * NOTE: main schema is the first in the imported list
! 26817: */
! 26818: xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
! 26819: }
! 26820: if (vctxt->depth > 0) {
! 26821: /*
! 26822: * Validate this element against the content model
! 26823: * of the parent.
! 26824: */
! 26825: ret = xmlSchemaValidateChildElem(vctxt);
! 26826: if (ret != 0) {
! 26827: if (ret < 0) {
! 26828: VERROR_INT("xmlSchemaValidateElem",
! 26829: "calling xmlSchemaStreamValidateChildElement()");
! 26830: goto internal_error;
! 26831: }
! 26832: goto exit;
! 26833: }
! 26834: if (vctxt->depth == vctxt->skipDepth)
! 26835: goto exit;
! 26836: if ((vctxt->inode->decl == NULL) &&
! 26837: (vctxt->inode->typeDef == NULL)) {
! 26838: VERROR_INT("xmlSchemaValidateElem",
! 26839: "the child element was valid but neither the "
! 26840: "declaration nor the type was set");
! 26841: goto internal_error;
! 26842: }
! 26843: } else {
! 26844: /*
! 26845: * Get the declaration of the validation root.
! 26846: */
! 26847: vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
! 26848: vctxt->inode->localName,
! 26849: vctxt->inode->nsName);
! 26850: if (vctxt->inode->decl == NULL) {
! 26851: ret = XML_SCHEMAV_CVC_ELT_1;
! 26852: VERROR(ret, NULL,
! 26853: "No matching global declaration available "
! 26854: "for the validation root");
! 26855: goto exit;
! 26856: }
! 26857: }
! 26858:
! 26859: if (vctxt->inode->decl == NULL)
! 26860: goto type_validation;
! 26861:
! 26862: if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
! 26863: int skip;
! 26864: /*
! 26865: * Wildcards.
! 26866: */
! 26867: ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
! 26868: if (ret != 0) {
! 26869: if (ret < 0) {
! 26870: VERROR_INT("xmlSchemaValidateElem",
! 26871: "calling xmlSchemaValidateElemWildcard()");
! 26872: goto internal_error;
! 26873: }
! 26874: goto exit;
! 26875: }
! 26876: if (skip) {
! 26877: vctxt->skipDepth = vctxt->depth;
! 26878: goto exit;
! 26879: }
! 26880: /*
! 26881: * The declaration might be set by the wildcard validation,
! 26882: * when the processContents is "lax" or "strict".
! 26883: */
! 26884: if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
! 26885: /*
! 26886: * Clear the "decl" field to not confuse further processing.
! 26887: */
! 26888: vctxt->inode->decl = NULL;
! 26889: goto type_validation;
! 26890: }
! 26891: }
! 26892: /*
! 26893: * Validate against the declaration.
! 26894: */
! 26895: ret = xmlSchemaValidateElemDecl(vctxt);
! 26896: if (ret != 0) {
! 26897: if (ret < 0) {
! 26898: VERROR_INT("xmlSchemaValidateElem",
! 26899: "calling xmlSchemaValidateElemDecl()");
! 26900: goto internal_error;
! 26901: }
! 26902: goto exit;
! 26903: }
! 26904: /*
! 26905: * Validate against the type definition.
! 26906: */
! 26907: type_validation:
! 26908:
! 26909: if (vctxt->inode->typeDef == NULL) {
! 26910: vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
! 26911: ret = XML_SCHEMAV_CVC_TYPE_1;
! 26912: VERROR(ret, NULL,
! 26913: "The type definition is absent");
! 26914: goto exit;
! 26915: }
! 26916: if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
! 26917: vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
! 26918: ret = XML_SCHEMAV_CVC_TYPE_2;
! 26919: VERROR(ret, NULL,
! 26920: "The type definition is abstract");
! 26921: goto exit;
! 26922: }
! 26923: /*
! 26924: * Evaluate IDCs. Do it here, since new IDC matchers are registered
! 26925: * during validation against the declaration. This must be done
! 26926: * _before_ attribute validation.
! 26927: */
! 26928: if (vctxt->xpathStates != NULL) {
! 26929: ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
! 26930: vctxt->inode->appliedXPath = 1;
! 26931: if (ret == -1) {
! 26932: VERROR_INT("xmlSchemaValidateElem",
! 26933: "calling xmlSchemaXPathEvaluate()");
! 26934: goto internal_error;
! 26935: }
! 26936: }
! 26937: /*
! 26938: * Validate attributes.
! 26939: */
! 26940: if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
! 26941: if ((vctxt->nbAttrInfos != 0) ||
! 26942: (vctxt->inode->typeDef->attrUses != NULL)) {
! 26943:
! 26944: ret = xmlSchemaVAttributesComplex(vctxt);
! 26945: }
! 26946: } else if (vctxt->nbAttrInfos != 0) {
! 26947:
! 26948: ret = xmlSchemaVAttributesSimple(vctxt);
! 26949: }
! 26950: /*
! 26951: * Clear registered attributes.
! 26952: */
! 26953: if (vctxt->nbAttrInfos != 0)
! 26954: xmlSchemaClearAttrInfos(vctxt);
! 26955: if (ret == -1) {
! 26956: VERROR_INT("xmlSchemaValidateElem",
! 26957: "calling attributes validation");
! 26958: goto internal_error;
! 26959: }
! 26960: /*
! 26961: * Don't return an error if attributes are invalid on purpose.
! 26962: */
! 26963: ret = 0;
! 26964:
! 26965: exit:
! 26966: if (ret != 0)
! 26967: vctxt->skipDepth = vctxt->depth;
! 26968: return (ret);
! 26969: internal_error:
! 26970: return (-1);
! 26971: }
! 26972:
! 26973: #ifdef XML_SCHEMA_READER_ENABLED
! 26974: static int
! 26975: xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
! 26976: {
! 26977: const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
! 26978: int depth, nodeType, ret = 0, consumed;
! 26979: xmlSchemaNodeInfoPtr ielem;
! 26980:
! 26981: vctxt->depth = -1;
! 26982: ret = xmlTextReaderRead(vctxt->reader);
! 26983: /*
! 26984: * Move to the document element.
! 26985: */
! 26986: while (ret == 1) {
! 26987: nodeType = xmlTextReaderNodeType(vctxt->reader);
! 26988: if (nodeType == XML_ELEMENT_NODE)
! 26989: goto root_found;
! 26990: ret = xmlTextReaderRead(vctxt->reader);
! 26991: }
! 26992: goto exit;
! 26993:
! 26994: root_found:
! 26995:
! 26996: do {
! 26997: depth = xmlTextReaderDepth(vctxt->reader);
! 26998: nodeType = xmlTextReaderNodeType(vctxt->reader);
! 26999:
! 27000: if (nodeType == XML_ELEMENT_NODE) {
! 27001:
! 27002: vctxt->depth++;
! 27003: if (xmlSchemaValidatorPushElem(vctxt) == -1) {
! 27004: VERROR_INT("xmlSchemaVReaderWalk",
! 27005: "calling xmlSchemaValidatorPushElem()");
! 27006: goto internal_error;
! 27007: }
! 27008: ielem = vctxt->inode;
! 27009: ielem->localName = xmlTextReaderLocalName(vctxt->reader);
! 27010: ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
! 27011: ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
! 27012: /*
! 27013: * Is the element empty?
! 27014: */
! 27015: ret = xmlTextReaderIsEmptyElement(vctxt->reader);
! 27016: if (ret == -1) {
! 27017: VERROR_INT("xmlSchemaVReaderWalk",
! 27018: "calling xmlTextReaderIsEmptyElement()");
! 27019: goto internal_error;
! 27020: }
! 27021: if (ret) {
! 27022: ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
! 27023: }
! 27024: /*
! 27025: * Register attributes.
! 27026: */
! 27027: vctxt->nbAttrInfos = 0;
! 27028: ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
! 27029: if (ret == -1) {
! 27030: VERROR_INT("xmlSchemaVReaderWalk",
! 27031: "calling xmlTextReaderMoveToFirstAttribute()");
! 27032: goto internal_error;
! 27033: }
! 27034: if (ret == 1) {
! 27035: do {
! 27036: /*
! 27037: * VAL TODO: How do we know that the reader works on a
! 27038: * node tree, to be able to pass a node here?
! 27039: */
! 27040: if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
! 27041: (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
! 27042: xmlTextReaderNamespaceUri(vctxt->reader), 1,
! 27043: xmlTextReaderValue(vctxt->reader), 1) == -1) {
! 27044:
! 27045: VERROR_INT("xmlSchemaVReaderWalk",
! 27046: "calling xmlSchemaValidatorPushAttribute()");
! 27047: goto internal_error;
! 27048: }
! 27049: ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
! 27050: if (ret == -1) {
! 27051: VERROR_INT("xmlSchemaVReaderWalk",
! 27052: "calling xmlTextReaderMoveToFirstAttribute()");
! 27053: goto internal_error;
! 27054: }
! 27055: } while (ret == 1);
! 27056: /*
! 27057: * Back to element position.
! 27058: */
! 27059: ret = xmlTextReaderMoveToElement(vctxt->reader);
! 27060: if (ret == -1) {
! 27061: VERROR_INT("xmlSchemaVReaderWalk",
! 27062: "calling xmlTextReaderMoveToElement()");
! 27063: goto internal_error;
! 27064: }
! 27065: }
! 27066: /*
! 27067: * Validate the element.
! 27068: */
! 27069: ret= xmlSchemaValidateElem(vctxt);
! 27070: if (ret != 0) {
! 27071: if (ret == -1) {
! 27072: VERROR_INT("xmlSchemaVReaderWalk",
! 27073: "calling xmlSchemaValidateElem()");
! 27074: goto internal_error;
! 27075: }
! 27076: goto exit;
! 27077: }
! 27078: if (vctxt->depth == vctxt->skipDepth) {
! 27079: int curDepth;
! 27080: /*
! 27081: * Skip all content.
! 27082: */
! 27083: if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
! 27084: ret = xmlTextReaderRead(vctxt->reader);
! 27085: curDepth = xmlTextReaderDepth(vctxt->reader);
! 27086: while ((ret == 1) && (curDepth != depth)) {
! 27087: ret = xmlTextReaderRead(vctxt->reader);
! 27088: curDepth = xmlTextReaderDepth(vctxt->reader);
! 27089: }
! 27090: if (ret < 0) {
! 27091: /*
! 27092: * VAL TODO: A reader error occured; what to do here?
! 27093: */
! 27094: ret = 1;
! 27095: goto exit;
! 27096: }
! 27097: }
! 27098: goto leave_elem;
! 27099: }
! 27100: /*
! 27101: * READER VAL TODO: Is an END_ELEM really never called
! 27102: * if the elem is empty?
! 27103: */
! 27104: if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
! 27105: goto leave_elem;
! 27106: } else if (nodeType == END_ELEM) {
! 27107: /*
! 27108: * Process END of element.
! 27109: */
! 27110: leave_elem:
! 27111: ret = xmlSchemaValidatorPopElem(vctxt);
! 27112: if (ret != 0) {
! 27113: if (ret < 0) {
! 27114: VERROR_INT("xmlSchemaVReaderWalk",
! 27115: "calling xmlSchemaValidatorPopElem()");
! 27116: goto internal_error;
! 27117: }
! 27118: goto exit;
! 27119: }
! 27120: if (vctxt->depth >= 0)
! 27121: ielem = vctxt->inode;
! 27122: else
! 27123: ielem = NULL;
! 27124: } else if ((nodeType == XML_TEXT_NODE) ||
! 27125: (nodeType == XML_CDATA_SECTION_NODE) ||
! 27126: (nodeType == WHTSP) ||
! 27127: (nodeType == SIGN_WHTSP)) {
! 27128: /*
! 27129: * Process character content.
! 27130: */
! 27131: xmlChar *value;
! 27132:
! 27133: if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
! 27134: nodeType = XML_TEXT_NODE;
! 27135:
! 27136: value = xmlTextReaderValue(vctxt->reader);
! 27137: ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
! 27138: -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
! 27139: if (! consumed)
! 27140: xmlFree(value);
! 27141: if (ret == -1) {
! 27142: VERROR_INT("xmlSchemaVReaderWalk",
! 27143: "calling xmlSchemaVPushText()");
! 27144: goto internal_error;
! 27145: }
! 27146: } else if ((nodeType == XML_ENTITY_NODE) ||
! 27147: (nodeType == XML_ENTITY_REF_NODE)) {
! 27148: /*
! 27149: * VAL TODO: What to do with entities?
! 27150: */
! 27151: TODO
! 27152: }
! 27153: /*
! 27154: * Read next node.
! 27155: */
! 27156: ret = xmlTextReaderRead(vctxt->reader);
! 27157: } while (ret == 1);
! 27158:
! 27159: exit:
! 27160: return (ret);
! 27161: internal_error:
! 27162: return (-1);
! 27163: }
! 27164: #endif
! 27165:
! 27166: /************************************************************************
! 27167: * *
! 27168: * SAX validation handlers *
! 27169: * *
! 27170: ************************************************************************/
! 27171:
! 27172: /*
! 27173: * Process text content.
! 27174: */
! 27175: static void
! 27176: xmlSchemaSAXHandleText(void *ctx,
! 27177: const xmlChar * ch,
! 27178: int len)
! 27179: {
! 27180: xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
! 27181:
! 27182: if (vctxt->depth < 0)
! 27183: return;
! 27184: if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
! 27185: return;
! 27186: if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
! 27187: vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
! 27188: if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
! 27189: XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
! 27190: VERROR_INT("xmlSchemaSAXHandleCDataSection",
! 27191: "calling xmlSchemaVPushText()");
! 27192: vctxt->err = -1;
! 27193: xmlStopParser(vctxt->parserCtxt);
! 27194: }
! 27195: }
! 27196:
! 27197: /*
! 27198: * Process CDATA content.
! 27199: */
! 27200: static void
! 27201: xmlSchemaSAXHandleCDataSection(void *ctx,
! 27202: const xmlChar * ch,
! 27203: int len)
! 27204: {
! 27205: xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
! 27206:
! 27207: if (vctxt->depth < 0)
! 27208: return;
! 27209: if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
! 27210: return;
! 27211: if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
! 27212: vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
! 27213: if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
! 27214: XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
! 27215: VERROR_INT("xmlSchemaSAXHandleCDataSection",
! 27216: "calling xmlSchemaVPushText()");
! 27217: vctxt->err = -1;
! 27218: xmlStopParser(vctxt->parserCtxt);
! 27219: }
! 27220: }
! 27221:
! 27222: static void
! 27223: xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
! 27224: const xmlChar * name ATTRIBUTE_UNUSED)
! 27225: {
! 27226: xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
! 27227:
! 27228: if (vctxt->depth < 0)
! 27229: return;
! 27230: if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
! 27231: return;
! 27232: /* SAX VAL TODO: What to do here? */
! 27233: TODO
! 27234: }
! 27235:
! 27236: static void
! 27237: xmlSchemaSAXHandleStartElementNs(void *ctx,
! 27238: const xmlChar * localname,
! 27239: const xmlChar * prefix ATTRIBUTE_UNUSED,
! 27240: const xmlChar * URI,
! 27241: int nb_namespaces,
! 27242: const xmlChar ** namespaces,
! 27243: int nb_attributes,
! 27244: int nb_defaulted ATTRIBUTE_UNUSED,
! 27245: const xmlChar ** attributes)
! 27246: {
! 27247: xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
! 27248: int ret;
! 27249: xmlSchemaNodeInfoPtr ielem;
! 27250: int i, j;
! 27251:
! 27252: /*
! 27253: * SAX VAL TODO: What to do with nb_defaulted?
! 27254: */
! 27255: /*
! 27256: * Skip elements if inside a "skip" wildcard or invalid.
! 27257: */
! 27258: vctxt->depth++;
! 27259: if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
! 27260: return;
! 27261: /*
! 27262: * Push the element.
! 27263: */
! 27264: if (xmlSchemaValidatorPushElem(vctxt) == -1) {
! 27265: VERROR_INT("xmlSchemaSAXHandleStartElementNs",
! 27266: "calling xmlSchemaValidatorPushElem()");
! 27267: goto internal_error;
! 27268: }
! 27269: ielem = vctxt->inode;
! 27270: /*
! 27271: * TODO: Is this OK?
! 27272: */
! 27273: ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
! 27274: ielem->localName = localname;
! 27275: ielem->nsName = URI;
! 27276: ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
! 27277: /*
! 27278: * Register namespaces on the elem info.
! 27279: */
! 27280: if (nb_namespaces != 0) {
! 27281: /*
! 27282: * Although the parser builds its own namespace list,
! 27283: * we have no access to it, so we'll use an own one.
! 27284: */
! 27285: for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
! 27286: /*
! 27287: * Store prefix and namespace name.
! 27288: */
! 27289: if (ielem->nsBindings == NULL) {
! 27290: ielem->nsBindings =
! 27291: (const xmlChar **) xmlMalloc(10 *
! 27292: sizeof(const xmlChar *));
! 27293: if (ielem->nsBindings == NULL) {
! 27294: xmlSchemaVErrMemory(vctxt,
! 27295: "allocating namespace bindings for SAX validation",
! 27296: NULL);
! 27297: goto internal_error;
! 27298: }
! 27299: ielem->nbNsBindings = 0;
! 27300: ielem->sizeNsBindings = 5;
! 27301: } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
! 27302: ielem->sizeNsBindings *= 2;
! 27303: ielem->nsBindings =
! 27304: (const xmlChar **) xmlRealloc(
! 27305: (void *) ielem->nsBindings,
! 27306: ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
! 27307: if (ielem->nsBindings == NULL) {
! 27308: xmlSchemaVErrMemory(vctxt,
! 27309: "re-allocating namespace bindings for SAX validation",
! 27310: NULL);
! 27311: goto internal_error;
! 27312: }
! 27313: }
! 27314:
! 27315: ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
! 27316: if (namespaces[j+1][0] == 0) {
! 27317: /*
! 27318: * Handle xmlns="".
! 27319: */
! 27320: ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
! 27321: } else
! 27322: ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
! 27323: namespaces[j+1];
! 27324: ielem->nbNsBindings++;
! 27325: }
! 27326: }
! 27327: /*
! 27328: * Register attributes.
! 27329: * SAX VAL TODO: We are not adding namespace declaration
! 27330: * attributes yet.
! 27331: */
! 27332: if (nb_attributes != 0) {
! 27333: xmlChar *value;
! 27334:
! 27335: for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
! 27336: /*
! 27337: * Duplicate the value.
! 27338: */
! 27339: value = xmlStrndup(attributes[j+3],
! 27340: attributes[j+4] - attributes[j+3]);
! 27341: /*
! 27342: * TODO: Set the node line.
! 27343: */
! 27344: ret = xmlSchemaValidatorPushAttribute(vctxt,
! 27345: NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
! 27346: value, 1);
! 27347: if (ret == -1) {
! 27348: VERROR_INT("xmlSchemaSAXHandleStartElementNs",
! 27349: "calling xmlSchemaValidatorPushAttribute()");
! 27350: goto internal_error;
! 27351: }
! 27352: }
! 27353: }
! 27354: /*
! 27355: * Validate the element.
! 27356: */
! 27357: ret = xmlSchemaValidateElem(vctxt);
! 27358: if (ret != 0) {
! 27359: if (ret == -1) {
! 27360: VERROR_INT("xmlSchemaSAXHandleStartElementNs",
! 27361: "calling xmlSchemaValidateElem()");
! 27362: goto internal_error;
! 27363: }
! 27364: goto exit;
! 27365: }
! 27366:
! 27367: exit:
! 27368: return;
! 27369: internal_error:
! 27370: vctxt->err = -1;
! 27371: xmlStopParser(vctxt->parserCtxt);
! 27372: return;
! 27373: }
! 27374:
! 27375: static void
! 27376: xmlSchemaSAXHandleEndElementNs(void *ctx,
! 27377: const xmlChar * localname ATTRIBUTE_UNUSED,
! 27378: const xmlChar * prefix ATTRIBUTE_UNUSED,
! 27379: const xmlChar * URI ATTRIBUTE_UNUSED)
! 27380: {
! 27381: xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
! 27382: int res;
! 27383:
! 27384: /*
! 27385: * Skip elements if inside a "skip" wildcard or if invalid.
! 27386: */
! 27387: if (vctxt->skipDepth != -1) {
! 27388: if (vctxt->depth > vctxt->skipDepth) {
! 27389: vctxt->depth--;
! 27390: return;
! 27391: } else
! 27392: vctxt->skipDepth = -1;
! 27393: }
! 27394: /*
! 27395: * SAX VAL TODO: Just a temporary check.
! 27396: */
! 27397: if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
! 27398: (!xmlStrEqual(vctxt->inode->nsName, URI))) {
! 27399: VERROR_INT("xmlSchemaSAXHandleEndElementNs",
! 27400: "elem pop mismatch");
! 27401: }
! 27402: res = xmlSchemaValidatorPopElem(vctxt);
! 27403: if (res != 0) {
! 27404: if (res < 0) {
! 27405: VERROR_INT("xmlSchemaSAXHandleEndElementNs",
! 27406: "calling xmlSchemaValidatorPopElem()");
! 27407: goto internal_error;
! 27408: }
! 27409: goto exit;
! 27410: }
! 27411: exit:
! 27412: return;
! 27413: internal_error:
! 27414: vctxt->err = -1;
! 27415: xmlStopParser(vctxt->parserCtxt);
! 27416: return;
! 27417: }
! 27418:
! 27419: /************************************************************************
! 27420: * *
! 27421: * Validation interfaces *
! 27422: * *
! 27423: ************************************************************************/
! 27424:
! 27425: /**
! 27426: * xmlSchemaNewValidCtxt:
! 27427: * @schema: a precompiled XML Schemas
! 27428: *
! 27429: * Create an XML Schemas validation context based on the given schema.
! 27430: *
! 27431: * Returns the validation context or NULL in case of error
! 27432: */
! 27433: xmlSchemaValidCtxtPtr
! 27434: xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
! 27435: {
! 27436: xmlSchemaValidCtxtPtr ret;
! 27437:
! 27438: ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
! 27439: if (ret == NULL) {
! 27440: xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
! 27441: return (NULL);
! 27442: }
! 27443: memset(ret, 0, sizeof(xmlSchemaValidCtxt));
! 27444: ret->type = XML_SCHEMA_CTXT_VALIDATOR;
! 27445: ret->dict = xmlDictCreate();
! 27446: ret->nodeQNames = xmlSchemaItemListCreate();
! 27447: ret->schema = schema;
! 27448: return (ret);
! 27449: }
! 27450:
! 27451: /**
! 27452: * xmlSchemaClearValidCtxt:
! 27453: * @ctxt: the schema validation context
! 27454: *
! 27455: * Free the resources associated to the schema validation context;
! 27456: * leaves some fields alive intended for reuse of the context.
! 27457: */
! 27458: static void
! 27459: xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
! 27460: {
! 27461: if (vctxt == NULL)
! 27462: return;
! 27463:
! 27464: /*
! 27465: * TODO: Should we clear the flags?
! 27466: * Might be problematic if one reuses the context
! 27467: * and assumes that the options remain the same.
! 27468: */
! 27469: vctxt->flags = 0;
! 27470: vctxt->validationRoot = NULL;
! 27471: vctxt->doc = NULL;
! 27472: #ifdef LIBXML_READER_ENABLED
! 27473: vctxt->reader = NULL;
! 27474: #endif
! 27475: vctxt->hasKeyrefs = 0;
! 27476:
! 27477: if (vctxt->value != NULL) {
! 27478: xmlSchemaFreeValue(vctxt->value);
! 27479: vctxt->value = NULL;
! 27480: }
! 27481: /*
! 27482: * Augmented IDC information.
! 27483: */
! 27484: if (vctxt->aidcs != NULL) {
! 27485: xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
! 27486: do {
! 27487: next = cur->next;
! 27488: xmlFree(cur);
! 27489: cur = next;
! 27490: } while (cur != NULL);
! 27491: vctxt->aidcs = NULL;
! 27492: }
! 27493: if (vctxt->idcMatcherCache != NULL) {
! 27494: xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
! 27495:
! 27496: while (matcher) {
! 27497: tmp = matcher;
! 27498: matcher = matcher->nextCached;
! 27499: xmlSchemaIDCFreeMatcherList(tmp);
! 27500: }
! 27501: vctxt->idcMatcherCache = NULL;
! 27502: }
! 27503:
! 27504:
! 27505: if (vctxt->idcNodes != NULL) {
! 27506: int i;
! 27507: xmlSchemaPSVIIDCNodePtr item;
! 27508:
! 27509: for (i = 0; i < vctxt->nbIdcNodes; i++) {
! 27510: item = vctxt->idcNodes[i];
! 27511: xmlFree(item->keys);
! 27512: xmlFree(item);
! 27513: }
! 27514: xmlFree(vctxt->idcNodes);
! 27515: vctxt->idcNodes = NULL;
! 27516: vctxt->nbIdcNodes = 0;
! 27517: vctxt->sizeIdcNodes = 0;
! 27518: }
! 27519: /*
! 27520: * Note that we won't delete the XPath state pool here.
! 27521: */
! 27522: if (vctxt->xpathStates != NULL) {
! 27523: xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
! 27524: vctxt->xpathStates = NULL;
! 27525: }
! 27526: /*
! 27527: * Attribute info.
! 27528: */
! 27529: if (vctxt->nbAttrInfos != 0) {
! 27530: xmlSchemaClearAttrInfos(vctxt);
! 27531: }
! 27532: /*
! 27533: * Element info.
! 27534: */
! 27535: if (vctxt->elemInfos != NULL) {
! 27536: int i;
! 27537: xmlSchemaNodeInfoPtr ei;
! 27538:
! 27539: for (i = 0; i < vctxt->sizeElemInfos; i++) {
! 27540: ei = vctxt->elemInfos[i];
! 27541: if (ei == NULL)
! 27542: break;
! 27543: xmlSchemaClearElemInfo(vctxt, ei);
! 27544: }
! 27545: }
! 27546: xmlSchemaItemListClear(vctxt->nodeQNames);
! 27547: /* Recreate the dict. */
! 27548: xmlDictFree(vctxt->dict);
! 27549: /*
! 27550: * TODO: Is is save to recreate it? Do we have a scenario
! 27551: * where the user provides the dict?
! 27552: */
! 27553: vctxt->dict = xmlDictCreate();
! 27554: }
! 27555:
! 27556: /**
! 27557: * xmlSchemaFreeValidCtxt:
! 27558: * @ctxt: the schema validation context
! 27559: *
! 27560: * Free the resources associated to the schema validation context
! 27561: */
! 27562: void
! 27563: xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
! 27564: {
! 27565: if (ctxt == NULL)
! 27566: return;
! 27567: if (ctxt->value != NULL)
! 27568: xmlSchemaFreeValue(ctxt->value);
! 27569: if (ctxt->pctxt != NULL)
! 27570: xmlSchemaFreeParserCtxt(ctxt->pctxt);
! 27571: if (ctxt->idcNodes != NULL) {
! 27572: int i;
! 27573: xmlSchemaPSVIIDCNodePtr item;
! 27574:
! 27575: for (i = 0; i < ctxt->nbIdcNodes; i++) {
! 27576: item = ctxt->idcNodes[i];
! 27577: xmlFree(item->keys);
! 27578: xmlFree(item);
! 27579: }
! 27580: xmlFree(ctxt->idcNodes);
! 27581: }
! 27582: if (ctxt->idcKeys != NULL) {
! 27583: int i;
! 27584: for (i = 0; i < ctxt->nbIdcKeys; i++)
! 27585: xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
! 27586: xmlFree(ctxt->idcKeys);
! 27587: }
! 27588:
! 27589: if (ctxt->xpathStates != NULL) {
! 27590: xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
! 27591: ctxt->xpathStates = NULL;
! 27592: }
! 27593: if (ctxt->xpathStatePool != NULL) {
! 27594: xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
! 27595: ctxt->xpathStatePool = NULL;
! 27596: }
! 27597:
! 27598: /*
! 27599: * Augmented IDC information.
! 27600: */
! 27601: if (ctxt->aidcs != NULL) {
! 27602: xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
! 27603: do {
! 27604: next = cur->next;
! 27605: xmlFree(cur);
! 27606: cur = next;
! 27607: } while (cur != NULL);
! 27608: }
! 27609: if (ctxt->attrInfos != NULL) {
! 27610: int i;
! 27611: xmlSchemaAttrInfoPtr attr;
! 27612:
! 27613: /* Just a paranoid call to the cleanup. */
! 27614: if (ctxt->nbAttrInfos != 0)
! 27615: xmlSchemaClearAttrInfos(ctxt);
! 27616: for (i = 0; i < ctxt->sizeAttrInfos; i++) {
! 27617: attr = ctxt->attrInfos[i];
! 27618: xmlFree(attr);
! 27619: }
! 27620: xmlFree(ctxt->attrInfos);
! 27621: }
! 27622: if (ctxt->elemInfos != NULL) {
! 27623: int i;
! 27624: xmlSchemaNodeInfoPtr ei;
! 27625:
! 27626: for (i = 0; i < ctxt->sizeElemInfos; i++) {
! 27627: ei = ctxt->elemInfos[i];
! 27628: if (ei == NULL)
! 27629: break;
! 27630: xmlSchemaClearElemInfo(ctxt, ei);
! 27631: xmlFree(ei);
! 27632: }
! 27633: xmlFree(ctxt->elemInfos);
! 27634: }
! 27635: if (ctxt->nodeQNames != NULL)
! 27636: xmlSchemaItemListFree(ctxt->nodeQNames);
! 27637: if (ctxt->dict != NULL)
! 27638: xmlDictFree(ctxt->dict);
! 27639: xmlFree(ctxt);
! 27640: }
! 27641:
! 27642: /**
! 27643: * xmlSchemaIsValid:
! 27644: * @ctxt: the schema validation context
! 27645: *
! 27646: * Check if any error was detected during validation.
! 27647: *
! 27648: * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
! 27649: * of internal error.
! 27650: */
! 27651: int
! 27652: xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
! 27653: {
! 27654: if (ctxt == NULL)
! 27655: return(-1);
! 27656: return(ctxt->err == 0);
! 27657: }
! 27658:
! 27659: /**
! 27660: * xmlSchemaSetValidErrors:
! 27661: * @ctxt: a schema validation context
! 27662: * @err: the error function
! 27663: * @warn: the warning function
! 27664: * @ctx: the functions context
! 27665: *
! 27666: * Set the error and warning callback informations
! 27667: */
! 27668: void
! 27669: xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
! 27670: xmlSchemaValidityErrorFunc err,
! 27671: xmlSchemaValidityWarningFunc warn, void *ctx)
! 27672: {
! 27673: if (ctxt == NULL)
! 27674: return;
! 27675: ctxt->error = err;
! 27676: ctxt->warning = warn;
! 27677: ctxt->errCtxt = ctx;
! 27678: if (ctxt->pctxt != NULL)
! 27679: xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
! 27680: }
! 27681:
! 27682: /**
! 27683: * xmlSchemaSetValidStructuredErrors:
! 27684: * @ctxt: a schema validation context
! 27685: * @serror: the structured error function
! 27686: * @ctx: the functions context
! 27687: *
! 27688: * Set the structured error callback
! 27689: */
! 27690: void
! 27691: xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
! 27692: xmlStructuredErrorFunc serror, void *ctx)
! 27693: {
! 27694: if (ctxt == NULL)
! 27695: return;
! 27696: ctxt->serror = serror;
! 27697: ctxt->error = NULL;
! 27698: ctxt->warning = NULL;
! 27699: ctxt->errCtxt = ctx;
! 27700: if (ctxt->pctxt != NULL)
! 27701: xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
! 27702: }
! 27703:
! 27704: /**
! 27705: * xmlSchemaGetValidErrors:
! 27706: * @ctxt: a XML-Schema validation context
! 27707: * @err: the error function result
! 27708: * @warn: the warning function result
! 27709: * @ctx: the functions context result
! 27710: *
! 27711: * Get the error and warning callback informations
! 27712: *
! 27713: * Returns -1 in case of error and 0 otherwise
! 27714: */
! 27715: int
! 27716: xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
! 27717: xmlSchemaValidityErrorFunc * err,
! 27718: xmlSchemaValidityWarningFunc * warn, void **ctx)
! 27719: {
! 27720: if (ctxt == NULL)
! 27721: return (-1);
! 27722: if (err != NULL)
! 27723: *err = ctxt->error;
! 27724: if (warn != NULL)
! 27725: *warn = ctxt->warning;
! 27726: if (ctx != NULL)
! 27727: *ctx = ctxt->errCtxt;
! 27728: return (0);
! 27729: }
! 27730:
! 27731:
! 27732: /**
! 27733: * xmlSchemaSetValidOptions:
! 27734: * @ctxt: a schema validation context
! 27735: * @options: a combination of xmlSchemaValidOption
! 27736: *
! 27737: * Sets the options to be used during the validation.
! 27738: *
! 27739: * Returns 0 in case of success, -1 in case of an
! 27740: * API error.
! 27741: */
! 27742: int
! 27743: xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
! 27744: int options)
! 27745:
! 27746: {
! 27747: int i;
! 27748:
! 27749: if (ctxt == NULL)
! 27750: return (-1);
! 27751: /*
! 27752: * WARNING: Change the start value if adding to the
! 27753: * xmlSchemaValidOption.
! 27754: * TODO: Is there an other, more easy to maintain,
! 27755: * way?
! 27756: */
! 27757: for (i = 1; i < (int) sizeof(int) * 8; i++) {
! 27758: if (options & 1<<i)
! 27759: return (-1);
! 27760: }
! 27761: ctxt->options = options;
! 27762: return (0);
! 27763: }
! 27764:
! 27765: /**
! 27766: * xmlSchemaValidCtxtGetOptions:
! 27767: * @ctxt: a schema validation context
! 27768: *
! 27769: * Get the validation context options.
! 27770: *
! 27771: * Returns the option combination or -1 on error.
! 27772: */
! 27773: int
! 27774: xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
! 27775:
! 27776: {
! 27777: if (ctxt == NULL)
! 27778: return (-1);
! 27779: else
! 27780: return (ctxt->options);
! 27781: }
! 27782:
! 27783: static int
! 27784: xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
! 27785: {
! 27786: xmlAttrPtr attr;
! 27787: int ret = 0;
! 27788: xmlSchemaNodeInfoPtr ielem = NULL;
! 27789: xmlNodePtr node, valRoot;
! 27790: const xmlChar *nsName;
! 27791:
! 27792: /* DOC VAL TODO: Move this to the start function. */
! 27793: valRoot = xmlDocGetRootElement(vctxt->doc);
! 27794: if (valRoot == NULL) {
! 27795: /* VAL TODO: Error code? */
! 27796: VERROR(1, NULL, "The document has no document element");
! 27797: return (1);
! 27798: }
! 27799: vctxt->depth = -1;
! 27800: vctxt->validationRoot = valRoot;
! 27801: node = valRoot;
! 27802: while (node != NULL) {
! 27803: if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
! 27804: goto next_sibling;
! 27805: if (node->type == XML_ELEMENT_NODE) {
! 27806:
! 27807: /*
! 27808: * Init the node-info.
! 27809: */
! 27810: vctxt->depth++;
! 27811: if (xmlSchemaValidatorPushElem(vctxt) == -1)
! 27812: goto internal_error;
! 27813: ielem = vctxt->inode;
! 27814: ielem->node = node;
! 27815: ielem->nodeLine = node->line;
! 27816: ielem->localName = node->name;
! 27817: if (node->ns != NULL)
! 27818: ielem->nsName = node->ns->href;
! 27819: ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
! 27820: /*
! 27821: * Register attributes.
! 27822: * DOC VAL TODO: We do not register namespace declaration
! 27823: * attributes yet.
! 27824: */
! 27825: vctxt->nbAttrInfos = 0;
! 27826: if (node->properties != NULL) {
! 27827: attr = node->properties;
! 27828: do {
! 27829: if (attr->ns != NULL)
! 27830: nsName = attr->ns->href;
! 27831: else
! 27832: nsName = NULL;
! 27833: ret = xmlSchemaValidatorPushAttribute(vctxt,
! 27834: (xmlNodePtr) attr,
! 27835: /*
! 27836: * Note that we give it the line number of the
! 27837: * parent element.
! 27838: */
! 27839: ielem->nodeLine,
! 27840: attr->name, nsName, 0,
! 27841: xmlNodeListGetString(attr->doc, attr->children, 1), 1);
! 27842: if (ret == -1) {
! 27843: VERROR_INT("xmlSchemaDocWalk",
! 27844: "calling xmlSchemaValidatorPushAttribute()");
! 27845: goto internal_error;
! 27846: }
! 27847: attr = attr->next;
! 27848: } while (attr);
! 27849: }
! 27850: /*
! 27851: * Validate the element.
! 27852: */
! 27853: ret = xmlSchemaValidateElem(vctxt);
! 27854: if (ret != 0) {
! 27855: if (ret == -1) {
! 27856: VERROR_INT("xmlSchemaDocWalk",
! 27857: "calling xmlSchemaValidateElem()");
! 27858: goto internal_error;
! 27859: }
! 27860: /*
! 27861: * Don't stop validation; just skip the content
! 27862: * of this element.
! 27863: */
! 27864: goto leave_node;
! 27865: }
! 27866: if ((vctxt->skipDepth != -1) &&
! 27867: (vctxt->depth >= vctxt->skipDepth))
! 27868: goto leave_node;
! 27869: } else if ((node->type == XML_TEXT_NODE) ||
! 27870: (node->type == XML_CDATA_SECTION_NODE)) {
! 27871: /*
! 27872: * Process character content.
! 27873: */
! 27874: if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
! 27875: ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
! 27876: ret = xmlSchemaVPushText(vctxt, node->type, node->content,
! 27877: -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
! 27878: if (ret < 0) {
! 27879: VERROR_INT("xmlSchemaVDocWalk",
! 27880: "calling xmlSchemaVPushText()");
! 27881: goto internal_error;
! 27882: }
! 27883: /*
! 27884: * DOC VAL TODO: Should we skip further validation of the
! 27885: * element content here?
! 27886: */
! 27887: } else if ((node->type == XML_ENTITY_NODE) ||
! 27888: (node->type == XML_ENTITY_REF_NODE)) {
! 27889: /*
! 27890: * DOC VAL TODO: What to do with entities?
! 27891: */
! 27892: VERROR_INT("xmlSchemaVDocWalk",
! 27893: "there is at least one entity reference in the node-tree "
! 27894: "currently being validated. Processing of entities with "
! 27895: "this XML Schema processor is not supported (yet). Please "
! 27896: "substitute entities before validation.");
! 27897: goto internal_error;
! 27898: } else {
! 27899: goto leave_node;
! 27900: /*
! 27901: * DOC VAL TODO: XInclude nodes, etc.
! 27902: */
! 27903: }
! 27904: /*
! 27905: * Walk the doc.
! 27906: */
! 27907: if (node->children != NULL) {
! 27908: node = node->children;
! 27909: continue;
! 27910: }
! 27911: leave_node:
! 27912: if (node->type == XML_ELEMENT_NODE) {
! 27913: /*
! 27914: * Leaving the scope of an element.
! 27915: */
! 27916: if (node != vctxt->inode->node) {
! 27917: VERROR_INT("xmlSchemaVDocWalk",
! 27918: "element position mismatch");
! 27919: goto internal_error;
! 27920: }
! 27921: ret = xmlSchemaValidatorPopElem(vctxt);
! 27922: if (ret != 0) {
! 27923: if (ret < 0) {
! 27924: VERROR_INT("xmlSchemaVDocWalk",
! 27925: "calling xmlSchemaValidatorPopElem()");
! 27926: goto internal_error;
! 27927: }
! 27928: }
! 27929: if (node == valRoot)
! 27930: goto exit;
! 27931: }
! 27932: next_sibling:
! 27933: if (node->next != NULL)
! 27934: node = node->next;
! 27935: else {
! 27936: node = node->parent;
! 27937: goto leave_node;
! 27938: }
! 27939: }
! 27940:
! 27941: exit:
! 27942: return (ret);
! 27943: internal_error:
! 27944: return (-1);
! 27945: }
! 27946:
! 27947: static int
! 27948: xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
! 27949: /*
! 27950: * Some initialization.
! 27951: */
! 27952: vctxt->err = 0;
! 27953: vctxt->nberrors = 0;
! 27954: vctxt->depth = -1;
! 27955: vctxt->skipDepth = -1;
! 27956: vctxt->xsiAssemble = 0;
! 27957: vctxt->hasKeyrefs = 0;
! 27958: #ifdef ENABLE_IDC_NODE_TABLES_TEST
! 27959: vctxt->createIDCNodeTables = 1;
! 27960: #else
! 27961: vctxt->createIDCNodeTables = 0;
! 27962: #endif
! 27963: /*
! 27964: * Create a schema + parser if necessary.
! 27965: */
! 27966: if (vctxt->schema == NULL) {
! 27967: xmlSchemaParserCtxtPtr pctxt;
! 27968:
! 27969: vctxt->xsiAssemble = 1;
! 27970: /*
! 27971: * If not schema was given then we will create a schema
! 27972: * dynamically using XSI schema locations.
! 27973: *
! 27974: * Create the schema parser context.
! 27975: */
! 27976: if ((vctxt->pctxt == NULL) &&
! 27977: (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
! 27978: return (-1);
! 27979: pctxt = vctxt->pctxt;
! 27980: pctxt->xsiAssemble = 1;
! 27981: /*
! 27982: * Create the schema.
! 27983: */
! 27984: vctxt->schema = xmlSchemaNewSchema(pctxt);
! 27985: if (vctxt->schema == NULL)
! 27986: return (-1);
! 27987: /*
! 27988: * Create the schema construction context.
! 27989: */
! 27990: pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
! 27991: if (pctxt->constructor == NULL)
! 27992: return(-1);
! 27993: pctxt->constructor->mainSchema = vctxt->schema;
! 27994: /*
! 27995: * Take ownership of the constructor to be able to free it.
! 27996: */
! 27997: pctxt->ownsConstructor = 1;
! 27998: }
! 27999: /*
! 28000: * Augment the IDC definitions for the main schema and all imported ones
! 28001: * NOTE: main schema if the first in the imported list
! 28002: */
! 28003: xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
! 28004:
! 28005: return(0);
! 28006: }
! 28007:
! 28008: static void
! 28009: xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
! 28010: if (vctxt->xsiAssemble) {
! 28011: if (vctxt->schema != NULL) {
! 28012: xmlSchemaFree(vctxt->schema);
! 28013: vctxt->schema = NULL;
! 28014: }
! 28015: }
! 28016: xmlSchemaClearValidCtxt(vctxt);
! 28017: }
! 28018:
! 28019: static int
! 28020: xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
! 28021: {
! 28022: int ret = 0;
! 28023:
! 28024: if (xmlSchemaPreRun(vctxt) < 0)
! 28025: return(-1);
! 28026:
! 28027: if (vctxt->doc != NULL) {
! 28028: /*
! 28029: * Tree validation.
! 28030: */
! 28031: ret = xmlSchemaVDocWalk(vctxt);
! 28032: #ifdef LIBXML_READER_ENABLED
! 28033: } else if (vctxt->reader != NULL) {
! 28034: /*
! 28035: * XML Reader validation.
! 28036: */
! 28037: #ifdef XML_SCHEMA_READER_ENABLED
! 28038: ret = xmlSchemaVReaderWalk(vctxt);
! 28039: #endif
! 28040: #endif
! 28041: } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
! 28042: /*
! 28043: * SAX validation.
! 28044: */
! 28045: ret = xmlParseDocument(vctxt->parserCtxt);
! 28046: } else {
! 28047: VERROR_INT("xmlSchemaVStart",
! 28048: "no instance to validate");
! 28049: ret = -1;
! 28050: }
! 28051:
! 28052: xmlSchemaPostRun(vctxt);
! 28053: if (ret == 0)
! 28054: ret = vctxt->err;
! 28055: return (ret);
! 28056: }
! 28057:
! 28058: /**
! 28059: * xmlSchemaValidateOneElement:
! 28060: * @ctxt: a schema validation context
! 28061: * @elem: an element node
! 28062: *
! 28063: * Validate a branch of a tree, starting with the given @elem.
! 28064: *
! 28065: * Returns 0 if the element and its subtree is valid, a positive error
! 28066: * code number otherwise and -1 in case of an internal or API error.
! 28067: */
! 28068: int
! 28069: xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
! 28070: {
! 28071: if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
! 28072: return (-1);
! 28073:
! 28074: if (ctxt->schema == NULL)
! 28075: return (-1);
! 28076:
! 28077: ctxt->doc = elem->doc;
! 28078: ctxt->node = elem;
! 28079: ctxt->validationRoot = elem;
! 28080: return(xmlSchemaVStart(ctxt));
! 28081: }
! 28082:
! 28083: /**
! 28084: * xmlSchemaValidateDoc:
! 28085: * @ctxt: a schema validation context
! 28086: * @doc: a parsed document tree
! 28087: *
! 28088: * Validate a document tree in memory.
! 28089: *
! 28090: * Returns 0 if the document is schemas valid, a positive error code
! 28091: * number otherwise and -1 in case of internal or API error.
! 28092: */
! 28093: int
! 28094: xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
! 28095: {
! 28096: if ((ctxt == NULL) || (doc == NULL))
! 28097: return (-1);
! 28098:
! 28099: ctxt->doc = doc;
! 28100: ctxt->node = xmlDocGetRootElement(doc);
! 28101: if (ctxt->node == NULL) {
! 28102: xmlSchemaCustomErr(ACTXT_CAST ctxt,
! 28103: XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
! 28104: (xmlNodePtr) doc, NULL,
! 28105: "The document has no document element", NULL, NULL);
! 28106: return (ctxt->err);
! 28107: }
! 28108: ctxt->validationRoot = ctxt->node;
! 28109: return (xmlSchemaVStart(ctxt));
! 28110: }
! 28111:
! 28112:
! 28113: /************************************************************************
! 28114: * *
! 28115: * Function and data for SAX streaming API *
! 28116: * *
! 28117: ************************************************************************/
! 28118: typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
! 28119: typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
! 28120:
! 28121: struct _xmlSchemaSplitSAXData {
! 28122: xmlSAXHandlerPtr user_sax;
! 28123: void *user_data;
! 28124: xmlSchemaValidCtxtPtr ctxt;
! 28125: xmlSAXHandlerPtr schemas_sax;
! 28126: };
! 28127:
! 28128: #define XML_SAX_PLUG_MAGIC 0xdc43ba21
! 28129:
! 28130: struct _xmlSchemaSAXPlug {
! 28131: unsigned int magic;
! 28132:
! 28133: /* the original callbacks informations */
! 28134: xmlSAXHandlerPtr *user_sax_ptr;
! 28135: xmlSAXHandlerPtr user_sax;
! 28136: void **user_data_ptr;
! 28137: void *user_data;
! 28138:
! 28139: /* the block plugged back and validation informations */
! 28140: xmlSAXHandler schemas_sax;
! 28141: xmlSchemaValidCtxtPtr ctxt;
! 28142: };
! 28143:
! 28144: /* All those functions just bounces to the user provided SAX handlers */
! 28145: static void
! 28146: internalSubsetSplit(void *ctx, const xmlChar *name,
! 28147: const xmlChar *ExternalID, const xmlChar *SystemID)
! 28148: {
! 28149: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28150: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28151: (ctxt->user_sax->internalSubset != NULL))
! 28152: ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
! 28153: SystemID);
! 28154: }
! 28155:
! 28156: static int
! 28157: isStandaloneSplit(void *ctx)
! 28158: {
! 28159: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28160: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28161: (ctxt->user_sax->isStandalone != NULL))
! 28162: return(ctxt->user_sax->isStandalone(ctxt->user_data));
! 28163: return(0);
! 28164: }
! 28165:
! 28166: static int
! 28167: hasInternalSubsetSplit(void *ctx)
! 28168: {
! 28169: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28170: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28171: (ctxt->user_sax->hasInternalSubset != NULL))
! 28172: return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
! 28173: return(0);
! 28174: }
! 28175:
! 28176: static int
! 28177: hasExternalSubsetSplit(void *ctx)
! 28178: {
! 28179: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28180: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28181: (ctxt->user_sax->hasExternalSubset != NULL))
! 28182: return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
! 28183: return(0);
! 28184: }
! 28185:
! 28186: static void
! 28187: externalSubsetSplit(void *ctx, const xmlChar *name,
! 28188: const xmlChar *ExternalID, const xmlChar *SystemID)
! 28189: {
! 28190: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28191: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28192: (ctxt->user_sax->externalSubset != NULL))
! 28193: ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
! 28194: SystemID);
! 28195: }
! 28196:
! 28197: static xmlParserInputPtr
! 28198: resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
! 28199: {
! 28200: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28201: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28202: (ctxt->user_sax->resolveEntity != NULL))
! 28203: return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
! 28204: systemId));
! 28205: return(NULL);
! 28206: }
! 28207:
! 28208: static xmlEntityPtr
! 28209: getEntitySplit(void *ctx, const xmlChar *name)
! 28210: {
! 28211: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28212: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28213: (ctxt->user_sax->getEntity != NULL))
! 28214: return(ctxt->user_sax->getEntity(ctxt->user_data, name));
! 28215: return(NULL);
! 28216: }
! 28217:
! 28218: static xmlEntityPtr
! 28219: getParameterEntitySplit(void *ctx, const xmlChar *name)
! 28220: {
! 28221: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28222: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28223: (ctxt->user_sax->getParameterEntity != NULL))
! 28224: return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
! 28225: return(NULL);
! 28226: }
! 28227:
! 28228:
! 28229: static void
! 28230: entityDeclSplit(void *ctx, const xmlChar *name, int type,
! 28231: const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
! 28232: {
! 28233: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28234: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28235: (ctxt->user_sax->entityDecl != NULL))
! 28236: ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
! 28237: systemId, content);
! 28238: }
! 28239:
! 28240: static void
! 28241: attributeDeclSplit(void *ctx, const xmlChar * elem,
! 28242: const xmlChar * name, int type, int def,
! 28243: const xmlChar * defaultValue, xmlEnumerationPtr tree)
! 28244: {
! 28245: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28246: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28247: (ctxt->user_sax->attributeDecl != NULL)) {
! 28248: ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
! 28249: def, defaultValue, tree);
! 28250: } else {
! 28251: xmlFreeEnumeration(tree);
! 28252: }
! 28253: }
! 28254:
! 28255: static void
! 28256: elementDeclSplit(void *ctx, const xmlChar *name, int type,
! 28257: xmlElementContentPtr content)
! 28258: {
! 28259: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28260: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28261: (ctxt->user_sax->elementDecl != NULL))
! 28262: ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
! 28263: }
! 28264:
! 28265: static void
! 28266: notationDeclSplit(void *ctx, const xmlChar *name,
! 28267: const xmlChar *publicId, const xmlChar *systemId)
! 28268: {
! 28269: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28270: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28271: (ctxt->user_sax->notationDecl != NULL))
! 28272: ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
! 28273: systemId);
! 28274: }
! 28275:
! 28276: static void
! 28277: unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
! 28278: const xmlChar *publicId, const xmlChar *systemId,
! 28279: const xmlChar *notationName)
! 28280: {
! 28281: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28282: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28283: (ctxt->user_sax->unparsedEntityDecl != NULL))
! 28284: ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
! 28285: systemId, notationName);
! 28286: }
! 28287:
! 28288: static void
! 28289: setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
! 28290: {
! 28291: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28292: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28293: (ctxt->user_sax->setDocumentLocator != NULL))
! 28294: ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
! 28295: }
! 28296:
! 28297: static void
! 28298: startDocumentSplit(void *ctx)
! 28299: {
! 28300: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28301: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28302: (ctxt->user_sax->startDocument != NULL))
! 28303: ctxt->user_sax->startDocument(ctxt->user_data);
! 28304: }
! 28305:
! 28306: static void
! 28307: endDocumentSplit(void *ctx)
! 28308: {
! 28309: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28310: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28311: (ctxt->user_sax->endDocument != NULL))
! 28312: ctxt->user_sax->endDocument(ctxt->user_data);
! 28313: }
! 28314:
! 28315: static void
! 28316: processingInstructionSplit(void *ctx, const xmlChar *target,
! 28317: const xmlChar *data)
! 28318: {
! 28319: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28320: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28321: (ctxt->user_sax->processingInstruction != NULL))
! 28322: ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
! 28323: }
! 28324:
! 28325: static void
! 28326: commentSplit(void *ctx, const xmlChar *value)
! 28327: {
! 28328: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28329: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28330: (ctxt->user_sax->comment != NULL))
! 28331: ctxt->user_sax->comment(ctxt->user_data, value);
! 28332: }
! 28333:
! 28334: /*
! 28335: * Varargs error callbacks to the user application, harder ...
! 28336: */
! 28337:
! 28338: static void XMLCDECL
! 28339: warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
! 28340: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28341: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28342: (ctxt->user_sax->warning != NULL)) {
! 28343: TODO
! 28344: }
! 28345: }
! 28346: static void XMLCDECL
! 28347: errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
! 28348: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28349: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28350: (ctxt->user_sax->error != NULL)) {
! 28351: TODO
! 28352: }
! 28353: }
! 28354: static void XMLCDECL
! 28355: fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
! 28356: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28357: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28358: (ctxt->user_sax->fatalError != NULL)) {
! 28359: TODO
! 28360: }
! 28361: }
! 28362:
! 28363: /*
! 28364: * Those are function where both the user handler and the schemas handler
! 28365: * need to be called.
! 28366: */
! 28367: static void
! 28368: charactersSplit(void *ctx, const xmlChar *ch, int len)
! 28369: {
! 28370: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28371: if (ctxt == NULL)
! 28372: return;
! 28373: if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
! 28374: ctxt->user_sax->characters(ctxt->user_data, ch, len);
! 28375: if (ctxt->ctxt != NULL)
! 28376: xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
! 28377: }
! 28378:
! 28379: static void
! 28380: ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
! 28381: {
! 28382: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28383: if (ctxt == NULL)
! 28384: return;
! 28385: if ((ctxt->user_sax != NULL) &&
! 28386: (ctxt->user_sax->ignorableWhitespace != NULL))
! 28387: ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
! 28388: if (ctxt->ctxt != NULL)
! 28389: xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
! 28390: }
! 28391:
! 28392: static void
! 28393: cdataBlockSplit(void *ctx, const xmlChar *value, int len)
! 28394: {
! 28395: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28396: if (ctxt == NULL)
! 28397: return;
! 28398: if ((ctxt->user_sax != NULL) &&
! 28399: (ctxt->user_sax->cdataBlock != NULL))
! 28400: ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
! 28401: if (ctxt->ctxt != NULL)
! 28402: xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
! 28403: }
! 28404:
! 28405: static void
! 28406: referenceSplit(void *ctx, const xmlChar *name)
! 28407: {
! 28408: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28409: if (ctxt == NULL)
! 28410: return;
! 28411: if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
! 28412: (ctxt->user_sax->reference != NULL))
! 28413: ctxt->user_sax->reference(ctxt->user_data, name);
! 28414: if (ctxt->ctxt != NULL)
! 28415: xmlSchemaSAXHandleReference(ctxt->user_data, name);
! 28416: }
! 28417:
! 28418: static void
! 28419: startElementNsSplit(void *ctx, const xmlChar * localname,
! 28420: const xmlChar * prefix, const xmlChar * URI,
! 28421: int nb_namespaces, const xmlChar ** namespaces,
! 28422: int nb_attributes, int nb_defaulted,
! 28423: const xmlChar ** attributes) {
! 28424: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28425: if (ctxt == NULL)
! 28426: return;
! 28427: if ((ctxt->user_sax != NULL) &&
! 28428: (ctxt->user_sax->startElementNs != NULL))
! 28429: ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
! 28430: URI, nb_namespaces, namespaces,
! 28431: nb_attributes, nb_defaulted,
! 28432: attributes);
! 28433: if (ctxt->ctxt != NULL)
! 28434: xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
! 28435: URI, nb_namespaces, namespaces,
! 28436: nb_attributes, nb_defaulted,
! 28437: attributes);
! 28438: }
! 28439:
! 28440: static void
! 28441: endElementNsSplit(void *ctx, const xmlChar * localname,
! 28442: const xmlChar * prefix, const xmlChar * URI) {
! 28443: xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
! 28444: if (ctxt == NULL)
! 28445: return;
! 28446: if ((ctxt->user_sax != NULL) &&
! 28447: (ctxt->user_sax->endElementNs != NULL))
! 28448: ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
! 28449: if (ctxt->ctxt != NULL)
! 28450: xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
! 28451: }
! 28452:
! 28453: /**
! 28454: * xmlSchemaSAXPlug:
! 28455: * @ctxt: a schema validation context
! 28456: * @sax: a pointer to the original xmlSAXHandlerPtr
! 28457: * @user_data: a pointer to the original SAX user data pointer
! 28458: *
! 28459: * Plug a SAX based validation layer in a SAX parsing event flow.
! 28460: * The original @saxptr and @dataptr data are replaced by new pointers
! 28461: * but the calls to the original will be maintained.
! 28462: *
! 28463: * Returns a pointer to a data structure needed to unplug the validation layer
! 28464: * or NULL in case of errors.
! 28465: */
! 28466: xmlSchemaSAXPlugPtr
! 28467: xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
! 28468: xmlSAXHandlerPtr *sax, void **user_data)
! 28469: {
! 28470: xmlSchemaSAXPlugPtr ret;
! 28471: xmlSAXHandlerPtr old_sax;
! 28472:
! 28473: if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
! 28474: return(NULL);
! 28475:
! 28476: /*
! 28477: * We only allow to plug into SAX2 event streams
! 28478: */
! 28479: old_sax = *sax;
! 28480: if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
! 28481: return(NULL);
! 28482: if ((old_sax != NULL) &&
! 28483: (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
! 28484: ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
! 28485: return(NULL);
! 28486:
! 28487: /*
! 28488: * everything seems right allocate the local data needed for that layer
! 28489: */
! 28490: ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
! 28491: if (ret == NULL) {
! 28492: return(NULL);
! 28493: }
! 28494: memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
! 28495: ret->magic = XML_SAX_PLUG_MAGIC;
! 28496: ret->schemas_sax.initialized = XML_SAX2_MAGIC;
! 28497: ret->ctxt = ctxt;
! 28498: ret->user_sax_ptr = sax;
! 28499: ret->user_sax = old_sax;
! 28500: if (old_sax == NULL) {
! 28501: /*
! 28502: * go direct, no need for the split block and functions.
! 28503: */
! 28504: ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
! 28505: ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
! 28506: /*
! 28507: * Note that we use the same text-function for both, to prevent
! 28508: * the parser from testing for ignorable whitespace.
! 28509: */
! 28510: ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
! 28511: ret->schemas_sax.characters = xmlSchemaSAXHandleText;
! 28512:
! 28513: ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
! 28514: ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
! 28515:
! 28516: ret->user_data = ctxt;
! 28517: *user_data = ctxt;
! 28518: } else {
! 28519: /*
! 28520: * for each callback unused by Schemas initialize it to the Split
! 28521: * routine only if non NULL in the user block, this can speed up
! 28522: * things at the SAX level.
! 28523: */
! 28524: if (old_sax->internalSubset != NULL)
! 28525: ret->schemas_sax.internalSubset = internalSubsetSplit;
! 28526: if (old_sax->isStandalone != NULL)
! 28527: ret->schemas_sax.isStandalone = isStandaloneSplit;
! 28528: if (old_sax->hasInternalSubset != NULL)
! 28529: ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
! 28530: if (old_sax->hasExternalSubset != NULL)
! 28531: ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
! 28532: if (old_sax->resolveEntity != NULL)
! 28533: ret->schemas_sax.resolveEntity = resolveEntitySplit;
! 28534: if (old_sax->getEntity != NULL)
! 28535: ret->schemas_sax.getEntity = getEntitySplit;
! 28536: if (old_sax->entityDecl != NULL)
! 28537: ret->schemas_sax.entityDecl = entityDeclSplit;
! 28538: if (old_sax->notationDecl != NULL)
! 28539: ret->schemas_sax.notationDecl = notationDeclSplit;
! 28540: if (old_sax->attributeDecl != NULL)
! 28541: ret->schemas_sax.attributeDecl = attributeDeclSplit;
! 28542: if (old_sax->elementDecl != NULL)
! 28543: ret->schemas_sax.elementDecl = elementDeclSplit;
! 28544: if (old_sax->unparsedEntityDecl != NULL)
! 28545: ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
! 28546: if (old_sax->setDocumentLocator != NULL)
! 28547: ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
! 28548: if (old_sax->startDocument != NULL)
! 28549: ret->schemas_sax.startDocument = startDocumentSplit;
! 28550: if (old_sax->endDocument != NULL)
! 28551: ret->schemas_sax.endDocument = endDocumentSplit;
! 28552: if (old_sax->processingInstruction != NULL)
! 28553: ret->schemas_sax.processingInstruction = processingInstructionSplit;
! 28554: if (old_sax->comment != NULL)
! 28555: ret->schemas_sax.comment = commentSplit;
! 28556: if (old_sax->warning != NULL)
! 28557: ret->schemas_sax.warning = warningSplit;
! 28558: if (old_sax->error != NULL)
! 28559: ret->schemas_sax.error = errorSplit;
! 28560: if (old_sax->fatalError != NULL)
! 28561: ret->schemas_sax.fatalError = fatalErrorSplit;
! 28562: if (old_sax->getParameterEntity != NULL)
! 28563: ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
! 28564: if (old_sax->externalSubset != NULL)
! 28565: ret->schemas_sax.externalSubset = externalSubsetSplit;
! 28566:
! 28567: /*
! 28568: * the 6 schemas callback have to go to the splitter functions
! 28569: * Note that we use the same text-function for ignorableWhitespace
! 28570: * if possible, to prevent the parser from testing for ignorable
! 28571: * whitespace.
! 28572: */
! 28573: ret->schemas_sax.characters = charactersSplit;
! 28574: if ((old_sax->ignorableWhitespace != NULL) &&
! 28575: (old_sax->ignorableWhitespace != old_sax->characters))
! 28576: ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
! 28577: else
! 28578: ret->schemas_sax.ignorableWhitespace = charactersSplit;
! 28579: ret->schemas_sax.cdataBlock = cdataBlockSplit;
! 28580: ret->schemas_sax.reference = referenceSplit;
! 28581: ret->schemas_sax.startElementNs = startElementNsSplit;
! 28582: ret->schemas_sax.endElementNs = endElementNsSplit;
! 28583:
! 28584: ret->user_data_ptr = user_data;
! 28585: ret->user_data = *user_data;
! 28586: *user_data = ret;
! 28587: }
! 28588:
! 28589: /*
! 28590: * plug the pointers back.
! 28591: */
! 28592: *sax = &(ret->schemas_sax);
! 28593: ctxt->sax = *sax;
! 28594: ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
! 28595: xmlSchemaPreRun(ctxt);
! 28596: return(ret);
! 28597: }
! 28598:
! 28599: /**
! 28600: * xmlSchemaSAXUnplug:
! 28601: * @plug: a data structure returned by xmlSchemaSAXPlug
! 28602: *
! 28603: * Unplug a SAX based validation layer in a SAX parsing event flow.
! 28604: * The original pointers used in the call are restored.
! 28605: *
! 28606: * Returns 0 in case of success and -1 in case of failure.
! 28607: */
! 28608: int
! 28609: xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
! 28610: {
! 28611: xmlSAXHandlerPtr *sax;
! 28612: void **user_data;
! 28613:
! 28614: if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
! 28615: return(-1);
! 28616: plug->magic = 0;
! 28617:
! 28618: xmlSchemaPostRun(plug->ctxt);
! 28619: /* restore the data */
! 28620: sax = plug->user_sax_ptr;
! 28621: *sax = plug->user_sax;
! 28622: if (plug->user_sax != NULL) {
! 28623: user_data = plug->user_data_ptr;
! 28624: *user_data = plug->user_data;
! 28625: }
! 28626:
! 28627: /* free and return */
! 28628: xmlFree(plug);
! 28629: return(0);
! 28630: }
! 28631:
! 28632: /**
! 28633: * xmlSchemaValidateStream:
! 28634: * @ctxt: a schema validation context
! 28635: * @input: the input to use for reading the data
! 28636: * @enc: an optional encoding information
! 28637: * @sax: a SAX handler for the resulting events
! 28638: * @user_data: the context to provide to the SAX handler.
! 28639: *
! 28640: * Validate an input based on a flow of SAX event from the parser
! 28641: * and forward the events to the @sax handler with the provided @user_data
! 28642: * the user provided @sax handler must be a SAX2 one.
! 28643: *
! 28644: * Returns 0 if the document is schemas valid, a positive error code
! 28645: * number otherwise and -1 in case of internal or API error.
! 28646: */
! 28647: int
! 28648: xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
! 28649: xmlParserInputBufferPtr input, xmlCharEncoding enc,
! 28650: xmlSAXHandlerPtr sax, void *user_data)
! 28651: {
! 28652: xmlSchemaSAXPlugPtr plug = NULL;
! 28653: xmlSAXHandlerPtr old_sax = NULL;
! 28654: xmlParserCtxtPtr pctxt = NULL;
! 28655: xmlParserInputPtr inputStream = NULL;
! 28656: int ret;
! 28657:
! 28658: if ((ctxt == NULL) || (input == NULL))
! 28659: return (-1);
! 28660:
! 28661: /*
! 28662: * prepare the parser
! 28663: */
! 28664: pctxt = xmlNewParserCtxt();
! 28665: if (pctxt == NULL)
! 28666: return (-1);
! 28667: old_sax = pctxt->sax;
! 28668: pctxt->sax = sax;
! 28669: pctxt->userData = user_data;
! 28670: #if 0
! 28671: if (options)
! 28672: xmlCtxtUseOptions(pctxt, options);
! 28673: #endif
! 28674: pctxt->linenumbers = 1;
! 28675:
! 28676: inputStream = xmlNewIOInputStream(pctxt, input, enc);;
! 28677: if (inputStream == NULL) {
! 28678: ret = -1;
! 28679: goto done;
! 28680: }
! 28681: inputPush(pctxt, inputStream);
! 28682: ctxt->parserCtxt = pctxt;
! 28683: ctxt->input = input;
! 28684:
! 28685: /*
! 28686: * Plug the validation and launch the parsing
! 28687: */
! 28688: plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
! 28689: if (plug == NULL) {
! 28690: ret = -1;
! 28691: goto done;
! 28692: }
! 28693: ctxt->input = input;
! 28694: ctxt->enc = enc;
! 28695: ctxt->sax = pctxt->sax;
! 28696: ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
! 28697: ret = xmlSchemaVStart(ctxt);
! 28698:
! 28699: if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
! 28700: ret = ctxt->parserCtxt->errNo;
! 28701: if (ret == 0)
! 28702: ret = 1;
! 28703: }
! 28704:
! 28705: done:
! 28706: ctxt->parserCtxt = NULL;
! 28707: ctxt->sax = NULL;
! 28708: ctxt->input = NULL;
! 28709: if (plug != NULL) {
! 28710: xmlSchemaSAXUnplug(plug);
! 28711: }
! 28712: /* cleanup */
! 28713: if (pctxt != NULL) {
! 28714: pctxt->sax = old_sax;
! 28715: xmlFreeParserCtxt(pctxt);
! 28716: }
! 28717: return (ret);
! 28718: }
! 28719:
! 28720: /**
! 28721: * xmlSchemaValidateFile:
! 28722: * @ctxt: a schema validation context
! 28723: * @filename: the URI of the instance
! 28724: * @options: a future set of options, currently unused
! 28725: *
! 28726: * Do a schemas validation of the given resource, it will use the
! 28727: * SAX streamable validation internally.
! 28728: *
! 28729: * Returns 0 if the document is valid, a positive error code
! 28730: * number otherwise and -1 in case of an internal or API error.
! 28731: */
! 28732: int
! 28733: xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
! 28734: const char * filename,
! 28735: int options ATTRIBUTE_UNUSED)
! 28736: {
! 28737: int ret;
! 28738: xmlParserInputBufferPtr input;
! 28739:
! 28740: if ((ctxt == NULL) || (filename == NULL))
! 28741: return (-1);
! 28742:
! 28743: input = xmlParserInputBufferCreateFilename(filename,
! 28744: XML_CHAR_ENCODING_NONE);
! 28745: if (input == NULL)
! 28746: return (-1);
! 28747: ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
! 28748: NULL, NULL);
! 28749: return (ret);
! 28750: }
! 28751:
! 28752: /**
! 28753: * xmlSchemaValidCtxtGetParserCtxt:
! 28754: * @ctxt: a schema validation context
! 28755: *
! 28756: * allow access to the parser context of the schema validation context
! 28757: *
! 28758: * Returns the parser context of the schema validation context or NULL
! 28759: * in case of error.
! 28760: */
! 28761: xmlParserCtxtPtr
! 28762: xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
! 28763: {
! 28764: if (ctxt == NULL)
! 28765: return(NULL);
! 28766: return (ctxt->parserCtxt);
! 28767: }
! 28768:
! 28769: #define bottom_xmlschemas
! 28770: #include "elfgcchack.h"
! 28771: #endif /* LIBXML_SCHEMAS_ENABLED */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>