2 * schemas.c : implementation of the XML Schema handling and
3 * schema validity checking
5 * See Copyright for the status of this software.
7 * Daniel Veillard <veillard@redhat.com>
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: ??
21 * - For xsi-driven schema acquisition, augment the IDCs after every
22 * acquisition episode (xmlSchemaAugmentIDC).
25 * - Elimated item creation for: <restriction>, <extension>,
26 * <simpleContent>, <complexContent>, <list>, <union>
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.
36 * Schema Component Constraint:
37 * All Group Limited (cos-all-limited)
40 * In xmlSchemaGroupDefReferenceTermFixup() and
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.
50 #ifdef LIBXML_SCHEMAS_ENABLED
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>
69 #ifdef LIBXML_READER_ENABLED
70 #include <libxml/xmlreader.h>
75 /* #define DEBUG_CONTENT 1 */
77 /* #define DEBUG_TYPE 1 */
79 /* #define DEBUG_CONTENT_REGEXP 1 */
81 /* #define DEBUG_AUTOMATA 1 */
83 /* #define DEBUG_IDC */
85 /* #define DEBUG_IDC_NODE_TABLE */
87 /* #define WXS_ELEM_DECL_CONS_ENABLED */
90 #ifndef DEBUG_IDC_NODE_TABLE
91 #define DEBUG_IDC_NODE_TABLE
95 /* #define ENABLE_PARTICLE_RESTRICTION 1 */
97 #define ENABLE_REDEFINE
99 /* #define ENABLE_NAMED_LOCALS */
101 /* #define ENABLE_IDC_NODE_TABLES_TEST */
103 #define DUMP_CONTENT_MODEL
105 #ifdef LIBXML_READER_ENABLED
106 /* #define XML_SCHEMA_READER_ENABLED */
109 #define UNBOUNDED (1 << 30)
111 xmlGenericError(xmlGenericErrorContext, \
112 "Unimplemented block at %s:%d\n", \
115 #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
118 * The XML Schemas namespaces
120 static const xmlChar *xmlSchemaNs = (const xmlChar *)
121 "http://www.w3.org/2001/XMLSchema";
123 static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
124 "http://www.w3.org/2001/XMLSchema-instance";
126 static const xmlChar *xmlNamespaceNs = (const xmlChar *)
127 "http://www.w3.org/2000/xmlns/";
130 * Come casting macros.
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)
151 * Macros to query common properties of components.
153 #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
155 #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
157 * Macros for element declarations.
159 #define WXS_ELEM_TYPEDEF(e) (e)->subtypes
161 #define WXS_SUBST_HEAD(item) (item)->refDecl
163 * Macros for attribute declarations.
165 #define WXS_ATTR_TYPEDEF(a) (a)->subtypes
167 * Macros for attribute uses.
169 #define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl
171 #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
173 #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
175 #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
177 * Macros for attribute groups.
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)
182 * Macros for particles.
184 #define WXS_PARTICLE(p) WXS_PTC_CAST (p)
186 #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
188 #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
190 #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
192 * Macros for model groups definitions.
194 #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
196 * Macros for model groups.
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))
203 #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
205 * Macros for schema buckets.
207 #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
208 ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
210 #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
211 ((t) == XML_SCHEMA_SCHEMA_IMPORT))
213 #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
215 #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
217 * Macros for complex/simple types.
219 #define WXS_IS_ANYTYPE(i) \
220 (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
221 ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
223 #define WXS_IS_COMPLEX(i) \
224 (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
225 ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
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)))
232 #define WXS_IS_ANY_SIMPLE_TYPE(i) \
233 (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
234 ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
236 #define WXS_IS_RESTRICTION(t) \
237 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
239 #define WXS_IS_EXTENSION(t) \
240 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
242 #define WXS_IS_TYPE_NOT_FIXED(i) \
243 (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
244 (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
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))
250 #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
252 #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
254 * Macros for exclusively for complex types.
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))
261 #define WXS_HAS_SIMPLE_CONTENT(item) \
262 ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
263 (item->contentType == XML_SCHEMA_CONTENT_BASIC))
265 #define WXS_HAS_MIXED_CONTENT(item) \
266 (item->contentType == XML_SCHEMA_CONTENT_MIXED)
268 #define WXS_EMPTIABLE(t) \
269 (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
271 #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
273 #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
275 #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
277 * Macros for exclusively for simple types.
279 #define WXS_LIST_ITEMTYPE(t) (t)->subtypes
281 #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
283 #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
285 #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
287 * Misc parser context macros.
289 #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
291 #define WXS_HAS_BUCKETS(ctx) \
292 ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
293 (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
295 #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
297 #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
299 #define WXS_SCHEMA(ctx) (ctx)->schema
301 #define WXS_ADD_LOCAL(ctx, item) \
302 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
304 #define WXS_ADD_GLOBAL(ctx, item) \
305 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
307 #define WXS_ADD_PENDING(ctx, item) \
308 xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
310 * xmlSchemaItemList macros.
312 #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
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)))
321 #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
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)))
328 #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
330 #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
332 #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
334 #define HFAILURE if (res == -1) goto exit_failure;
336 #define HERROR if (res != 0) goto exit_error;
338 #define HSTOP(ctx) if ((ctx)->stop) goto exit;
340 * Some flags used for various schema constraints.
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
348 typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
349 typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
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 */
359 #define XML_SCHEMA_CTXT_PARSER 1
360 #define XML_SCHEMA_CTXT_VALIDATOR 2
362 typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
363 typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
364 struct _xmlSchemaAbstractCtxt {
365 int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
368 typedef struct _xmlSchemaBucket xmlSchemaBucket;
369 typedef xmlSchemaBucket *xmlSchemaBucketPtr;
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
377 * xmlSchemaSchemaRelation:
379 * Used to create a graph of schema relationships.
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;
390 #define XML_SCHEMA_BUCKET_MARKED 1<<0
391 #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
393 struct _xmlSchemaBucket {
396 const xmlChar *schemaLocation;
397 const xmlChar *origTargetNamespace;
398 const xmlChar *targetNamespace;
400 xmlSchemaSchemaRelationPtr relations;
405 xmlSchemaItemListPtr globals; /* Global components. */
406 xmlSchemaItemListPtr locals; /* Local components. */
411 * (extends xmlSchemaBucket)
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.
417 typedef struct _xmlSchemaImport xmlSchemaImport;
418 typedef xmlSchemaImport *xmlSchemaImportPtr;
419 struct _xmlSchemaImport {
420 int type; /* Main OR import OR include. */
422 const xmlChar *schemaLocation; /* The URI of the schema document. */
423 /* For chameleon includes, @origTargetNamespace will be NULL */
424 const xmlChar *origTargetNamespace;
426 * For chameleon includes, @targetNamespace will be the
427 * targetNamespace of the including schema.
429 const xmlChar *targetNamespace;
430 xmlDocPtr doc; /* The schema node-tree. */
431 /* @relations will hold any included/imported/redefined schemas. */
432 xmlSchemaSchemaRelationPtr relations;
437 xmlSchemaItemListPtr globals;
438 xmlSchemaItemListPtr locals;
439 /* The imported schema. */
444 * (extends xmlSchemaBucket)
446 typedef struct _xmlSchemaInclude xmlSchemaInclude;
447 typedef xmlSchemaInclude *xmlSchemaIncludePtr;
448 struct _xmlSchemaInclude {
451 const xmlChar *schemaLocation;
452 const xmlChar *origTargetNamespace;
453 const xmlChar *targetNamespace;
455 xmlSchemaSchemaRelationPtr relations;
460 xmlSchemaItemListPtr globals; /* Global components. */
461 xmlSchemaItemListPtr locals; /* Local components. */
463 /* The owning main or import schema bucket. */
464 xmlSchemaImportPtr ownerImport;
468 * xmlSchemaBasicItem:
470 * The abstract base type for schema components.
472 typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
473 typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
474 struct _xmlSchemaBasicItem {
475 xmlSchemaTypeType type;
479 * xmlSchemaAnnotItem:
481 * The abstract base type for annotated schema components.
482 * (Extends xmlSchemaBasicItem)
484 typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
485 typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
486 struct _xmlSchemaAnnotItem {
487 xmlSchemaTypeType type;
488 xmlSchemaAnnotPtr annot;
494 * The abstract base type for tree-like structured schema components.
495 * (Extends xmlSchemaAnnotItem)
497 typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
498 typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
499 struct _xmlSchemaTreeItem {
500 xmlSchemaTypeType type;
501 xmlSchemaAnnotPtr annot;
502 xmlSchemaTreeItemPtr next;
503 xmlSchemaTreeItemPtr children;
507 #define XML_SCHEMA_ATTR_USE_FIXED 1<<0
509 * xmlSchemaAttributeUsePtr:
511 * The abstract base type for tree-like structured schema components.
512 * (Extends xmlSchemaTreeItem)
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. */
521 * The attr. decl. OR a QName-ref. to an attr. decl. OR
522 * a QName-ref. to an attribute group definition.
524 xmlSchemaAttributePtr attrDecl;
528 int occurs; /* required, optional */
529 const xmlChar * defValue;
530 xmlSchemaValPtr defVal;
534 * xmlSchemaAttributeUseProhibPtr:
536 * A helper component to reflect attribute prohibitions.
537 * (Extends xmlSchemaBasicItem)
539 typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
540 typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
541 struct _xmlSchemaAttributeUseProhib {
542 xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
545 const xmlChar *targetNamespace;
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. */
566 * xmlSchemaConstructionCtxt:
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 */
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
579 xmlHashTablePtr substGroups;
580 xmlSchemaRedefPtr redefs;
581 xmlSchemaRedefPtr lastRedef;
584 #define XML_SCHEMAS_PARSE_ERROR 1
585 #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
587 struct _xmlSchemaParserCtxt {
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 */
594 xmlStructuredErrorFunc serror;
596 xmlSchemaConstructionCtxtPtr constructor;
597 int ownsConstructor; /* TODO: Move this to parser *flags*. */
599 /* xmlSchemaPtr topschema; */
600 /* xmlHashTablePtr namespaces; */
602 xmlSchemaPtr schema; /* The main schema in use */
607 int preserve; /* Whether the doc should be freed */
613 * Used to build complex element content models
616 xmlAutomataStatePtr start;
617 xmlAutomataStatePtr end;
618 xmlAutomataStatePtr state;
620 xmlDictPtr dict; /* dictionnary for interned string names */
621 xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
623 xmlSchemaValidCtxtPtr vctxt;
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. */
631 xmlSchemaRedefPtr redef; /* Used for redefinitions. */
632 int redefCounter; /* Used for redefinitions. */
633 xmlSchemaItemListPtr attrProhibs;
639 * A component reference item (not a schema component)
640 * (Extends xmlSchemaBasicItem)
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;
649 const xmlChar *targetNamespace;
656 * A particle component.
657 * (Extends xmlSchemaTreeItem)
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),
674 * xmlSchemaModelGroup:
676 * A model group component.
677 * (Extends xmlSchemaTreeItem)
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") */
689 #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
690 #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
692 * xmlSchemaModelGroupDef:
694 * A model group definition component.
695 * (Extends xmlSchemaTreeItem)
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" */
705 const xmlChar *targetNamespace;
710 typedef struct _xmlSchemaIDC xmlSchemaIDC;
711 typedef xmlSchemaIDC *xmlSchemaIDCPtr;
714 * xmlSchemaIDCSelect:
716 * The identity-constraint "field" and "selector" item, holding the
719 typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
720 typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
721 struct _xmlSchemaIDCSelect {
722 xmlSchemaIDCSelectPtr next;
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 */
732 * The identity-constraint definition component.
733 * (Extends xmlSchemaAnnotItem)
736 struct _xmlSchemaIDC {
737 xmlSchemaTypeType type;
738 xmlSchemaAnnotPtr annot;
739 xmlSchemaIDCPtr next;
742 const xmlChar *targetNamespace;
743 xmlSchemaIDCSelectPtr selector;
744 xmlSchemaIDCSelectPtr fields;
746 xmlSchemaQNameRefPtr ref;
752 * The augmented IDC information used for validation.
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 */
764 * xmlSchemaPSVIIDCKeySequence:
766 * The key sequence of a node table item.
768 typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
769 typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
770 struct _xmlSchemaPSVIIDCKey {
771 xmlSchemaTypePtr type;
776 * xmlSchemaPSVIIDCNode:
778 * The node table item of a node table.
780 typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
781 typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
782 struct _xmlSchemaPSVIIDCNode {
784 xmlSchemaPSVIIDCKeyPtr *keys;
791 * xmlSchemaPSVIIDCBinding:
793 * The identity-constraint binding item of the [identity-constraint table].
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;
807 #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
808 #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
810 #define XPATH_STATE_OBJ_MATCHES -2
811 #define XPATH_STATE_OBJ_BLOCKED -3
813 typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
814 typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
817 * xmlSchemaIDCStateObj:
819 * The state object used to evaluate XPath expressions.
821 typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
822 typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
823 struct _xmlSchemaIDCStateObj {
825 xmlSchemaIDCStateObjPtr next; /* next if in a list */
826 int depth; /* depth of creation */
827 int *history; /* list of (depth, state-id) tuples */
830 xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
832 xmlSchemaIDCSelectPtr sel;
836 #define IDC_MATCHER 0
839 * xmlSchemaIDCMatcher:
841 * Used to evaluate IDC selectors (and fields).
843 struct _xmlSchemaIDCMatcher {
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 */
850 xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
853 xmlSchemaItemListPtr targets; /* list of target-node
854 (xmlSchemaPSVIIDCNodePtr) entries */
858 * Element info flags.
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
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
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
877 * Holds information of an element node.
879 struct _xmlSchemaNodeInfo {
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 */
889 int flags; /* combination of node info flags */
894 xmlSchemaElementPtr decl; /* the element/attribute declaration */
896 xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
897 for the scope element*/
898 xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
900 xmlRegExecCtxtPtr regexCtxt;
902 const xmlChar **nsBindings; /* Namespace bindings on this element */
907 int appliedXPath; /* Indicates that an XPath has been applied. */
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
928 * @metaType values of xmlSchemaAttrInfo.
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
936 typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
937 typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
938 struct _xmlSchemaAttrInfo {
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 */
949 xmlSchemaAttributePtr decl; /* the attribute declaration */
950 xmlSchemaAttributeUsePtr use; /* the attribute use */
953 const xmlChar *vcValue; /* the value constraint value */
954 xmlSchemaNodeInfoPtr parent;
958 #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
960 * xmlSchemaValidCtxt:
962 * A Schemas validation context
964 struct _xmlSchemaValidCtxt {
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;
971 xmlSchemaPtr schema; /* The schema in use */
973 xmlParserInputBufferPtr input;
975 xmlSAXHandlerPtr sax;
976 xmlParserCtxtPtr parserCtxt;
977 void *user_data; /* TODO: What is this for? */
984 /* xmlSchemaTypePtr type; */
986 xmlRegExecCtxtPtr regexp;
987 xmlSchemaValPtr value;
991 xmlNodePtr validationRoot;
992 xmlSchemaParserCtxtPtr pctxt;
996 xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */
998 xmlSchemaNodeInfoPtr inode; /* the current element information */
1000 xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */
1002 xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
1003 xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
1004 xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
1006 xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
1010 xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
1018 #ifdef LIBXML_READER_ENABLED
1019 xmlTextReaderPtr reader;
1022 xmlSchemaAttrInfoPtr *attrInfos;
1027 xmlSchemaItemListPtr nodeQNames;
1029 int createIDCNodeTables;
1030 int psviExposeIDCNodeTables;
1034 * xmlSchemaSubstGroup:
1038 typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
1039 typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
1040 struct _xmlSchemaSubstGroup {
1041 xmlSchemaElementPtr head;
1042 xmlSchemaItemListPtr members;
1045 /************************************************************************
1047 * Some predeclarations *
1049 ************************************************************************/
1051 static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
1052 xmlSchemaPtr schema,
1054 static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
1055 xmlSchemaPtr schema,
1058 xmlSchemaTypeFixup(xmlSchemaTypePtr type,
1059 xmlSchemaAbstractCtxtPtr ctxt);
1060 static const xmlChar *
1061 xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
1063 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1066 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
1067 xmlSchemaParserCtxtPtr ctxt);
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,
1076 static const xmlChar *
1077 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
1078 static xmlSchemaTypeLinkPtr
1079 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
1081 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
1082 const char *funcName,
1083 const char *message);
1085 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
1086 xmlSchemaTypePtr type,
1087 xmlSchemaTypePtr baseType,
1090 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
1091 xmlSchemaParserCtxtPtr ctxt);
1093 xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
1094 static xmlSchemaQNameRefPtr
1095 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
1096 xmlSchemaPtr schema,
1099 /************************************************************************
1101 * Helper functions *
1103 ************************************************************************/
1106 * xmlSchemaItemTypeToStr:
1107 * @type: the type of the schema item
1109 * Returns the component name of a schema item.
1111 static const xmlChar *
1112 xmlSchemaItemTypeToStr(xmlSchemaTypeType 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");
1157 return(BAD_CAST "Not a schema component");
1162 * xmlSchemaGetComponentTypeStr:
1163 * @type: the type of the schema item
1165 * Returns the component name of a schema item.
1167 static const xmlChar *
1168 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
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");
1175 return(BAD_CAST "simple type definition");
1177 return(xmlSchemaItemTypeToStr(item->type));
1182 * xmlSchemaGetComponentNode:
1183 * @item: a schema component
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.
1192 xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
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);
1225 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1226 return (((xmlSchemaAttributeUsePtr) item)->node);
1234 * xmlSchemaGetNextComponent:
1235 * @item: a schema component
1237 * Returns the next sibling of the schema component.
1239 static xmlSchemaBasicItemPtr
1240 xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
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:
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:
1259 case XML_SCHEMA_TYPE_GROUP:
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);
1275 * xmlSchemaFormatQName:
1276 * @buf: the string buffer
1277 * @namespaceName: the namespace name
1278 * @localName: the local name
1280 * Returns the given QName in the format "{namespaceName}localName" or
1281 * just "localName" if @namespaceName is NULL.
1283 * Returns the localName if @namespaceName is NULL, a formatted
1286 static const xmlChar*
1287 xmlSchemaFormatQName(xmlChar **buf,
1288 const xmlChar *namespaceName,
1289 const xmlChar *localName)
1292 if (namespaceName != NULL) {
1293 *buf = xmlStrdup(BAD_CAST "{");
1294 *buf = xmlStrcat(*buf, namespaceName);
1295 *buf = xmlStrcat(*buf, BAD_CAST "}");
1297 if (localName != NULL) {
1298 if (namespaceName == NULL)
1300 *buf = xmlStrcat(*buf, localName);
1302 *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
1304 return ((const xmlChar *) *buf);
1307 static const xmlChar*
1308 xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
1311 return (xmlSchemaFormatQName(buf, ns->href, localName));
1313 return (xmlSchemaFormatQName(buf, NULL, localName));
1316 static const xmlChar *
1317 xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
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)));
1342 case XML_SCHEMA_EXTRA_QNAMEREF:
1343 return (((xmlSchemaQNameRefPtr) item)->name);
1344 case XML_SCHEMA_TYPE_NOTATION:
1345 return (((xmlSchemaNotationPtr) item)->name);
1348 * Other components cannot have names.
1355 #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
1356 #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
1358 static const xmlChar *
1359 xmlSchemaGetQNameRefName(void *ref)
1361 return(((xmlSchemaQNameRefPtr) ref)->name);
1364 static const xmlChar *
1365 xmlSchemaGetQNameRefTargetNs(void *ref)
1367 return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
1371 static const xmlChar *
1372 xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
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)));
1397 /* TODO: Will returning NULL break something? */
1399 case XML_SCHEMA_EXTRA_QNAMEREF:
1400 return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
1401 case XML_SCHEMA_TYPE_NOTATION:
1402 return (((xmlSchemaNotationPtr) item)->targetNamespace);
1405 * Other components cannot have names.
1412 static const xmlChar*
1413 xmlSchemaGetComponentQName(xmlChar **buf,
1416 return (xmlSchemaFormatQName(buf,
1417 xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
1418 xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
1421 static const xmlChar*
1422 xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
1424 xmlChar *str = NULL;
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 "'");
1435 static const xmlChar*
1436 xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
1438 return(xmlSchemaGetComponentDesignation(buf, idc));
1442 * xmlSchemaWildcardPCToString:
1443 * @pc: the type of processContents
1445 * Returns a string representation of the type of
1448 static const xmlChar *
1449 xmlSchemaWildcardPCToString(int 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");
1459 return (BAD_CAST "invalid process contents");
1464 * xmlSchemaGetCanonValueWhtspExt:
1465 * @val: the precomputed value
1466 * @retValue: the returned value
1467 * @ws: the whitespace type of the value
1469 * Get a the cononical representation of the value.
1470 * The caller has to free the returned retValue.
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.
1476 xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
1477 xmlSchemaWhitespaceValueType ws,
1481 xmlSchemaValType valType;
1482 const xmlChar *value, *value2 = NULL;
1485 if ((retValue == NULL) || (val == NULL))
1487 list = xmlSchemaValueGetNext(val) ? 1 : 0;
1491 valType = xmlSchemaGetValType(val);
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);
1507 if (xmlSchemaGetCanonValue(val, &value2) == -1) {
1509 xmlFree((xmlChar *) value2);
1510 goto internal_error;
1514 if (*retValue == NULL)
1515 if (value == NULL) {
1517 *retValue = xmlStrdup(BAD_CAST "");
1519 *retValue = xmlStrdup(value);
1520 else if (value != NULL) {
1522 *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
1523 *retValue = xmlStrcat((xmlChar *) *retValue, value);
1525 FREE_AND_NULL(value2)
1526 val = xmlSchemaValueGetNext(val);
1527 } while (val != NULL);
1531 if (*retValue != NULL)
1532 xmlFree((xmlChar *) (*retValue));
1534 xmlFree((xmlChar *) value2);
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
1548 * Returns a representation of the given item used
1549 * for error reports.
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
1559 * If the itemNode is an attribute node, the name of the attribute
1560 * will be appended to the result.
1562 * Returns the formatted string and sets @buf to the resulting value.
1565 xmlSchemaFormatItemForReport(xmlChar **buf,
1566 const xmlChar *itemDes,
1567 xmlSchemaBasicItemPtr item,
1568 xmlNodePtr itemNode)
1570 xmlChar *str = NULL;
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;
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:");
1592 *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
1593 *buf = xmlStrcat(*buf, type->name);
1594 *buf = xmlStrcat(*buf, BAD_CAST "'");
1597 case XML_SCHEMA_TYPE_SIMPLE: {
1598 xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1600 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1601 *buf = xmlStrdup(BAD_CAST"");
1603 *buf = xmlStrdup(BAD_CAST "local ");
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");
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 "'");
1620 case XML_SCHEMA_TYPE_COMPLEX: {
1621 xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1623 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
1624 *buf = xmlStrdup(BAD_CAST "");
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 "'");
1635 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
1636 xmlSchemaAttributeUsePtr ause;
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)));
1645 *buf = xmlStrcat(*buf, BAD_CAST "'");
1647 *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
1651 case XML_SCHEMA_TYPE_ATTRIBUTE: {
1652 xmlSchemaAttributePtr attr;
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));
1660 *buf = xmlStrcat(*buf, BAD_CAST "'");
1663 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1664 xmlSchemaGetComponentDesignation(buf, item);
1666 case XML_SCHEMA_TYPE_ELEMENT: {
1667 xmlSchemaElementPtr elem;
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 "'");
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 '");
1685 *buf = xmlStrdup(BAD_CAST "keyRef '");
1686 *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
1687 *buf = xmlStrcat(*buf, BAD_CAST "'");
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");
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 "'");
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 "'");
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));
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 "'");
1738 if ((named == 0) && (itemNode != NULL)) {
1741 if (itemNode->type == XML_ATTRIBUTE_NODE)
1742 elem = itemNode->parent;
1745 *buf = xmlStrdup(BAD_CAST "Element '");
1746 if (elem->ns != NULL) {
1747 *buf = xmlStrcat(*buf,
1748 xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
1751 *buf = xmlStrcat(*buf, elem->name);
1752 *buf = xmlStrcat(*buf, BAD_CAST "'");
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));
1762 *buf = xmlStrcat(*buf, itemNode->name);
1763 *buf = xmlStrcat(*buf, BAD_CAST "'");
1771 * xmlSchemaFormatFacetEnumSet:
1772 * @buf: the string buffer
1773 * @type: the type holding the enumeration facets
1775 * Builds a string consisting of all enumeration elements.
1777 * Returns a string of all enumeration elements.
1779 static const xmlChar *
1780 xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
1781 xmlChar **buf, xmlSchemaTypePtr type)
1783 xmlSchemaFacetPtr facet;
1784 xmlSchemaWhitespaceValueType ws;
1785 xmlChar *value = NULL;
1794 * Use the whitespace type of the base type.
1796 ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
1797 for (facet = type->facets; facet != NULL; facet = facet->next) {
1798 if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
1801 res = xmlSchemaGetCanonValueWhtspExt(facet->val,
1804 xmlSchemaInternalErr(actxt,
1805 "xmlSchemaFormatFacetEnumSet",
1806 "compute the canonical lexical representation");
1813 *buf = xmlStrdup(BAD_CAST "'");
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);
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.
1831 type = type->baseType;
1832 } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
1834 return ((const xmlChar *) *buf);
1837 /************************************************************************
1841 ************************************************************************/
1845 xmlSchemaErrMemory(const char *msg)
1847 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
1853 xmlSchemaPSimpleErr(const char *msg)
1855 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
1860 * xmlSchemaPErrMemory:
1861 * @node: a context node
1862 * @extra: extra informations
1864 * Handle an out of memory condition
1867 xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
1868 const char *extra, xmlNodePtr node)
1872 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
1878 * @ctxt: the parsing context
1879 * @node: the context node
1880 * @error: the error code
1881 * @msg: the error message
1885 * Handle a parser error
1888 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
1889 const char *msg, const xmlChar * str1, const xmlChar * str2)
1891 xmlGenericErrorFunc channel = NULL;
1892 xmlStructuredErrorFunc schannel = NULL;
1898 channel = ctxt->error;
1899 data = ctxt->errCtxt;
1900 schannel = ctxt->serror;
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,
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
1918 * Handle a parser error
1921 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
1922 xmlNodePtr child, int error,
1923 const char *msg, const xmlChar * str1, const xmlChar * str2)
1926 xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
1928 xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
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
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
1947 * Handle a parser error
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)
1957 xmlGenericErrorFunc channel = NULL;
1958 xmlStructuredErrorFunc schannel = NULL;
1964 channel = ctxt->error;
1965 data = ctxt->errCtxt;
1966 schannel = ctxt->serror;
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,
1975 /************************************************************************
1977 * Allround error functions *
1979 ************************************************************************/
1982 * xmlSchemaVTypeErrMemory:
1983 * @node: a context node
1984 * @extra: extra informations
1986 * Handle an out of memory condition
1989 xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
1990 const char *extra, xmlNodePtr node)
1994 ctxt->err = XML_SCHEMAV_INTERNAL;
1996 __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
2001 xmlSchemaPSimpleInternalErr(xmlNodePtr node,
2002 const char *msg, const xmlChar *str)
2004 __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
2005 msg, (const char *) str);
2008 #define WXS_ERROR_TYPE_ERROR 1
2009 #define WXS_ERROR_TYPE_WARNING 2
2012 * @ctxt: the validation context
2013 * @node: the context node
2014 * @error: the error code
2015 * @msg: the error message
2020 * Handle a validation error
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)
2029 xmlStructuredErrorFunc schannel = NULL;
2030 xmlGenericErrorFunc channel = 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) {
2040 channel = vctxt->error;
2042 channel = vctxt->warning;
2044 schannel = vctxt->serror;
2045 data = vctxt->errCtxt;
2048 * Error node. If we specify a line number, then
2049 * do not channel any node to the error function.
2052 if ((node == NULL) &&
2053 (vctxt->depth >= 0) &&
2054 (vctxt->inode != NULL)) {
2055 node = vctxt->inode->node;
2058 * Get filename and line if no node-tree.
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;
2068 * Override the given node's (if any) position
2069 * and channel only the given line number.
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;
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);
2087 } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
2088 xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
2089 if (errorLevel != XML_ERR_WARNING) {
2092 channel = pctxt->error;
2094 channel = pctxt->warning;
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);
2111 * @ctxt: the validation context
2112 * @node: the context node
2113 * @error: the error code
2114 * @msg: the error message
2119 * Handle a validation error
2122 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
2123 int error, xmlNodePtr node, const char *msg,
2124 const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
2126 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2127 msg, str1, str2, str3, NULL);
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)
2136 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2137 msg, str1, str2, str3, str4);
2141 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
2142 int error, xmlNodePtr node, const char *msg,
2143 const xmlChar *str1, const xmlChar *str2)
2145 xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
2149 xmlSchemaFormatNodeForError(xmlChar ** msg,
2150 xmlSchemaAbstractCtxtPtr actxt,
2153 xmlChar *str = NULL;
2156 if ((node != NULL) &&
2157 (node->type != XML_ELEMENT_NODE) &&
2158 (node->type != XML_ATTRIBUTE_NODE))
2161 * Don't try to format other nodes than element and
2163 * Play save and return an empty string.
2165 *msg = xmlStrdup(BAD_CAST "");
2170 * Work on tree nodes.
2172 if (node->type == XML_ATTRIBUTE_NODE) {
2173 xmlNodePtr elem = node->parent;
2175 *msg = xmlStrdup(BAD_CAST "Element '");
2176 if (elem->ns != NULL)
2177 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2178 elem->ns->href, elem->name));
2180 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2183 *msg = xmlStrcat(*msg, BAD_CAST "', ");
2184 *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2186 *msg = xmlStrdup(BAD_CAST "Element '");
2188 if (node->ns != NULL)
2189 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2190 node->ns->href, node->name));
2192 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2195 *msg = xmlStrcat(*msg, BAD_CAST "': ");
2196 } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2197 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
2199 * Work on node infos.
2201 if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
2202 xmlSchemaNodeInfoPtr ielem =
2203 vctxt->elemInfos[vctxt->depth];
2205 *msg = xmlStrdup(BAD_CAST "Element '");
2206 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2207 ielem->nsName, ielem->localName));
2209 *msg = xmlStrcat(*msg, BAD_CAST "', ");
2210 *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2212 *msg = xmlStrdup(BAD_CAST "Element '");
2214 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2215 vctxt->inode->nsName, vctxt->inode->localName));
2217 *msg = xmlStrcat(*msg, BAD_CAST "': ");
2218 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
2220 * Hmm, no node while parsing?
2221 * Return an empty string, in case NULL will break something.
2223 *msg = xmlStrdup(BAD_CAST "");
2229 * VAL TODO: The output of the given schema component is currently
2233 if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
2234 *msg = xmlStrcat(*msg, BAD_CAST " [");
2235 *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
2236 NULL, type, NULL, 0));
2238 *msg = xmlStrcat(*msg, BAD_CAST "]");
2245 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
2246 const char *funcName,
2247 const char *message,
2248 const xmlChar *str1,
2249 const xmlChar *str2)
2251 xmlChar *msg = NULL;
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");
2261 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
2262 xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL,
2263 (const char *) msg, str1, str2);
2265 else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
2266 xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL,
2267 (const char *) msg, str1, str2);
2273 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
2274 const char *funcName,
2275 const char *message)
2277 xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
2282 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
2283 const char *funcName,
2284 const char *message,
2285 const xmlChar *str1,
2286 const xmlChar *str2)
2288 xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
2294 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
2295 xmlParserErrors error,
2297 xmlSchemaBasicItemPtr item,
2298 const char *message,
2299 const xmlChar *str1, const xmlChar *str2,
2300 const xmlChar *str3, const xmlChar *str4)
2302 xmlChar *msg = NULL;
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 ": ");
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);
2319 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
2320 xmlParserErrors error,
2322 xmlSchemaBasicItemPtr item,
2323 const char *message,
2324 const xmlChar *str1,
2325 const xmlChar *str2)
2327 xmlSchemaCustomErr4(actxt, error, node, item,
2328 message, str1, str2, NULL, NULL);
2334 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
2335 xmlParserErrors error,
2337 xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2338 const char *message,
2339 const xmlChar *str1,
2340 const xmlChar *str2,
2341 const xmlChar *str3)
2343 xmlChar *msg = NULL;
2345 xmlSchemaFormatNodeForError(&msg, actxt, node);
2346 msg = xmlStrcat(msg, (const xmlChar *) message);
2347 msg = xmlStrcat(msg, BAD_CAST ".\n");
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);
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)
2367 xmlChar *msg = NULL, *qname = NULL;
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]),
2378 FREE_AND_NULL(qname);
2383 xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
2387 return (node->type);
2388 if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
2389 (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
2390 return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
2395 xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
2397 switch (item->type) {
2398 case XML_SCHEMA_TYPE_COMPLEX:
2399 case XML_SCHEMA_TYPE_SIMPLE:
2400 if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
2403 case XML_SCHEMA_TYPE_GROUP:
2405 case XML_SCHEMA_TYPE_ELEMENT:
2406 if ( ((xmlSchemaElementPtr) item)->flags &
2407 XML_SCHEMAS_ELEM_GLOBAL)
2410 case XML_SCHEMA_TYPE_ATTRIBUTE:
2411 if ( ((xmlSchemaAttributePtr) item)->flags &
2412 XML_SCHEMAS_ATTR_GLOBAL)
2415 /* Note that attribute groups are always global. */
2423 xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2424 xmlParserErrors error,
2426 const xmlChar *value,
2427 xmlSchemaTypePtr type,
2430 xmlChar *msg = NULL;
2432 xmlSchemaFormatNodeForError(&msg, actxt, node);
2434 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2435 XML_ATTRIBUTE_NODE))
2436 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
2438 msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
2441 if (! xmlSchemaIsGlobalItem(type))
2442 msg = xmlStrcat(msg, BAD_CAST "the local ");
2444 msg = xmlStrcat(msg, BAD_CAST "the ");
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");
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);
2460 msg = xmlStrcat(msg,
2461 xmlSchemaFormatQName(&str,
2462 type->targetNamespace, type->name));
2463 msg = xmlStrcat(msg, BAD_CAST "'");
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);
2471 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2475 static const xmlChar *
2476 xmlSchemaFormatErrorNodeQName(xmlChar ** str,
2477 xmlSchemaNodeInfoPtr ni,
2481 if (node->ns != NULL)
2482 return (xmlSchemaFormatQName(str, node->ns->href, node->name));
2484 return (xmlSchemaFormatQName(str, NULL, node->name));
2485 } else if (ni != NULL)
2486 return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
2491 xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
2492 xmlParserErrors error,
2493 xmlSchemaAttrInfoPtr ni,
2496 xmlChar *msg = NULL, *str = NULL;
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),
2508 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2509 xmlParserErrors error,
2511 xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2512 const char *message,
2517 xmlChar *str = NULL, *msg = NULL;
2518 xmlChar *localName, *nsName;
2519 const xmlChar *cur, *end;
2522 xmlSchemaFormatNodeForError(&msg, actxt, node);
2523 msg = xmlStrcat(msg, (const xmlChar *) message);
2524 msg = xmlStrcat(msg, BAD_CAST ".");
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.
2530 if (nbval + nbneg > 0) {
2531 if (nbval + nbneg > 1) {
2532 str = xmlStrdup(BAD_CAST " Expected is one of ( ");
2534 str = xmlStrdup(BAD_CAST " Expected is ( ");
2537 for (i = 0; i < nbval + nbneg; i++) {
2541 if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
2544 str = xmlStrcat(str, BAD_CAST "##other");
2547 * Get the local name.
2553 localName = xmlStrdup(BAD_CAST "*");
2556 while ((*end != 0) && (*end != '|'))
2558 localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
2563 * Skip "*|*" if they come with negated expressions, since
2564 * they represent the same negated wildcard.
2566 if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
2568 * Get the namespace name.
2572 nsName = xmlStrdup(BAD_CAST "{*}");
2578 nsName = xmlStrdup(BAD_CAST "{##other:");
2580 nsName = xmlStrdup(BAD_CAST "{");
2582 nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
2583 nsName = xmlStrcat(nsName, BAD_CAST "}");
2585 str = xmlStrcat(str, BAD_CAST nsName);
2586 FREE_AND_NULL(nsName)
2588 FREE_AND_NULL(localName);
2592 str = xmlStrcat(str, BAD_CAST localName);
2593 FREE_AND_NULL(localName);
2595 if (i < nbval + nbneg -1)
2596 str = xmlStrcat(str, BAD_CAST ", ");
2598 str = xmlStrcat(str, BAD_CAST " ).\n");
2599 msg = xmlStrcat(msg, BAD_CAST str);
2602 msg = xmlStrcat(msg, BAD_CAST "\n");
2603 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2608 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
2609 xmlParserErrors error,
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)
2619 xmlChar *str = NULL, *msg = NULL;
2620 xmlSchemaTypeType facetType;
2621 int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
2623 xmlSchemaFormatNodeForError(&msg, actxt, node);
2624 if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
2625 facetType = XML_SCHEMA_FACET_ENUMERATION;
2627 * If enumerations are validated, one must not expect the
2628 * facet to be given.
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) {
2638 * Use a default message.
2640 if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
2641 (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
2642 (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
2644 char len[25], actLen[25];
2646 /* FIXME, TODO: What is the max expected string length of the
2649 if (nodeType == XML_ATTRIBUTE_NODE)
2650 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
2652 msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
2654 snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
2655 snprintf(actLen, 24, "%lu", length);
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");
2667 if (nodeType == XML_ATTRIBUTE_NODE)
2668 xmlSchemaErr3(actxt, error, node, (const char *) msg,
2669 value, (const xmlChar *) actLen, (const xmlChar *) len);
2671 xmlSchemaErr(actxt, error, node, (const char *) msg,
2672 (const xmlChar *) actLen, (const xmlChar *) len);
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,
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,
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,
2694 } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
2695 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
2697 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2699 } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
2700 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
2702 xmlSchemaErr(actxt, error, node, (const char *) msg, 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,
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,
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);
2718 msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
2719 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2722 msg = xmlStrcat(msg, (const xmlChar *) message);
2723 msg = xmlStrcat(msg, BAD_CAST ".\n");
2724 xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
2730 #define VERROR(err, type, msg) \
2731 xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
2733 #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
2735 #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
2736 #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
2738 #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
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
2751 * Reports an illegal attribute.
2754 xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
2755 xmlParserErrors error,
2756 xmlSchemaBasicItemPtr ownerItem,
2757 xmlNodePtr ownerElem,
2759 const char *message)
2761 xmlChar *des = NULL;
2763 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2765 if (message != NULL)
2766 xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
2768 xmlSchemaPErr(ctxt, ownerElem, error,
2769 "%s: The attribute '%s' is required but missing.\n",
2770 BAD_CAST des, BAD_CAST name);
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
2787 * Used to report QName attribute values that failed to resolve
2788 * to schema components.
2791 xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
2792 xmlParserErrors error,
2793 xmlSchemaBasicItemPtr ownerItem,
2794 xmlNodePtr ownerElem,
2796 const xmlChar *refName,
2797 const xmlChar *refURI,
2798 xmlSchemaTypeType refType,
2799 const char *refTypeStr)
2801 xmlChar *des = NULL, *strA = NULL;
2803 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2804 if (refTypeStr == NULL)
2805 refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
2806 xmlSchemaPErrExt(ctxt, ownerElem, error,
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);
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
2824 * Reports an illegal attribute during the parse.
2827 xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
2828 xmlParserErrors error,
2830 xmlSchemaBasicItemPtr ownerItem,
2834 xmlChar *des = NULL;
2836 if (ownerDes == NULL)
2837 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
2838 else if (*ownerDes == NULL) {
2839 xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
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);
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);
2853 if (ownerDes == NULL)
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
2865 * Reports an illegal attribute during the parse.
2868 xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
2869 xmlParserErrors error,
2870 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
2873 xmlChar *strA = NULL, *strB = NULL;
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),
2880 FREE_AND_NULL(strA);
2881 FREE_AND_NULL(strB);
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
2896 * Reports an error during parsing.
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)
2908 xmlChar *des = NULL, *msg = NULL;
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);
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
2932 * Reports an error during parsing.
2935 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
2936 xmlParserErrors error,
2937 xmlSchemaBasicItemPtr item,
2938 xmlNodePtr itemElem,
2939 const char *message,
2940 const xmlChar *str1)
2942 xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
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
2957 * Reports an attribute use error during parsing.
2960 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
2961 xmlParserErrors error,
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)
2969 xmlChar *str = NULL, *msg = NULL;
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));
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);
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
2993 * Reports an illegal facet for atomic simple types.
2996 xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
2997 xmlParserErrors error,
2998 xmlSchemaTypePtr type,
2999 xmlSchemaTypePtr baseType,
3000 xmlSchemaFacetPtr facet)
3002 xmlChar *des = NULL, *strT = NULL;
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 "
3008 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
3009 xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
3012 FREE_AND_NULL(strT);
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
3023 * Reports an illegal facet for <list> and <union>.
3026 xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
3027 xmlParserErrors error,
3028 xmlSchemaTypePtr type,
3029 xmlSchemaFacetPtr facet)
3031 xmlChar *des = NULL;
3033 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
3035 xmlSchemaPErr(ctxt, type->node, error,
3036 "%s: The facet '%s' is not allowed.\n",
3037 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
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
3049 * Reports an illegal attribute.
3052 xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
3053 xmlParserErrors error,
3054 xmlSchemaBasicItemPtr ownerItem,
3059 xmlChar *des = NULL;
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);
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
3078 * Reports a simple type validation error.
3079 * TODO: Should this report the value of an element as well?
3082 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
3083 xmlParserErrors error,
3084 xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
3086 xmlSchemaTypePtr type,
3087 const char *expected,
3088 const xmlChar *value,
3089 const char *message,
3090 const xmlChar *str1,
3091 const xmlChar *str2)
3093 xmlChar *msg = NULL;
3095 xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
3096 if (message == NULL) {
3098 * Use default messages.
3101 if (node->type == XML_ATTRIBUTE_NODE)
3102 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
3104 msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
3106 if (! xmlSchemaIsGlobalItem(type))
3107 msg = xmlStrcat(msg, BAD_CAST "the local ");
3109 msg = xmlStrcat(msg, BAD_CAST "the ");
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");
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);
3125 msg = xmlStrcat(msg,
3126 xmlSchemaFormatQName(&str,
3127 type->targetNamespace, type->name));
3128 msg = xmlStrcat(msg, BAD_CAST "'.");
3132 if (node->type == XML_ATTRIBUTE_NODE)
3133 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
3135 msg = xmlStrcat(msg, BAD_CAST "The character content is not "
3139 msg = xmlStrcat(msg, BAD_CAST " Expected is '");
3140 msg = xmlStrcat(msg, BAD_CAST expected);
3141 msg = xmlStrcat(msg, BAD_CAST "'.\n");
3143 msg = xmlStrcat(msg, BAD_CAST "\n");
3144 if (node->type == XML_ATTRIBUTE_NODE)
3145 xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
3147 xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
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);
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
3169 * Reports an error concerning the content of a schema element.
3172 xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
3173 xmlParserErrors error,
3174 xmlSchemaBasicItemPtr ownerItem,
3175 xmlNodePtr ownerElem,
3177 const char *message,
3178 const char *content)
3180 xmlChar *des = NULL;
3182 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
3183 if (message != NULL)
3184 xmlSchemaPErr2(ctxt, ownerElem, child, error,
3186 BAD_CAST des, BAD_CAST message);
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);
3193 xmlSchemaPErr2(ctxt, ownerElem, child, error,
3194 "%s: The content is not valid.\n",
3195 BAD_CAST des, NULL);
3201 /************************************************************************
3203 * Streamable error functions *
3205 ************************************************************************/
3210 /************************************************************************
3212 * Validation helper functions *
3214 ************************************************************************/
3217 /************************************************************************
3219 * Allocation functions *
3221 ************************************************************************/
3224 * xmlSchemaNewSchemaForParserCtxt:
3225 * @ctxt: a schema validation context
3227 * Allocate a new Schema structure.
3229 * Returns the newly allocated structure or NULL in case or error
3232 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
3236 ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
3238 xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
3241 memset(ret, 0, sizeof(xmlSchema));
3242 ret->dict = ctxt->dict;
3243 xmlDictReference(ret->dict);
3249 * xmlSchemaNewFacet:
3251 * Allocate a new Facet structure.
3253 * Returns the newly allocated structure or NULL in case or error
3256 xmlSchemaNewFacet(void)
3258 xmlSchemaFacetPtr ret;
3260 ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
3264 memset(ret, 0, sizeof(xmlSchemaFacet));
3270 * xmlSchemaNewAnnot:
3271 * @ctxt: a schema validation context
3274 * Allocate a new annotation structure.
3276 * Returns the newly allocated structure or NULL in case or error
3278 static xmlSchemaAnnotPtr
3279 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
3281 xmlSchemaAnnotPtr ret;
3283 ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
3285 xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
3288 memset(ret, 0, sizeof(xmlSchemaAnnot));
3289 ret->content = node;
3293 static xmlSchemaItemListPtr
3294 xmlSchemaItemListCreate(void)
3296 xmlSchemaItemListPtr ret;
3298 ret = xmlMalloc(sizeof(xmlSchemaItemList));
3300 xmlSchemaPErrMemory(NULL,
3301 "allocating an item list structure", NULL);
3304 memset(ret, 0, sizeof(xmlSchemaItemList));
3309 xmlSchemaItemListClear(xmlSchemaItemListPtr list)
3311 if (list->items != NULL) {
3312 xmlFree(list->items);
3316 list->sizeItems = 0;
3320 xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
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);
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;
3340 list->items[list->nbItems++] = item;
3345 xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
3349 if (list->items == NULL) {
3350 if (initialSize <= 0)
3352 list->items = (void **) xmlMalloc(
3353 initialSize * sizeof(void *));
3354 if (list->items == NULL) {
3355 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
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;
3369 list->items[list->nbItems++] = item;
3374 xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
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);
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;
3395 * Just append if the index is greater/equal than the item count.
3397 if (idx >= list->nbItems) {
3398 list->items[list->nbItems++] = item;
3401 for (i = list->nbItems; i > idx; i--)
3402 list->items[i] = list->items[i-1];
3403 list->items[idx] = item;
3409 #if 0 /* enable if ever needed */
3411 xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
3416 if (list->items == NULL) {
3417 if (initialSize <= 0)
3419 list->items = (void **) xmlMalloc(
3420 initialSize * sizeof(void *));
3421 if (list->items == NULL) {
3422 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
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;
3437 * Just append if the index is greater/equal than the item count.
3439 if (idx >= list->nbItems) {
3440 list->items[list->nbItems++] = item;
3443 for (i = list->nbItems; i > idx; i--)
3444 list->items[i] = list->items[i-1];
3445 list->items[idx] = item;
3453 xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
3456 if ((list->items == NULL) || (idx >= list->nbItems)) {
3457 xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
3462 if (list->nbItems == 1) {
3463 /* TODO: Really free the list? */
3464 xmlFree(list->items);
3467 list->sizeItems = 0;
3468 } else if (list->nbItems -1 == idx) {
3471 for (i = idx; i < list->nbItems -1; i++)
3472 list->items[i] = list->items[i+1];
3479 * xmlSchemaItemListFree:
3480 * @annot: a schema type structure
3482 * Deallocate a annotation structure
3485 xmlSchemaItemListFree(xmlSchemaItemListPtr list)
3489 if (list->items != NULL)
3490 xmlFree(list->items);
3495 xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
3499 if (bucket->globals != NULL) {
3500 xmlSchemaComponentListFree(bucket->globals);
3501 xmlSchemaItemListFree(bucket->globals);
3503 if (bucket->locals != NULL) {
3504 xmlSchemaComponentListFree(bucket->locals);
3505 xmlSchemaItemListFree(bucket->locals);
3507 if (bucket->relations != NULL) {
3508 xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
3513 } while (cur != NULL);
3515 if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
3516 xmlFreeDoc(bucket->doc);
3518 if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
3519 if (WXS_IMPBUCKET(bucket)->schema != NULL)
3520 xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
3525 static xmlSchemaBucketPtr
3526 xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
3527 int type, const xmlChar *targetNamespace)
3529 xmlSchemaBucketPtr ret;
3531 xmlSchemaPtr mainSchema;
3533 if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
3534 PERROR_INT("xmlSchemaBucketCreate",
3535 "no main schema on constructor");
3538 mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
3539 /* Create the schema bucket. */
3540 if (WXS_IS_BUCKET_INCREDEF(type))
3541 size = sizeof(xmlSchemaInclude);
3543 size = sizeof(xmlSchemaImport);
3544 ret = (xmlSchemaBucketPtr) xmlMalloc(size);
3546 xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
3549 memset(ret, 0, size);
3550 ret->targetNamespace = targetNamespace;
3552 ret->globals = xmlSchemaItemListCreate();
3553 if (ret->globals == NULL) {
3557 ret->locals = xmlSchemaItemListCreate();
3558 if (ret->locals == NULL) {
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.
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);
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;
3582 * Ensure that the main schema gets a targetNamespace.
3584 mainSchema->targetNamespace = targetNamespace;
3586 if (type == XML_SCHEMA_SCHEMA_MAIN) {
3587 PERROR_INT("xmlSchemaBucketCreate",
3588 "main bucket but it's not the first one");
3589 xmlSchemaBucketFree(ret);
3591 } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
3593 * Create a schema for imports and assign the
3596 WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
3597 if (WXS_IMPBUCKET(ret)->schema == NULL) {
3598 xmlSchemaBucketFree(ret);
3601 WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
3604 if (WXS_IS_BUCKET_IMPMAIN(type)) {
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.
3611 if (mainSchema->schemasImports == NULL) {
3612 mainSchema->schemasImports = xmlHashCreateDict(5,
3613 WXS_CONSTRUCTOR(pctxt)->dict);
3614 if (mainSchema->schemasImports == NULL) {
3615 xmlSchemaBucketFree(ret);
3619 if (targetNamespace == NULL)
3620 res = xmlHashAddEntry(mainSchema->schemasImports,
3621 XML_SCHEMAS_NO_NAMESPACE, ret);
3623 res = xmlHashAddEntry(mainSchema->schemasImports,
3624 targetNamespace, ret);
3626 PERROR_INT("xmlSchemaBucketCreate",
3627 "failed to add the schema bucket to the hash");
3628 xmlSchemaBucketFree(ret);
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);
3637 WXS_INCBUCKET(ret)->ownerImport =
3638 WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
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);
3648 xmlSchemaItemListAdd(mainSchema->includes, ret);
3651 * Add to list of all buckets; this is used for lookup
3652 * during schema construction time only.
3654 if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
3660 xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
3662 if (*list == NULL) {
3663 *list = xmlSchemaItemListCreate();
3667 xmlSchemaItemListAddSize(*list, initialSize, item);
3672 * xmlSchemaFreeAnnot:
3673 * @annot: a schema type structure
3675 * Deallocate a annotation structure
3678 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
3682 if (annot->next == NULL) {
3685 xmlSchemaAnnotPtr prev;
3689 annot = annot->next;
3691 } while (annot != NULL);
3696 * xmlSchemaFreeNotation:
3697 * @schema: a schema notation structure
3699 * Deallocate a Schema Notation structure.
3702 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
3710 * xmlSchemaFreeAttribute:
3711 * @attr: an attribute declaration
3713 * Deallocates an attribute declaration structure.
3716 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
3720 if (attr->annot != NULL)
3721 xmlSchemaFreeAnnot(attr->annot);
3722 if (attr->defVal != NULL)
3723 xmlSchemaFreeValue(attr->defVal);
3728 * xmlSchemaFreeAttributeUse:
3729 * @use: an attribute use
3731 * Deallocates an attribute use structure.
3734 xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
3738 if (use->annot != NULL)
3739 xmlSchemaFreeAnnot(use->annot);
3740 if (use->defVal != NULL)
3741 xmlSchemaFreeValue(use->defVal);
3746 * xmlSchemaFreeAttributeUseProhib:
3747 * @prohib: an attribute use prohibition
3749 * Deallocates an attribute use structure.
3752 xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
3760 * xmlSchemaFreeWildcardNsSet:
3761 * set: a schema wildcard namespace
3763 * Deallocates a list of wildcard constraint structures.
3766 xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
3768 xmlSchemaWildcardNsPtr next;
3770 while (set != NULL) {
3778 * xmlSchemaFreeWildcard:
3779 * @wildcard: a wildcard structure
3781 * Deallocates a wildcard structure.
3784 xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
3786 if (wildcard == NULL)
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);
3798 * xmlSchemaFreeAttributeGroup:
3799 * @schema: a schema attribute group structure
3801 * Deallocate a Schema Attribute Group structure.
3804 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
3808 if (attrGr->annot != NULL)
3809 xmlSchemaFreeAnnot(attrGr->annot);
3810 if (attrGr->attrUses != NULL)
3811 xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
3816 * xmlSchemaFreeQNameRef:
3817 * @item: a QName reference structure
3819 * Deallocatea a QName reference structure.
3822 xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
3828 * xmlSchemaFreeTypeLinkList:
3829 * @alink: a type link
3831 * Deallocate a list of types.
3834 xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
3836 xmlSchemaTypeLinkPtr next;
3838 while (link != NULL) {
3846 xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
3848 xmlSchemaIDCStateObjPtr next;
3849 while (sto != NULL) {
3851 if (sto->history != NULL)
3852 xmlFree(sto->history);
3853 if (sto->xpathCtxt != NULL)
3854 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
3862 * @idc: a identity-constraint definition
3864 * Deallocates an identity-constraint definition.
3867 xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
3869 xmlSchemaIDCSelectPtr cur, prev;
3873 if (idcDef->annot != NULL)
3874 xmlSchemaFreeAnnot(idcDef->annot);
3876 if (idcDef->selector != NULL) {
3877 if (idcDef->selector->xpathComp != NULL)
3878 xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
3879 xmlFree(idcDef->selector);
3882 if (idcDef->fields != NULL) {
3883 cur = idcDef->fields;
3887 if (prev->xpathComp != NULL)
3888 xmlFreePattern((xmlPatternPtr) prev->xpathComp);
3890 } while (cur != NULL);
3896 * xmlSchemaFreeElement:
3897 * @schema: a schema element structure
3899 * Deallocate a Schema Element structure.
3902 xmlSchemaFreeElement(xmlSchemaElementPtr elem)
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);
3916 * xmlSchemaFreeFacet:
3917 * @facet: a schema facet structure
3919 * Deallocate a Schema Facet structure.
3922 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
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);
3936 * xmlSchemaFreeType:
3937 * @type: a schema type structure
3939 * Deallocate a Schema Type structure.
3942 xmlSchemaFreeType(xmlSchemaTypePtr type)
3946 if (type->annot != NULL)
3947 xmlSchemaFreeAnnot(type->annot);
3948 if (type->facets != NULL) {
3949 xmlSchemaFacetPtr facet, next;
3951 facet = type->facets;
3952 while (facet != NULL) {
3954 xmlSchemaFreeFacet(facet);
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;
3965 link = type->facetSet;
3970 } while (link != NULL);
3972 if (type->contModel != NULL)
3973 xmlRegFreeRegexp(type->contModel);
3978 * xmlSchemaFreeModelGroupDef:
3979 * @item: a schema model group definition
3981 * Deallocates a schema model group definition.
3984 xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
3986 if (item->annot != NULL)
3987 xmlSchemaFreeAnnot(item->annot);
3992 * xmlSchemaFreeModelGroup:
3993 * @item: a schema model group
3995 * Deallocates a schema model group structure.
3998 xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
4000 if (item->annot != NULL)
4001 xmlSchemaFreeAnnot(item->annot);
4006 xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
4008 if ((list == NULL) || (list->nbItems == 0))
4011 xmlSchemaTreeItemPtr item;
4012 xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
4015 for (i = 0; i < list->nbItems; i++) {
4019 switch (item->type) {
4020 case XML_SCHEMA_TYPE_SIMPLE:
4021 case XML_SCHEMA_TYPE_COMPLEX:
4022 xmlSchemaFreeType((xmlSchemaTypePtr) item);
4024 case XML_SCHEMA_TYPE_ATTRIBUTE:
4025 xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
4027 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
4028 xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
4030 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
4031 xmlSchemaFreeAttributeUseProhib(
4032 (xmlSchemaAttributeUseProhibPtr) item);
4034 case XML_SCHEMA_TYPE_ELEMENT:
4035 xmlSchemaFreeElement((xmlSchemaElementPtr) item);
4037 case XML_SCHEMA_TYPE_PARTICLE:
4038 if (item->annot != NULL)
4039 xmlSchemaFreeAnnot(item->annot);
4042 case XML_SCHEMA_TYPE_SEQUENCE:
4043 case XML_SCHEMA_TYPE_CHOICE:
4044 case XML_SCHEMA_TYPE_ALL:
4045 xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
4047 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
4048 xmlSchemaFreeAttributeGroup(
4049 (xmlSchemaAttributeGroupPtr) item);
4051 case XML_SCHEMA_TYPE_GROUP:
4052 xmlSchemaFreeModelGroupDef(
4053 (xmlSchemaModelGroupDefPtr) item);
4055 case XML_SCHEMA_TYPE_ANY:
4056 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
4057 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
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);
4064 case XML_SCHEMA_TYPE_NOTATION:
4065 xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
4067 case XML_SCHEMA_EXTRA_QNAMEREF:
4068 xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
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));
4086 * @schema: a schema structure
4088 * Deallocate a Schema structure.
4091 xmlSchemaFree(xmlSchemaPtr schema)
4095 /* @volatiles is not used anymore :-/ */
4096 if (schema->volatiles != NULL)
4099 * Note that those slots are not responsible for freeing
4100 * schema components anymore; this will now be done by
4101 * the schema buckets.
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);
4118 if (schema->schemasImports != NULL)
4119 xmlHashFree(schema->schemasImports,
4120 (xmlHashDeallocator) xmlSchemaBucketFree);
4121 if (schema->includes != NULL) {
4122 xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
4124 for (i = 0; i < list->nbItems; i++) {
4125 xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
4127 xmlSchemaItemListFree(list);
4129 if (schema->annot != NULL)
4130 xmlSchemaFreeAnnot(schema->annot);
4131 /* Never free the doc here, since this will be done by the buckets. */
4133 xmlDictFree(schema->dict);
4137 /************************************************************************
4141 ************************************************************************/
4143 #ifdef LIBXML_OUTPUT_ENABLED
4146 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
4149 * xmlSchemaElementDump:
4151 * @output: the file output
4156 xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output,
4157 const xmlChar * name ATTRIBUTE_UNUSED,
4158 const xmlChar * namespace ATTRIBUTE_UNUSED,
4159 const xmlChar * context ATTRIBUTE_UNUSED)
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");
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);
4180 fprintf(output, "\n");
4184 * Misc other properties.
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");
4202 * Default/fixed value.
4204 if (elem->value != NULL)
4205 fprintf(output, " value: '%s'\n", elem->value);
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);
4214 fprintf(output, "\n");
4215 } else if (elem->subtypes != NULL) {
4219 xmlSchemaTypeDump(elem->subtypes, output);
4222 * Substitution group.
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);
4229 fprintf(output, "\n");
4234 * xmlSchemaAnnotDump:
4235 * @output: the file output
4236 * @annot: a annotation
4238 * Dump the annotation
4241 xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
4248 content = xmlNodeGetContent(annot->content);
4249 if (content != NULL) {
4250 fprintf(output, " Annot: %s\n", content);
4253 fprintf(output, " Annot: empty\n");
4257 * xmlSchemaContentModelDump:
4258 * @particle: the schema particle
4259 * @output: the file output
4260 * @depth: the depth used for intentation
4262 * Dump a SchemaType structure
4265 xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
4267 xmlChar *str = NULL;
4268 xmlSchemaTreeItemPtr term;
4272 if (particle == NULL)
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");
4282 term = particle->children;
4284 fprintf(output, "(NULL)");
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));
4293 case XML_SCHEMA_TYPE_SEQUENCE:
4294 fprintf(output, "SEQUENCE");
4296 case XML_SCHEMA_TYPE_CHOICE:
4297 fprintf(output, "CHOICE");
4299 case XML_SCHEMA_TYPE_ALL:
4300 fprintf(output, "ALL");
4302 case XML_SCHEMA_TYPE_ANY:
4303 fprintf(output, "ANY");
4306 fprintf(output, "UNKNOWN\n");
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");
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,
4325 if (particle->next != NULL)
4326 xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
4331 * xmlSchemaAttrUsesDump:
4332 * @uses: attribute uses list
4333 * @output: the file output
4335 * Dumps a list of attribute use components.
4338 xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
4340 xmlSchemaAttributeUsePtr use;
4341 xmlSchemaAttributeUseProhibPtr prohib;
4342 xmlSchemaQNameRefPtr ref;
4343 const xmlChar *name, *tns;
4344 xmlChar *str = NULL;
4347 if ((uses == NULL) || (uses->nbItems == 0))
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;
4362 tns = ref->targetNamespace;
4364 fprintf(output, " [use] ");
4365 name = WXS_ATTRUSE_DECL_NAME(use);
4366 tns = WXS_ATTRUSE_DECL_TNS(use);
4368 fprintf(output, "'%s'\n",
4369 (const char *) xmlSchemaFormatQName(&str, tns, name));
4375 * xmlSchemaTypeDump:
4376 * @output: the file output
4377 * @type: a type structure
4379 * Dump a SchemaType structure
4382 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
4385 fprintf(output, "Type: NULL\n");
4388 fprintf(output, "Type: ");
4389 if (type->name != NULL)
4390 fprintf(output, "'%s' ", type->name);
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] ");
4399 case XML_SCHEMA_TYPE_SIMPLE:
4400 fprintf(output, "[simple] ");
4402 case XML_SCHEMA_TYPE_COMPLEX:
4403 fprintf(output, "[complex] ");
4405 case XML_SCHEMA_TYPE_SEQUENCE:
4406 fprintf(output, "[sequence] ");
4408 case XML_SCHEMA_TYPE_CHOICE:
4409 fprintf(output, "[choice] ");
4411 case XML_SCHEMA_TYPE_ALL:
4412 fprintf(output, "[all] ");
4414 case XML_SCHEMA_TYPE_UR:
4415 fprintf(output, "[ur] ");
4417 case XML_SCHEMA_TYPE_RESTRICTION:
4418 fprintf(output, "[restriction] ");
4420 case XML_SCHEMA_TYPE_EXTENSION:
4421 fprintf(output, "[extension] ");
4424 fprintf(output, "[unknown type %d] ", type->type);
4427 fprintf(output, "content: ");
4428 switch (type->contentType) {
4429 case XML_SCHEMA_CONTENT_UNKNOWN:
4430 fprintf(output, "[unknown] ");
4432 case XML_SCHEMA_CONTENT_EMPTY:
4433 fprintf(output, "[empty] ");
4435 case XML_SCHEMA_CONTENT_ELEMENTS:
4436 fprintf(output, "[element] ");
4438 case XML_SCHEMA_CONTENT_MIXED:
4439 fprintf(output, "[mixed] ");
4441 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
4444 case XML_SCHEMA_CONTENT_BASIC:
4445 fprintf(output, "[basic] ");
4447 case XML_SCHEMA_CONTENT_SIMPLE:
4448 fprintf(output, "[simple] ");
4450 case XML_SCHEMA_CONTENT_ANY:
4451 fprintf(output, "[any] ");
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);
4460 fprintf(output, "\n");
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,
4477 * @output: the file output
4478 * @schema: a schema structure
4480 * Dump a Schema structure.
4483 xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
4487 if (schema == NULL) {
4488 fprintf(output, "Schemas: NULL\n");
4491 fprintf(output, "Schemas: ");
4492 if (schema->name != NULL)
4493 fprintf(output, "%s, ", schema->name);
4495 fprintf(output, "no name, ");
4496 if (schema->targetNamespace != NULL)
4497 fprintf(output, "%s", (const char *) schema->targetNamespace);
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,
4505 xmlHashScanFull(schema->elemDecl,
4506 (xmlHashScannerFull) xmlSchemaElementDump, output);
4509 #ifdef DEBUG_IDC_NODE_TABLE
4511 * xmlSchemaDebugDumpIDCTable:
4512 * @vctxt: the WXS validation context
4514 * Displays the current IDC table for debug purposes.
4517 xmlSchemaDebugDumpIDCTable(FILE * output,
4518 const xmlChar *namespaceName,
4519 const xmlChar *localName,
4520 xmlSchemaPSVIIDCBindingPtr bind)
4522 xmlChar *str = NULL;
4523 const xmlChar *value;
4524 xmlSchemaPSVIIDCNodePtr tab;
4525 xmlSchemaPSVIIDCKeyPtr key;
4528 fprintf(output, "IDC: TABLES on '%s'\n",
4529 xmlSchemaFormatQName(&str, namespaceName, localName));
4535 fprintf(output, "IDC: BINDING '%s' (%d)\n",
4536 xmlSchemaGetComponentQName(&str,
4537 bind->definition), bind->nbNodes);
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++) {
4544 if ((key != NULL) && (key->val != NULL)) {
4545 res = xmlSchemaGetCanonValue(key->val, &value);
4547 fprintf(output, "'%s' ", value);
4549 fprintf(output, "CANON-VALUE-FAILED ");
4551 FREE_AND_NULL(value)
4552 } else if (key != NULL)
4553 fprintf(output, "(no val), ");
4555 fprintf(output, "(key missing), ");
4557 fprintf(output, ")\n");
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++) {
4566 if ((key != NULL) && (key->val != NULL)) {
4567 res = xmlSchemaGetCanonValue(key->val, &value);
4569 fprintf(output, "'%s' ", value);
4571 fprintf(output, "CANON-VALUE-FAILED ");
4573 FREE_AND_NULL(value)
4574 } else if (key != NULL)
4575 fprintf(output, "(no val), ");
4577 fprintf(output, "(key missing), ");
4579 fprintf(output, ")\n");
4583 } while (bind != NULL);
4585 #endif /* DEBUG_IDC */
4586 #endif /* LIBXML_OUTPUT_ENABLED */
4588 /************************************************************************
4592 ************************************************************************/
4595 * xmlSchemaGetPropNode:
4596 * @node: the element node
4597 * @name: the name of the attribute
4599 * Seeks an attribute with a name of @name in
4602 * Returns the attribute or NULL if not present.
4605 xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
4609 if ((node == NULL) || (name == NULL))
4611 prop = node->properties;
4612 while (prop != NULL) {
4613 if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
4621 * xmlSchemaGetPropNodeNs:
4622 * @node: the element node
4624 * @name: the name of the attribute
4626 * Seeks an attribute with a local name of @name and
4627 * a namespace URI of @uri.
4629 * Returns the attribute or NULL if not present.
4632 xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
4636 if ((node == NULL) || (name == 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))
4649 static const xmlChar *
4650 xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
4655 val = xmlNodeGetContent(node);
4657 val = xmlStrdup((xmlChar *)"");
4658 ret = xmlDictLookup(ctxt->dict, val, -1);
4663 static const xmlChar *
4664 xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
4666 return((const xmlChar*) xmlNodeGetContent(node));
4671 * @ctxt: the parser context
4673 * @name: the property name
4675 * Read a attribute value and internalize the string
4677 * Returns the string or NULL if not present.
4679 static const xmlChar *
4680 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
4686 val = xmlGetNoNsProp(node, BAD_CAST name);
4689 ret = xmlDictLookup(ctxt->dict, val, -1);
4694 /************************************************************************
4696 * Parsing functions *
4698 ************************************************************************/
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; \
4705 if (xmlHashSize(schema->schemasImports) > 1) { \
4706 xmlSchemaImportPtr import; \
4707 if (nsName == NULL) \
4708 import = xmlHashLookup(schema->schemasImports, \
4709 XML_SCHEMAS_NO_NAMESPACE); \
4711 import = xmlHashLookup(schema->schemasImports, nsName); \
4712 if (import == NULL) \
4714 ret = xmlHashLookup(import->schema->slot, name); \
4719 * @schema: the schema context
4720 * @name: the element name
4721 * @ns: the element namespace
4723 * Lookup a global element declaration in the schema.
4725 * Returns the element declaration or NULL if not found.
4727 static xmlSchemaElementPtr
4728 xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
4729 const xmlChar * nsName)
4731 xmlSchemaElementPtr ret = NULL;
4733 if ((name == NULL) || (schema == NULL))
4735 if (schema != NULL) {
4736 WXS_FIND_GLOBAL_ITEM(elemDecl)
4742 fprintf(stderr, "Unable to lookup element decl. %s", name);
4744 fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
4753 * @schema: the main schema
4754 * @name: the type's name
4755 * nsName: the type's namespace
4757 * Lookup a type in the schemas or the predefined types
4759 * Returns the group definition or NULL if not found.
4761 static xmlSchemaTypePtr
4762 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
4763 const xmlChar * nsName)
4765 xmlSchemaTypePtr ret = NULL;
4769 /* First try the built-in types. */
4770 if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
4771 ret = xmlSchemaGetPredefinedType(name, nsName);
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?
4781 if (schema != NULL) {
4782 WXS_FIND_GLOBAL_ITEM(typeDecl)
4789 fprintf(stderr, "Unable to lookup type %s", name);
4791 fprintf(stderr, "Unable to lookup type %s:%s", name,
4799 * xmlSchemaGetAttributeDecl:
4800 * @schema: the context of the schema
4801 * @name: the name of the attribute
4802 * @ns: the target namespace of the attribute
4804 * Lookup a an attribute in the schema or imported schemas
4806 * Returns the attribute declaration or NULL if not found.
4808 static xmlSchemaAttributePtr
4809 xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
4810 const xmlChar * nsName)
4812 xmlSchemaAttributePtr ret = NULL;
4814 if ((name == NULL) || (schema == NULL))
4816 if (schema != NULL) {
4817 WXS_FIND_GLOBAL_ITEM(attrDecl)
4823 fprintf(stderr, "Unable to lookup attribute %s", name);
4825 fprintf(stderr, "Unable to lookup attribute %s:%s", name,
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
4838 * Lookup a an attribute group in the schema or imported schemas
4840 * Returns the attribute group definition or NULL if not found.
4842 static xmlSchemaAttributeGroupPtr
4843 xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
4844 const xmlChar * nsName)
4846 xmlSchemaAttributeGroupPtr ret = NULL;
4848 if ((name == NULL) || (schema == NULL))
4850 if (schema != NULL) {
4851 WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
4855 if ((ret != NULL) && (ret->redef != NULL)) {
4856 * Return the last redefinition. *
4863 fprintf(stderr, "Unable to lookup attribute group %s", name);
4865 fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
4873 * xmlSchemaGetGroup:
4874 * @schema: the context of the schema
4875 * @name: the name of the group
4876 * @ns: the target namespace of the group
4878 * Lookup a group in the schema or imported schemas
4880 * Returns the group definition or NULL if not found.
4882 static xmlSchemaModelGroupDefPtr
4883 xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
4884 const xmlChar * nsName)
4886 xmlSchemaModelGroupDefPtr ret = NULL;
4888 if ((name == NULL) || (schema == NULL))
4890 if (schema != NULL) {
4891 WXS_FIND_GLOBAL_ITEM(groupDecl)
4898 fprintf(stderr, "Unable to lookup group %s", name);
4900 fprintf(stderr, "Unable to lookup group %s:%s", name,
4907 static xmlSchemaNotationPtr
4908 xmlSchemaGetNotation(xmlSchemaPtr schema,
4909 const xmlChar *name,
4910 const xmlChar *nsName)
4912 xmlSchemaNotationPtr ret = NULL;
4914 if ((name == NULL) || (schema == NULL))
4916 if (schema != NULL) {
4917 WXS_FIND_GLOBAL_ITEM(notaDecl)
4923 static xmlSchemaIDCPtr
4924 xmlSchemaGetIDC(xmlSchemaPtr schema,
4925 const xmlChar *name,
4926 const xmlChar *nsName)
4928 xmlSchemaIDCPtr ret = NULL;
4930 if ((name == NULL) || (schema == NULL))
4932 if (schema != NULL) {
4933 WXS_FIND_GLOBAL_ITEM(idcDef)
4940 * xmlSchemaGetNamedComponent:
4941 * @schema: the schema
4942 * @name: the name of the group
4943 * @ns: the target namespace of the group
4945 * Lookup a group in the schema or imported schemas
4947 * Returns the group definition or NULL if not found.
4949 static xmlSchemaBasicItemPtr
4950 xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
4951 xmlSchemaTypeType itemType,
4952 const xmlChar *name,
4953 const xmlChar *targetNs)
4956 case XML_SCHEMA_TYPE_GROUP:
4957 return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
4959 case XML_SCHEMA_TYPE_ELEMENT:
4960 return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
4968 /************************************************************************
4970 * Parsing functions *
4972 ************************************************************************/
4974 #define IS_BLANK_NODE(n) \
4975 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
4980 * @len: the length of the string or -1
4982 * Check if a string is ignorable
4984 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
4987 xmlSchemaIsBlank(xmlChar * str, int len)
4993 if (!(IS_BLANK_CH(*str)))
4997 } else while ((*str != 0) && (len != 0)) {
4998 if (!(IS_BLANK_CH(*str)))
5007 #define WXS_COMP_NAME(c, t) ((t) (c))->name
5008 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
5010 * xmlSchemaFindRedefCompInGraph:
5011 * ATTENTION TODO: This uses pointer comp. for strings.
5013 static xmlSchemaBasicItemPtr
5014 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
5015 xmlSchemaTypeType type,
5016 const xmlChar *name,
5017 const xmlChar *nsName)
5019 xmlSchemaBasicItemPtr ret;
5022 if ((bucket == NULL) || (name == NULL))
5024 if ((bucket->globals == NULL) ||
5025 (bucket->globals->nbItems == 0))
5028 * Search in global components.
5030 for (i = 0; i < bucket->globals->nbItems; i++) {
5031 ret = bucket->globals->items[i];
5032 if (ret->type == 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) ==
5043 case XML_SCHEMA_TYPE_GROUP:
5044 if ((WXS_COMP_NAME(ret,
5045 xmlSchemaModelGroupDefPtr) == name) &&
5047 xmlSchemaModelGroupDefPtr) == nsName))
5052 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
5053 if ((WXS_COMP_NAME(ret,
5054 xmlSchemaAttributeGroupPtr) == name) &&
5056 xmlSchemaAttributeGroupPtr) == nsName))
5062 /* Should not be hit. */
5069 * Process imported/included schemas.
5071 if (bucket->relations != NULL) {
5072 xmlSchemaSchemaRelationPtr rel = bucket->relations;
5075 * TODO: Marking the bucket will not avoid multiple searches
5076 * in the same schema, but avoids at least circularity.
5078 bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
5080 if ((rel->bucket != NULL) &&
5081 ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
5082 ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
5083 type, name, nsName);
5088 } while (rel != NULL);
5089 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
5095 * xmlSchemaAddNotation:
5096 * @ctxt: a schema parser context
5097 * @schema: the schema being built
5098 * @name: the item name
5100 * Add an XML schema annotation declaration
5101 * *WARNING* this interface is highly subject to change
5103 * Returns the new struture or NULL in case of error
5105 static xmlSchemaNotationPtr
5106 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5107 const xmlChar *name, const xmlChar *nsName,
5108 xmlNodePtr node ATTRIBUTE_UNUSED)
5110 xmlSchemaNotationPtr ret = NULL;
5112 if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5115 ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
5117 xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
5120 memset(ret, 0, sizeof(xmlSchemaNotation));
5121 ret->type = XML_SCHEMA_TYPE_NOTATION;
5123 ret->targetNamespace = nsName;
5124 /* TODO: do we need the node to be set?
5125 * ret->node = node;*/
5126 WXS_ADD_GLOBAL(ctxt, ret);
5131 * xmlSchemaAddAttribute:
5132 * @ctxt: a schema parser context
5133 * @schema: the schema being built
5134 * @name: the item name
5135 * @namespace: the namespace
5137 * Add an XML schema Attrribute declaration
5138 * *WARNING* this interface is highly subject to change
5140 * Returns the new struture or NULL in case of error
5142 static xmlSchemaAttributePtr
5143 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5144 const xmlChar * name, const xmlChar * nsName,
5145 xmlNodePtr node, int topLevel)
5147 xmlSchemaAttributePtr ret = NULL;
5149 if ((ctxt == NULL) || (schema == NULL))
5152 ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
5154 xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
5157 memset(ret, 0, sizeof(xmlSchemaAttribute));
5158 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
5161 ret->targetNamespace = nsName;
5164 WXS_ADD_GLOBAL(ctxt, ret);
5166 WXS_ADD_LOCAL(ctxt, ret);
5167 WXS_ADD_PENDING(ctxt, ret);
5172 * xmlSchemaAddAttributeUse:
5173 * @ctxt: a schema parser context
5174 * @schema: the schema being built
5175 * @name: the item name
5176 * @namespace: the namespace
5178 * Add an XML schema Attrribute declaration
5179 * *WARNING* this interface is highly subject to change
5181 * Returns the new struture or NULL in case of error
5183 static xmlSchemaAttributeUsePtr
5184 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
5187 xmlSchemaAttributeUsePtr ret = NULL;
5192 ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
5194 xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
5197 memset(ret, 0, sizeof(xmlSchemaAttributeUse));
5198 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
5201 WXS_ADD_LOCAL(pctxt, ret);
5206 * xmlSchemaAddRedef:
5208 * Adds a redefinition information. This is used at a later stage to:
5209 * resolve references to the redefined components and to check constraints.
5211 static xmlSchemaRedefPtr
5212 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
5213 xmlSchemaBucketPtr targetBucket,
5215 const xmlChar *refName,
5216 const xmlChar *refTargetNs)
5218 xmlSchemaRedefPtr ret;
5220 ret = (xmlSchemaRedefPtr)
5221 xmlMalloc(sizeof(xmlSchemaRedef));
5223 xmlSchemaPErrMemory(pctxt,
5224 "allocating redefinition info", NULL);
5227 memset(ret, 0, sizeof(xmlSchemaRedef));
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;
5235 WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
5236 WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
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
5249 * Add an XML schema Attrribute Group definition.
5251 * Returns the new struture or NULL in case of error
5253 static xmlSchemaAttributeGroupPtr
5254 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
5255 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
5256 const xmlChar *name,
5257 const xmlChar *nsName,
5260 xmlSchemaAttributeGroupPtr ret = NULL;
5262 if ((pctxt == NULL) || (name == NULL))
5265 ret = (xmlSchemaAttributeGroupPtr)
5266 xmlMalloc(sizeof(xmlSchemaAttributeGroup));
5268 xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
5271 memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
5272 ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
5274 ret->targetNamespace = nsName;
5277 /* TODO: Remove the flag. */
5278 ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
5279 if (pctxt->isRedefine) {
5280 pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
5282 if (pctxt->redef == NULL) {
5286 pctxt->redefCounter = 0;
5288 WXS_ADD_GLOBAL(pctxt, ret);
5289 WXS_ADD_PENDING(pctxt, ret);
5294 * xmlSchemaAddElement:
5295 * @ctxt: a schema parser context
5296 * @schema: the schema being built
5297 * @name: the type name
5298 * @namespace: the type namespace
5300 * Add an XML schema Element declaration
5301 * *WARNING* this interface is highly subject to change
5303 * Returns the new struture or NULL in case of error
5305 static xmlSchemaElementPtr
5306 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
5307 const xmlChar * name, const xmlChar * nsName,
5308 xmlNodePtr node, int topLevel)
5310 xmlSchemaElementPtr ret = NULL;
5312 if ((ctxt == NULL) || (name == NULL))
5315 ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
5317 xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
5320 memset(ret, 0, sizeof(xmlSchemaElement));
5321 ret->type = XML_SCHEMA_TYPE_ELEMENT;
5323 ret->targetNamespace = nsName;
5327 WXS_ADD_GLOBAL(ctxt, ret);
5329 WXS_ADD_LOCAL(ctxt, ret);
5330 WXS_ADD_PENDING(ctxt, ret);
5336 * @ctxt: a schema parser context
5337 * @schema: the schema being built
5338 * @name: the item name
5339 * @namespace: the namespace
5341 * Add an XML schema item
5342 * *WARNING* this interface is highly subject to change
5344 * Returns the new struture or NULL in case of error
5346 static xmlSchemaTypePtr
5347 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5348 xmlSchemaTypeType type,
5349 const xmlChar * name, const xmlChar * nsName,
5350 xmlNodePtr node, int topLevel)
5352 xmlSchemaTypePtr ret = NULL;
5354 if ((ctxt == NULL) || (schema == NULL))
5357 ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
5359 xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
5362 memset(ret, 0, sizeof(xmlSchemaType));
5365 ret->targetNamespace = nsName;
5368 if (ctxt->isRedefine) {
5369 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5371 if (ctxt->redef == NULL) {
5375 ctxt->redefCounter = 0;
5377 WXS_ADD_GLOBAL(ctxt, ret);
5379 WXS_ADD_LOCAL(ctxt, ret);
5380 WXS_ADD_PENDING(ctxt, ret);
5384 static xmlSchemaQNameRefPtr
5385 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
5386 xmlSchemaTypeType refType,
5387 const xmlChar *refName,
5388 const xmlChar *refNs)
5390 xmlSchemaQNameRefPtr ret;
5392 ret = (xmlSchemaQNameRefPtr)
5393 xmlMalloc(sizeof(xmlSchemaQNameRef));
5395 xmlSchemaPErrMemory(pctxt,
5396 "allocating QName reference item", NULL);
5400 ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
5401 ret->name = refName;
5402 ret->targetNamespace = refNs;
5404 ret->itemType = refType;
5406 * Store the reference item in the schema.
5408 WXS_ADD_LOCAL(pctxt, ret);
5412 static xmlSchemaAttributeUseProhibPtr
5413 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
5415 xmlSchemaAttributeUseProhibPtr ret;
5417 ret = (xmlSchemaAttributeUseProhibPtr)
5418 xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
5420 xmlSchemaPErrMemory(pctxt,
5421 "allocating attribute use prohibition", NULL);
5424 memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
5425 ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
5426 WXS_ADD_LOCAL(pctxt, ret);
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
5438 * Adds a schema model group
5439 * *WARNING* this interface is highly subject to change
5441 * Returns the new struture or NULL in case of error
5443 static xmlSchemaModelGroupPtr
5444 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
5445 xmlSchemaPtr schema,
5446 xmlSchemaTypeType type,
5449 xmlSchemaModelGroupPtr ret = NULL;
5451 if ((ctxt == NULL) || (schema == NULL))
5454 ret = (xmlSchemaModelGroupPtr)
5455 xmlMalloc(sizeof(xmlSchemaModelGroup));
5457 xmlSchemaPErrMemory(ctxt, "allocating model group component",
5461 memset(ret, 0, sizeof(xmlSchemaModelGroup));
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);
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
5480 * Adds an XML schema particle component.
5481 * *WARNING* this interface is highly subject to change
5483 * Returns the new struture or NULL in case of error
5485 static xmlSchemaParticlePtr
5486 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
5487 xmlNodePtr node, int min, int max)
5489 xmlSchemaParticlePtr ret = NULL;
5494 fprintf(stderr, "Adding particle component\n");
5496 ret = (xmlSchemaParticlePtr)
5497 xmlMalloc(sizeof(xmlSchemaParticle));
5499 xmlSchemaPErrMemory(ctxt, "allocating particle component",
5503 ret->type = XML_SCHEMA_TYPE_PARTICLE;
5506 ret->minOccurs = min;
5507 ret->maxOccurs = max;
5509 ret->children = NULL;
5511 WXS_ADD_LOCAL(ctxt, ret);
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);
5522 * xmlSchemaAddModelGroupDefinition:
5523 * @ctxt: a schema validation context
5524 * @schema: the schema being built
5525 * @name: the group name
5527 * Add an XML schema Group definition
5529 * Returns the new struture or NULL in case of error
5531 static xmlSchemaModelGroupDefPtr
5532 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
5533 xmlSchemaPtr schema,
5534 const xmlChar *name,
5535 const xmlChar *nsName,
5538 xmlSchemaModelGroupDefPtr ret = NULL;
5540 if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5543 ret = (xmlSchemaModelGroupDefPtr)
5544 xmlMalloc(sizeof(xmlSchemaModelGroupDef));
5546 xmlSchemaPErrMemory(ctxt, "adding group", NULL);
5549 memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
5551 ret->type = XML_SCHEMA_TYPE_GROUP;
5553 ret->targetNamespace = nsName;
5555 if (ctxt->isRedefine) {
5556 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5558 if (ctxt->redef == NULL) {
5562 ctxt->redefCounter = 0;
5564 WXS_ADD_GLOBAL(ctxt, ret);
5565 WXS_ADD_PENDING(ctxt, ret);
5570 * xmlSchemaNewWildcardNs:
5571 * @ctxt: a schema validation context
5573 * Creates a new wildcard namespace constraint.
5575 * Returns the new struture or NULL in case of error
5577 static xmlSchemaWildcardNsPtr
5578 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
5580 xmlSchemaWildcardNsPtr ret;
5582 ret = (xmlSchemaWildcardNsPtr)
5583 xmlMalloc(sizeof(xmlSchemaWildcardNs));
5585 xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
5593 static xmlSchemaIDCPtr
5594 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5595 const xmlChar *name, const xmlChar *nsName,
5596 int category, xmlNodePtr node)
5598 xmlSchemaIDCPtr ret = NULL;
5600 if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5603 ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
5605 xmlSchemaPErrMemory(ctxt,
5606 "allocating an identity-constraint definition", NULL);
5609 memset(ret, 0, sizeof(xmlSchemaIDC));
5610 /* The target namespace of the parent element declaration. */
5611 ret->targetNamespace = nsName;
5613 ret->type = category;
5616 WXS_ADD_GLOBAL(ctxt, ret);
5618 * Only keyrefs need to be fixup up.
5620 if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
5621 WXS_ADD_PENDING(ctxt, ret);
5626 * xmlSchemaAddWildcard:
5627 * @ctxt: a schema validation context
5631 * It corresponds to a xsd:anyAttribute and xsd:any.
5633 * Returns the new struture or NULL in case of error
5635 static xmlSchemaWildcardPtr
5636 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5637 xmlSchemaTypeType type, xmlNodePtr node)
5639 xmlSchemaWildcardPtr ret = NULL;
5641 if ((ctxt == NULL) || (schema == NULL))
5644 ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
5646 xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
5649 memset(ret, 0, sizeof(xmlSchemaWildcard));
5652 WXS_ADD_LOCAL(ctxt, ret);
5657 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
5661 if (group->members != NULL)
5662 xmlSchemaItemListFree(group->members);
5666 static xmlSchemaSubstGroupPtr
5667 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
5668 xmlSchemaElementPtr head)
5670 xmlSchemaSubstGroupPtr ret;
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)
5678 /* Create a new substitution group. */
5679 ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
5681 xmlSchemaPErrMemory(NULL,
5682 "allocating a substitution group container", NULL);
5685 memset(ret, 0, sizeof(xmlSchemaSubstGroup));
5687 /* Create list of members. */
5688 ret->members = xmlSchemaItemListCreate();
5689 if (ret->members == NULL) {
5690 xmlSchemaSubstGroupFree(ret);
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);
5704 static xmlSchemaSubstGroupPtr
5705 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
5706 xmlSchemaElementPtr head)
5708 if (WXS_SUBST_GROUPS(pctxt) == NULL)
5710 return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
5711 head->name, head->targetNamespace));
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
5721 * Allocate a new annotation structure.
5723 * Returns the newly allocated structure or NULL in case or error
5726 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
5727 xmlSchemaElementPtr head,
5728 xmlSchemaElementPtr member)
5730 xmlSchemaSubstGroupPtr substGroup = NULL;
5732 if ((pctxt == NULL) || (head == NULL) || (member == NULL))
5735 substGroup = xmlSchemaSubstGroupGet(pctxt, head);
5736 if (substGroup == NULL)
5737 substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
5738 if (substGroup == NULL)
5740 if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
5745 /************************************************************************
5747 * Utilities for parsing *
5749 ************************************************************************/
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
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.
5765 * Returns 0, in case the QName is valid, a positive error code
5766 * if not valid and -1 if an internal error occurs.
5769 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
5770 xmlSchemaPtr schema,
5771 xmlSchemaBasicItemPtr ownerItem,
5773 const xmlChar *value,
5774 const xmlChar **uri,
5775 const xmlChar **local)
5777 const xmlChar *pref;
5783 ret = xmlValidateQName(value, 1);
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);
5795 if (!strchr((char *) value, ':')) {
5796 ns = xmlSearchNs(attr->doc, attr->parent, NULL);
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. */
5803 * This one takes care of included schemas with no
5806 *uri = ctxt->targetNamespace;
5808 *local = xmlDictLookup(ctxt->dict, value, -1);
5812 * At this point xmlSplitQName3 has to return a local name.
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);
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);
5827 *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
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
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.
5846 * Returns 0, in case the QName is valid, a positive error code
5847 * if not valid and -1 if an internal error occurs.
5850 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
5851 xmlSchemaPtr schema,
5852 xmlSchemaBasicItemPtr ownerItem,
5854 const xmlChar **uri,
5855 const xmlChar **local)
5857 const xmlChar *value;
5859 value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5860 return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
5861 ownerItem, attr, value, uri, local));
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
5875 * Extracts and validates the QName of an attribute value.
5877 * Returns 0, in case the QName is valid, a positive error code
5878 * if not valid and -1 if an internal error occurs.
5881 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
5882 xmlSchemaPtr schema,
5883 xmlSchemaBasicItemPtr ownerItem,
5884 xmlNodePtr ownerElem,
5886 const xmlChar **uri,
5887 const xmlChar **local)
5891 attr = xmlSchemaGetPropNode(ownerElem, name);
5897 return (xmlSchemaPValAttrNodeQName(ctxt, schema,
5898 ownerItem, attr, uri, local));
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
5910 * Extracts and validates the ID of an attribute value.
5912 * Returns 0, in case the ID is valid, a positive error code
5913 * if not valid and -1 if an internal error occurs.
5916 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
5919 const xmlChar *value;
5923 value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
5924 ret = xmlValidateNCName(value, 1);
5927 * NOTE: the IDness might have already be declared in the DTD
5929 if (attr->atype != XML_ATTRIBUTE_ID) {
5934 * TODO: Use xmlSchemaStrip here; it's not exported at this
5937 strip = xmlSchemaCollapseString(value);
5938 if (strip != NULL) {
5939 xmlFree((xmlChar *) value);
5942 res = xmlAddID(NULL, attr->doc, value, attr);
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);
5952 attr->atype = XML_ATTRIBUTE_ID;
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'",
5965 xmlFree((xmlChar *)value);
5971 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
5972 xmlNodePtr ownerElem,
5973 const xmlChar *name)
5977 attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
5980 return(xmlSchemaPValAttrNodeID(ctxt, attr));
5986 * @ctxt: a schema validation context
5987 * @node: a subtree containing XML Schema informations
5989 * Get the maxOccurs property
5991 * Returns the default if not found, or the value
5994 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
5995 int min, int max, int def, const char *expected)
5997 const xmlChar *val, *cur;
6001 attr = xmlSchemaGetPropNode(node, "maxOccurs");
6004 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
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);
6015 return (UNBOUNDED); /* encoding it with -1 might be another option */
6019 while (IS_BLANK_CH(*cur))
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);
6029 while ((*cur >= '0') && (*cur <= '9')) {
6030 ret = ret * 10 + (*cur - '0');
6033 while (IS_BLANK_CH(*cur))
6036 * TODO: Restrict the maximal value to Integer.
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);
6051 * @ctxt: a schema validation context
6052 * @node: a subtree containing XML Schema informations
6054 * Get the minOccurs property
6056 * Returns the default if not found, or the value
6059 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
6060 int min, int max, int def, const char *expected)
6062 const xmlChar *val, *cur;
6066 attr = xmlSchemaGetPropNode(node, "minOccurs");
6069 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6071 while (IS_BLANK_CH(*cur))
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);
6081 while ((*cur >= '0') && (*cur <= '9')) {
6082 ret = ret * 10 + (*cur - '0');
6085 while (IS_BLANK_CH(*cur))
6088 * TODO: Restrict the maximal value to Integer.
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);
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
6108 * Converts a boolean string value into 1 or 0.
6113 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
6114 xmlSchemaBasicItemPtr ownerItem,
6117 xmlChar *value = NULL;
6120 value = xmlNodeGetContent(node);
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}.
6126 if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
6128 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
6130 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
6132 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
6135 xmlSchemaPSimpleTypeErr(ctxt,
6136 XML_SCHEMAP_INVALID_BOOLEAN,
6138 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6139 NULL, BAD_CAST value,
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
6154 * Evaluate if a boolean property is set
6156 * Returns the default if not found, 0 if found to be false,
6157 * 1 if found to be true
6160 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
6162 const char *name, int def)
6166 val = xmlSchemaGetProp(ctxt, node, name);
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}.
6174 if (xmlStrEqual(val, BAD_CAST "true"))
6176 else if (xmlStrEqual(val, BAD_CAST "false"))
6178 else if (xmlStrEqual(val, BAD_CAST "1"))
6180 else if (xmlStrEqual(val, BAD_CAST "0"))
6183 xmlSchemaPSimpleTypeErr(ctxt,
6184 XML_SCHEMAP_INVALID_BOOLEAN,
6186 (xmlNodePtr) xmlSchemaGetPropNode(node, name),
6187 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6188 NULL, val, NULL, NULL, NULL);
6193 /************************************************************************
6195 * Shema extraction from an Infoset *
6197 ************************************************************************/
6198 static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
6199 ctxt, xmlSchemaPtr schema,
6202 static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
6204 xmlSchemaPtr schema,
6207 static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
6209 xmlSchemaPtr schema,
6211 xmlSchemaTypeType parentType);
6212 static xmlSchemaBasicItemPtr
6213 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
6214 xmlSchemaPtr schema,
6216 xmlSchemaItemListPtr uses,
6218 static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
6219 xmlSchemaPtr schema,
6221 static xmlSchemaWildcardPtr
6222 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
6223 xmlSchemaPtr schema, xmlNodePtr node);
6226 * xmlSchemaPValAttrNodeValue:
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
6233 * @type: the built-in type to be validated against
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.
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.
6243 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
6244 xmlSchemaBasicItemPtr ownerItem,
6246 const xmlChar *value,
6247 xmlSchemaTypePtr type)
6253 * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
6254 * one is really meant to be used internally, so better not.
6256 if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
6258 if (type->type != XML_SCHEMA_TYPE_BASIC) {
6259 PERROR_INT("xmlSchemaPValAttrNodeValue",
6260 "the given type is not a built-in type");
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,
6273 PERROR_INT("xmlSchemaPValAttrNodeValue",
6274 "validation using the given type is not supported while "
6275 "parsing a schema");
6280 * TODO: Should we use the S4S error codes instead?
6283 PERROR_INT("xmlSchemaPValAttrNodeValue",
6284 "failed to validate a schema attribute value");
6286 } else if (ret > 0) {
6287 if (WXS_IS_LIST(type))
6288 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
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);
6299 * xmlSchemaPValAttrNode:
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
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.
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.
6316 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
6317 xmlSchemaBasicItemPtr ownerItem,
6319 xmlSchemaTypePtr type,
6320 const xmlChar **value)
6324 if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
6327 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6331 return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
6336 * xmlSchemaPValAttr:
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
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.
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.
6355 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
6356 xmlSchemaBasicItemPtr ownerItem,
6357 xmlNodePtr ownerElem,
6359 xmlSchemaTypePtr type,
6360 const xmlChar **value)
6364 if ((ctxt == NULL) || (type == NULL)) {
6369 if (type->type != XML_SCHEMA_TYPE_BASIC) {
6372 xmlSchemaPErr(ctxt, ownerElem,
6373 XML_SCHEMAP_INTERNAL,
6374 "Internal error: xmlSchemaPValAttr, the given "
6375 "type '%s' is not a built-in type.\n",
6379 attr = xmlSchemaGetPropNode(ownerElem, name);
6385 return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
6390 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
6391 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6394 const xmlChar *namespaceName)
6396 /* TODO: Pointer comparison instead? */
6397 if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
6399 if (xmlStrEqual(xmlSchemaNs, namespaceName))
6402 * Check if the referenced namespace was <import>ed.
6404 if (WXS_BUCKET(pctxt)->relations != NULL) {
6405 xmlSchemaSchemaRelationPtr rel;
6407 rel = WXS_BUCKET(pctxt)->relations;
6409 if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
6410 xmlStrEqual(namespaceName, rel->importNamespace))
6413 } while (rel != NULL);
6416 * No matching <import>ed namespace found.
6419 xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
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);
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);
6434 return (XML_SCHEMAP_SRC_RESOLVE);
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
6444 * Parses attribute uses and attribute declarations and
6445 * attribute group references.
6448 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6449 xmlNodePtr *child, xmlSchemaItemListPtr *list,
6450 int parentType, int *hasRefs)
6454 while ((IS_SCHEMA((*child), "attribute")) ||
6455 (IS_SCHEMA((*child), "attributeGroup"))) {
6456 if (IS_SCHEMA((*child), "attribute")) {
6457 item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
6460 item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
6461 if ((item != NULL) && (hasRefs != NULL))
6465 if (*list == NULL) {
6466 /* TODO: Customize grow factor. */
6467 *list = xmlSchemaItemListCreate();
6471 if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
6474 *child = (*child)->next;
6480 * xmlSchemaParseAnnotation:
6481 * @ctxt: a schema validation context
6482 * @schema: the schema being built
6483 * @node: a subtree containing XML Schema informations
6485 * parse a XML schema Attrribute declaration
6486 * *WARNING* this interface is highly subject to change
6488 * Returns -1 in case of error, 0 if the declaration is improper and
6489 * 1 in case of success.
6491 static xmlSchemaAnnotPtr
6492 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
6494 xmlSchemaAnnotPtr ret;
6495 xmlNodePtr child = NULL;
6500 * INFO: S4S completed.
6504 * {any attributes with non-schema namespace . . .}>
6505 * Content: (appinfo | documentation)*
6507 if ((ctxt == NULL) || (node == NULL))
6510 ret = xmlSchemaNewAnnot(ctxt, node);
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))) {
6520 xmlSchemaPIllegalAttrErr(ctxt,
6521 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6525 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6527 * And now for the children...
6529 child = node->children;
6530 while (child != NULL) {
6531 if (IS_SCHEMA(child, "appinfo")) {
6532 /* TODO: make available the content of "appinfo". */
6535 * {any attributes with non-schema namespace . . .}>
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))) {
6545 xmlSchemaPIllegalAttrErr(ctxt,
6546 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
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". */
6557 * {any attributes with non-schema namespace . . .}>
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);
6568 if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
6569 (xmlStrEqual(attr->name, BAD_CAST "lang") &&
6570 (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
6572 xmlSchemaPIllegalAttrErr(ctxt,
6573 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6579 * Attribute "xml:lang".
6581 attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
6583 xmlSchemaPValAttrNode(ctxt, NULL, attr,
6584 xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
6585 child = child->next;
6588 xmlSchemaPContentErr(ctxt,
6589 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6590 NULL, node, child, NULL, "(appinfo | documentation)*");
6592 child = child->next;
6600 * xmlSchemaParseFacet:
6601 * @ctxt: a schema validation context
6602 * @schema: the schema being built
6603 * @node: a subtree containing XML Schema informations
6605 * parse a XML schema Facet declaration
6606 * *WARNING* this interface is highly subject to change
6608 * Returns the new type structure or NULL in case of error
6610 static xmlSchemaFacetPtr
6611 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6614 xmlSchemaFacetPtr facet;
6615 xmlNodePtr child = NULL;
6616 const xmlChar *value;
6618 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6621 facet = xmlSchemaNewFacet();
6622 if (facet == NULL) {
6623 xmlSchemaPErrMemory(ctxt, "allocating facet", 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);
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;
6659 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
6660 "Unknown facet type %s\n", node->name, NULL);
6661 xmlSchemaFreeFacet(facet);
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;
6670 fixed = xmlSchemaGetProp(ctxt, node, "fixed");
6671 if (fixed != NULL) {
6672 if (xmlStrEqual(fixed, BAD_CAST "true"))
6676 child = node->children;
6678 if (IS_SCHEMA(child, "annotation")) {
6679 facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6680 child = child->next;
6682 if (child != NULL) {
6683 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
6684 "Facet %s has unexpected child content\n",
6691 * xmlSchemaParseWildcardNs:
6692 * @ctxt: a schema parser context
6693 * @wildc: the wildcard, already created
6694 * @node: a subtree containing XML Schema informations
6696 * Parses the attribute "processContents" and "namespace"
6697 * of a xsd:anyAttribute and xsd:any.
6698 * *WARNING* this interface is highly subject to change
6700 * Returns 0 if everything goes fine, a positive error code
6701 * if something is not valid and -1 if an internal error occurs.
6704 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
6705 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6706 xmlSchemaWildcardPtr wildc,
6709 const xmlChar *pc, *ns, *dictnsItem;
6712 xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
6715 pc = xmlSchemaGetProp(ctxt, node, "processContents");
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;
6724 xmlSchemaPSimpleTypeErr(ctxt,
6725 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6727 NULL, "(strict | skip | lax)", pc,
6729 wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6730 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
6733 * Build the namespace constraints.
6735 attr = xmlSchemaGetPropNode(node, "namespace");
6736 ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6737 if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
6739 else if (xmlStrEqual(ns, BAD_CAST "##other")) {
6740 wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
6741 if (wildc->negNsSet == NULL) {
6744 wildc->negNsSet->value = ctxt->targetNamespace;
6746 const xmlChar *end, *cur;
6750 while (IS_BLANK_CH(*cur))
6753 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
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,
6764 "((##any | ##other) | List of (xs:anyURI | "
6765 "(##targetNamespace | ##local)))",
6766 nsItem, NULL, NULL, NULL);
6767 ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
6769 if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
6770 dictnsItem = ctxt->targetNamespace;
6771 } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
6775 * Validate the item (anyURI).
6777 xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
6778 nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
6779 dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
6782 * Avoid dublicate namespaces.
6785 while (tmp != NULL) {
6786 if (dictnsItem == tmp->value)
6791 tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
6796 tmp->value = dictnsItem;
6798 if (wildc->nsSet == NULL)
6800 else if (lastNs != NULL)
6808 } while (*cur != 0);
6814 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
6815 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
6820 if ((maxOccurs == 0) && ( minOccurs == 0))
6822 if (maxOccurs != UNBOUNDED) {
6824 * TODO: Maybe we should better not create the particle,
6825 * if min/max is invalid, since it could confuse the build of the
6829 * 3.9.6 Schema Component Constraint: Particle Correct
6832 if (maxOccurs < 1) {
6834 * 2.2 {max occurs} must be greater than or equal to 1.
6836 xmlSchemaPCustomAttrErr(ctxt,
6837 XML_SCHEMAP_P_PROPS_CORRECT_2_2,
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) {
6844 * 2.1 {min occurs} must not be greater than {max occurs}.
6846 xmlSchemaPCustomAttrErr(ctxt,
6847 XML_SCHEMAP_P_PROPS_CORRECT_2_1,
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);
6858 * xmlSchemaParseAny:
6859 * @ctxt: a schema validation context
6860 * @schema: the schema being built
6861 * @node: a subtree containing XML Schema informations
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
6868 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
6870 static xmlSchemaParticlePtr
6871 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6874 xmlSchemaParticlePtr particle;
6875 xmlNodePtr child = NULL;
6876 xmlSchemaWildcardPtr wild;
6879 xmlSchemaAnnotPtr annot = NULL;
6881 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6884 * Check for illegal attributes.
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);
6897 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
6898 xmlSchemaPIllegalAttrErr(ctxt,
6899 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6903 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6905 * minOccurs/maxOccurs.
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);
6913 * Create & parse the wildcard.
6915 wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
6918 xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
6920 * And now for the children...
6922 child = node->children;
6923 if (IS_SCHEMA(child, "annotation")) {
6924 annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6925 child = child->next;
6927 if (child != NULL) {
6928 xmlSchemaPContentErr(ctxt,
6929 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6931 NULL, "(annotation?)");
6934 * No component if minOccurs==maxOccurs==0.
6936 if ((min == 0) && (max == 0)) {
6937 /* Don't free the wildcard, since it's already on the list. */
6941 * Create the particle.
6943 particle = xmlSchemaAddParticle(ctxt, node, min, max);
6944 if (particle == NULL)
6946 particle->annot = annot;
6947 particle->children = (xmlSchemaTreeItemPtr) wild;
6953 * xmlSchemaParseNotation:
6954 * @ctxt: a schema validation context
6955 * @schema: the schema being built
6956 * @node: a subtree containing XML Schema informations
6958 * parse a XML schema Notation declaration
6960 * Returns the new structure or NULL in case of error
6962 static xmlSchemaNotationPtr
6963 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6966 const xmlChar *name;
6967 xmlSchemaNotationPtr ret;
6968 xmlNodePtr child = NULL;
6970 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6972 name = xmlSchemaGetProp(ctxt, node, "name");
6974 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
6975 "Notation has no name\n", NULL, NULL);
6978 ret = xmlSchemaAddNotation(ctxt, schema, name,
6979 ctxt->targetNamespace, node);
6982 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6984 child = node->children;
6985 if (IS_SCHEMA(child, "annotation")) {
6986 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6987 child = child->next;
6989 if (child != NULL) {
6990 xmlSchemaPContentErr(ctxt,
6991 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6993 NULL, "(annotation?)");
7000 * xmlSchemaParseAnyAttribute:
7001 * @ctxt: a schema validation context
7002 * @schema: the schema being built
7003 * @node: a subtree containing XML Schema informations
7005 * parse a XML schema AnyAttrribute declaration
7006 * *WARNING* this interface is highly subject to change
7008 * Returns a wildcard or NULL.
7010 static xmlSchemaWildcardPtr
7011 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
7012 xmlSchemaPtr schema, xmlNodePtr node)
7014 xmlSchemaWildcardPtr ret;
7015 xmlNodePtr child = NULL;
7018 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
7021 ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
7027 * Check for illegal attributes.
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);
7038 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7039 xmlSchemaPIllegalAttrErr(ctxt,
7040 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7044 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
7046 * Parse the namespace list.
7048 if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
7051 * And now for the children...
7053 child = node->children;
7054 if (IS_SCHEMA(child, "annotation")) {
7055 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
7056 child = child->next;
7058 if (child != NULL) {
7059 xmlSchemaPContentErr(ctxt,
7060 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7062 NULL, "(annotation?)");
7070 * xmlSchemaParseAttribute:
7071 * @ctxt: a schema validation context
7072 * @schema: the schema being built
7073 * @node: a subtree containing XML Schema informations
7075 * parse a XML schema Attrribute declaration
7076 * *WARNING* this interface is highly subject to change
7078 * Returns the attribute declaration.
7080 static xmlSchemaBasicItemPtr
7081 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
7082 xmlSchemaPtr schema,
7084 xmlSchemaItemListPtr uses,
7087 const xmlChar *attrValue, *name = NULL, *ns = NULL;
7088 xmlSchemaAttributeUsePtr use = NULL;
7089 xmlNodePtr child = NULL;
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;
7095 #define WXS_ATTR_DEF_VAL_DEFAULT 1
7096 #define WXS_ATTR_DEF_VAL_FIXED 2
7099 * 3.2.3 Constraints on XML Representations of Attribute Declarations
7102 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7104 attr = xmlSchemaGetPropNode(node, "ref");
7106 if (xmlSchemaPValAttrNodeQName(pctxt, schema,
7107 NULL, attr, &tmpNs, &tmpName) != 0) {
7110 if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
7114 nberrors = pctxt->nberrors;
7116 * Check for illegal attributes.
7118 attr = node->properties;
7119 while (attr != NULL) {
7120 if (attr->ns == NULL) {
7122 if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7123 xmlSchemaPValAttrNodeID(pctxt, attr);
7125 } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
7129 if (xmlStrEqual(attr->name, BAD_CAST "name")) {
7131 } else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7132 xmlSchemaPValAttrNodeID(pctxt, attr);
7134 } else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
7135 xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
7136 attr, &tmpNs, &tmpName);
7138 } else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
7140 * Evaluate the target namespace
7143 attrValue = xmlSchemaGetNodeContent(pctxt,
7145 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
7146 ns = pctxt->targetNamespace;
7147 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
7149 xmlSchemaPSimpleTypeErr(pctxt,
7150 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
7151 NULL, (xmlNodePtr) attr,
7152 NULL, "(qualified | unqualified)",
7153 attrValue, NULL, NULL, NULL);
7158 if (xmlStrEqual(attr->name, BAD_CAST "use")) {
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;
7169 xmlSchemaPSimpleTypeErr(pctxt,
7170 XML_SCHEMAP_INVALID_ATTR_USE,
7171 NULL, (xmlNodePtr) attr,
7172 NULL, "(optional | prohibited | required)",
7173 attrValue, NULL, NULL, NULL);
7176 } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
7179 * default and fixed must not both be present.
7182 xmlSchemaPMutualExclAttrErr(pctxt,
7183 XML_SCHEMAP_SRC_ATTRIBUTE_1,
7184 NULL, attr, "default", "fixed");
7186 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7187 defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
7190 } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
7193 * default and fixed must not both be present.
7196 xmlSchemaPMutualExclAttrErr(pctxt,
7197 XML_SCHEMAP_SRC_ATTRIBUTE_1,
7198 NULL, attr, "default", "fixed");
7200 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7201 defValueType = WXS_ATTR_DEF_VAL_FIXED;
7205 } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
7208 xmlSchemaPIllegalAttrErr(pctxt,
7209 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7216 * If default and use are both present, use must have
7217 * the actual value optional.
7219 if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
7220 (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
7221 xmlSchemaPSimpleTypeErr(pctxt,
7222 XML_SCHEMAP_SRC_ATTRIBUTE_2,
7224 "(optional | prohibited | required)", NULL,
7225 "The value of the attribute 'use' must be 'optional' "
7226 "if the attribute 'default' is present",
7230 * We want correct attributes.
7232 if (nberrors != pctxt->nberrors)
7235 xmlSchemaAttributePtr attrDecl;
7237 /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
7238 if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
7239 ns = pctxt->targetNamespace;
7241 * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7242 * TODO: Move this to the component layer.
7244 if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
7245 xmlSchemaCustomErr(ACTXT_CAST pctxt,
7248 "The target namespace must not match '%s'",
7249 xmlSchemaInstanceNs, NULL);
7251 attr = xmlSchemaGetPropNode(node, "name");
7253 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7254 NULL, node, "name", NULL);
7257 if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7258 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7262 * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7263 * TODO: Move this to the component layer.
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'",
7274 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
7275 goto check_children;
7277 * Create the attribute use component.
7279 use = xmlSchemaAddAttributeUse(pctxt, node);
7282 use->occurs = occurs;
7284 * Create the attribute declaration.
7286 attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
7287 if (attrDecl == NULL)
7289 if (tmpName != NULL) {
7290 attrDecl->typeName = tmpName;
7291 attrDecl->typeNs = tmpNs;
7293 use->attrDecl = attrDecl;
7297 if (defValue != NULL) {
7298 attrDecl->defValue = defValue;
7299 if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7300 attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
7302 } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7303 xmlSchemaQNameRefPtr ref;
7306 * Create the attribute use component.
7308 use = xmlSchemaAddAttributeUse(pctxt, node);
7312 * We need to resolve the reference at later stage.
7314 WXS_ADD_PENDING(pctxt, use);
7315 use->occurs = occurs;
7317 * Create a QName reference to the attribute declaration.
7319 ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
7324 * Assign the reference. This will be substituted for the
7325 * referenced attribute declaration when the QName is resolved.
7327 use->attrDecl = WXS_ATTR_CAST ref;
7331 if (defValue != NULL)
7332 use->defValue = defValue;
7333 if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7334 use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
7339 * And now for the children...
7341 child = node->children;
7342 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7343 xmlSchemaAttributeUseProhibPtr prohib;
7345 if (IS_SCHEMA(child, "annotation")) {
7346 xmlSchemaParseAnnotation(pctxt, child, 0);
7347 child = child->next;
7349 if (child != NULL) {
7350 xmlSchemaPContentErr(pctxt,
7351 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7352 NULL, node, child, NULL,
7356 * Check for pointlessness of attribute prohibitions.
7358 if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
7359 xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7360 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7362 "Skipping attribute use prohibition, since it is "
7363 "pointless inside an <attributeGroup>",
7366 } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
7367 xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7368 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7370 "Skipping attribute use prohibition, since it is "
7371 "pointless when extending a type",
7380 * Check for duplicate attribute prohibitions.
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))
7391 xmlChar *str = NULL;
7393 xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7394 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7396 "Skipping duplicate attribute use prohibition '%s'",
7397 xmlSchemaFormatQName(&str, tmpNs, tmpName),
7405 * Create the attribute prohibition helper component.
7407 prohib = xmlSchemaAddAttributeUseProhib(pctxt);
7410 prohib->node = node;
7411 prohib->name = tmpName;
7412 prohib->targetNamespace = tmpNs;
7415 * We need at least to resolve to the attribute declaration.
7417 WXS_ADD_PENDING(pctxt, prohib);
7419 return(WXS_BASIC_CAST prohib);
7421 if (IS_SCHEMA(child, "annotation")) {
7423 * TODO: Should this go into the attr decl?
7425 use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7426 child = child->next;
7429 if (child != NULL) {
7430 if (IS_SCHEMA(child, "simpleType"))
7433 * If ref is present, then all of <simpleType>,
7434 * form and type must be absent.
7436 xmlSchemaPContentErr(pctxt,
7437 XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
7438 NULL, node, child, NULL,
7441 xmlSchemaPContentErr(pctxt,
7442 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7443 NULL, node, child, NULL,
7447 if (IS_SCHEMA(child, "simpleType")) {
7448 if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
7451 * type and <simpleType> must not both be present.
7453 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7455 "The attribute 'type' and the <simpleType> child "
7456 "are mutually exclusive", NULL);
7458 WXS_ATTRUSE_TYPEDEF(use) =
7459 xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7460 child = child->next;
7463 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7464 NULL, node, child, NULL,
7465 "(annotation?, simpleType?)");
7468 return (WXS_BASIC_CAST use);
7472 static xmlSchemaAttributePtr
7473 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
7474 xmlSchemaPtr schema,
7477 const xmlChar *attrValue;
7478 xmlSchemaAttributePtr ret;
7479 xmlNodePtr child = NULL;
7483 * Note that the w3c spec assumes the schema to be validated with schema
7484 * for schemas beforehand.
7486 * 3.2.3 Constraints on XML Representations of Attribute Declarations
7488 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7492 * One of ref or name must be present, but not both
7494 attr = xmlSchemaGetPropNode(node, "name");
7496 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7497 NULL, node, "name", NULL);
7500 if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7501 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
7505 * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7506 * TODO: Move this to the component layer.
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'",
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.
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);
7530 ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
7531 pctxt->targetNamespace, node, 1);
7534 ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
7537 * Check for illegal attributes.
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")))
7548 xmlSchemaPIllegalAttrErr(pctxt,
7549 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7551 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7552 xmlSchemaPIllegalAttrErr(pctxt,
7553 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7557 xmlSchemaPValAttrQName(pctxt, schema, NULL,
7558 node, "type", &ret->typeNs, &ret->typeName);
7560 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7562 * Attribute "fixed".
7564 ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
7565 if (ret->defValue != NULL)
7566 ret->flags |= XML_SCHEMAS_ATTR_FIXED;
7568 * Attribute "default".
7570 attr = xmlSchemaGetPropNode(node, "default");
7574 * default and fixed must not both be present.
7576 if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
7577 xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
7578 WXS_BASIC_CAST ret, attr, "default", "fixed");
7580 ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7583 * And now for the children...
7585 child = node->children;
7586 if (IS_SCHEMA(child, "annotation")) {
7587 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7588 child = child->next;
7590 if (IS_SCHEMA(child, "simpleType")) {
7591 if (ret->typeName != NULL) {
7594 * type and <simpleType> must not both be present.
7596 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7598 "The attribute 'type' and the <simpleType> child "
7599 "are mutually exclusive", NULL);
7601 ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7602 child = child->next;
7605 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7606 NULL, node, child, NULL,
7607 "(annotation?, simpleType?)");
7613 * xmlSchemaParseAttributeGroupRef:
7614 * @ctxt: a schema validation context
7615 * @schema: the schema being built
7616 * @node: a subtree containing XML Schema informations
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
7623 * Returns the attribute group or NULL in case of error.
7625 static xmlSchemaQNameRefPtr
7626 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
7627 xmlSchemaPtr schema,
7630 xmlSchemaQNameRefPtr ret;
7631 xmlNodePtr child = NULL;
7633 const xmlChar *refNs = NULL, *ref = NULL;
7635 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7638 attr = xmlSchemaGetPropNode(node, "ref");
7640 xmlSchemaPMissingAttrErr(pctxt,
7641 XML_SCHEMAP_S4S_ATTR_MISSING,
7642 NULL, node, "ref", NULL);
7645 xmlSchemaPValAttrNodeQName(pctxt, schema,
7646 NULL, attr, &refNs, &ref);
7647 if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
7651 * Check for illegal attributes.
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")))
7659 xmlSchemaPIllegalAttrErr(pctxt,
7660 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7662 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7663 xmlSchemaPIllegalAttrErr(pctxt,
7664 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7669 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7672 * And now for the children...
7674 child = node->children;
7675 if (IS_SCHEMA(child, "annotation")) {
7677 * TODO: We do not have a place to store the annotation, do we?
7679 xmlSchemaParseAnnotation(pctxt, child, 0);
7680 child = child->next;
7682 if (child != NULL) {
7683 xmlSchemaPContentErr(pctxt,
7684 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7685 NULL, node, child, NULL,
7690 * Handle attribute group redefinitions.
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))
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."
7705 if (pctxt->redefCounter != 0) {
7706 xmlChar *str = NULL;
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);
7717 pctxt->redefCounter++;
7719 * URGENT TODO: How to ensure that the reference will not be
7720 * handled by the normal component resolution mechanism?
7722 ret = xmlSchemaNewQNameRef(pctxt,
7723 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7727 pctxt->redef->reference = WXS_BASIC_CAST ret;
7730 * Create a QName-reference helper component. We will substitute this
7731 * component for the attribute uses of the referenced attribute group
7734 ret = xmlSchemaNewQNameRef(pctxt,
7735 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7739 /* Add to pending items, to be able to resolve the reference. */
7740 WXS_ADD_PENDING(pctxt, ret);
7746 * xmlSchemaParseAttributeGroupDefinition:
7747 * @pctxt: a schema validation context
7748 * @schema: the schema being built
7749 * @node: a subtree containing XML Schema informations
7751 * parse a XML schema Attribute Group declaration
7752 * *WARNING* this interface is highly subject to change
7754 * Returns the attribute group definition or NULL in case of error.
7756 static xmlSchemaAttributeGroupPtr
7757 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
7758 xmlSchemaPtr schema,
7761 const xmlChar *name;
7762 xmlSchemaAttributeGroupPtr ret;
7763 xmlNodePtr child = NULL;
7767 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7770 attr = xmlSchemaGetPropNode(node, "name");
7772 xmlSchemaPMissingAttrErr(pctxt,
7773 XML_SCHEMAP_S4S_ATTR_MISSING,
7774 NULL, node, "name", NULL);
7778 * The name is crucial, exit if invalid.
7780 if (xmlSchemaPValAttrNode(pctxt,
7782 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7785 ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
7786 name, pctxt->targetNamespace, node);
7790 * Check for illegal attributes.
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")))
7798 xmlSchemaPIllegalAttrErr(pctxt,
7799 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7801 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7802 xmlSchemaPIllegalAttrErr(pctxt,
7803 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7808 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7810 * And now for the children...
7812 child = node->children;
7813 if (IS_SCHEMA(child, "annotation")) {
7814 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7815 child = child->next;
7818 * Parse contained attribute decls/refs.
7820 if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
7821 (xmlSchemaItemListPtr *) &(ret->attrUses),
7822 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
7825 ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
7827 * Parse the attribute wildcard.
7829 if (IS_SCHEMA(child, "anyAttribute")) {
7830 ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
7832 child = child->next;
7834 if (child != NULL) {
7835 xmlSchemaPContentErr(pctxt,
7836 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7837 NULL, node, child, NULL,
7838 "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
7844 * xmlSchemaPValAttrFormDefault:
7846 * @flags: the flags to be modified
7847 * @flagQualified: the specific flag for "qualified"
7849 * Returns 0 if the value is valid, 1 otherwise.
7852 xmlSchemaPValAttrFormDefault(const xmlChar *value,
7856 if (xmlStrEqual(value, BAD_CAST "qualified")) {
7857 if ((*flags & flagQualified) == 0)
7858 *flags |= flagQualified;
7859 } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
7866 * xmlSchemaPValAttrBlockFinal:
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"
7876 * Validates the value of the attribute "final" and "block". The value
7877 * is converted into the specified flag values and returned in @flags.
7879 * Returns 0 if the value is valid, 1 otherwise.
7883 xmlSchemaPValAttrBlockFinal(const xmlChar *value,
7887 int flagRestriction,
7888 int flagSubstitution,
7895 * TODO: This does not check for dublicate entries.
7897 if ((flags == NULL) || (value == NULL))
7901 if (xmlStrEqual(value, BAD_CAST "#all")) {
7905 if (flagExtension != -1)
7906 *flags |= flagExtension;
7907 if (flagRestriction != -1)
7908 *flags |= flagRestriction;
7909 if (flagSubstitution != -1)
7910 *flags |= flagSubstitution;
7913 if (flagUnion != -1)
7914 *flags |= flagUnion;
7917 const xmlChar *end, *cur = value;
7921 while (IS_BLANK_CH(*cur))
7924 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
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;
7935 } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
7936 if (flagRestriction != -1) {
7937 if ((*flags & flagRestriction) == 0)
7938 *flags |= flagRestriction;
7941 } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
7942 if (flagSubstitution != -1) {
7943 if ((*flags & flagSubstitution) == 0)
7944 *flags |= flagSubstitution;
7947 } else if (xmlStrEqual(item, BAD_CAST "list")) {
7948 if (flagList != -1) {
7949 if ((*flags & flagList) == 0)
7953 } else if (xmlStrEqual(item, BAD_CAST "union")) {
7954 if (flagUnion != -1) {
7955 if ((*flags & flagUnion) == 0)
7956 *flags |= flagUnion;
7964 } while ((ret == 0) && (*cur != 0));
7971 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
7972 xmlSchemaIDCPtr idc,
7973 xmlSchemaIDCSelectPtr selector,
7981 * Schema Component Constraint: Selector Value OK
7983 * TODO: 1 The {selector} must be a valid XPath expression, as defined
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);
7996 node = (xmlNodePtr) attr;
7997 if (selector->xpath == NULL) {
7998 xmlSchemaPCustomErr(ctxt,
7999 /* TODO: Adjust error code. */
8000 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8002 "The XPath expression of the selector is not valid", NULL);
8003 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
8005 const xmlChar **nsArray = NULL;
8006 xmlNsPtr *nsList = NULL;
8008 * Compile the XPath expression.
8011 * TODO: We need the array of in-scope namespaces for compilation.
8012 * TODO: Call xmlPatterncompile with different options for selector/
8018 nsList = xmlGetNsList(attr->doc, attr->parent);
8020 * Build an array of prefixes and namespaces.
8022 if (nsList != NULL) {
8025 for (i = 0; nsList[i] != NULL; i++)
8028 nsArray = (const xmlChar **) xmlMalloc(
8029 (count * 2 + 1) * sizeof(const xmlChar *));
8030 if (nsArray == NULL) {
8031 xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
8036 for (i = 0; i < count; i++) {
8037 nsArray[2 * i] = nsList[i]->href;
8038 nsArray[2 * i + 1] = nsList[i]->prefix;
8040 nsArray[count * 2] = NULL;
8044 * TODO: Differentiate between "selector" and "field".
8047 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8048 NULL, XML_PATTERN_XSFIELD, nsArray);
8050 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8051 NULL, XML_PATTERN_XSSEL, nsArray);
8052 if (nsArray != NULL)
8053 xmlFree((xmlChar **) nsArray);
8055 if (selector->xpathComp == NULL) {
8056 xmlSchemaPCustomErr(ctxt,
8057 /* TODO: Adjust error code? */
8058 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8060 "The XPath expression '%s' could not be "
8061 "compiled", selector->xpath);
8062 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
8068 #define ADD_ANNOTATION(annot) \
8069 xmlSchemaAnnotPtr cur = item->annot; \
8070 if (item->annot == NULL) { \
8071 item->annot = annot; \
8074 cur = item->annot; \
8075 if (cur->next != NULL) { \
8081 * xmlSchemaAssignAnnotation:
8082 * @item: the schema component
8083 * @annot: the annotation
8085 * Adds the annotation to the given schema component.
8087 * Returns the given annotaion.
8089 static xmlSchemaAnnotPtr
8090 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
8091 xmlSchemaAnnotPtr annot)
8093 if ((annItem == NULL) || (annot == NULL))
8095 switch (annItem->type) {
8096 case XML_SCHEMA_TYPE_ELEMENT: {
8097 xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
8098 ADD_ANNOTATION(annot)
8101 case XML_SCHEMA_TYPE_ATTRIBUTE: {
8102 xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
8103 ADD_ANNOTATION(annot)
8106 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
8107 case XML_SCHEMA_TYPE_ANY: {
8108 xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
8109 ADD_ANNOTATION(annot)
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)
8120 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
8121 xmlSchemaAttributeGroupPtr item =
8122 (xmlSchemaAttributeGroupPtr) annItem;
8123 ADD_ANNOTATION(annot)
8126 case XML_SCHEMA_TYPE_NOTATION: {
8127 xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
8128 ADD_ANNOTATION(annot)
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)
8147 case XML_SCHEMA_TYPE_SIMPLE:
8148 case XML_SCHEMA_TYPE_COMPLEX: {
8149 xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
8150 ADD_ANNOTATION(annot)
8153 case XML_SCHEMA_TYPE_GROUP: {
8154 xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
8155 ADD_ANNOTATION(annot)
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)
8166 xmlSchemaPCustomErr(NULL,
8167 XML_SCHEMAP_INTERNAL,
8169 "Internal error: xmlSchemaAddAnnotation, "
8170 "The item is not a annotated schema component", NULL);
8177 * xmlSchemaParseIDCSelectorAndField:
8178 * @ctxt: a schema validation context
8179 * @schema: the schema being built
8180 * @node: a subtree containing XML Schema informations
8182 * Parses a XML Schema identity-contraint definition's
8183 * <selector> and <field> elements.
8185 * Returns the parsed identity-constraint definition.
8187 static xmlSchemaIDCSelectPtr
8188 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
8189 xmlSchemaIDCPtr idc,
8193 xmlSchemaIDCSelectPtr item;
8194 xmlNodePtr child = NULL;
8198 * Check for illegal attributes.
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);
8208 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8209 xmlSchemaPIllegalAttrErr(ctxt,
8210 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8217 item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
8219 xmlSchemaPErrMemory(ctxt,
8220 "allocating a 'selector' of an identity-constraint definition",
8224 memset(item, 0, sizeof(xmlSchemaIDCSelect));
8226 * Attribute "xpath" (mandatory).
8228 attr = xmlSchemaGetPropNode(node, "xpath");
8230 xmlSchemaPMissingAttrErr(ctxt,
8231 XML_SCHEMAP_S4S_ATTR_MISSING,
8235 item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8237 * URGENT TODO: "field"s have an other syntax than "selector"s.
8240 if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
8244 XML_SCHEMAP_INTERNAL,
8245 "Internal error: xmlSchemaParseIDCSelectorAndField, "
8246 "validating the XPath expression of a IDC selector.\n",
8251 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8253 * And now for the children...
8255 child = node->children;
8256 if (IS_SCHEMA(child, "annotation")) {
8258 * Add the annotation to the parent IDC.
8260 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
8261 xmlSchemaParseAnnotation(ctxt, child, 1));
8262 child = child->next;
8264 if (child != NULL) {
8265 xmlSchemaPContentErr(ctxt,
8266 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8268 NULL, "(annotation?)");
8275 * xmlSchemaParseIDC:
8276 * @ctxt: a schema validation context
8277 * @schema: the schema being built
8278 * @node: a subtree containing XML Schema informations
8280 * Parses a XML Schema identity-contraint definition.
8282 * Returns the parsed identity-constraint definition.
8284 static xmlSchemaIDCPtr
8285 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
8286 xmlSchemaPtr schema,
8288 xmlSchemaTypeType idcCategory,
8289 const xmlChar *targetNamespace)
8291 xmlSchemaIDCPtr item = NULL;
8292 xmlNodePtr child = NULL;
8294 const xmlChar *name = NULL;
8295 xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
8298 * Check for illegal attributes.
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);
8310 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8311 xmlSchemaPIllegalAttrErr(ctxt,
8312 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8317 * Attribute "name" (mandatory).
8319 attr = xmlSchemaGetPropNode(node, "name");
8321 xmlSchemaPMissingAttrErr(ctxt,
8322 XML_SCHEMAP_S4S_ATTR_MISSING,
8326 } else if (xmlSchemaPValAttrNode(ctxt,
8328 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
8331 /* Create the component. */
8332 item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
8337 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8338 if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
8340 * Attribute "refer" (mandatory).
8342 attr = xmlSchemaGetPropNode(node, "refer");
8344 xmlSchemaPMissingAttrErr(ctxt,
8345 XML_SCHEMAP_S4S_ATTR_MISSING,
8350 * Create a reference item.
8352 item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
8354 if (item->ref == NULL)
8356 xmlSchemaPValAttrNodeQName(ctxt, schema,
8358 &(item->ref->targetNamespace),
8359 &(item->ref->name));
8360 xmlSchemaCheckReference(ctxt, schema, node, attr,
8361 item->ref->targetNamespace);
8365 * And now for the children...
8367 child = node->children;
8368 if (IS_SCHEMA(child, "annotation")) {
8369 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8370 child = child->next;
8372 if (child == NULL) {
8373 xmlSchemaPContentErr(ctxt,
8374 XML_SCHEMAP_S4S_ELEM_MISSING,
8376 "A child element is missing",
8377 "(annotation?, (selector, field+))");
8380 * Child element <selector>.
8382 if (IS_SCHEMA(child, "selector")) {
8383 item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
8385 child = child->next;
8387 * Child elements <field>.
8389 if (IS_SCHEMA(child, "field")) {
8391 field = xmlSchemaParseIDCSelectorAndField(ctxt,
8393 if (field != NULL) {
8394 field->index = item->nbFields;
8396 if (lastField != NULL)
8397 lastField->next = field;
8399 item->fields = field;
8402 child = child->next;
8403 } while (IS_SCHEMA(child, "field"));
8405 xmlSchemaPContentErr(ctxt,
8406 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8408 NULL, "(annotation?, (selector, field+))");
8411 if (child != NULL) {
8412 xmlSchemaPContentErr(ctxt,
8413 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8415 NULL, "(annotation?, (selector, field+))");
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
8428 * Parses a XML schema element declaration.
8429 * *WARNING* this interface is highly subject to change
8431 * Returns the element declaration or a particle; NULL in case
8432 * of an error or if the particle has minOccurs==maxOccurs==0.
8434 static xmlSchemaBasicItemPtr
8435 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8436 xmlNodePtr node, int *isElemRef, int topLevel)
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;
8446 /* 3.3.3 Constraints on XML Representations of Element Declarations */
8447 /* TODO: Complete implementation of 3.3.6 */
8449 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8452 if (isElemRef != NULL)
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
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);
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;
8478 * Skip particle part if a global declaration.
8481 goto declaration_part;
8483 * The particle part ==================================================
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)
8492 /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
8495 const xmlChar *refNs = NULL, *ref = NULL;
8496 xmlSchemaQNameRefPtr refer = NULL;
8498 * The reference part =============================================
8500 if (isElemRef != NULL)
8503 xmlSchemaPValAttrNodeQName(ctxt, schema,
8504 NULL, attr, &refNs, &ref);
8505 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
8507 * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
8509 if (nameAttr != NULL) {
8510 xmlSchemaPMutualExclAttrErr(ctxt,
8511 XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
8514 * Check for illegal attributes.
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"))
8528 /* SPEC (3.3.3 : 2.2) */
8529 xmlSchemaPCustomAttrErr(ctxt,
8530 XML_SCHEMAP_SRC_ELEMENT_2_2,
8532 "Only the attributes 'minOccurs', 'maxOccurs' and "
8533 "'id' are allowed in addition to 'ref'");
8536 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8537 xmlSchemaPIllegalAttrErr(ctxt,
8538 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8543 * No children except <annotation> expected.
8545 if (child != NULL) {
8546 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8547 NULL, node, child, NULL, "(annotation?)");
8549 if ((min == 0) && (max == 0))
8552 * Create the reference item and attach it to the particle.
8554 refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
8558 particle->children = (xmlSchemaTreeItemPtr) refer;
8559 particle->annot = annot;
8561 * Add the particle to pending components, since the reference
8562 * need to be resolved.
8564 WXS_ADD_PENDING(ctxt, particle);
8565 return ((xmlSchemaBasicItemPtr) particle);
8568 * The declaration part ===============================================
8572 const xmlChar *ns = NULL, *fixed, *name, *attrValue;
8573 xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
8575 if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
8576 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
8579 * Evaluate the target namespace.
8582 ns = ctxt->targetNamespace;
8584 attr = xmlSchemaGetPropNode(node, "form");
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);
8596 } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
8597 ns = ctxt->targetNamespace;
8599 decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
8604 * Check for illegal attributes.
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")))
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")))
8622 xmlSchemaPIllegalAttrErr(ctxt,
8623 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8625 } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
8626 (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
8627 (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
8629 xmlSchemaPIllegalAttrErr(ctxt,
8630 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8633 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8635 xmlSchemaPIllegalAttrErr(ctxt,
8636 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8641 * Extract/validate attributes.
8645 * Process top attributes of global element declarations here.
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;
8655 * Attribute "final".
8657 attr = xmlSchemaGetPropNode(node, "final");
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;
8664 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8665 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
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);
8678 * Attribute "block".
8680 attr = xmlSchemaGetPropNode(node, "block");
8683 * Apply default "block" values.
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;
8692 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8693 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
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,
8706 if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
8707 decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
8709 attr = xmlSchemaGetPropNode(node, "type");
8711 xmlSchemaPValAttrNodeQName(ctxt, schema,
8713 &(decl->namedTypeNs), &(decl->namedType));
8714 xmlSchemaCheckReference(ctxt, schema, node,
8715 attr, decl->namedTypeNs);
8717 decl->value = xmlSchemaGetProp(ctxt, node, "default");
8718 attr = xmlSchemaGetPropNode(node, "fixed");
8720 fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8721 if (decl->value != NULL) {
8724 * default and fixed must not both be present.
8726 xmlSchemaPMutualExclAttrErr(ctxt,
8727 XML_SCHEMAP_SRC_ELEMENT_1,
8728 NULL, attr, "default", "fixed");
8730 decl->flags |= XML_SCHEMAS_ELEM_FIXED;
8731 decl->value = fixed;
8735 * And now for the children...
8737 if (IS_SCHEMA(child, "complexType")) {
8740 * "type" and either <simpleType> or <complexType> are mutually
8743 if (decl->namedType != NULL) {
8744 xmlSchemaPContentErr(ctxt,
8745 XML_SCHEMAP_SRC_ELEMENT_3,
8747 "The attribute 'type' and the <complexType> child are "
8748 "mutually exclusive", NULL);
8750 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
8751 child = child->next;
8752 } else if (IS_SCHEMA(child, "simpleType")) {
8755 * "type" and either <simpleType> or <complexType> are
8756 * mutually exclusive
8758 if (decl->namedType != NULL) {
8759 xmlSchemaPContentErr(ctxt,
8760 XML_SCHEMAP_SRC_ELEMENT_3,
8762 "The attribute 'type' and the <simpleType> child are "
8763 "mutually exclusive", NULL);
8765 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8766 child = child->next;
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);
8780 if (lastIDC != NULL)
8781 lastIDC->next = curIDC;
8783 decl->idcs = (void *) curIDC;
8785 child = child->next;
8787 if (child != NULL) {
8788 xmlSchemaPContentErr(ctxt,
8789 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8791 NULL, "(annotation?, ((simpleType | complexType)?, "
8792 "(unique | key | keyref)*))");
8794 decl->annot = annot;
8797 * NOTE: Element Declaration Representation OK 4. will be checked at a
8802 return ((xmlSchemaBasicItemPtr) decl);
8804 particle->children = (xmlSchemaTreeItemPtr) decl;
8805 return ((xmlSchemaBasicItemPtr) particle);
8810 if (annot != NULL) {
8811 if (particle != NULL)
8812 particle->annot = NULL;
8815 xmlSchemaFreeAnnot(annot);
8821 * xmlSchemaParseUnion:
8822 * @ctxt: a schema validation context
8823 * @schema: the schema being built
8824 * @node: a subtree containing XML Schema informations
8826 * parse a XML schema Union definition
8827 * *WARNING* this interface is highly subject to change
8829 * Returns -1 in case of internal error, 0 in case of success and a positive
8830 * error code otherwise.
8833 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8836 xmlSchemaTypePtr type;
8837 xmlNodePtr child = NULL;
8839 const xmlChar *cur = NULL;
8841 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8843 /* Not a component, don't create it. */
8844 type = ctxt->ctxtType;
8846 * Mark the simple type as being of variety "union".
8848 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
8850 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
8851 * then the �simple ur-type definition�."
8853 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
8855 * Check for illegal attributes.
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);
8865 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8866 xmlSchemaPIllegalAttrErr(ctxt,
8867 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8871 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8873 * Attribute "memberTypes". This is a list of QNames.
8874 * TODO: Check the value to contain anything.
8876 attr = xmlSchemaGetPropNode(node, "memberTypes");
8880 const xmlChar *localName, *nsName;
8881 xmlSchemaTypeLinkPtr link, lastLink = NULL;
8882 xmlSchemaQNameRefPtr ref;
8884 cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8887 while (IS_BLANK_CH(*cur))
8890 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
8894 tmp = xmlStrndup(cur, end - cur);
8895 if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
8896 NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
8898 * Create the member type link.
8900 link = (xmlSchemaTypeLinkPtr)
8901 xmlMalloc(sizeof(xmlSchemaTypeLink));
8903 xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
8904 "allocating a type link", NULL);
8909 if (lastLink == NULL)
8910 type->memberTypes = link;
8912 lastLink->next = link;
8915 * Create a reference item.
8917 ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
8924 * Assign the reference to the link, it will be resolved
8925 * later during fixup of the union simple type.
8927 link->type = (xmlSchemaTypePtr) ref;
8931 } while (*cur != 0);
8935 * And now for the children...
8937 child = node->children;
8938 if (IS_SCHEMA(child, "annotation")) {
8940 * Add the annotation to the simple type ancestor.
8942 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
8943 xmlSchemaParseAnnotation(ctxt, child, 1));
8944 child = child->next;
8946 if (IS_SCHEMA(child, "simpleType")) {
8947 xmlSchemaTypePtr subtype, last = NULL;
8950 * Anchor the member types in the "subtypes" field of the
8953 while (IS_SCHEMA(child, "simpleType")) {
8954 subtype = (xmlSchemaTypePtr)
8955 xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8956 if (subtype != NULL) {
8958 type->subtypes = subtype;
8961 last->next = subtype;
8966 child = child->next;
8969 if (child != NULL) {
8970 xmlSchemaPContentErr(ctxt,
8971 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8972 NULL, node, child, NULL, "(annotation?, simpleType*)");
8974 if ((attr == NULL) && (type->subtypes == NULL)) {
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].
8980 xmlSchemaPCustomErr(ctxt,
8981 XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
8983 "Either the attribute 'memberTypes' or "
8984 "at least one <simpleType> child must be present", NULL);
8990 * xmlSchemaParseList:
8991 * @ctxt: a schema validation context
8992 * @schema: the schema being built
8993 * @node: a subtree containing XML Schema informations
8995 * parse a XML schema List definition
8996 * *WARNING* this interface is highly subject to change
8998 * Returns -1 in case of error, 0 if the declaration is improper and
8999 * 1 in case of success.
9001 static xmlSchemaTypePtr
9002 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
9005 xmlSchemaTypePtr type;
9006 xmlNodePtr child = NULL;
9009 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9011 /* Not a component, don't create it. */
9012 type = ctxt->ctxtType;
9014 * Mark the type as being of variety "list".
9016 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
9018 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
9019 * then the �simple ur-type definition�."
9021 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
9023 * Check for illegal attributes.
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);
9033 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9034 xmlSchemaPIllegalAttrErr(ctxt,
9035 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9040 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9043 * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
9044 * fields for holding the reference to the itemType.
9046 * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
9049 xmlSchemaPValAttrQName(ctxt, schema, NULL,
9050 node, "itemType", &(type->baseNs), &(type->base));
9052 * And now for the children...
9054 child = node->children;
9055 if (IS_SCHEMA(child, "annotation")) {
9056 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
9057 xmlSchemaParseAnnotation(ctxt, child, 1));
9058 child = child->next;
9060 if (IS_SCHEMA(child, "simpleType")) {
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.
9066 if (type->base != NULL) {
9067 xmlSchemaPCustomErr(ctxt,
9068 XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9070 "The attribute 'itemType' and the <simpleType> child "
9071 "are mutually exclusive", NULL);
9073 type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
9075 child = child->next;
9076 } else if (type->base == NULL) {
9077 xmlSchemaPCustomErr(ctxt,
9078 XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9080 "Either the attribute 'itemType' or the <simpleType> child "
9081 "must be present", NULL);
9083 if (child != NULL) {
9084 xmlSchemaPContentErr(ctxt,
9085 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9086 NULL, node, child, NULL, "(annotation?, simpleType?)");
9088 if ((type->base == NULL) &&
9089 (type->subtypes == NULL) &&
9090 (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
9091 xmlSchemaPCustomErr(ctxt,
9092 XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9094 "Either the attribute 'itemType' or the <simpleType> child "
9095 "must be present", NULL);
9101 * xmlSchemaParseSimpleType:
9102 * @ctxt: a schema validation context
9103 * @schema: the schema being built
9104 * @node: a subtree containing XML Schema informations
9106 * parse a XML schema Simple Type definition
9107 * *WARNING* this interface is highly subject to change
9109 * Returns -1 in case of error, 0 if the declaration is improper and
9110 * 1 in case of success.
9112 static xmlSchemaTypePtr
9113 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
9114 xmlNodePtr node, int topLevel)
9116 xmlSchemaTypePtr type, oldCtxtType;
9117 xmlNodePtr child = NULL;
9118 const xmlChar *attrValue = NULL;
9120 int hasRestriction = 0;
9122 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9126 attr = xmlSchemaGetPropNode(node, "name");
9128 xmlSchemaPMissingAttrErr(ctxt,
9129 XML_SCHEMAP_S4S_ATTR_MISSING,
9134 if (xmlSchemaPValAttrNode(ctxt,
9136 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
9139 * Skip built-in types.
9142 xmlSchemaTypePtr biType;
9144 if (ctxt->isRedefine) {
9146 * REDEFINE: Disallow redefinition of built-in-types.
9147 * TODO: It seems that the spec does not say anything
9150 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9152 "Redefinition of built-in simple types is not "
9156 biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
9164 * SPEC "The �actual value� of the targetNamespace [attribute]
9165 * of the <schema> ancestor element information item if present,
9166 * otherwise �absent�.
9168 if (topLevel == 0) {
9169 #ifdef ENABLE_NAMED_LOCALS
9173 * Parse as local simple type definition.
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);
9182 type = xmlSchemaAddType(ctxt, schema,
9183 XML_SCHEMA_TYPE_SIMPLE,
9184 NULL, ctxt->targetNamespace, node, 0);
9188 type->type = XML_SCHEMA_TYPE_SIMPLE;
9189 type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9191 * Check for illegal attributes.
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);
9200 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9201 xmlSchemaPIllegalAttrErr(ctxt,
9202 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9208 * Parse as global simple type definition.
9210 * Note that attrValue is the value of the attribute "name" here.
9212 type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
9213 attrValue, ctxt->targetNamespace, node, 1);
9216 type->type = XML_SCHEMA_TYPE_SIMPLE;
9217 type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9218 type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
9220 * Check for illegal attributes.
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);
9231 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9232 xmlSchemaPIllegalAttrErr(ctxt,
9233 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9238 * Attribute "final".
9240 attr = xmlSchemaGetPropNode(node, "final");
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;
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) {
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);
9263 type->targetNamespace = ctxt->targetNamespace;
9264 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9266 * And now for the children...
9268 oldCtxtType = ctxt->ctxtType;
9270 ctxt->ctxtType = type;
9272 child = node->children;
9273 if (IS_SCHEMA(child, "annotation")) {
9274 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9275 child = child->next;
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);
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;
9293 if (child != NULL) {
9294 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9295 NULL, node, child, NULL,
9296 "(annotation?, (restriction | list | union))");
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;"
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);
9311 ctxt->ctxtType = oldCtxtType;
9316 * xmlSchemaParseModelGroupDefRef:
9317 * @ctxt: the parser context
9318 * @schema: the schema being built
9321 * Parses a reference to a model group definition.
9323 * We will return a particle component with a qname-component or
9324 * NULL in case of an error.
9326 static xmlSchemaTreeItemPtr
9327 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
9328 xmlSchemaPtr schema,
9331 xmlSchemaParticlePtr item;
9332 xmlNodePtr child = NULL;
9334 const xmlChar *ref = NULL, *refNs = NULL;
9337 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9340 attr = xmlSchemaGetPropNode(node, "ref");
9342 xmlSchemaPMissingAttrErr(ctxt,
9343 XML_SCHEMAP_S4S_ATTR_MISSING,
9344 NULL, node, "ref", NULL);
9346 } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
9347 attr, &refNs, &ref) != 0) {
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)");
9355 * Check for illegal attributes.
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);
9367 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9368 xmlSchemaPIllegalAttrErr(ctxt,
9369 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9373 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9374 item = xmlSchemaAddParticle(ctxt, node, min, max);
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.
9381 item->children = (xmlSchemaTreeItemPtr)
9382 xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
9383 xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
9385 * And now for the children...
9387 child = node->children;
9388 /* TODO: Is annotation even allowed for a model group reference? */
9389 if (IS_SCHEMA(child, "annotation")) {
9391 * TODO: What to do exactly with the annotation?
9393 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9394 child = child->next;
9396 if (child != NULL) {
9397 xmlSchemaPContentErr(ctxt,
9398 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9399 NULL, node, child, NULL,
9403 * Corresponds to no component at all if minOccurs==maxOccurs==0.
9405 if ((min == 0) && (max == 0))
9408 return ((xmlSchemaTreeItemPtr) item);
9412 * xmlSchemaParseModelGroupDefinition:
9413 * @ctxt: a schema validation context
9414 * @schema: the schema being built
9415 * @node: a subtree containing XML Schema informations
9417 * Parses a XML schema model group definition.
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.
9423 * *WARNING* this interface is highly subject to change
9425 * Returns -1 in case of error, 0 if the declaration is improper and
9426 * 1 in case of success.
9428 static xmlSchemaModelGroupDefPtr
9429 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
9430 xmlSchemaPtr schema,
9433 xmlSchemaModelGroupDefPtr item;
9434 xmlNodePtr child = NULL;
9436 const xmlChar *name;
9438 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9441 attr = xmlSchemaGetPropNode(node, "name");
9443 xmlSchemaPMissingAttrErr(ctxt,
9444 XML_SCHEMAP_S4S_ATTR_MISSING,
9448 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
9449 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
9452 item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
9453 ctxt->targetNamespace, node);
9457 * Check for illegal attributes.
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);
9467 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9468 xmlSchemaPIllegalAttrErr(ctxt,
9469 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9473 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9475 * And now for the children...
9477 child = node->children;
9478 if (IS_SCHEMA(child, "annotation")) {
9479 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9480 child = child->next;
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;
9498 if (child != NULL) {
9499 xmlSchemaPContentErr(ctxt,
9500 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9501 NULL, node, child, NULL,
9502 "(annotation?, (all | choice | sequence)?)");
9508 * xmlSchemaCleanupDoc:
9509 * @ctxt: a schema validation context
9510 * @node: the root of the document.
9512 * removes unwanted nodes in a schemas document tree
9515 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
9517 xmlNodePtr delete, cur;
9519 if ((ctxt == NULL) || (root == NULL)) return;
9522 * Remove all the blank text nodes
9526 while (cur != NULL) {
9527 if (delete != NULL) {
9528 xmlUnlinkNode(delete);
9529 xmlFreeNode(delete);
9532 if (cur->type == XML_TEXT_NODE) {
9533 if (IS_BLANK_NODE(cur)) {
9534 if (xmlNodeGetSpacePreserve(cur) != 1) {
9538 } else if ((cur->type != XML_ELEMENT_NODE) &&
9539 (cur->type != XML_CDATA_SECTION_NODE)) {
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;
9556 if (cur->next != NULL) {
9569 if (cur->next != NULL) {
9573 } while (cur != NULL);
9575 if (delete != NULL) {
9576 xmlUnlinkNode(delete);
9577 xmlFreeNode(delete);
9584 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
9586 if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
9587 schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
9589 if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
9590 schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
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;
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;
9610 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
9611 xmlSchemaPtr schema,
9616 int res = 0, oldErrs = ctxt->nberrors;
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.
9623 res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9627 * Since the version is of type xs:token, we won't bother to
9631 attr = xmlSchemaGetPropNode(node, "version");
9633 res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
9634 xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
9638 attr = xmlSchemaGetPropNode(node, "targetNamespace");
9640 res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
9641 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
9644 ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
9648 attr = xmlSchemaGetPropNode(node, "elementFormDefault");
9650 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9651 res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9652 XML_SCHEMAS_QUALIF_ELEM);
9655 xmlSchemaPSimpleTypeErr(ctxt,
9656 XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
9657 NULL, (xmlNodePtr) attr, NULL,
9658 "(qualified | unqualified)", val, NULL, NULL, NULL);
9661 attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
9663 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9664 res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9665 XML_SCHEMAS_QUALIF_ATTR);
9668 xmlSchemaPSimpleTypeErr(ctxt,
9669 XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
9670 NULL, (xmlNodePtr) attr, NULL,
9671 "(qualified | unqualified)", val, NULL, NULL, NULL);
9674 attr = xmlSchemaGetPropNode(node, "finalDefault");
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,
9681 XML_SCHEMAS_FINAL_DEFAULT_LIST,
9682 XML_SCHEMAS_FINAL_DEFAULT_UNION);
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);
9692 attr = xmlSchemaGetPropNode(node, "blockDefault");
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);
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);
9710 if (oldErrs != ctxt->nberrors)
9718 * xmlSchemaParseSchemaTopLevel:
9719 * @ctxt: a schema validation context
9720 * @schema: the schemas
9721 * @nodes: the list of top level nodes
9723 * Returns the internal XML Schema structure built from the resource or
9724 * NULL in case of error
9727 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
9728 xmlSchemaPtr schema, xmlNodePtr nodes)
9731 xmlSchemaAnnotPtr annot;
9732 int res = 0, oldErrs, tmpOldErrs;
9734 if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
9737 oldErrs = ctxt->nberrors;
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;
9748 xmlSchemaFreeAnnot(annot);
9749 } else if (IS_SCHEMA(child, "import")) {
9750 tmpOldErrs = ctxt->nberrors;
9751 res = xmlSchemaParseImport(ctxt, schema, child);
9754 if (tmpOldErrs != ctxt->nberrors)
9756 } else if (IS_SCHEMA(child, "include")) {
9757 tmpOldErrs = ctxt->nberrors;
9758 res = xmlSchemaParseInclude(ctxt, schema, child);
9761 if (tmpOldErrs != ctxt->nberrors)
9763 } else if (IS_SCHEMA(child, "redefine")) {
9764 tmpOldErrs = ctxt->nberrors;
9765 res = xmlSchemaParseRedefine(ctxt, schema, child);
9768 if (tmpOldErrs != ctxt->nberrors)
9771 child = child->next;
9774 * URGENT TODO: Change the functions to return int results.
9775 * We need especially to catch internal errors.
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;
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;
9808 while (IS_SCHEMA(child, "annotation")) {
9810 * TODO: We should add all annotations.
9812 annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9813 if (schema->annot == NULL)
9814 schema->annot = annot;
9816 xmlSchemaFreeAnnot(annot);
9817 child = child->next;
9821 ctxt->ctxtType = NULL;
9822 if (oldErrs != ctxt->nberrors)
9829 static xmlSchemaSchemaRelationPtr
9830 xmlSchemaSchemaRelationCreate(void)
9832 xmlSchemaSchemaRelationPtr ret;
9834 ret = (xmlSchemaSchemaRelationPtr)
9835 xmlMalloc(sizeof(xmlSchemaSchemaRelation));
9837 xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
9840 memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
9846 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
9853 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
9855 xmlSchemaRedefPtr prev;
9857 while (redef != NULL) {
9859 redef = redef->next;
9865 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
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.
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);
9887 static xmlSchemaConstructionCtxtPtr
9888 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
9890 xmlSchemaConstructionCtxtPtr ret;
9892 ret = (xmlSchemaConstructionCtxtPtr)
9893 xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
9895 xmlSchemaPErrMemory(NULL,
9896 "allocating schema construction context", NULL);
9899 memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
9901 ret->buckets = xmlSchemaItemListCreate();
9902 if (ret->buckets == NULL) {
9903 xmlSchemaPErrMemory(NULL,
9904 "allocating list of schema buckets", NULL);
9908 ret->pending = xmlSchemaItemListCreate();
9909 if (ret->pending == NULL) {
9910 xmlSchemaPErrMemory(NULL,
9911 "allocating list of pending global components", NULL);
9912 xmlSchemaConstructionCtxtFree(ret);
9916 xmlDictReference(dict);
9920 static xmlSchemaParserCtxtPtr
9921 xmlSchemaParserCtxtCreate(void)
9923 xmlSchemaParserCtxtPtr ret;
9925 ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
9927 xmlSchemaPErrMemory(NULL, "allocating schema parser context",
9931 memset(ret, 0, sizeof(xmlSchemaParserCtxt));
9932 ret->type = XML_SCHEMA_CTXT_PARSER;
9933 ret->attrProhibs = xmlSchemaItemListCreate();
9934 if (ret->attrProhibs == NULL) {
9942 * xmlSchemaNewParserCtxtUseDict:
9943 * @URL: the location of the schema
9944 * @dict: the dictionary to be used
9946 * Create an XML Schemas parse context for that file/resource expected
9947 * to contain an XML Schemas file.
9949 * Returns the parser context or NULL in case of error
9951 static xmlSchemaParserCtxtPtr
9952 xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
9954 xmlSchemaParserCtxtPtr ret;
9956 ret = xmlSchemaParserCtxtCreate();
9960 xmlDictReference(dict);
9962 ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
9967 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
9969 if (vctxt->pctxt == NULL) {
9970 if (vctxt->schema != NULL)
9972 xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
9974 vctxt->pctxt = xmlSchemaNewParserCtxt("*");
9975 if (vctxt->pctxt == NULL) {
9976 VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
9977 "failed to create a temp. parser context");
9980 /* TODO: Pass user data. */
9981 xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
9982 vctxt->warning, vctxt->errCtxt);
9983 xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
9990 * xmlSchemaGetSchemaBucket:
9991 * @pctxt: the schema parser context
9992 * @schemaLocation: the URI of the schema document
9994 * Returns a schema bucket if it was already parsed.
9996 * Returns a schema bucket if it was already parsed from
9997 * @schemaLocation, NULL otherwise.
9999 static xmlSchemaBucketPtr
10000 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10001 const xmlChar *schemaLocation)
10003 xmlSchemaBucketPtr cur;
10004 xmlSchemaItemListPtr list;
10006 list = pctxt->constructor->buckets;
10007 if (list->nbItems == 0)
10011 for (i = 0; i < list->nbItems; i++) {
10012 cur = (xmlSchemaBucketPtr) list->items[i];
10013 /* Pointer comparison! */
10014 if (cur->schemaLocation == schemaLocation)
10021 static xmlSchemaBucketPtr
10022 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10023 const xmlChar *schemaLocation,
10024 const xmlChar *targetNamespace)
10026 xmlSchemaBucketPtr cur;
10027 xmlSchemaItemListPtr list;
10029 list = pctxt->constructor->buckets;
10030 if (list->nbItems == 0)
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))
10047 #define IS_BAD_SCHEMA_DOC(b) \
10048 (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
10050 static xmlSchemaBucketPtr
10051 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
10052 const xmlChar *targetNamespace,
10055 xmlSchemaBucketPtr cur;
10056 xmlSchemaItemListPtr list;
10058 list = pctxt->constructor->buckets;
10059 if (list->nbItems == 0)
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))))
10076 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
10077 xmlSchemaPtr schema,
10078 xmlSchemaBucketPtr bucket)
10084 xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
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.
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;
10099 * Keep the current target namespace on the parser *not* on the
10102 pctxt->targetNamespace = bucket->targetNamespace;
10103 WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
10105 if ((bucket->targetNamespace != NULL) &&
10106 xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
10108 * We are parsing the schema for schemas!
10112 /* Mark it as parsed, even if parsing fails. */
10114 /* Compile the schema doc. */
10115 node = xmlDocGetRootElement(bucket->doc);
10116 ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
10119 /* An empty schema; just get out. */
10120 if (node->children == NULL)
10122 oldErrs = pctxt->nberrors;
10123 ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
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
10131 if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
10137 WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
10138 /* Restore schema values. */
10139 schema->doc = oldDoc;
10140 schema->flags = oldFlags;
10145 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
10146 xmlSchemaPtr schema,
10147 xmlSchemaBucketPtr bucket)
10149 xmlSchemaParserCtxtPtr newpctxt;
10152 if (bucket == NULL)
10154 if (bucket->parsed) {
10155 PERROR_INT("xmlSchemaParseNewDoc",
10156 "reparsing a schema doc");
10159 if (bucket->doc == NULL) {
10160 PERROR_INT("xmlSchemaParseNewDoc",
10161 "parsing a schema doc, but there's no doc");
10164 if (pctxt->constructor == NULL) {
10165 PERROR_INT("xmlSchemaParseNewDoc",
10169 /* Create and init the temporary parser context. */
10170 newpctxt = xmlSchemaNewParserCtxtUseDict(
10171 (const char *) bucket->schemaLocation, pctxt->dict);
10172 if (newpctxt == NULL)
10174 newpctxt->constructor = pctxt->constructor;
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
10180 newpctxt->schema = schema;
10181 xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
10183 xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
10185 newpctxt->counter = pctxt->counter;
10188 res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
10190 /* Channel back errors and cleanup the temporary parser context. */
10193 pctxt->nberrors += newpctxt->nberrors;
10194 pctxt->counter = newpctxt->counter;
10195 newpctxt->constructor = NULL;
10196 /* Free the parser context. */
10197 xmlSchemaFreeParserCtxt(newpctxt);
10202 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
10203 xmlSchemaSchemaRelationPtr rel)
10205 xmlSchemaSchemaRelationPtr cur = bucket->relations;
10208 bucket->relations = rel;
10211 while (cur->next != NULL)
10217 static const xmlChar *
10218 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
10219 xmlNodePtr ctxtNode)
10222 * Build an absolue location URI.
10224 if (location != NULL) {
10225 if (ctxtNode == NULL)
10228 xmlChar *base, *URI;
10229 const xmlChar *ret = NULL;
10231 base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
10232 if (base == NULL) {
10233 URI = xmlBuildURI(location, ctxtNode->doc->URL);
10235 URI = xmlBuildURI(location, base);
10239 ret = xmlDictLookup(dict, URI, -1);
10251 * xmlSchemaAddSchemaDoc:
10252 * @pctxt: a schema validation context
10253 * @schema: the schema being built
10254 * @node: a subtree containing XML Schema informations
10256 * Parse an included (and to-be-redefined) XML schema document.
10258 * Returns 0 on success, a positive error code on errors and
10259 * -1 in case of an internal or API error.
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)
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;
10280 if (bucket != NULL)
10284 case XML_SCHEMA_SCHEMA_IMPORT:
10285 case XML_SCHEMA_SCHEMA_MAIN:
10286 err = XML_SCHEMAP_SRC_IMPORT;
10288 case XML_SCHEMA_SCHEMA_INCLUDE:
10289 err = XML_SCHEMAP_SRC_INCLUDE;
10291 case XML_SCHEMA_SCHEMA_REDEFINE:
10292 err = XML_SCHEMAP_SRC_REDEFINE;
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.
10301 if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
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. */
10311 xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10312 invokingNode, NULL,
10313 "The schema must not import/include/redefine itself",
10319 * Create a relation for the graph of schemas.
10321 relation = xmlSchemaSchemaRelationCreate();
10322 if (relation == NULL)
10324 xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
10326 relation->type = type;
10329 * Save the namespace import information.
10331 if (WXS_IS_BUCKET_IMPMAIN(type)) {
10332 relation->importNamespace = importNamespace;
10333 if (schemaLocation == NULL) {
10335 * No location; this is just an import of the namespace.
10336 * Note that we don't assign a bucket to the relation
10341 targetNamespace = importNamespace;
10344 /* Did we already fetch the doc? */
10346 if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
10348 * We included/redefined and then try to import a schema,
10349 * but the new location provided for import was different.
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);
10362 } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
10364 * We imported and then try to include/redefine a schema,
10365 * but the new location provided for the include/redefine
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);
10382 if (WXS_IS_BUCKET_IMPMAIN(type)) {
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.
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.
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.
10401 * NOTE: (3) and (5) are not supported.
10404 relation->bucket = bkt;
10407 bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
10408 importNamespace, 1);
10411 relation->bucket = bkt;
10412 if (bkt->schemaLocation == NULL) {
10413 /* First given location of the schema; load the doc. */
10414 bkt->schemaLocation = schemaLocation;
10416 if (!xmlStrEqual(schemaLocation,
10417 bkt->schemaLocation)) {
10419 * Additional location given; just skip it.
10420 * URGENT TODO: We should report a warning here.
10421 * res = XML_SCHEMAP_SRC_IMPORT;
10423 if (schemaLocation == NULL)
10424 schemaLocation = BAD_CAST "in_memory_buffer";
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);
10438 * No bucket + first location: load the doc and create a
10442 /* <include> and <redefine> */
10445 if ((bkt->origTargetNamespace == NULL) &&
10446 (bkt->targetNamespace != sourceTargetNamespace)) {
10447 xmlSchemaBucketPtr chamel;
10450 * Chameleon include/redefine: skip loading only if it was
10451 * aleady build for the targetNamespace of the including
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
10466 chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
10467 schemaLocation, sourceTargetNamespace);
10468 if (chamel != NULL) {
10469 /* A fitting chameleon was already parsed; NOP. */
10470 relation->bucket = chamel;
10474 * We need to parse the chameleon again for a different
10476 * CHAMELEON TODO: Optimize this by only parsing the
10477 * chameleon once, and then copying the components to
10478 * the new targetNamespace.
10482 relation->bucket = bkt;
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");
10496 * Load the document.
10498 if (schemaDoc != NULL) {
10500 /* Don' free this one, since it was provided by the caller. */
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);
10507 schemaLocation = BAD_CAST "in_memory_buffer";
10508 } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
10509 xmlParserCtxtPtr parserCtxt;
10511 parserCtxt = xmlNewParserCtxt();
10512 if (parserCtxt == NULL) {
10513 xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
10514 "allocating a parser context", NULL);
10517 if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
10519 * TODO: Do we have to burden the schema parser dict with all
10520 * the content of the schema doc?
10522 xmlDictFree(parserCtxt->dict);
10523 parserCtxt->dict = pctxt->dict;
10524 xmlDictReference(parserCtxt->dict);
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";
10536 doc->URL = xmlStrdup(schemaLocation);
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.
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.
10553 lerr = xmlGetLastError();
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.
10560 if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
10562 * We assume a parser error here.
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);
10573 xmlFreeParserCtxt(parserCtxt);
10574 if ((doc == NULL) && located)
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",
10585 * Preprocess the document.
10588 xmlNodePtr docElem = NULL;
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);
10600 * Remove all the blank text nodes.
10602 xmlSchemaCleanupDoc(pctxt, docElem);
10604 * Check the schema's top level element.
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);
10614 * Note that we don't apply a type check for the
10615 * targetNamespace value here.
10617 targetNamespace = xmlSchemaGetProp(pctxt, docElem,
10618 "targetNamespace");
10621 /* after_doc_loading: */
10622 if ((bkt == NULL) && located) {
10623 /* Only create a bucket if the schema was located. */
10624 bkt = xmlSchemaBucketCreate(pctxt, type,
10630 bkt->schemaLocation = schemaLocation;
10631 bkt->located = located;
10634 bkt->targetNamespace = targetNamespace;
10635 bkt->origTargetNamespace = targetNamespace;
10637 bkt->preserveDoc = 1;
10639 if (WXS_IS_BUCKET_IMPMAIN(type))
10642 * Add it to the graph of schemas.
10644 if (relation != NULL)
10645 relation->bucket = bkt;
10650 * Return the bucket explicitely; this is needed for the
10653 if (bucket != NULL)
10658 if ((doc != NULL) && (! preserveDoc)) {
10663 return(pctxt->err);
10666 if ((doc != NULL) && (! preserveDoc)) {
10675 * xmlSchemaParseImport:
10676 * @ctxt: a schema validation context
10677 * @schema: the schema being built
10678 * @node: a subtree containing XML Schema informations
10680 * parse a XML schema Import definition
10681 * *WARNING* this interface is highly subject to change
10683 * Returns 0 in case of success, a positive error code if
10684 * not valid and -1 in case of an internal error.
10687 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
10691 const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
10692 const xmlChar *thisTargetNamespace;
10695 xmlSchemaBucketPtr bucket = NULL;
10697 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10701 * Check for illegal attributes.
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);
10712 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10713 xmlSchemaPIllegalAttrErr(pctxt,
10714 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10719 * Extract and validate attributes.
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,
10727 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10728 NULL, namespaceName, NULL, NULL, NULL);
10729 return (pctxt->err);
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,
10738 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10739 NULL, namespaceName, NULL, NULL, NULL);
10740 return (pctxt->err);
10743 * And now for the children...
10745 child = node->children;
10746 if (IS_SCHEMA(child, "annotation")) {
10748 * the annotation here is simply discarded ...
10751 child = child->next;
10753 if (child != NULL) {
10754 xmlSchemaPContentErr(pctxt,
10755 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
10756 NULL, node, child, NULL,
10760 * Apply additional constraints.
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).
10767 thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
10768 if (namespaceName != NULL) {
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].
10774 if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
10775 xmlSchemaPCustomErr(pctxt,
10776 XML_SCHEMAP_SRC_IMPORT_1_1,
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);
10785 * 1.2 If the namespace [attribute] is not present, then the enclosing
10786 * <schema> must have a targetNamespace [attribute].
10788 if (thisTargetNamespace == NULL) {
10789 xmlSchemaPCustomErr(pctxt,
10790 XML_SCHEMAP_SRC_IMPORT_1_2,
10792 "The attribute 'namespace' must be existent if "
10793 "the importing schema has no target namespace",
10795 return (pctxt->err);
10799 * Locate and acquire the schema document.
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);
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.
10818 if ((bucket == NULL) && (schemaLocation != NULL)) {
10819 xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10820 XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
10822 "Failed to locate a schema at location '%s'. "
10823 "Skipping the import", schemaLocation, NULL, NULL);
10826 if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
10827 ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
10834 xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
10835 xmlSchemaPtr schema,
10837 xmlChar **schemaLocation,
10842 if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
10843 (schemaLocation == NULL))
10846 *schemaLocation = NULL;
10848 * Check for illegal attributes.
10849 * Applies for both <include> and <redefine>.
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);
10859 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10860 xmlSchemaPIllegalAttrErr(pctxt,
10861 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10865 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
10867 * Preliminary step, extract the URI-Reference and make an URI
10871 * Attribute "schemaLocation" is mandatory.
10873 attr = xmlSchemaGetPropNode(node, "schemaLocation");
10874 if (attr != NULL) {
10875 xmlChar *base = NULL;
10876 xmlChar *uri = NULL;
10878 if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
10879 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10880 (const xmlChar **) schemaLocation) != 0)
10882 base = xmlNodeGetBase(node->doc, node);
10883 if (base == NULL) {
10884 uri = xmlBuildURI(*schemaLocation, node->doc->URL);
10886 uri = xmlBuildURI(*schemaLocation, base);
10890 PERROR_INT("xmlSchemaParseIncludeOrRedefine",
10891 "could not build an URI from the schemaLocation")
10894 (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
10897 xmlSchemaPMissingAttrErr(pctxt,
10898 XML_SCHEMAP_S4S_ATTR_MISSING,
10899 NULL, node, "schemaLocation", NULL);
10903 * Report self-inclusion and self-redefinition.
10905 if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
10906 if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
10907 xmlSchemaPCustomErr(pctxt,
10908 XML_SCHEMAP_SRC_REDEFINE,
10910 "The schema document '%s' cannot redefine itself.",
10913 xmlSchemaPCustomErr(pctxt,
10914 XML_SCHEMAP_SRC_INCLUDE,
10916 "The schema document '%s' cannot include itself.",
10924 return(pctxt->err);
10930 xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
10931 xmlSchemaPtr schema,
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;
10941 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10945 * Parse attributes. Note that the returned schemaLocation will
10946 * be already converted to an absolute URI.
10948 res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
10949 node, (xmlChar **) (&schemaLocation), type);
10953 * Load and add the schema document.
10955 res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
10956 NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
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.
10964 if ((bucket == NULL) || (bucket->doc == NULL)) {
10965 if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
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
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?"
10977 res = XML_SCHEMAP_SRC_INCLUDE;
10978 xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10980 "Failed to load the document '%s' for inclusion",
10981 schemaLocation, NULL);
10984 * NOTE: This was changed to raise an error even if no redefinitions
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
10994 res = XML_SCHEMAP_SRC_REDEFINE;
10995 xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10997 "Failed to load the document '%s' for redefinition",
10998 schemaLocation, NULL);
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.
11006 if (bucket->origTargetNamespace != NULL) {
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])."
11013 if (pctxt->targetNamespace == NULL) {
11014 xmlSchemaCustomErr(ACTXT_CAST pctxt,
11015 XML_SCHEMAP_SRC_INCLUDE,
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);
11022 } else if (!xmlStrEqual(bucket->origTargetNamespace,
11023 pctxt->targetNamespace)) {
11024 /* TODO: Change error function. */
11025 xmlSchemaPCustomErrExt(pctxt,
11026 XML_SCHEMAP_SRC_INCLUDE,
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);
11035 } else if (pctxt->targetNamespace != NULL) {
11037 * Chameleons: the original target namespace will
11038 * differ from the resulting namespace.
11041 if (bucket->parsed &&
11042 bucket->origTargetNamespace != NULL) {
11043 xmlSchemaCustomErr(ACTXT_CAST pctxt,
11044 XML_SCHEMAP_SRC_INCLUDE,
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);
11052 bucket->targetNamespace = pctxt->targetNamespace;
11056 * Parse the schema.
11058 if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
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;
11066 xmlSchemaParseNewDoc(pctxt, schema, bucket);
11067 /* Restore chameleon flag. */
11068 if (isChameleon && (!wasChameleon))
11069 schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11072 * And now for the children...
11074 child = node->children;
11075 if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11077 * Parse (simpleType | complexType | group | attributeGroup))*
11079 pctxt->redefined = bucket;
11081 * How to proceed if the redefined schema was not located?
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")) {
11091 * TODO: discard or not?
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,
11102 } else if (IS_SCHEMA(child, "attributeGroup")) {
11103 /* hasRedefinitions = 1; */
11104 xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
11107 child = child->next;
11109 pctxt->redefined = NULL;
11110 pctxt->isRedefine = 0;
11112 if (IS_SCHEMA(child, "annotation")) {
11114 * TODO: discard or not?
11116 child = child->next;
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))*");
11126 xmlSchemaPContentErr(pctxt, res,
11127 NULL, node, child, NULL,
11134 return(pctxt->err);
11138 xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11142 #ifndef ENABLE_REDEFINE
11146 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11147 XML_SCHEMA_SCHEMA_REDEFINE);
11154 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11159 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11160 XML_SCHEMA_SCHEMA_INCLUDE);
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
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)
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.
11186 * *WARNING* this interface is highly subject to change
11188 * Returns -1 in case of error, 0 if the declaration is improper and
11189 * 1 in case of success.
11191 static xmlSchemaTreeItemPtr
11192 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11193 xmlNodePtr node, xmlSchemaTypeType type,
11196 xmlSchemaModelGroupPtr item;
11197 xmlSchemaParticlePtr particle = NULL;
11198 xmlNodePtr child = NULL;
11200 int min = 1, max = 1, isElemRef, hasRefs = 0;
11202 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11205 * Create a model group with the given compositor.
11207 item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
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");
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)");
11221 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
11223 * Create a particle
11225 particle = xmlSchemaAddParticle(ctxt, node, min, max);
11226 if (particle == NULL)
11228 particle->children = (xmlSchemaTreeItemPtr) item;
11230 * Check for illegal attributes.
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);
11241 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11242 xmlSchemaPIllegalAttrErr(ctxt,
11243 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11249 * Check for illegal attributes.
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);
11258 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11259 xmlSchemaPIllegalAttrErr(ctxt,
11260 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11267 * Extract and validate attributes.
11269 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11271 * And now for the children...
11273 child = node->children;
11274 if (IS_SCHEMA(child, "annotation")) {
11275 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
11276 child = child->next;
11278 if (type == XML_SCHEMA_TYPE_ALL) {
11279 xmlSchemaParticlePtr part, last = NULL;
11281 while (IS_SCHEMA(child, "element")) {
11282 part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
11283 schema, child, &isElemRef, 0);
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.
11289 if (part != NULL) {
11292 if (part->minOccurs > 1) {
11293 xmlSchemaPCustomErr(ctxt,
11294 XML_SCHEMAP_COS_ALL_LIMITED,
11296 "Invalid value for minOccurs (must be 0 or 1)",
11299 part->minOccurs = 1;
11301 if (part->maxOccurs > 1) {
11302 xmlSchemaPCustomErr(ctxt,
11303 XML_SCHEMAP_COS_ALL_LIMITED,
11305 "Invalid value for maxOccurs (must be 0 or 1)",
11308 part->maxOccurs = 1;
11311 item->children = (xmlSchemaTreeItemPtr) part;
11313 last->next = (xmlSchemaTreeItemPtr) part;
11316 child = child->next;
11318 if (child != NULL) {
11319 xmlSchemaPContentErr(ctxt,
11320 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11321 NULL, node, child, NULL,
11322 "(annotation?, (annotation?, element*)");
11325 /* choice + sequence */
11326 xmlSchemaTreeItemPtr part = NULL, last = NULL;
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"))) {
11334 if (IS_SCHEMA(child, "element")) {
11335 part = (xmlSchemaTreeItemPtr)
11336 xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
11337 if (part && isElemRef)
11339 } else if (IS_SCHEMA(child, "group")) {
11341 xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11345 * Handle redefinitions.
11347 if (ctxt->isRedefine && ctxt->redef &&
11348 (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
11349 part && part->children)
11351 if ((xmlSchemaGetQNameRefName(part->children) ==
11352 ctxt->redef->refName) &&
11353 (xmlSchemaGetQNameRefTargetNs(part->children) ==
11354 ctxt->redef->refTargetNs))
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."
11365 if (ctxt->redefCounter != 0) {
11366 xmlChar *str = NULL;
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),
11379 } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
11380 ((WXS_PARTICLE(part))->maxOccurs != 1))
11382 xmlChar *str = NULL;
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�).
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),
11402 ctxt->redef->reference = WXS_BASIC_CAST part;
11403 ctxt->redefCounter++;
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);
11416 if (part != NULL) {
11418 item->children = part;
11423 child = child->next;
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)*)");
11432 if ((max == 0) && (min == 0))
11436 * We need to resolve references.
11438 WXS_ADD_PENDING(ctxt, item);
11441 return ((xmlSchemaTreeItemPtr) particle);
11443 return ((xmlSchemaTreeItemPtr) item);
11447 * xmlSchemaParseRestriction:
11448 * @ctxt: a schema validation context
11449 * @schema: the schema being built
11450 * @node: a subtree containing XML Schema informations
11452 * parse a XML schema Restriction definition
11453 * *WARNING* this interface is highly subject to change
11455 * Returns the type definition or NULL in case of error
11457 static xmlSchemaTypePtr
11458 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11459 xmlNodePtr node, xmlSchemaTypeType parentType)
11461 xmlSchemaTypePtr type;
11462 xmlNodePtr child = NULL;
11465 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11467 /* Not a component, don't create it. */
11468 type = ctxt->ctxtType;
11469 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
11472 * Check for illegal attributes.
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);
11482 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11483 xmlSchemaPIllegalAttrErr(ctxt,
11484 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11489 * Extract and validate attributes.
11491 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11496 * Extract the base type. The "base" attribute is mandatory if inside
11497 * a complex type or if redefining.
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]"
11504 if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
11505 &(type->baseNs), &(type->base)) == 0)
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))
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)))
11521 xmlChar *str1 = NULL, *str2 = NULL;
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;"
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. */
11540 type->baseNs = NULL;
11545 * And now for the children...
11547 child = node->children;
11548 if (IS_SCHEMA(child, "annotation")) {
11550 * Add the annotation to the simple type ancestor.
11552 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11553 xmlSchemaParseAnnotation(ctxt, child, 1));
11554 child = child->next;
11556 if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
11558 * Corresponds to <simpleType><restriction><simpleType>.
11560 if (IS_SCHEMA(child, "simpleType")) {
11561 if (type->base != NULL) {
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.
11567 xmlSchemaPContentErr(ctxt,
11568 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11570 "The attribute 'base' and the <simpleType> child are "
11571 "mutually exclusive", NULL);
11573 type->baseType = (xmlSchemaTypePtr)
11574 xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11576 child = child->next;
11577 } else if (type->base == NULL) {
11578 xmlSchemaPContentErr(ctxt,
11579 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11581 "Either the attribute 'base' or a <simpleType> child "
11582 "must be present", NULL);
11584 } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11586 * Corresponds to <complexType><complexContent><restriction>...
11589 * Model groups <all>, <choice> and <sequence>.
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;
11607 * Model group reference <group>.
11609 } else if (IS_SCHEMA(child, "group")) {
11610 type->subtypes = (xmlSchemaTypePtr)
11611 xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11613 * Note that the reference will be resolved in
11614 * xmlSchemaResolveTypeReferences();
11616 child = child->next;
11618 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11620 * Corresponds to <complexType><simpleContent><restriction>...
11622 * "1.1 the simple type definition corresponding to the <simpleType>
11623 * among the [children] of <restriction> if there is one;"
11625 if (IS_SCHEMA(child, "simpleType")) {
11627 * We will store the to-be-restricted simple type in
11628 * type->contentTypeDef *temporarily*.
11630 type->contentTypeDef = (xmlSchemaTypePtr)
11631 xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11632 if ( type->contentTypeDef == NULL)
11634 child = child->next;
11638 if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
11639 (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
11640 xmlSchemaFacetPtr facet, lastfacet = NULL;
11642 * Corresponds to <complexType><simpleContent><restriction>...
11643 * <simpleType><restriction>...
11647 * Add the facets to the simple type ancestor.
11650 * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
11651 * Simple Type Definition Schema Representation Constraint:
11652 * *Single Facet Value*
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;
11671 lastfacet->next = facet;
11673 lastfacet->next = NULL;
11675 child = child->next;
11678 * Create links for derivation and validation.
11680 if (type->facets != NULL) {
11681 xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
11683 facet = type->facets;
11685 facetLink = (xmlSchemaFacetLinkPtr)
11686 xmlMalloc(sizeof(xmlSchemaFacetLink));
11687 if (facetLink == NULL) {
11688 xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
11689 xmlFree(facetLink);
11692 facetLink->facet = facet;
11693 facetLink->next = NULL;
11694 if (lastFacetLink == NULL)
11695 type->facetSet = facetLink;
11697 lastFacetLink->next = facetLink;
11698 lastFacetLink = facetLink;
11699 facet = facet->next;
11700 } while (facet != NULL);
11703 if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
11705 * Attribute uses/declarations.
11707 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11708 (xmlSchemaItemListPtr *) &(type->attrUses),
11709 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
11712 * Attribute wildcard.
11714 if (IS_SCHEMA(child, "anyAttribute")) {
11715 type->attributeWildcard =
11716 xmlSchemaParseAnyAttribute(ctxt, schema, child);
11717 child = child->next;
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?))");
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 | "
11750 * xmlSchemaParseExtension:
11751 * @ctxt: a schema validation context
11752 * @schema: the schema being built
11753 * @node: a subtree containing XML Schema informations
11755 * Parses an <extension>, which is found inside a
11756 * <simpleContent> or <complexContent>.
11757 * *WARNING* this interface is highly subject to change.
11759 * TODO: Returns the type definition or NULL in case of error
11761 static xmlSchemaTypePtr
11762 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11763 xmlNodePtr node, xmlSchemaTypeType parentType)
11765 xmlSchemaTypePtr type;
11766 xmlNodePtr child = NULL;
11769 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11771 /* Not a component, don't create it. */
11772 type = ctxt->ctxtType;
11773 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
11776 * Check for illegal attributes.
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);
11786 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11787 xmlSchemaPIllegalAttrErr(ctxt,
11788 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11793 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11796 * Attribute "base" - mandatory.
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);
11806 * And now for the children...
11808 child = node->children;
11809 if (IS_SCHEMA(child, "annotation")) {
11811 * Add the annotation to the type ancestor.
11813 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11814 xmlSchemaParseAnnotation(ctxt, child, 1));
11815 child = child->next;
11817 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11819 * Corresponds to <complexType><complexContent><extension>... and:
11821 * Model groups <all>, <choice>, <sequence> and <group>.
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);
11842 * Note that the reference will be resolved in
11843 * xmlSchemaResolveTypeReferences();
11845 child = child->next;
11848 if (child != NULL) {
11850 * Attribute uses/declarations.
11852 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11853 (xmlSchemaItemListPtr *) &(type->attrUses),
11854 XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
11857 * Attribute wildcard.
11859 if (IS_SCHEMA(child, "anyAttribute")) {
11860 ctxt->ctxtType->attributeWildcard =
11861 xmlSchemaParseAnyAttribute(ctxt, schema, child);
11862 child = child->next;
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?)))");
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?))");
11886 * xmlSchemaParseSimpleContent:
11887 * @ctxt: a schema validation context
11888 * @schema: the schema being built
11889 * @node: a subtree containing XML Schema informations
11891 * parse a XML schema SimpleContent definition
11892 * *WARNING* this interface is highly subject to change
11894 * Returns the type definition or NULL in case of error
11897 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
11898 xmlSchemaPtr schema, xmlNodePtr node,
11899 int *hasRestrictionOrExtension)
11901 xmlSchemaTypePtr type;
11902 xmlNodePtr child = NULL;
11905 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11906 (hasRestrictionOrExtension == NULL))
11908 *hasRestrictionOrExtension = 0;
11909 /* Not a component, don't create it. */
11910 type = ctxt->ctxtType;
11911 type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
11913 * Check for illegal attributes.
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);
11922 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11923 xmlSchemaPIllegalAttrErr(ctxt,
11924 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11929 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11932 * And now for the children...
11934 child = node->children;
11935 if (IS_SCHEMA(child, "annotation")) {
11937 * Add the annotation to the complex type ancestor.
11939 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11940 xmlSchemaParseAnnotation(ctxt, child, 1));
11941 child = child->next;
11943 if (child == NULL) {
11944 xmlSchemaPContentErr(ctxt,
11945 XML_SCHEMAP_S4S_ELEM_MISSING,
11946 NULL, node, NULL, NULL,
11947 "(annotation?, (restriction | extension))");
11949 if (child == NULL) {
11950 xmlSchemaPContentErr(ctxt,
11951 XML_SCHEMAP_S4S_ELEM_MISSING,
11952 NULL, node, NULL, NULL,
11953 "(annotation?, (restriction | extension))");
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;
11966 if (child != NULL) {
11967 xmlSchemaPContentErr(ctxt,
11968 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11969 NULL, node, child, NULL,
11970 "(annotation?, (restriction | extension))");
11976 * xmlSchemaParseComplexContent:
11977 * @ctxt: a schema validation context
11978 * @schema: the schema being built
11979 * @node: a subtree containing XML Schema informations
11981 * parse a XML schema ComplexContent definition
11982 * *WARNING* this interface is highly subject to change
11984 * Returns the type definition or NULL in case of error
11987 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
11988 xmlSchemaPtr schema, xmlNodePtr node,
11989 int *hasRestrictionOrExtension)
11991 xmlSchemaTypePtr type;
11992 xmlNodePtr child = NULL;
11995 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11996 (hasRestrictionOrExtension == NULL))
11998 *hasRestrictionOrExtension = 0;
11999 /* Not a component, don't create it. */
12000 type = ctxt->ctxtType;
12002 * Check for illegal attributes.
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")))
12010 xmlSchemaPIllegalAttrErr(ctxt,
12011 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12013 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12014 xmlSchemaPIllegalAttrErr(ctxt,
12015 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12020 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12023 * Set the 'mixed' on the complex type ancestor.
12025 if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) {
12026 if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
12027 type->flags |= XML_SCHEMAS_TYPE_MIXED;
12029 child = node->children;
12030 if (IS_SCHEMA(child, "annotation")) {
12032 * Add the annotation to the complex type ancestor.
12034 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
12035 xmlSchemaParseAnnotation(ctxt, child, 1));
12036 child = child->next;
12038 if (child == NULL) {
12039 xmlSchemaPContentErr(ctxt,
12040 XML_SCHEMAP_S4S_ELEM_MISSING,
12042 NULL, "(annotation?, (restriction | extension))");
12044 if (child == NULL) {
12045 xmlSchemaPContentErr(ctxt,
12046 XML_SCHEMAP_S4S_ELEM_MISSING,
12048 NULL, "(annotation?, (restriction | extension))");
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;
12061 if (child != NULL) {
12062 xmlSchemaPContentErr(ctxt,
12063 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12065 NULL, "(annotation?, (restriction | extension))");
12071 * xmlSchemaParseComplexType:
12072 * @ctxt: a schema validation context
12073 * @schema: the schema being built
12074 * @node: a subtree containing XML Schema informations
12076 * parse a XML schema Complex Type definition
12077 * *WARNING* this interface is highly subject to change
12079 * Returns the type definition or NULL in case of error
12081 static xmlSchemaTypePtr
12082 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
12083 xmlNodePtr node, int topLevel)
12085 xmlSchemaTypePtr type, ctxtType;
12086 xmlNodePtr child = NULL;
12087 const xmlChar *name = NULL;
12089 const xmlChar *attrValue;
12090 #ifdef ENABLE_NAMED_LOCALS
12093 int final = 0, block = 0, hasRestrictionOrExtension = 0;
12096 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
12099 ctxtType = ctxt->ctxtType;
12102 attr = xmlSchemaGetPropNode(node, "name");
12103 if (attr == NULL) {
12104 xmlSchemaPMissingAttrErr(ctxt,
12105 XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
12107 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
12108 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
12113 if (topLevel == 0) {
12115 * Parse as local complex type definition.
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);
12124 type = xmlSchemaAddType(ctxt, schema,
12125 XML_SCHEMA_TYPE_COMPLEX,
12126 NULL, ctxt->targetNamespace, node, 0);
12132 type->type = XML_SCHEMA_TYPE_COMPLEX;
12134 * TODO: We need the target namespace.
12138 * Parse as global complex type definition.
12140 type = xmlSchemaAddType(ctxt, schema,
12141 XML_SCHEMA_TYPE_COMPLEX,
12142 name, ctxt->targetNamespace, node, 1);
12146 type->type = XML_SCHEMA_TYPE_COMPLEX;
12147 type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
12149 type->targetNamespace = ctxt->targetNamespace;
12151 * Handle attributes.
12153 attr = node->properties;
12154 while (attr != NULL) {
12155 if (attr->ns == NULL) {
12156 if (xmlStrEqual(attr->name, BAD_CAST "id")) {
12160 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12161 } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
12163 * Attribute "mixed".
12165 if (xmlSchemaPGetBoolNodeValue(ctxt,
12166 NULL, (xmlNodePtr) attr))
12167 type->flags |= XML_SCHEMAS_TYPE_MIXED;
12168 } else if (topLevel) {
12170 * Attributes of global complex type definitions.
12172 if (xmlStrEqual(attr->name, BAD_CAST "name")) {
12174 } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
12176 * Attribute "abstract".
12178 if (xmlSchemaPGetBoolNodeValue(ctxt,
12179 NULL, (xmlNodePtr) attr))
12180 type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
12181 } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
12183 * Attribute "final".
12185 attrValue = xmlSchemaGetNodeContent(ctxt,
12186 (xmlNodePtr) attr);
12187 if (xmlSchemaPValAttrBlockFinal(attrValue,
12190 XML_SCHEMAS_TYPE_FINAL_EXTENSION,
12191 XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
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);
12201 } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
12203 * Attribute "block".
12205 attrValue = xmlSchemaGetNodeContent(ctxt,
12206 (xmlNodePtr) attr);
12207 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
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);
12220 xmlSchemaPIllegalAttrErr(ctxt,
12221 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12224 xmlSchemaPIllegalAttrErr(ctxt,
12225 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12227 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12228 xmlSchemaPIllegalAttrErr(ctxt,
12229 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12235 * Apply default "block" values.
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;
12244 * Apply default "block" values.
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;
12252 * And now for the children...
12254 child = node->children;
12255 if (IS_SCHEMA(child, "annotation")) {
12256 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
12257 child = child->next;
12259 ctxt->ctxtType = type;
12260 if (IS_SCHEMA(child, "simpleContent")) {
12262 * <complexType><simpleContent>...
12264 * Specifying mixed='true' when the <simpleContent>
12265 * alternative is chosen has no effect
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")) {
12274 * <complexType><complexContent>...
12276 type->contentType = XML_SCHEMA_CONTENT_EMPTY;
12277 xmlSchemaParseComplexContent(ctxt, schema, child,
12278 &hasRestrictionOrExtension);
12279 child = child->next;
12282 * E.g <complexType><sequence>... or <complexType><attribute>... etc.
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.
12290 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
12291 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
12293 * Parse model groups.
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);
12314 * Note that the reference will be resolved in
12315 * xmlSchemaResolveTypeReferences();
12317 child = child->next;
12320 * Parse attribute decls/refs.
12322 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
12323 (xmlSchemaItemListPtr *) &(type->attrUses),
12324 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
12327 * Parse attribute wildcard.
12329 if (IS_SCHEMA(child, "anyAttribute")) {
12330 type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
12331 child = child->next;
12334 if (child != NULL) {
12335 xmlSchemaPContentErr(ctxt,
12336 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12338 NULL, "(annotation?, (simpleContent | complexContent | "
12339 "((group | all | choice | sequence)?, ((attribute | "
12340 "attributeGroup)*, anyAttribute?))))");
12343 * REDEFINE: SPEC src-redefine (5)
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);
12351 ctxt->ctxtType = ctxtType;
12355 /************************************************************************
12357 * Validating using Schemas *
12359 ************************************************************************/
12361 /************************************************************************
12363 * Reading/Writing Schemas *
12365 ************************************************************************/
12367 #if 0 /* Will be enabled if it is clear what options are needed. */
12369 * xmlSchemaParserCtxtSetOptions:
12370 * @ctxt: a schema parser context
12371 * @options: a combination of xmlSchemaParserOption
12373 * Sets the options to be used during the parse.
12375 * Returns 0 in case of success, -1 in case of an
12379 xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
12388 * WARNING: Change the start value if adding to the
12389 * xmlSchemaParseOption.
12391 for (i = 1; i < (int) sizeof(int) * 8; i++) {
12392 if (options & 1<<i) {
12396 ctxt->options = options;
12401 * xmlSchemaValidCtxtGetOptions:
12402 * @ctxt: a schema parser context
12404 * Returns the option combination of the parser context.
12407 xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
12413 return (ctxt->options);
12418 * xmlSchemaNewParserCtxt:
12419 * @URL: the location of the schema
12421 * Create an XML Schemas parse context for that file/resource expected
12422 * to contain an XML Schemas file.
12424 * Returns the parser context or NULL in case of error
12426 xmlSchemaParserCtxtPtr
12427 xmlSchemaNewParserCtxt(const char *URL)
12429 xmlSchemaParserCtxtPtr ret;
12434 ret = xmlSchemaParserCtxtCreate();
12437 ret->dict = xmlDictCreate();
12438 ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
12443 * xmlSchemaNewMemParserCtxt:
12444 * @buffer: a pointer to a char array containing the schemas
12445 * @size: the size of the array
12447 * Create an XML Schemas parse context for that memory buffer expected
12448 * to contain an XML Schemas file.
12450 * Returns the parser context or NULL in case of error
12452 xmlSchemaParserCtxtPtr
12453 xmlSchemaNewMemParserCtxt(const char *buffer, int size)
12455 xmlSchemaParserCtxtPtr ret;
12457 if ((buffer == NULL) || (size <= 0))
12459 ret = xmlSchemaParserCtxtCreate();
12462 ret->buffer = buffer;
12464 ret->dict = xmlDictCreate();
12469 * xmlSchemaNewDocParserCtxt:
12470 * @doc: a preparsed document tree
12472 * Create an XML Schemas parse context for that document.
12473 * NB. The document may be modified during the parsing process.
12475 * Returns the parser context or NULL in case of error
12477 xmlSchemaParserCtxtPtr
12478 xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
12480 xmlSchemaParserCtxtPtr ret;
12484 ret = xmlSchemaParserCtxtCreate();
12488 ret->dict = xmlDictCreate();
12489 /* The application has responsibility for the document */
12496 * xmlSchemaFreeParserCtxt:
12497 * @ctxt: the schema parser context
12499 * Free the resources associated to the schema parser context
12502 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
12506 if (ctxt->doc != NULL && !ctxt->preserve)
12507 xmlFreeDoc(ctxt->doc);
12508 if (ctxt->vctxt != NULL) {
12509 xmlSchemaFreeValidCtxt(ctxt->vctxt);
12511 if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
12512 xmlSchemaConstructionCtxtFree(ctxt->constructor);
12513 ctxt->constructor = NULL;
12514 ctxt->ownsConstructor = 0;
12516 if (ctxt->attrProhibs != NULL)
12517 xmlSchemaItemListFree(ctxt->attrProhibs);
12518 xmlDictFree(ctxt->dict);
12522 /************************************************************************
12524 * Building the content models *
12526 ************************************************************************/
12529 * xmlSchemaBuildContentModelForSubstGroup:
12531 * Returns 1 if nillable, 0 otherwise
12534 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
12535 xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
12537 xmlAutomataStatePtr start, tmp;
12538 xmlSchemaElementPtr elemDecl, member;
12539 xmlSchemaSubstGroupPtr substGroup;
12543 elemDecl = (xmlSchemaElementPtr) particle->children;
12545 * Wrap the substitution group with a CHOICE.
12547 start = pctxt->state;
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);
12559 if (counter >= 0) {
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
12566 tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
12567 xmlAutomataNewTransition2(pctxt->am, tmp, end,
12568 elemDecl->name, elemDecl->targetNamespace, elemDecl);
12570 * Add subst. group members.
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);
12577 } else if (particle->maxOccurs == 1) {
12579 * NOTE that we put the declaration in, even if it's abstract,
12581 xmlAutomataNewEpsilon(pctxt->am,
12582 xmlAutomataNewTransition2(pctxt->am,
12584 elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
12586 * Add subst. group members.
12588 for (i = 0; i < substGroup->members->nbItems; i++) {
12589 member = (xmlSchemaElementPtr) substGroup->members->items[i];
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.
12599 * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
12600 * member->name, member->targetNamespace,
12603 tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
12604 member->name, member->targetNamespace, member);
12605 xmlAutomataNewEpsilon(pctxt->am, tmp, end);
12608 xmlAutomataStatePtr hop;
12609 int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12610 UNBOUNDED : particle->maxOccurs - 1;
12611 int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12614 xmlAutomataNewCounter(pctxt->am, minOccurs,
12616 hop = xmlAutomataNewState(pctxt->am);
12618 xmlAutomataNewEpsilon(pctxt->am,
12619 xmlAutomataNewTransition2(pctxt->am,
12621 elemDecl->name, elemDecl->targetNamespace, elemDecl),
12624 * Add subst. group members.
12626 for (i = 0; i < substGroup->members->nbItems; i++) {
12627 member = (xmlSchemaElementPtr) substGroup->members->items[i];
12628 xmlAutomataNewEpsilon(pctxt->am,
12629 xmlAutomataNewTransition2(pctxt->am,
12631 member->name, member->targetNamespace, member),
12634 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12635 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12637 if (particle->minOccurs == 0) {
12638 xmlAutomataNewEpsilon(pctxt->am, start, end);
12641 pctxt->state = end;
12646 * xmlSchemaBuildContentModelForElement:
12648 * Returns 1 if nillable, 0 otherwise
12651 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
12652 xmlSchemaParticlePtr particle)
12656 if (((xmlSchemaElementPtr) particle->children)->flags &
12657 XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
12659 * Substitution groups.
12661 ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
12663 xmlSchemaElementPtr elemDecl;
12664 xmlAutomataStatePtr start;
12666 elemDecl = (xmlSchemaElementPtr) particle->children;
12668 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
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);
12684 int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12685 UNBOUNDED : particle->maxOccurs - 1;
12686 int minOccurs = particle->minOccurs < 1 ?
12687 0 : particle->minOccurs - 1;
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,
12697 if (particle->minOccurs == 0) {
12698 xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
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
12711 * Create the automaton for the {content type} of a complex type.
12713 * Returns 1 if the content is nillable, 0 otherwise
12716 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
12717 xmlSchemaParticlePtr particle)
12721 if (particle == NULL) {
12722 PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
12725 if (particle->children == NULL) {
12727 * Just return in this case. A missing "term" of the particle
12728 * might arise due to an invalid "term" component.
12733 switch (particle->children->type) {
12734 case XML_SCHEMA_TYPE_ANY: {
12735 xmlAutomataStatePtr start, end;
12736 xmlSchemaWildcardPtr wild;
12737 xmlSchemaWildcardNsPtr ns;
12739 wild = (xmlSchemaWildcardPtr) particle->children;
12741 start = pctxt->state;
12742 end = xmlAutomataNewState(pctxt->am);
12744 if (particle->maxOccurs == 1) {
12745 if (wild->any == 1) {
12747 * We need to add both transitions:
12749 * 1. the {"*", "*"} for elements in a namespace.
12752 xmlAutomataNewTransition2(pctxt->am,
12753 start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12754 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12756 * 2. the {"*"} for elements in no namespace.
12759 xmlAutomataNewTransition2(pctxt->am,
12760 start, NULL, BAD_CAST "*", NULL, wild);
12761 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12763 } else if (wild->nsSet != NULL) {
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);
12771 } while (ns != NULL);
12773 } else if (wild->negNsSet != NULL) {
12774 pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12775 start, end, BAD_CAST "*", wild->negNsSet->value,
12780 xmlAutomataStatePtr hop;
12782 particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
12783 particle->maxOccurs - 1;
12785 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12787 counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12788 hop = xmlAutomataNewState(pctxt->am);
12789 if (wild->any == 1) {
12791 xmlAutomataNewTransition2(pctxt->am,
12792 start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12793 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12795 xmlAutomataNewTransition2(pctxt->am,
12796 start, NULL, BAD_CAST "*", NULL, wild);
12797 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12798 } else if (wild->nsSet != NULL) {
12802 xmlAutomataNewTransition2(pctxt->am,
12803 start, NULL, BAD_CAST "*", ns->value, wild);
12804 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12806 } while (ns != NULL);
12808 } else if (wild->negNsSet != NULL) {
12809 pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12810 start, hop, BAD_CAST "*", wild->negNsSet->value,
12813 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12814 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12816 if (particle->minOccurs == 0) {
12817 xmlAutomataNewEpsilon(pctxt->am, start, end);
12820 pctxt->state = end;
12823 case XML_SCHEMA_TYPE_ELEMENT:
12824 ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
12826 case XML_SCHEMA_TYPE_SEQUENCE:{
12827 xmlSchemaTreeItemPtr sub;
12831 * If max and min occurances are default (1) then
12832 * simply iterate over the particles of the <sequence>.
12834 if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
12835 sub = particle->children->children;
12837 while (sub != NULL) {
12838 tmp2 = xmlSchemaBuildAContentModel(pctxt,
12839 (xmlSchemaParticlePtr) sub);
12840 if (tmp2 != 1) ret = 0;
12844 xmlAutomataStatePtr oldstate = pctxt->state;
12846 if (particle->maxOccurs >= UNBOUNDED) {
12847 if (particle->minOccurs > 1) {
12848 xmlAutomataStatePtr tmp;
12851 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12853 oldstate = pctxt->state;
12855 counter = xmlAutomataNewCounter(pctxt->am,
12856 particle->minOccurs - 1, UNBOUNDED);
12858 sub = particle->children->children;
12859 while (sub != NULL) {
12860 tmp2 = xmlSchemaBuildAContentModel(pctxt,
12861 (xmlSchemaParticlePtr) sub);
12862 if (tmp2 != 1) ret = 0;
12865 tmp = pctxt->state;
12866 xmlAutomataNewCountedTrans(pctxt->am, tmp,
12867 oldstate, counter);
12869 xmlAutomataNewCounterTrans(pctxt->am, tmp,
12872 xmlAutomataNewEpsilon(pctxt->am,
12873 oldstate, pctxt->state);
12876 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12878 oldstate = pctxt->state;
12880 sub = particle->children->children;
12881 while (sub != NULL) {
12882 tmp2 = xmlSchemaBuildAContentModel(pctxt,
12883 (xmlSchemaParticlePtr) sub);
12884 if (tmp2 != 1) ret = 0;
12887 xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
12890 * epsilon needed to block previous trans from
12891 * being allowed to enter back from another
12894 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12895 pctxt->state, NULL);
12896 if (particle->minOccurs == 0) {
12897 xmlAutomataNewEpsilon(pctxt->am,
12898 oldstate, pctxt->state);
12902 } else if ((particle->maxOccurs > 1)
12903 || (particle->minOccurs > 1)) {
12904 xmlAutomataStatePtr tmp;
12907 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12909 oldstate = pctxt->state;
12911 counter = xmlAutomataNewCounter(pctxt->am,
12912 particle->minOccurs - 1,
12913 particle->maxOccurs - 1);
12915 sub = particle->children->children;
12916 while (sub != NULL) {
12917 tmp2 = xmlSchemaBuildAContentModel(pctxt,
12918 (xmlSchemaParticlePtr) sub);
12919 if (tmp2 != 1) ret = 0;
12922 tmp = pctxt->state;
12923 xmlAutomataNewCountedTrans(pctxt->am,
12924 tmp, oldstate, counter);
12926 xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
12928 if ((particle->minOccurs == 0) || (ret == 1)) {
12929 xmlAutomataNewEpsilon(pctxt->am,
12930 oldstate, pctxt->state);
12934 sub = particle->children->children;
12935 while (sub != NULL) {
12936 tmp2 = xmlSchemaBuildAContentModel(pctxt,
12937 (xmlSchemaParticlePtr) sub);
12938 if (tmp2 != 1) ret = 0;
12941 if (particle->minOccurs == 0) {
12942 xmlAutomataNewEpsilon(pctxt->am, oldstate,
12950 case XML_SCHEMA_TYPE_CHOICE:{
12951 xmlSchemaTreeItemPtr sub;
12952 xmlAutomataStatePtr start, end;
12955 start = pctxt->state;
12956 end = xmlAutomataNewState(pctxt->am);
12959 * iterate over the subtypes and remerge the end with an
12960 * epsilon transition
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);
12974 xmlAutomataStatePtr hop, base;
12975 int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12976 UNBOUNDED : particle->maxOccurs - 1;
12978 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12981 * use a counter to keep track of the number of transtions
12982 * which went through the choice.
12985 xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12986 hop = xmlAutomataNewState(pctxt->am);
12987 base = xmlAutomataNewState(pctxt->am);
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);
12998 xmlAutomataNewEpsilon(pctxt->am, start, base);
12999 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
13000 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
13002 xmlAutomataNewEpsilon(pctxt->am, base, end);
13004 if (particle->minOccurs == 0) {
13005 xmlAutomataNewEpsilon(pctxt->am, start, end);
13008 pctxt->state = end;
13011 case XML_SCHEMA_TYPE_ALL:{
13012 xmlAutomataStatePtr start, tmp;
13013 xmlSchemaParticlePtr sub;
13014 xmlSchemaElementPtr elemDecl;
13018 sub = (xmlSchemaParticlePtr) particle->children->children;
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;
13031 elemDecl = (xmlSchemaElementPtr) sub->children;
13032 if (elemDecl == NULL) {
13033 PERROR_INT("xmlSchemaBuildAContentModel",
13034 "<element> particle has no term");
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
13043 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
13047 * This is an abstract group, we need to share
13048 * the same counter for all the element transitions
13049 * derived from the group
13051 counter = xmlAutomataNewCounter(pctxt->am,
13052 sub->minOccurs, sub->maxOccurs);
13053 xmlSchemaBuildContentModelForSubstGroup(pctxt,
13054 sub, counter, pctxt->state);
13056 if ((sub->minOccurs == 1) &&
13057 (sub->maxOccurs == 1)) {
13058 xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
13061 elemDecl->targetNamespace,
13063 } else if ((sub->minOccurs == 0) &&
13064 (sub->maxOccurs == 1)) {
13066 xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
13069 elemDecl->targetNamespace,
13075 sub = (xmlSchemaParticlePtr) sub->next;
13078 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
13079 if (particle->minOccurs == 0) {
13080 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
13085 case XML_SCHEMA_TYPE_GROUP:
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.
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);
13106 * xmlSchemaBuildContentModel:
13107 * @ctxt: the schema parser context
13108 * @type: the complex type definition
13109 * @name: the element name
13111 * Builds the content model of the complex type.
13114 xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
13115 xmlSchemaParserCtxtPtr ctxt)
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)))
13123 #ifdef DEBUG_CONTENT
13124 xmlGenericError(xmlGenericErrorContext,
13125 "Building content model for %s\n", name);
13128 ctxt->am = xmlNewAutomata();
13129 if (ctxt->am == NULL) {
13130 xmlGenericError(xmlGenericErrorContext,
13131 "Cannot create automata for complex type %s\n", type->name);
13134 ctxt->state = xmlAutomataGetInitState(ctxt->am);
13136 * Build the automaton.
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);
13153 #ifdef DEBUG_CONTENT_REGEXP
13154 xmlGenericError(xmlGenericErrorContext,
13155 "Content model of %s:\n", type->name);
13156 xmlRegexpPrint(stderr, type->contModel);
13159 ctxt->state = NULL;
13160 xmlFreeAutomata(ctxt->am);
13165 * xmlSchemaResolveElementReferences:
13166 * @elem: the schema element context
13167 * @ctxt: the schema parser context
13169 * Resolves the references of an element declaration
13170 * or particle, which has an element declaration as it's
13174 xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
13175 xmlSchemaParserCtxtPtr ctxt)
13177 if ((ctxt == NULL) || (elemDecl == NULL) ||
13178 ((elemDecl != NULL) &&
13179 (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
13181 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
13183 if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
13184 xmlSchemaTypePtr type;
13186 /* (type definition) ... otherwise the type definition �resolved�
13187 * to by the �actual value� of the type [attribute] ...
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");
13198 elemDecl->subtypes = type;
13200 if (elemDecl->substGroup != NULL) {
13201 xmlSchemaElementPtr substHead;
13204 * FIXME TODO: Do we need a new field in _xmlSchemaElement for
13205 * substitutionGroup?
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);
13216 xmlSchemaResolveElementReferences(substHead, ctxt);
13218 * Set the "substitution group affiliation".
13219 * NOTE that now we use the "refDecl" field for this.
13221 WXS_SUBST_HEAD(elemDecl) = substHead;
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"
13228 if (elemDecl->subtypes == NULL)
13229 elemDecl->subtypes = substHead->subtypes;
13233 * SPEC "The definition of anyType serves as the default type definition
13234 * for element declarations whose XML representation does not specify one."
13236 if ((elemDecl->subtypes == NULL) &&
13237 (elemDecl->namedType == NULL) &&
13238 (elemDecl->substGroup == NULL))
13239 elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
13243 * xmlSchemaResolveUnionMemberTypes:
13244 * @ctxt: the schema parser context
13245 * @type: the schema simple type definition
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()
13251 * Returns -1 in case of an internal error, 0 otherwise.
13254 xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
13255 xmlSchemaTypePtr type)
13258 xmlSchemaTypeLinkPtr link, lastLink, newLink;
13259 xmlSchemaTypePtr memberType;
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."
13269 * Resolve references.
13271 link = type->memberTypes;
13273 while (link != NULL) {
13274 const xmlChar *name, *nsName;
13276 name = ((xmlSchemaQNameRefPtr) link->type)->name;
13277 nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
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);
13285 * Remove the member type link.
13287 if (lastLink == NULL)
13288 type->memberTypes = link->next;
13290 lastLink->next = link->next;
13295 link->type = memberType;
13301 * Add local simple types,
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);
13310 link->type = memberType;
13312 if (lastLink == NULL)
13313 type->memberTypes = link;
13315 lastLink->next = link;
13317 memberType = memberType->next;
13323 * xmlSchemaIsDerivedFromBuiltInType:
13324 * @ctxt: the schema parser context
13325 * @type: the type definition
13326 * @valType: the value type
13329 * Returns 1 if the type has the given value type, or
13330 * is derived from such a type.
13333 xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13337 if (WXS_IS_COMPLEX(type))
13339 if (type->type == XML_SCHEMA_TYPE_BASIC) {
13340 if (type->builtInType == valType)
13342 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13343 (type->builtInType == XML_SCHEMAS_ANYTYPE))
13345 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13347 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13352 * xmlSchemaIsDerivedFromBuiltInType:
13353 * @ctxt: the schema parser context
13354 * @type: the type definition
13355 * @valType: the value type
13358 * Returns 1 if the type has the given value type, or
13359 * is derived from such a type.
13362 xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13366 if (WXS_IS_COMPLEX(type))
13368 if (type->type == XML_SCHEMA_TYPE_BASIC) {
13369 if (type->builtInType == valType)
13373 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13378 static xmlSchemaTypePtr
13379 xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
13383 if (WXS_IS_COMPLEX(type))
13385 if (type->type == XML_SCHEMA_TYPE_BASIC)
13387 return(xmlSchemaQueryBuiltInType(type->subtypes));
13392 * xmlSchemaGetPrimitiveType:
13393 * @type: the simpleType definition
13395 * Returns the primitive type of the given type or
13396 * NULL in case of error.
13398 static xmlSchemaTypePtr
13399 xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
13402 while (type != NULL) {
13404 * Note that anySimpleType is actually not a primitive type
13405 * but we need that here.
13407 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13408 (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
13410 type = type->baseType;
13418 * xmlSchemaGetBuiltInTypeAncestor:
13419 * @type: the simpleType definition
13421 * Returns the primitive type of the given type or
13422 * NULL in case of error.
13424 static xmlSchemaTypePtr
13425 xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
13427 if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
13429 while (type != NULL) {
13430 if (type->type == XML_SCHEMA_TYPE_BASIC)
13432 type = type->baseType;
13440 * xmlSchemaCloneWildcardNsConstraints:
13441 * @ctxt: the schema parser context
13442 * @dest: the destination wildcard
13443 * @source: the source wildcard
13445 * Clones the namespace constraints of source
13446 * and assignes them to dest.
13447 * Returns -1 on internal error, 0 otherwise.
13450 xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
13451 xmlSchemaWildcardPtr dest,
13452 xmlSchemaWildcardPtr source)
13454 xmlSchemaWildcardNsPtr cur, tmp, last;
13456 if ((source == NULL) || (dest == NULL))
13458 dest->any = source->any;
13459 cur = source->nsSet;
13461 while (cur != NULL) {
13462 tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13465 tmp->value = cur->value;
13473 if (dest->negNsSet != NULL)
13474 xmlSchemaFreeWildcardNsSet(dest->negNsSet);
13475 if (source->negNsSet != NULL) {
13476 dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13477 if (dest->negNsSet == NULL)
13479 dest->negNsSet->value = source->negNsSet->value;
13481 dest->negNsSet = NULL;
13486 * xmlSchemaUnionWildcards:
13487 * @ctxt: the schema parser context
13488 * @completeWild: the first wildcard
13489 * @curWild: the second wildcard
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.
13497 xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
13498 xmlSchemaWildcardPtr completeWild,
13499 xmlSchemaWildcardPtr curWild)
13501 xmlSchemaWildcardNsPtr cur, curB, tmp;
13504 * 1 If O1 and O2 are the same value, then that value must be the
13507 if ((completeWild->any == curWild->any) &&
13508 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13509 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13511 if ((completeWild->negNsSet == NULL) ||
13512 (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13514 if (completeWild->nsSet != NULL) {
13518 * Check equality of sets.
13520 cur = completeWild->nsSet;
13521 while (cur != NULL) {
13523 curB = curWild->nsSet;
13524 while (curB != NULL) {
13525 if (cur->value == curB->value) {
13542 * 2 If either O1 or O2 is any, then any must be the value
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;
13551 if (completeWild->negNsSet != NULL) {
13552 xmlFree(completeWild->negNsSet);
13553 completeWild->negNsSet = NULL;
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.
13562 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13564 xmlSchemaWildcardNsPtr start;
13566 cur = curWild->nsSet;
13567 start = completeWild->nsSet;
13568 while (cur != NULL) {
13571 while (curB != NULL) {
13572 if (cur->value == curB->value) {
13579 tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13582 tmp->value = cur->value;
13583 tmp->next = completeWild->nsSet;
13584 completeWild->nsSet = tmp;
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.
13595 if ((completeWild->negNsSet != NULL) &&
13596 (curWild->negNsSet != NULL) &&
13597 (completeWild->negNsSet->value != curWild->negNsSet->value)) {
13598 completeWild->negNsSet->value = NULL;
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))) {
13612 int nsFound, absentFound = 0;
13614 if (completeWild->nsSet != NULL) {
13615 cur = completeWild->nsSet;
13616 curB = curWild->negNsSet;
13618 cur = curWild->nsSet;
13619 curB = completeWild->negNsSet;
13622 while (cur != NULL) {
13623 if (cur->value == NULL)
13625 else if (cur->value == curB->value)
13627 if (nsFound && absentFound)
13632 if (nsFound && absentFound) {
13634 * 5.1 If the set S includes both the negated namespace
13635 * name and �absent�, then any must be the value.
13637 completeWild->any = 1;
13638 if (completeWild->nsSet != NULL) {
13639 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13640 completeWild->nsSet = NULL;
13642 if (completeWild->negNsSet != NULL) {
13643 xmlFree(completeWild->negNsSet);
13644 completeWild->negNsSet = NULL;
13646 } else if (nsFound && (!absentFound)) {
13648 * 5.2 If the set S includes the negated namespace name
13649 * but not �absent�, then a pair of not and �absent� must
13652 if (completeWild->nsSet != NULL) {
13653 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13654 completeWild->nsSet = NULL;
13656 if (completeWild->negNsSet == NULL) {
13657 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13658 if (completeWild->negNsSet == NULL)
13661 completeWild->negNsSet->value = NULL;
13662 } else if ((!nsFound) && absentFound) {
13664 * 5.3 If the set S includes �absent� but not the negated
13665 * namespace name, then the union is not expressible.
13667 xmlSchemaPErr(ctxt, completeWild->node,
13668 XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
13669 "The union of the wilcard is not expressible.\n",
13671 return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
13672 } else if ((!nsFound) && (!absentFound)) {
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.
13678 if (completeWild->negNsSet == NULL) {
13679 if (completeWild->nsSet != NULL) {
13680 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13681 completeWild->nsSet = NULL;
13683 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13684 if (completeWild->negNsSet == NULL)
13686 completeWild->negNsSet->value = curWild->negNsSet->value;
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))) {
13701 if (completeWild->nsSet != NULL) {
13702 cur = completeWild->nsSet;
13704 cur = curWild->nsSet;
13706 while (cur != NULL) {
13707 if (cur->value == NULL) {
13709 * 6.1 If the set S includes �absent�, then any must be the
13712 completeWild->any = 1;
13713 if (completeWild->nsSet != NULL) {
13714 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13715 completeWild->nsSet = NULL;
13717 if (completeWild->negNsSet != NULL) {
13718 xmlFree(completeWild->negNsSet);
13719 completeWild->negNsSet = NULL;
13725 if (completeWild->negNsSet == NULL) {
13727 * 6.2 If the set S does not include �absent�, then a pair of not
13728 * and �absent� must be the value.
13730 if (completeWild->nsSet != NULL) {
13731 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13732 completeWild->nsSet = NULL;
13734 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13735 if (completeWild->negNsSet == NULL)
13737 completeWild->negNsSet->value = NULL;
13746 * xmlSchemaIntersectWildcards:
13747 * @ctxt: the schema parser context
13748 * @completeWild: the first wildcard
13749 * @curWild: the second wildcard
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.
13757 xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
13758 xmlSchemaWildcardPtr completeWild,
13759 xmlSchemaWildcardPtr curWild)
13761 xmlSchemaWildcardNsPtr cur, curB, prev, tmp;
13764 * 1 If O1 and O2 are the same value, then that value must be the
13767 if ((completeWild->any == curWild->any) &&
13768 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13769 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13771 if ((completeWild->negNsSet == NULL) ||
13772 (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13774 if (completeWild->nsSet != NULL) {
13778 * Check equality of sets.
13780 cur = completeWild->nsSet;
13781 while (cur != NULL) {
13783 curB = curWild->nsSet;
13784 while (curB != NULL) {
13785 if (cur->value == curB->value) {
13802 * 2 If either O1 or O2 is any, then the other must be the value.
13804 if ((completeWild->any != curWild->any) && (completeWild->any)) {
13805 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
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.
13815 if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
13816 ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
13817 const xmlChar *neg;
13819 if (completeWild->nsSet == NULL) {
13820 neg = completeWild->negNsSet->value;
13821 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13824 neg = curWild->negNsSet->value;
13826 * Remove absent and negated.
13829 cur = completeWild->nsSet;
13830 while (cur != NULL) {
13831 if (cur->value == NULL) {
13833 completeWild->nsSet = cur->next;
13835 prev->next = cur->next;
13844 cur = completeWild->nsSet;
13845 while (cur != NULL) {
13846 if (cur->value == neg) {
13848 completeWild->nsSet = cur->next;
13850 prev->next = cur->next;
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.
13865 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13868 cur = completeWild->nsSet;
13870 while (cur != NULL) {
13872 curB = curWild->nsSet;
13873 while (curB != NULL) {
13874 if (cur->value == curB->value) {
13882 completeWild->nsSet = cur->next;
13884 prev->next = cur->next;
13896 /* 5 If the two are negations of different namespace names,
13897 * then the intersection is not expressible
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)) {
13905 xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
13906 "The intersection of the wilcard is not expressible.\n",
13908 return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
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.
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;
13924 * xmlSchemaIsWildcardNsConstraintSubset:
13925 * @ctxt: the schema parser context
13926 * @sub: the first wildcard
13927 * @super: the second wildcard
13929 * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
13931 * Returns 0 if the namespace constraint of @sub is an intensional
13932 * subset of @super, 1 otherwise.
13935 xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
13936 xmlSchemaWildcardPtr super)
13939 * 1 super must be any.
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.
13947 if ((sub->negNsSet != NULL) &&
13948 (super->negNsSet != NULL) &&
13949 (sub->negNsSet->value == super->negNsSet->value))
13952 * 3.1 sub must be a set whose members are either namespace names or �absent�.
13954 if (sub->nsSet != NULL) {
13956 * 3.2.1 super must be the same set or a superset thereof.
13958 if (super->nsSet != NULL) {
13959 xmlSchemaWildcardNsPtr cur, curB;
13963 while (cur != NULL) {
13965 curB = super->nsSet;
13966 while (curB != NULL) {
13967 if (cur->value == curB->value) {
13979 } else if (super->negNsSet != NULL) {
13980 xmlSchemaWildcardNsPtr cur;
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.
13986 while (cur != NULL) {
13987 if (cur->value == super->negNsSet->value)
13998 xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
14000 const xmlChar **value,
14001 xmlSchemaValPtr *val)
14008 if (attruse->defValue != NULL) {
14009 *value = attruse->defValue;
14011 *val = attruse->defVal;
14012 if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
14015 } else if ((attruse->attrDecl != NULL) &&
14016 (attruse->attrDecl->defValue != NULL)) {
14017 *value = attruse->attrDecl->defValue;
14019 *val = attruse->attrDecl->defVal;
14020 if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
14027 * xmlSchemaCheckCVCWildcardNamespace:
14028 * @wild: the wildcard
14029 * @ns: the namespace
14031 * Validation Rule: Wildcard allows Namespace Name
14032 * (cvc-wildcard-namespace)
14034 * Returns 0 if the given namespace matches the wildcard,
14035 * 1 otherwise and -1 on API errors.
14038 xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
14046 else if (wild->nsSet != NULL) {
14047 xmlSchemaWildcardNsPtr cur;
14050 while (cur != NULL) {
14051 if (xmlStrEqual(cur->value, ns))
14055 } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
14056 (!xmlStrEqual(wild->negNsSet->value, ns)))
14062 #define XML_SCHEMA_ACTION_DERIVE 0
14063 #define XML_SCHEMA_ACTION_REDEFINE 1
14065 #define WXS_ACTION_STR(a) \
14066 ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
14069 * Schema Component Constraint:
14070 * Derivation Valid (Restriction, Complex)
14071 * derivation-ok-restriction (2) - (4)
14074 * In XML Schema 1.1 this will be:
14076 * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
14080 xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
14082 xmlSchemaBasicItemPtr item,
14083 xmlSchemaBasicItemPtr baseItem,
14084 xmlSchemaItemListPtr uses,
14085 xmlSchemaItemListPtr baseUses,
14086 xmlSchemaWildcardPtr wild,
14087 xmlSchemaWildcardPtr baseWild)
14089 xmlSchemaAttributeUsePtr cur = NULL, bcur;
14090 int i, j, found; /* err = 0; */
14091 const xmlChar *bEffValue;
14094 if (uses != NULL) {
14095 for (i = 0; i < uses->nbItems; i++) {
14096 cur = uses->items[i];
14098 if (baseUses == NULL)
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)))
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:"
14115 if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
14116 (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
14118 xmlChar *str = NULL;
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."
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 "
14130 WXS_ACTION_STR(action),
14131 xmlSchemaGetComponentDesignation(&str, baseItem),
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)
14139 xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
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)."
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; */
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} .
14172 xmlSchemaGetEffectiveValueConstraint(bcur,
14173 &effFixed, &bEffValue, NULL);
14175 * 2.1.3 ... one of the following must be true
14177 * 2.1.3.1 B's �effective value constraint� is
14178 * �absent� or default.
14180 if ((bEffValue != NULL) &&
14182 const xmlChar *rEffValue = NULL;
14184 xmlSchemaGetEffectiveValueConstraint(bcur,
14185 &effFixed, &rEffValue, NULL);
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.
14193 if ((effFixed == 0) ||
14194 (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
14196 xmlChar *str = NULL;
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,
14208 FREE_AND_NULL(str);
14209 /* err = pctxt->err; */
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)."
14225 if ((baseWild == NULL) ||
14226 (xmlSchemaCheckCVCWildcardNamespace(baseWild,
14227 (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
14229 xmlChar *str = NULL;
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),
14239 FREE_AND_NULL(str);
14240 /* err = pctxt->err; */
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.
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)
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))) {
14272 xmlChar *strA = NULL, *strB = NULL;
14274 xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14275 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
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),
14283 FREE_AND_NULL(strA);
14284 FREE_AND_NULL(strB);
14289 * derivation-ok-restriction (4)
14291 if (wild != NULL) {
14293 * (4) "If there is an {attribute wildcard}, all of the
14294 * following must be true:"
14296 if (baseWild == NULL) {
14297 xmlChar *str = NULL;
14300 * (4.1) "The {base type definition} must also have one."
14302 xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14303 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
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))
14316 xmlChar *str = NULL;
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)."
14323 xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14324 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
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),
14332 FREE_AND_NULL(str);
14333 return(pctxt->err);
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.
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,
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),
14355 return(pctxt->err);
14363 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
14364 xmlSchemaBasicItemPtr item,
14365 xmlSchemaWildcardPtr *completeWild,
14366 xmlSchemaItemListPtr list,
14367 xmlSchemaItemListPtr prohibs);
14369 * xmlSchemaFixupTypeAttributeUses:
14370 * @ctxt: the schema parser context
14371 * @type: the complex type definition
14374 * Builds the wildcard and the attribute uses on the given complex type.
14375 * Returns -1 if an internal error occurs, 0 otherwise.
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.
14383 xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
14384 xmlSchemaTypePtr type)
14386 xmlSchemaTypePtr baseType = NULL;
14387 xmlSchemaAttributeUsePtr use;
14388 xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
14390 if (type->baseType == NULL) {
14391 PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14395 baseType = type->baseType;
14396 if (WXS_IS_TYPE_NOT_FIXED(baseType))
14397 if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
14400 uses = type->attrUses;
14401 baseUses = baseType->attrUses;
14403 * Expand attribute group references. And build the 'complete'
14404 * wildcard, i.e. intersect multiple wildcards.
14405 * Move attribute prohibitions into a separate list.
14407 if (uses != NULL) {
14408 if (WXS_IS_RESTRICTION(type)) {
14410 * This one will transfer all attr. prohibitions
14411 * into pctxt->attrProhibs.
14413 if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14414 WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14415 pctxt->attrProhibs) == -1)
14417 PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14418 "failed to expand attributes");
14420 if (pctxt->attrProhibs->nbItems != 0)
14421 prohibs = pctxt->attrProhibs;
14423 if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14424 WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14427 PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14428 "failed to expand attributes");
14433 * Inherit the attribute uses of the base type.
14435 if (baseUses != NULL) {
14437 xmlSchemaAttributeUseProhibPtr pro;
14439 if (WXS_IS_RESTRICTION(type)) {
14441 xmlSchemaAttributeUsePtr tmp;
14444 usesCount = uses->nbItems;
14449 for (i = 0; i < baseUses->nbItems; i++) {
14450 use = baseUses->items[i];
14453 * Filter out prohibited uses.
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))
14467 * Filter out existing uses.
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)))
14480 if (uses == NULL) {
14481 type->attrUses = xmlSchemaItemListCreate();
14482 if (type->attrUses == NULL)
14484 uses = type->attrUses;
14486 xmlSchemaItemListAddSize(uses, 2, use);
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)
14497 uses = type->attrUses;
14499 xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
14504 * Shrink attr. uses.
14507 if (uses->nbItems == 0) {
14508 xmlSchemaItemListFree(uses);
14509 type->attrUses = NULL;
14512 * TODO: We could shrink the size of the array
14513 * to fit the actual number of items.
14517 * Compute the complete wildcard.
14519 if (WXS_IS_EXTENSION(type)) {
14520 if (baseType->attributeWildcard != NULL) {
14522 * (3.2.2.1) "If the �base wildcard� is non-�absent�, then
14523 * the appropriate case among the following:"
14525 if (type->attributeWildcard != NULL) {
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)."
14536 if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
14537 baseType->attributeWildcard) == -1)
14541 * (3.2.2.1.1) "If the �complete wildcard� is �absent�,
14542 * then the �base wildcard�."
14544 type->attributeWildcard = baseType->attributeWildcard;
14548 * (3.2.2.2) "otherwise (the �base wildcard� is �absent�) the
14549 * �complete wildcard"
14555 * SPEC {attribute wildcard}
14556 * (3.1) "If the <restriction> alternative is chosen, then the
14557 * �complete wildcard�;"
14569 * xmlSchemaTypeFinalContains:
14570 * @schema: the schema
14571 * @type: the type definition
14572 * @final: the final
14574 * Evaluates if a type definition contains the given "final".
14575 * This does take "finalDefault" into account as well.
14577 * Returns 1 if the type does containt the given "final",
14581 xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
14585 if (type->flags & final)
14592 * xmlSchemaGetUnionSimpleTypeMemberTypes:
14593 * @type: the Union Simple Type
14595 * Returns a list of member types of @type if existing,
14596 * returns NULL otherwise.
14598 static xmlSchemaTypeLinkPtr
14599 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
14601 while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
14602 if (type->memberTypes != NULL)
14603 return (type->memberTypes);
14605 type = type->baseType;
14611 * xmlSchemaGetParticleTotalRangeMin:
14612 * @particle: the particle
14614 * Schema Component Constraint: Effective Total Range
14615 * (all and sequence) + (choice)
14617 * Returns the minimun Effective Total Range.
14620 xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
14622 if ((particle->children == NULL) ||
14623 (particle->minOccurs == 0))
14625 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14627 xmlSchemaParticlePtr part =
14628 (xmlSchemaParticlePtr) particle->children->children;
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;
14637 cur = xmlSchemaGetParticleTotalRangeMin(part);
14640 if ((min > cur) || (min == -1))
14642 part = (xmlSchemaParticlePtr) part->next;
14644 return (particle->minOccurs * min);
14646 /* <all> and <sequence> */
14648 xmlSchemaParticlePtr part =
14649 (xmlSchemaParticlePtr) particle->children->children;
14654 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14655 (part->children->type == XML_SCHEMA_TYPE_ANY))
14656 sum += part->minOccurs;
14658 sum += xmlSchemaGetParticleTotalRangeMin(part);
14659 part = (xmlSchemaParticlePtr) part->next;
14660 } while (part != NULL);
14661 return (particle->minOccurs * sum);
14667 * xmlSchemaGetParticleTotalRangeMax:
14668 * @particle: the particle
14670 * Schema Component Constraint: Effective Total Range
14671 * (all and sequence) + (choice)
14673 * Returns the maximum Effective Total Range.
14676 xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
14678 if ((particle->children == NULL) ||
14679 (particle->children->children == NULL))
14681 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14683 xmlSchemaParticlePtr part =
14684 (xmlSchemaParticlePtr) particle->children->children;
14686 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14687 if (part->children == NULL)
14689 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14690 (part->children->type == XML_SCHEMA_TYPE_ANY))
14691 cur = part->maxOccurs;
14693 cur = xmlSchemaGetParticleTotalRangeMax(part);
14694 if (cur == UNBOUNDED)
14695 return (UNBOUNDED);
14696 if ((max < cur) || (max == -1))
14699 /* TODO: Handle overflows? */
14700 return (particle->maxOccurs * max);
14702 /* <all> and <sequence> */
14704 xmlSchemaParticlePtr part =
14705 (xmlSchemaParticlePtr) particle->children->children;
14707 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14708 if (part->children == NULL)
14710 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14711 (part->children->type == XML_SCHEMA_TYPE_ANY))
14712 cur = part->maxOccurs;
14714 cur = xmlSchemaGetParticleTotalRangeMax(part);
14715 if (cur == UNBOUNDED)
14716 return (UNBOUNDED);
14717 if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
14718 return (UNBOUNDED);
14721 /* TODO: Handle overflows? */
14722 return (particle->maxOccurs * sum);
14728 * xmlSchemaIsParticleEmptiable:
14729 * @particle: the particle
14731 * Schema Component Constraint: Particle Emptiable
14732 * Checks whether the given particle is emptiable.
14734 * Returns 1 if emptiable, 0 otherwise.
14737 xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
14740 * SPEC (1) "Its {min occurs} is 0."
14742 if ((particle == NULL) || (particle->minOccurs == 0) ||
14743 (particle->children == NULL))
14746 * SPEC (2) "Its {term} is a group and the minimum part of the
14747 * effective total range of that group, [...] is 0."
14749 if (WXS_IS_MODEL_GROUP(particle->children)) {
14750 if (xmlSchemaGetParticleTotalRangeMin(particle) == 0)
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.)
14763 * Schema Component Constraint:
14764 * Type Derivation OK (Simple) (cos-st-derived-OK)
14766 * Checks wheter @type can be validly
14767 * derived from @baseType.
14769 * Returns 0 on success, an positive error code otherwise.
14772 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
14773 xmlSchemaTypePtr type,
14774 xmlSchemaTypePtr baseType,
14778 * 1 They are the same type definition.
14779 * TODO: The identy check might have to be more complex than this.
14781 if (type == baseType)
14784 * 2.1 restriction is not in the subset, or in the {final}
14785 * of its own {base type definition};
14787 * NOTE that this will be used also via "xsi:type".
14789 * TODO: Revise this, it looks strange. How can the "type"
14790 * not be fixed or *in* fixing?
14792 if (WXS_IS_TYPE_NOT_FIXED(type))
14793 if (xmlSchemaTypeFixup(type, actxt) == -1)
14795 if (WXS_IS_TYPE_NOT_FIXED(baseType))
14796 if (xmlSchemaTypeFixup(baseType, actxt) == -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);
14804 if (type->baseType == baseType) {
14806 * 2.2.1 D's �base type definition� is B.
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
14815 if ((! WXS_IS_ANYTYPE(type->baseType)) &&
14816 (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
14817 baseType, subset) == 0)) {
14821 * 2.2.3 D's {variety} is list or union and B is the �simple ur-type
14824 if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
14825 (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
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.
14833 * NOTE: This seems not to involve built-in types, since there is no
14834 * built-in Union Simple Type.
14836 if (WXS_IS_UNION(baseType)) {
14837 xmlSchemaTypeLinkPtr cur;
14839 cur = baseType->memberTypes;
14840 while (cur != NULL) {
14841 if (WXS_IS_TYPE_NOT_FIXED(cur->type))
14842 if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
14844 if (xmlSchemaCheckCOSSTDerivedOK(actxt,
14845 type, cur->type, subset) == 0)
14848 * It just has to be validly derived from at least one
14856 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
14860 * xmlSchemaCheckTypeDefCircularInternal:
14861 * @pctxt: the schema parser context
14862 * @ctxtType: the type definition
14863 * @ancestor: an ancestor of @ctxtType
14865 * Checks st-props-correct (2) + ct-props-correct (3).
14866 * Circular type definitions are not allowed.
14868 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
14869 * circular, 0 otherwise.
14872 xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
14873 xmlSchemaTypePtr ctxtType,
14874 xmlSchemaTypePtr ancestor)
14878 if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
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);
14888 if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
14890 * Avoid inifinite recursion on circular types not yet checked.
14894 ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
14895 ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
14896 ancestor->baseType);
14897 ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
14902 * xmlSchemaCheckTypeDefCircular:
14903 * @item: the complex/simple type definition
14904 * @ctxt: the parser context
14907 * Checks for circular type definitions.
14910 xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
14911 xmlSchemaParserCtxtPtr ctxt)
14913 if ((item == NULL) ||
14914 (item->type == XML_SCHEMA_TYPE_BASIC) ||
14915 (item->baseType == NULL))
14917 xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
14922 * Simple Type Definition Representation OK (src-simple-type) 4
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>."
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.
14935 xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
14936 xmlSchemaTypePtr ctxType,
14937 xmlSchemaTypeLinkPtr members)
14939 xmlSchemaTypeLinkPtr member;
14940 xmlSchemaTypePtr memberType;
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);
14954 if ((WXS_IS_UNION(memberType)) &&
14955 ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
14958 memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
14959 res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
14961 xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
14962 memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
14966 memberType = memberType->baseType;
14968 member = member->next;
14974 xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
14975 xmlSchemaTypePtr type)
14977 if (! WXS_IS_UNION(type))
14979 return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
14980 type->memberTypes));
14984 * xmlSchemaResolveTypeReferences:
14985 * @item: the complex/simple type definition
14986 * @ctxt: the parser context
14989 * Resolvese type definition references
14992 xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
14993 xmlSchemaParserCtxtPtr ctxt)
14995 if (typeDef == NULL)
14999 * Resolve the base type.
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);
15013 if (WXS_IS_SIMPLE(typeDef)) {
15014 if (WXS_IS_UNION(typeDef)) {
15016 * Resolve the memberTypes.
15018 xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
15020 } else if (WXS_IS_LIST(typeDef)) {
15022 * Resolve the itemType.
15024 if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
15026 typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
15027 typeDef->base, typeDef->baseNs);
15029 if ((typeDef->subtypes == NULL) ||
15030 (! WXS_IS_SIMPLE(typeDef->subtypes)))
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);
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
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))
15055 xmlSchemaQNameRefPtr ref =
15056 WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
15057 xmlSchemaModelGroupDefPtr groupDef;
15060 * URGENT TODO: Test this.
15062 WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
15064 * Resolve the MG definition reference.
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,
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;
15081 * Assign the MG definition's {model group} to the
15082 * particle's {term}.
15084 WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
15086 if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
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."
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",
15110 * xmlSchemaCheckSTPropsCorrect:
15111 * @ctxt: the schema parser context
15112 * @type: the simple type definition
15114 * Checks st-props-correct.
15116 * Returns 0 if the properties are correct,
15117 * if not, a positive error code and -1 on internal
15121 xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
15122 xmlSchemaTypePtr type)
15124 xmlSchemaTypePtr baseType = type->baseType;
15125 xmlChar *str = NULL;
15127 /* STATE: error funcs converted. */
15129 * Schema Component Constraint: Simple Type Definition Properties Correct
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.
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).
15138 if (baseType == NULL) {
15140 * TODO: Think about: "modulo the impact of Missing
15141 * Sub-components (�5.3)."
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);
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));
15157 return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15159 if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
15160 (WXS_IS_RESTRICTION(type) == 0) &&
15161 ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
15162 (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
15163 xmlSchemaPCustomErr(ctxt,
15164 XML_SCHEMAP_ST_PROPS_CORRECT_1,
15165 WXS_BASIC_CAST type, NULL,
15166 "A type, derived by list or union, must have "
15167 "the simple ur-type definition as base type, not '%s'",
15168 xmlSchemaGetComponentQName(&str, baseType));
15170 return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15173 * Variety: One of {atomic, list, union}.
15175 if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
15176 (! WXS_IS_LIST(type))) {
15177 xmlSchemaPCustomErr(ctxt,
15178 XML_SCHEMAP_ST_PROPS_CORRECT_1,
15179 WXS_BASIC_CAST type, NULL,
15180 "The variety is absent", NULL);
15181 return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15183 /* TODO: Finish this. Hmm, is this finished? */
15186 * 3 The {final} of the {base type definition} must not contain restriction.
15188 if (xmlSchemaTypeFinalContains(baseType,
15189 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15190 xmlSchemaPCustomErr(ctxt,
15191 XML_SCHEMAP_ST_PROPS_CORRECT_3,
15192 WXS_BASIC_CAST type, NULL,
15193 "The 'final' of its base type '%s' must not contain "
15195 xmlSchemaGetComponentQName(&str, baseType));
15197 return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
15201 * 2 All simple type definitions must be derived ultimately from the �simple
15202 * ur-type definition (so� circular definitions are disallowed). That is, it
15203 * must be possible to reach a built-in primitive datatype or the �simple
15204 * ur-type definition� by repeatedly following the {base type definition}.
15206 * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
15212 * xmlSchemaCheckCOSSTRestricts:
15213 * @ctxt: the schema parser context
15214 * @type: the simple type definition
15216 * Schema Component Constraint:
15217 * Derivation Valid (Restriction, Simple) (cos-st-restricts)
15219 * Checks if the given @type (simpleType) is derived validly by restriction.
15222 * Returns -1 on internal errors, 0 if the type is validly derived,
15223 * a positive error code otherwise.
15226 xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
15227 xmlSchemaTypePtr type)
15229 xmlChar *str = NULL;
15231 if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
15232 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15233 "given type is not a user-derived simpleType");
15237 if (WXS_IS_ATOMIC(type)) {
15238 xmlSchemaTypePtr primitive;
15240 * 1.1 The {base type definition} must be an atomic simple
15241 * type definition or a built-in primitive datatype.
15243 if (! WXS_IS_ATOMIC(type->baseType)) {
15244 xmlSchemaPCustomErr(pctxt,
15245 XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
15246 WXS_BASIC_CAST type, NULL,
15247 "The base type '%s' is not an atomic simple type",
15248 xmlSchemaGetComponentQName(&str, type->baseType));
15250 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
15252 /* 1.2 The {final} of the {base type definition} must not contain
15255 /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
15256 if (xmlSchemaTypeFinalContains(type->baseType,
15257 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15258 xmlSchemaPCustomErr(pctxt,
15259 XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
15260 WXS_BASIC_CAST type, NULL,
15261 "The final of its base type '%s' must not contain 'restriction'",
15262 xmlSchemaGetComponentQName(&str, type->baseType));
15264 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
15268 * 1.3.1 DF must be an allowed constraining facet for the {primitive
15269 * type definition}, as specified in the appropriate subsection of 3.2
15270 * Primitive datatypes.
15272 if (type->facets != NULL) {
15273 xmlSchemaFacetPtr facet;
15276 primitive = xmlSchemaGetPrimitiveType(type);
15277 if (primitive == NULL) {
15278 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15279 "failed to get primitive type");
15282 facet = type->facets;
15284 if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
15286 xmlSchemaPIllegalFacetAtomicErr(pctxt,
15287 XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
15288 type, primitive, facet);
15290 facet = facet->next;
15291 } while (facet != NULL);
15293 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
15296 * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
15297 * of the {base type definition} (call this BF),then the DF's {value}
15298 * must be a valid restriction of BF's {value} as defined in
15299 * [XML Schemas: Datatypes]."
15301 * NOTE (1.3.2) Facet derivation constraints are currently handled in
15302 * xmlSchemaDeriveAndValidateFacets()
15304 } else if (WXS_IS_LIST(type)) {
15305 xmlSchemaTypePtr itemType = NULL;
15307 itemType = type->subtypes;
15308 if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
15309 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15310 "failed to evaluate the item type");
15313 if (WXS_IS_TYPE_NOT_FIXED(itemType))
15314 xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
15316 * 2.1 The {item type definition} must have a {variety} of atomic or
15317 * union (in which case all the {member type definitions}
15320 if ((! WXS_IS_ATOMIC(itemType)) &&
15321 (! WXS_IS_UNION(itemType))) {
15322 xmlSchemaPCustomErr(pctxt,
15323 XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15324 WXS_BASIC_CAST type, NULL,
15325 "The item type '%s' does not have a variety of atomic or union",
15326 xmlSchemaGetComponentQName(&str, itemType));
15328 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15329 } else if (WXS_IS_UNION(itemType)) {
15330 xmlSchemaTypeLinkPtr member;
15332 member = itemType->memberTypes;
15333 while (member != NULL) {
15334 if (! WXS_IS_ATOMIC(member->type)) {
15335 xmlSchemaPCustomErr(pctxt,
15336 XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15337 WXS_BASIC_CAST type, NULL,
15338 "The item type is a union type, but the "
15339 "member type '%s' of this item type is not atomic",
15340 xmlSchemaGetComponentQName(&str, member->type));
15342 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15344 member = member->next;
15348 if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
15349 xmlSchemaFacetPtr facet;
15351 * This is the case if we have: <simpleType><list ..
15355 * 2.3.1.1 The {final} of the {item type definition} must not
15358 if (xmlSchemaTypeFinalContains(itemType,
15359 XML_SCHEMAS_TYPE_FINAL_LIST)) {
15360 xmlSchemaPCustomErr(pctxt,
15361 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
15362 WXS_BASIC_CAST type, NULL,
15363 "The final of its item type '%s' must not contain 'list'",
15364 xmlSchemaGetComponentQName(&str, itemType));
15366 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
15369 * 2.3.1.2 The {facets} must only contain the whiteSpace
15371 * OPTIMIZE TODO: the S4S already disallows any facet
15374 if (type->facets != NULL) {
15375 facet = type->facets;
15377 if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
15378 xmlSchemaPIllegalFacetListUnionErr(pctxt,
15379 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
15381 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
15383 facet = facet->next;
15384 } while (facet != NULL);
15387 * MAYBE TODO: (Hmm, not really) Datatypes states:
15388 * A �list� datatype can be �derived� from an �atomic� datatype
15389 * whose �lexical space� allows space (such as string or anyURI)or
15390 * a �union� datatype any of whose {member type definitions}'s
15391 * �lexical space� allows space.
15395 * This is the case if we have: <simpleType><restriction ...
15396 * I.e. the variety of "list" is inherited.
15400 * 2.3.2.1 The {base type definition} must have a {variety} of list.
15402 if (! WXS_IS_LIST(type->baseType)) {
15403 xmlSchemaPCustomErr(pctxt,
15404 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
15405 WXS_BASIC_CAST type, NULL,
15406 "The base type '%s' must be a list type",
15407 xmlSchemaGetComponentQName(&str, type->baseType));
15409 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
15412 * 2.3.2.2 The {final} of the {base type definition} must not
15413 * contain restriction.
15415 if (xmlSchemaTypeFinalContains(type->baseType,
15416 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15417 xmlSchemaPCustomErr(pctxt,
15418 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
15419 WXS_BASIC_CAST type, NULL,
15420 "The 'final' of the base type '%s' must not contain 'restriction'",
15421 xmlSchemaGetComponentQName(&str, type->baseType));
15423 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
15426 * 2.3.2.3 The {item type definition} must be validly derived
15427 * from the {base type definition}'s {item type definition} given
15428 * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6).
15431 xmlSchemaTypePtr baseItemType;
15433 baseItemType = type->baseType->subtypes;
15434 if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
15435 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15436 "failed to eval the item type of a base type");
15439 if ((itemType != baseItemType) &&
15440 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
15441 baseItemType, 0) != 0)) {
15442 xmlChar *strBIT = NULL, *strBT = NULL;
15443 xmlSchemaPCustomErrExt(pctxt,
15444 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
15445 WXS_BASIC_CAST type, NULL,
15446 "The item type '%s' is not validly derived from "
15447 "the item type '%s' of the base type '%s'",
15448 xmlSchemaGetComponentQName(&str, itemType),
15449 xmlSchemaGetComponentQName(&strBIT, baseItemType),
15450 xmlSchemaGetComponentQName(&strBT, type->baseType));
15453 FREE_AND_NULL(strBIT)
15454 FREE_AND_NULL(strBT)
15455 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
15459 if (type->facets != NULL) {
15460 xmlSchemaFacetPtr facet;
15463 * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
15464 * and enumeration facet components are allowed among the {facets}.
15466 facet = type->facets;
15468 switch (facet->type) {
15469 case XML_SCHEMA_FACET_LENGTH:
15470 case XML_SCHEMA_FACET_MINLENGTH:
15471 case XML_SCHEMA_FACET_MAXLENGTH:
15472 case XML_SCHEMA_FACET_WHITESPACE:
15474 * TODO: 2.5.1.2 List datatypes
15475 * The value of �whiteSpace� is fixed to the value collapse.
15477 case XML_SCHEMA_FACET_PATTERN:
15478 case XML_SCHEMA_FACET_ENUMERATION:
15481 xmlSchemaPIllegalFacetListUnionErr(pctxt,
15482 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
15485 * We could return, but it's nicer to report all
15491 facet = facet->next;
15492 } while (facet != NULL);
15494 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
15496 * SPEC (2.3.2.5) (same as 1.3.2)
15498 * NOTE (2.3.2.5) This is currently done in
15499 * xmlSchemaDeriveAndValidateFacets()
15503 } else if (WXS_IS_UNION(type)) {
15505 * 3.1 The {member type definitions} must all have {variety} of
15508 xmlSchemaTypeLinkPtr member;
15510 member = type->memberTypes;
15511 while (member != NULL) {
15512 if (WXS_IS_TYPE_NOT_FIXED(member->type))
15513 xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
15515 if ((! WXS_IS_ATOMIC(member->type)) &&
15516 (! WXS_IS_LIST(member->type))) {
15517 xmlSchemaPCustomErr(pctxt,
15518 XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
15519 WXS_BASIC_CAST type, NULL,
15520 "The member type '%s' is neither an atomic, nor a list type",
15521 xmlSchemaGetComponentQName(&str, member->type));
15523 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
15525 member = member->next;
15528 * 3.3.1 If the {base type definition} is the �simple ur-type
15531 if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
15533 * 3.3.1.1 All of the {member type definitions} must have a
15534 * {final} which does not contain union.
15536 member = type->memberTypes;
15537 while (member != NULL) {
15538 if (xmlSchemaTypeFinalContains(member->type,
15539 XML_SCHEMAS_TYPE_FINAL_UNION)) {
15540 xmlSchemaPCustomErr(pctxt,
15541 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
15542 WXS_BASIC_CAST type, NULL,
15543 "The 'final' of member type '%s' contains 'union'",
15544 xmlSchemaGetComponentQName(&str, member->type));
15546 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
15548 member = member->next;
15551 * 3.3.1.2 The {facets} must be empty.
15553 if (type->facetSet != NULL) {
15554 xmlSchemaPCustomErr(pctxt,
15555 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
15556 WXS_BASIC_CAST type, NULL,
15557 "No facets allowed", NULL);
15558 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
15562 * 3.3.2.1 The {base type definition} must have a {variety} of union.
15563 * I.e. the variety of "list" is inherited.
15565 if (! WXS_IS_UNION(type->baseType)) {
15566 xmlSchemaPCustomErr(pctxt,
15567 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
15568 WXS_BASIC_CAST type, NULL,
15569 "The base type '%s' is not a union type",
15570 xmlSchemaGetComponentQName(&str, type->baseType));
15572 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
15575 * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
15577 if (xmlSchemaTypeFinalContains(type->baseType,
15578 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15579 xmlSchemaPCustomErr(pctxt,
15580 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
15581 WXS_BASIC_CAST type, NULL,
15582 "The 'final' of its base type '%s' must not contain 'restriction'",
15583 xmlSchemaGetComponentQName(&str, type->baseType));
15585 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
15588 * 3.3.2.3 The {member type definitions}, in order, must be validly
15589 * derived from the corresponding type definitions in the {base
15590 * type definition}'s {member type definitions} given the empty set,
15591 * as defined in Type Derivation OK (Simple) (�3.14.6).
15594 xmlSchemaTypeLinkPtr baseMember;
15597 * OPTIMIZE: if the type is restricting, it has no local defined
15598 * member types and inherits the member types of the base type;
15599 * thus a check for equality can be skipped.
15602 * Even worse: I cannot see a scenario where a restricting
15603 * union simple type can have other member types as the member
15604 * types of it's base type. This check seems not necessary with
15605 * respect to the derivation process in libxml2.
15606 * But necessary if constructing types with an API.
15608 if (type->memberTypes != NULL) {
15609 member = type->memberTypes;
15610 baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
15611 if ((member == NULL) && (baseMember != NULL)) {
15612 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15613 "different number of member types in base");
15615 while (member != NULL) {
15616 if (baseMember == NULL) {
15617 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15618 "different number of member types in base");
15619 } else if ((member->type != baseMember->type) &&
15620 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
15621 member->type, baseMember->type, 0) != 0)) {
15622 xmlChar *strBMT = NULL, *strBT = NULL;
15624 xmlSchemaPCustomErrExt(pctxt,
15625 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
15626 WXS_BASIC_CAST type, NULL,
15627 "The member type %s is not validly "
15628 "derived from its corresponding member "
15629 "type %s of the base type %s",
15630 xmlSchemaGetComponentQName(&str, member->type),
15631 xmlSchemaGetComponentQName(&strBMT, baseMember->type),
15632 xmlSchemaGetComponentQName(&strBT, type->baseType));
15634 FREE_AND_NULL(strBMT)
15635 FREE_AND_NULL(strBT)
15636 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
15638 member = member->next;
15639 if (baseMember != NULL)
15640 baseMember = baseMember->next;
15645 * 3.3.2.4 Only pattern and enumeration facet components are
15646 * allowed among the {facets}.
15648 if (type->facets != NULL) {
15649 xmlSchemaFacetPtr facet;
15652 facet = type->facets;
15654 if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
15655 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
15656 xmlSchemaPIllegalFacetListUnionErr(pctxt,
15657 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
15661 facet = facet->next;
15662 } while (facet != NULL);
15664 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
15668 * SPEC (3.3.2.5) (same as 1.3.2)
15670 * NOTE (3.3.2.5) This is currently done in
15671 * xmlSchemaDeriveAndValidateFacets()
15680 * xmlSchemaCheckSRCSimpleType:
15681 * @ctxt: the schema parser context
15682 * @type: the simple type definition
15684 * Checks crc-simple-type constraints.
15686 * Returns 0 if the constraints are satisfied,
15687 * if not a positive error code and -1 on internal
15692 xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
15693 xmlSchemaTypePtr type)
15696 * src-simple-type.1 The corresponding simple type definition, if any,
15697 * must satisfy the conditions set out in Constraints on Simple Type
15698 * Definition Schema Components (�3.14.6).
15700 if (WXS_IS_RESTRICTION(type)) {
15702 * src-simple-type.2 "If the <restriction> alternative is chosen,
15703 * either it must have a base [attribute] or a <simpleType> among its
15704 * [children], but not both."
15705 * NOTE: This is checked in the parse function of <restriction>.
15710 } else if (WXS_IS_LIST(type)) {
15711 /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
15712 * an itemType [attribute] or a <simpleType> among its [children],
15715 * NOTE: This is checked in the parse function of <list>.
15717 } else if (WXS_IS_UNION(type)) {
15719 * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
15727 xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
15729 if (ctxt->vctxt == NULL) {
15730 ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
15731 if (ctxt->vctxt == NULL) {
15732 xmlSchemaPErr(ctxt, NULL,
15733 XML_SCHEMAP_INTERNAL,
15734 "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
15735 "failed to create a temp. validation context.\n",
15739 /* TODO: Pass user data. */
15740 xmlSchemaSetValidErrors(ctxt->vctxt,
15741 ctxt->error, ctxt->warning, ctxt->errCtxt);
15742 xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
15743 ctxt->serror, ctxt->errCtxt);
15749 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
15751 xmlSchemaTypePtr type,
15752 const xmlChar *value,
15753 xmlSchemaValPtr *retVal,
15759 * xmlSchemaParseCheckCOSValidDefault:
15760 * @pctxt: the schema parser context
15761 * @type: the simple type definition
15762 * @value: the default value
15763 * @node: an optional node (the holder of the value)
15765 * Schema Component Constraint: Element Default Valid (Immediate)
15766 * (cos-valid-default)
15767 * This will be used by the parser only. For the validator there's
15768 * an other version.
15770 * Returns 0 if the constraints are satisfied,
15771 * if not, a positive error code and -1 on internal
15775 xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
15777 xmlSchemaTypePtr type,
15778 const xmlChar *value,
15779 xmlSchemaValPtr *val)
15784 * cos-valid-default:
15785 * Schema Component Constraint: Element Default Valid (Immediate)
15786 * For a string to be a valid default with respect to a type
15787 * definition the appropriate case among the following must be true:
15789 if WXS_IS_COMPLEX(type) {
15793 * SPEC (2.1) "its {content type} must be a simple type definition
15795 * SPEC (2.2.2) "If the {content type} is mixed, then the {content
15796 * type}'s particle must be �emptiable� as defined by
15797 * Particle Emptiable (�3.9.6)."
15799 if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
15800 ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
15801 /* NOTE that this covers (2.2.2) as well. */
15802 xmlSchemaPCustomErr(pctxt,
15803 XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
15804 WXS_BASIC_CAST type, type->node,
15805 "For a string to be a valid default, the type definition "
15806 "must be a simple type or a complex type with mixed content "
15807 "and a particle emptiable", NULL);
15808 return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
15812 * 1 If the type definition is a simple type definition, then the string
15813 * must be �valid� with respect to that definition as defined by String
15814 * Valid (�3.14.4).
15818 * 2.2.1 If the {content type} is a simple type definition, then the
15819 * string must be �valid� with respect to that simple type definition
15820 * as defined by String Valid (�3.14.4).
15822 if (WXS_IS_SIMPLE(type))
15823 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15824 type, value, val, 1, 1, 0);
15825 else if (WXS_HAS_SIMPLE_CONTENT(type))
15826 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15827 type->contentTypeDef, value, val, 1, 1, 0);
15832 PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
15833 "calling xmlSchemaVCheckCVCSimpleType()");
15840 * xmlSchemaCheckCTPropsCorrect:
15841 * @ctxt: the schema parser context
15842 * @type: the complex type definition
15844 *.(4.6) Constraints on Complex Type Definition Schema Components
15845 * Schema Component Constraint:
15846 * Complex Type Definition Properties Correct (ct-props-correct)
15847 * STATUS: (seems) complete
15849 * Returns 0 if the constraints are satisfied, a positive
15850 * error code if not and -1 if an internal error occured.
15853 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
15854 xmlSchemaTypePtr type)
15857 * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
15859 * SPEC (1) "The values of the properties of a complex type definition must
15860 * be as described in the property tableau in The Complex Type Definition
15861 * Schema Component (�3.4.1), modulo the impact of Missing
15862 * Sub-components (�5.3)."
15864 if ((type->baseType != NULL) &&
15865 (WXS_IS_SIMPLE(type->baseType)) &&
15866 (WXS_IS_EXTENSION(type) == 0)) {
15868 * SPEC (2) "If the {base type definition} is a simple type definition,
15869 * the {derivation method} must be extension."
15871 xmlSchemaCustomErr(ACTXT_CAST pctxt,
15872 XML_SCHEMAP_SRC_CT_1,
15873 NULL, WXS_BASIC_CAST type,
15874 "If the base type is a simple type, the derivation method must be "
15875 "'extension'", NULL, NULL);
15876 return (XML_SCHEMAP_SRC_CT_1);
15879 * SPEC (3) "Circular definitions are disallowed, except for the �ur-type
15880 * definition�. That is, it must be possible to reach the �ur-type
15881 * definition by repeatedly following the {base type definition}."
15883 * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
15886 * NOTE that (4) and (5) need the following:
15887 * - attribute uses need to be already inherited (apply attr. prohibitions)
15888 * - attribute group references need to be expanded already
15889 * - simple types need to be typefixed already
15891 if (type->attrUses &&
15892 (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
15894 xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
15895 xmlSchemaAttributeUsePtr use, tmp;
15896 int i, j, hasId = 0;
15898 for (i = uses->nbItems -1; i >= 0; i--) {
15899 use = uses->items[i];
15902 * SPEC ct-props-correct
15903 * (4) "Two distinct attribute declarations in the
15904 * {attribute uses} must not have identical {name}s and
15905 * {target namespace}s."
15908 for (j = i -1; j >= 0; j--) {
15909 tmp = uses->items[j];
15910 if ((WXS_ATTRUSE_DECL_NAME(use) ==
15911 WXS_ATTRUSE_DECL_NAME(tmp)) &&
15912 (WXS_ATTRUSE_DECL_TNS(use) ==
15913 WXS_ATTRUSE_DECL_TNS(tmp)))
15915 xmlChar *str = NULL;
15917 xmlSchemaCustomErr(ACTXT_CAST pctxt,
15918 XML_SCHEMAP_AG_PROPS_CORRECT,
15919 NULL, WXS_BASIC_CAST type,
15921 xmlSchemaGetComponentDesignation(&str, use),
15923 FREE_AND_NULL(str);
15925 * Remove the duplicate.
15927 if (xmlSchemaItemListRemove(uses, i) == -1)
15934 * SPEC ct-props-correct
15935 * (5) "Two distinct attribute declarations in the
15936 * {attribute uses} must not have {type definition}s which
15937 * are or are derived from ID."
15939 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
15940 if (xmlSchemaIsDerivedFromBuiltInType(
15941 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
15944 xmlChar *str = NULL;
15946 xmlSchemaCustomErr(ACTXT_CAST pctxt,
15947 XML_SCHEMAP_AG_PROPS_CORRECT,
15948 NULL, WXS_BASIC_CAST type,
15949 "There must not exist more than one attribute "
15950 "declaration of type 'xs:ID' "
15951 "(or derived from 'xs:ID'). The %s violates this "
15953 xmlSchemaGetComponentDesignation(&str, use),
15955 FREE_AND_NULL(str);
15956 if (xmlSchemaItemListRemove(uses, i) == -1)
15972 xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
15973 xmlSchemaTypePtr typeB)
15976 * TODO: This should implement component-identity
15979 if ((typeA == NULL) || (typeB == NULL))
15981 return (typeA == typeB);
15985 * xmlSchemaCheckCOSCTDerivedOK:
15986 * @ctxt: the schema parser context
15987 * @type: the to-be derived complex type definition
15988 * @baseType: the base complex type definition
15989 * @set: the given set
15991 * Schema Component Constraint:
15992 * Type Derivation OK (Complex) (cos-ct-derived-ok)
15994 * STATUS: completed
15996 * Returns 0 if the constraints are satisfied, or 1
16000 xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16001 xmlSchemaTypePtr type,
16002 xmlSchemaTypePtr baseType,
16005 int equal = xmlSchemaAreEqualTypes(type, baseType);
16006 /* TODO: Error codes. */
16008 * SPEC "For a complex type definition (call it D, for derived)
16009 * to be validly derived from a type definition (call this
16010 * B, for base) given a subset of {extension, restriction}
16011 * all of the following must be true:"
16015 * SPEC (1) "If B and D are not the same type definition, then the
16016 * {derivation method} of D must not be in the subset."
16018 if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
16019 ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
16023 * SPEC (2.1) "B and D must be the same type definition."
16028 * SPEC (2.2) "B must be D's {base type definition}."
16030 if (type->baseType == baseType)
16033 * SPEC (2.3.1) "D's {base type definition} must not be the �ur-type
16036 if (WXS_IS_ANYTYPE(type->baseType))
16039 if (WXS_IS_COMPLEX(type->baseType)) {
16041 * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
16042 * must be validly derived from B given the subset as defined by this
16045 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
16049 * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
16050 * must be validly derived from B given the subset as defined in Type
16051 * Derivation OK (Simple) (�3.14.6).
16053 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
16059 * xmlSchemaCheckCOSDerivedOK:
16060 * @type: the derived simple type definition
16061 * @baseType: the base type definition
16064 * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
16066 * Checks wheter @type can be validly derived from @baseType.
16068 * Returns 0 on success, an positive error code otherwise.
16071 xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16072 xmlSchemaTypePtr type,
16073 xmlSchemaTypePtr baseType,
16076 if (WXS_IS_SIMPLE(type))
16077 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
16079 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
16083 * xmlSchemaCheckCOSCTExtends:
16084 * @ctxt: the schema parser context
16085 * @type: the complex type definition
16087 * (3.4.6) Constraints on Complex Type Definition Schema Components
16088 * Schema Component Constraint:
16089 * Derivation Valid (Extension) (cos-ct-extends)
16094 * (1.4.3.2.2.2) "Particle Valid (Extension)"
16096 * Returns 0 if the constraints are satisfied, a positive
16097 * error code if not and -1 if an internal error occured.
16100 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
16101 xmlSchemaTypePtr type)
16103 xmlSchemaTypePtr base = type->baseType;
16105 * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
16106 * temporarily only.
16109 * SPEC (1) "If the {base type definition} is a complex type definition,
16110 * then all of the following must be true:"
16112 if (WXS_IS_COMPLEX(base)) {
16114 * SPEC (1.1) "The {final} of the {base type definition} must not
16115 * contain extension."
16117 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16118 xmlSchemaPCustomErr(ctxt,
16119 XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16120 WXS_BASIC_CAST type, NULL,
16121 "The 'final' of the base type definition "
16122 "contains 'extension'", NULL);
16123 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16127 * ATTENTION: The constrains (1.2) and (1.3) are not applied,
16128 * since they are automatically satisfied through the
16129 * inheriting mechanism.
16130 * Note that even if redefining components, the inheriting mechanism
16135 * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
16137 * of the complex type definition itself, that is, for every attribute
16138 * use in the {attribute uses} of the {base type definition}, there
16139 * must be an attribute use in the {attribute uses} of the complex
16140 * type definition itself whose {attribute declaration} has the same
16141 * {name}, {target namespace} and {type definition} as its attribute
16144 if (base->attrUses != NULL) {
16146 xmlSchemaAttributeUsePtr use, buse;
16148 for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
16149 buse = (WXS_LIST_CAST base->attrUses)->items[i];
16151 if (type->attrUses != NULL) {
16152 use = (WXS_LIST_CAST type->attrUses)->items[j];
16153 for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
16155 if ((WXS_ATTRUSE_DECL_NAME(use) ==
16156 WXS_ATTRUSE_DECL_NAME(buse)) &&
16157 (WXS_ATTRUSE_DECL_TNS(use) ==
16158 WXS_ATTRUSE_DECL_TNS(buse)) &&
16159 (WXS_ATTRUSE_TYPEDEF(use) ==
16160 WXS_ATTRUSE_TYPEDEF(buse))
16168 xmlChar *str = NULL;
16170 xmlSchemaCustomErr(ACTXT_CAST ctxt,
16171 XML_SCHEMAP_COS_CT_EXTENDS_1_2,
16172 NULL, WXS_BASIC_CAST type,
16174 * TODO: The report does not indicate that also the
16175 * type needs to be the same.
16177 "This type is missing a matching correspondent "
16178 "for its {base type}'s %s in its {attribute uses}",
16179 xmlSchemaGetComponentDesignation(&str,
16187 * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
16188 * definition must also have one, and the base type definition's
16189 * {attribute wildcard}'s {namespace constraint} must be a subset
16190 * of the complex type definition's {attribute wildcard}'s {namespace
16191 * constraint}, as defined by Wildcard Subset (�3.10.6)."
16195 * MAYBE TODO: Enable if ever needed. But this will be needed only
16196 * if created the type via a schema construction API.
16198 if (base->attributeWildcard != NULL) {
16199 if (type->attributeWilcard == NULL) {
16200 xmlChar *str = NULL;
16202 xmlSchemaCustomErr(ACTXT_CAST pctxt,
16203 XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16205 "The base %s has an attribute wildcard, "
16206 "but this type is missing an attribute wildcard",
16207 xmlSchemaGetComponentDesignation(&str, base));
16210 } else if (xmlSchemaCheckCOSNSSubset(
16211 base->attributeWildcard, type->attributeWildcard))
16213 xmlChar *str = NULL;
16215 xmlSchemaCustomErr(ACTXT_CAST pctxt,
16216 XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16218 "The attribute wildcard is not a valid "
16219 "superset of the one in the base %s",
16220 xmlSchemaGetComponentDesignation(&str, base));
16226 * SPEC (1.4) "One of the following must be true:"
16228 if ((type->contentTypeDef != NULL) &&
16229 (type->contentTypeDef == base->contentTypeDef)) {
16231 * SPEC (1.4.1) "The {content type} of the {base type definition}
16232 * and the {content type} of the complex type definition itself
16233 * must be the same simple type definition"
16236 } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
16237 (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
16239 * SPEC (1.4.2) "The {content type} of both the {base type
16240 * definition} and the complex type definition itself must
16246 * SPEC (1.4.3) "All of the following must be true:"
16248 if (type->subtypes == NULL) {
16250 * SPEC 1.4.3.1 The {content type} of the complex type
16251 * definition itself must specify a particle.
16253 xmlSchemaPCustomErr(ctxt,
16254 XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16255 WXS_BASIC_CAST type, NULL,
16256 "The content type must specify a particle", NULL);
16257 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16260 * SPEC (1.4.3.2) "One of the following must be true:"
16262 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16264 * SPEC (1.4.3.2.1) "The {content type} of the {base type
16265 * definition} must be empty.
16270 * SPEC (1.4.3.2.2) "All of the following must be true:"
16272 if ((type->contentType != base->contentType) ||
16273 ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
16274 (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
16276 * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
16277 * or both must be element-only."
16279 xmlSchemaPCustomErr(ctxt,
16280 XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16281 WXS_BASIC_CAST type, NULL,
16282 "The content type of both, the type and its base "
16283 "type, must either 'mixed' or 'element-only'", NULL);
16284 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16287 * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
16288 * complex type definition must be a �valid extension�
16289 * of the {base type definition}'s particle, as defined
16290 * in Particle Valid (Extension) (�3.9.6)."
16292 * NOTE that we won't check "Particle Valid (Extension)",
16293 * since it is ensured by the derivation process in
16294 * xmlSchemaTypeFixup(). We need to implement this when heading
16295 * for a construction API
16296 * TODO: !! This is needed to be checked if redefining a type !!
16300 * URGENT TODO (1.5)
16305 * SPEC (2) "If the {base type definition} is a simple type definition,
16306 * then all of the following must be true:"
16308 if (type->contentTypeDef != base) {
16310 * SPEC (2.1) "The {content type} must be the same simple type
16313 xmlSchemaPCustomErr(ctxt,
16314 XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16315 WXS_BASIC_CAST type, NULL,
16316 "The content type must be the simple base type", NULL);
16317 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16319 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16321 * SPEC (2.2) "The {final} of the {base type definition} must not
16322 * contain extension"
16323 * NOTE that this is the same as (1.1).
16325 xmlSchemaPCustomErr(ctxt,
16326 XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16327 WXS_BASIC_CAST type, NULL,
16328 "The 'final' of the base type definition "
16329 "contains 'extension'", NULL);
16330 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16337 * xmlSchemaCheckDerivationOKRestriction:
16338 * @ctxt: the schema parser context
16339 * @type: the complex type definition
16341 * (3.4.6) Constraints on Complex Type Definition Schema Components
16342 * Schema Component Constraint:
16343 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
16350 * In XML Schema 1.1 this will be:
16351 * Validation Rule: Checking complex type subsumption
16353 * Returns 0 if the constraints are satisfied, a positive
16354 * error code if not and -1 if an internal error occured.
16357 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
16358 xmlSchemaTypePtr type)
16360 xmlSchemaTypePtr base;
16363 * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
16364 * temporarily only.
16366 base = type->baseType;
16367 if (! WXS_IS_COMPLEX(base)) {
16368 xmlSchemaCustomErr(ACTXT_CAST ctxt,
16369 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16370 type->node, WXS_BASIC_CAST type,
16371 "The base type must be a complex type", NULL, NULL);
16374 if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
16376 * SPEC (1) "The {base type definition} must be a complex type
16377 * definition whose {final} does not contain restriction."
16379 xmlSchemaCustomErr(ACTXT_CAST ctxt,
16380 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16381 type->node, WXS_BASIC_CAST type,
16382 "The 'final' of the base type definition "
16383 "contains 'restriction'", NULL, NULL);
16384 return (ctxt->err);
16387 * SPEC (2), (3) and (4)
16388 * Those are handled in a separate function, since the
16389 * same constraints are needed for redefinition of
16390 * attribute groups as well.
16392 if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
16393 XML_SCHEMA_ACTION_DERIVE,
16394 WXS_BASIC_CAST type, WXS_BASIC_CAST base,
16395 type->attrUses, base->attrUses,
16396 type->attributeWildcard,
16397 base->attributeWildcard) == -1)
16402 * SPEC (5) "One of the following must be true:"
16404 if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
16406 * SPEC (5.1) "The {base type definition} must be the
16407 * �ur-type definition�."
16410 } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16411 (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16413 * SPEC (5.2.1) "The {content type} of the complex type definition
16414 * must be a simple type definition"
16416 * SPEC (5.2.2) "One of the following must be true:"
16418 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16419 (base->contentType == XML_SCHEMA_CONTENT_BASIC))
16423 * SPEC (5.2.2.1) "The {content type} of the {base type
16424 * definition} must be a simple type definition from which
16425 * the {content type} is validly derived given the empty
16426 * set as defined in Type Derivation OK (Simple) (�3.14.6)."
16428 * ATTENTION TODO: This seems not needed if the type implicitely
16429 * derived from the base type.
16432 err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
16433 type->contentTypeDef, base->contentTypeDef, 0);
16435 xmlChar *strA = NULL, *strB = NULL;
16439 xmlSchemaCustomErr(ACTXT_CAST ctxt,
16440 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16441 NULL, WXS_BASIC_CAST type,
16442 "The {content type} %s is not validly derived from the "
16443 "base type's {content type} %s",
16444 xmlSchemaGetComponentDesignation(&strA,
16445 type->contentTypeDef),
16446 xmlSchemaGetComponentDesignation(&strB,
16447 base->contentTypeDef));
16448 FREE_AND_NULL(strA);
16449 FREE_AND_NULL(strB);
16452 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16453 (xmlSchemaIsParticleEmptiable(
16454 (xmlSchemaParticlePtr) base->subtypes))) {
16456 * SPEC (5.2.2.2) "The {base type definition} must be mixed
16457 * and have a particle which is �emptiable� as defined in
16458 * Particle Emptiable (�3.9.6)."
16462 xmlSchemaPCustomErr(ctxt,
16463 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16464 WXS_BASIC_CAST type, NULL,
16465 "The content type of the base type must be either "
16466 "a simple type or 'mixed' and an emptiable particle", NULL);
16467 return (ctxt->err);
16469 } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16471 * SPEC (5.3.1) "The {content type} of the complex type itself must
16474 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16476 * SPEC (5.3.2.1) "The {content type} of the {base type
16477 * definition} must also be empty."
16480 } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16481 (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
16482 xmlSchemaIsParticleEmptiable(
16483 (xmlSchemaParticlePtr) base->subtypes)) {
16485 * SPEC (5.3.2.2) "The {content type} of the {base type
16486 * definition} must be elementOnly or mixed and have a particle
16487 * which is �emptiable� as defined in Particle Emptiable (�3.9.6)."
16491 xmlSchemaPCustomErr(ctxt,
16492 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16493 WXS_BASIC_CAST type, NULL,
16494 "The content type of the base type must be either "
16495 "empty or 'mixed' (or 'elements-only') and an emptiable "
16497 return (ctxt->err);
16499 } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16500 WXS_HAS_MIXED_CONTENT(type)) {
16502 * SPEC (5.4.1.1) "The {content type} of the complex type definition
16503 * itself must be element-only"
16505 if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
16507 * SPEC (5.4.1.2) "The {content type} of the complex type
16508 * definition itself and of the {base type definition} must be
16511 xmlSchemaPCustomErr(ctxt,
16512 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16513 WXS_BASIC_CAST type, NULL,
16514 "If the content type is 'mixed', then the content type of the "
16515 "base type must also be 'mixed'", NULL);
16516 return (ctxt->err);
16519 * SPEC (5.4.2) "The particle of the complex type definition itself
16520 * must be a �valid restriction� of the particle of the {content
16521 * type} of the {base type definition} as defined in Particle Valid
16522 * (Restriction) (�3.9.6).
16524 * URGENT TODO: (5.4.2)
16527 xmlSchemaPCustomErr(ctxt,
16528 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16529 WXS_BASIC_CAST type, NULL,
16530 "The type is not a valid restriction of its base type", NULL);
16531 return (ctxt->err);
16537 * xmlSchemaCheckCTComponent:
16538 * @ctxt: the schema parser context
16539 * @type: the complex type definition
16541 * (3.4.6) Constraints on Complex Type Definition Schema Components
16543 * Returns 0 if the constraints are satisfied, a positive
16544 * error code if not and -1 if an internal error occured.
16547 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
16548 xmlSchemaTypePtr type)
16552 * Complex Type Definition Properties Correct
16554 ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
16557 if (WXS_IS_EXTENSION(type))
16558 ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
16560 ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
16565 * xmlSchemaCheckSRCCT:
16566 * @ctxt: the schema parser context
16567 * @type: the complex type definition
16569 * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
16570 * Schema Representation Constraint:
16571 * Complex Type Definition Representation OK (src-ct)
16573 * Returns 0 if the constraints are satisfied, a positive
16574 * error code if not and -1 if an internal error occured.
16577 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
16578 xmlSchemaTypePtr type)
16580 xmlSchemaTypePtr base;
16584 * TODO: Adjust the error codes here, as I used
16585 * XML_SCHEMAP_SRC_CT_1 only yet.
16587 base = type->baseType;
16588 if (! WXS_HAS_SIMPLE_CONTENT(type)) {
16590 * 1 If the <complexContent> alternative is chosen, the type definition
16591 * �resolved� to by the �actual value� of the base [attribute]
16592 * must be a complex type definition;
16594 if (! WXS_IS_COMPLEX(base)) {
16595 xmlChar *str = NULL;
16596 xmlSchemaPCustomErr(ctxt,
16597 XML_SCHEMAP_SRC_CT_1,
16598 WXS_BASIC_CAST type, type->node,
16599 "If using <complexContent>, the base type is expected to be "
16600 "a complex type. The base type '%s' is a simple type",
16601 xmlSchemaFormatQName(&str, base->targetNamespace,
16604 return (XML_SCHEMAP_SRC_CT_1);
16609 * 2 If the <simpleContent> alternative is chosen, all of the
16610 * following must be true:
16611 * 2.1 The type definition �resolved� to by the �actual value� of the
16612 * base [attribute] must be one of the following:
16614 if (WXS_IS_SIMPLE(base)) {
16615 if (WXS_IS_EXTENSION(type) == 0) {
16616 xmlChar *str = NULL;
16618 * 2.1.3 only if the <extension> alternative is also
16619 * chosen, a simple type definition.
16621 /* TODO: Change error code to ..._SRC_CT_2_1_3. */
16622 xmlSchemaPCustomErr(ctxt,
16623 XML_SCHEMAP_SRC_CT_1,
16624 WXS_BASIC_CAST type, NULL,
16625 "If using <simpleContent> and <restriction>, the base "
16626 "type must be a complex type. The base type '%s' is "
16628 xmlSchemaFormatQName(&str, base->targetNamespace,
16631 return (XML_SCHEMAP_SRC_CT_1);
16634 /* Base type is a complex type. */
16635 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16636 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16638 * 2.1.1 a complex type definition whose {content type} is a
16639 * simple type definition;
16642 if (base->contentTypeDef == NULL) {
16643 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
16644 WXS_BASIC_CAST type, NULL,
16645 "Internal error: xmlSchemaCheckSRCCT, "
16646 "'%s', base type has no content type",
16650 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16651 (WXS_IS_RESTRICTION(type))) {
16654 * 2.1.2 only if the <restriction> alternative is also
16655 * chosen, a complex type definition whose {content type}
16656 * is mixed and a particle emptiable.
16658 if (! xmlSchemaIsParticleEmptiable(
16659 (xmlSchemaParticlePtr) base->subtypes)) {
16660 ret = XML_SCHEMAP_SRC_CT_1;
16663 * Attention: at this point the <simpleType> child is in
16664 * ->contentTypeDef (put there during parsing).
16666 if (type->contentTypeDef == NULL) {
16667 xmlChar *str = NULL;
16669 * 2.2 If clause 2.1.2 above is satisfied, then there
16670 * must be a <simpleType> among the [children] of
16673 /* TODO: Change error code to ..._SRC_CT_2_2. */
16674 xmlSchemaPCustomErr(ctxt,
16675 XML_SCHEMAP_SRC_CT_1,
16676 WXS_BASIC_CAST type, NULL,
16677 "A <simpleType> is expected among the children "
16678 "of <restriction>, if <simpleContent> is used and "
16679 "the base type '%s' is a complex type",
16680 xmlSchemaFormatQName(&str, base->targetNamespace,
16683 return (XML_SCHEMAP_SRC_CT_1);
16686 ret = XML_SCHEMAP_SRC_CT_1;
16690 xmlChar *str = NULL;
16691 if (WXS_IS_RESTRICTION(type)) {
16692 xmlSchemaPCustomErr(ctxt,
16693 XML_SCHEMAP_SRC_CT_1,
16694 WXS_BASIC_CAST type, NULL,
16695 "If <simpleContent> and <restriction> is used, the "
16696 "base type must be a simple type or a complex type with "
16697 "mixed content and particle emptiable. The base type "
16698 "'%s' is none of those",
16699 xmlSchemaFormatQName(&str, base->targetNamespace,
16702 xmlSchemaPCustomErr(ctxt,
16703 XML_SCHEMAP_SRC_CT_1,
16704 WXS_BASIC_CAST type, NULL,
16705 "If <simpleContent> and <extension> is used, the "
16706 "base type must be a simple type. The base type '%s' "
16707 "is a complex type",
16708 xmlSchemaFormatQName(&str, base->targetNamespace,
16715 * SPEC (3) "The corresponding complex type definition component must
16716 * satisfy the conditions set out in Constraints on Complex Type
16717 * Definition Schema Components (�3.4.6);"
16718 * NOTE (3) will be done in xmlSchemaTypeFixup().
16721 * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
16722 * above for {attribute wildcard} is satisfied, the intensional
16723 * intersection must be expressible, as defined in Attribute Wildcard
16724 * Intersection (�3.10.6).
16725 * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
16730 #ifdef ENABLE_PARTICLE_RESTRICTION
16732 * xmlSchemaCheckParticleRangeOK:
16733 * @ctxt: the schema parser context
16734 * @type: the complex type definition
16736 * (3.9.6) Constraints on Particle Schema Components
16737 * Schema Component Constraint:
16738 * Occurrence Range OK (range-ok)
16742 * Returns 0 if the constraints are satisfied, a positive
16743 * error code if not and -1 if an internal error occured.
16746 xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
16747 int bmin, int bmax)
16751 if ((bmax != UNBOUNDED) &&
16758 * xmlSchemaCheckRCaseNameAndTypeOK:
16759 * @ctxt: the schema parser context
16760 * @r: the restricting element declaration particle
16761 * @b: the base element declaration particle
16763 * (3.9.6) Constraints on Particle Schema Components
16764 * Schema Component Constraint:
16765 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
16766 * (rcase-NameAndTypeOK)
16772 * Returns 0 if the constraints are satisfied, a positive
16773 * error code if not and -1 if an internal error occured.
16776 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
16777 xmlSchemaParticlePtr r,
16778 xmlSchemaParticlePtr b)
16780 xmlSchemaElementPtr elemR, elemB;
16782 /* TODO: Error codes (rcase-NameAndTypeOK). */
16783 elemR = (xmlSchemaElementPtr) r->children;
16784 elemB = (xmlSchemaElementPtr) b->children;
16786 * SPEC (1) "The declarations' {name}s and {target namespace}s are
16789 if ((elemR != elemB) &&
16790 ((! xmlStrEqual(elemR->name, elemB->name)) ||
16791 (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
16794 * SPEC (2) "R's occurrence range is a valid restriction of B's
16795 * occurrence range as defined by Occurrence Range OK (�3.9.6)."
16797 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16798 b->minOccurs, b->maxOccurs) != 0)
16801 * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
16802 * {scope} are global."
16804 if (elemR == elemB)
16807 * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
16809 if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
16810 (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
16813 * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
16814 * or is not fixed, or R's declaration's {value constraint} is fixed
16815 * with the same value."
16817 if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
16818 ((elemR->value == NULL) ||
16819 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
16820 /* TODO: Equality of the initial value or normalized or canonical? */
16821 (! xmlStrEqual(elemR->value, elemB->value))))
16824 * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
16825 * definitions} is a subset of B's declaration's {identity-constraint
16826 * definitions}, if any."
16828 if (elemB->idcs != NULL) {
16832 * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
16833 * superset of B's declaration's {disallowed substitutions}."
16835 if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
16836 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
16837 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
16838 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
16839 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
16840 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
16843 * SPEC (3.2.5) "R's {type definition} is validly derived given
16844 * {extension, list, union} from B's {type definition}"
16846 * BADSPEC TODO: What's the point of adding "list" and "union" to the
16847 * set, if the corresponding constraints handle "restriction" and
16848 * "extension" only?
16854 set |= SUBSET_EXTENSION;
16855 set |= SUBSET_LIST;
16856 set |= SUBSET_UNION;
16857 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
16858 elemB->subtypes, set) != 0)
16865 * xmlSchemaCheckRCaseNSCompat:
16866 * @ctxt: the schema parser context
16867 * @r: the restricting element declaration particle
16868 * @b: the base wildcard particle
16870 * (3.9.6) Constraints on Particle Schema Components
16871 * Schema Component Constraint:
16872 * Particle Derivation OK (Elt:Any -- NSCompat)
16877 * Returns 0 if the constraints are satisfied, a positive
16878 * error code if not and -1 if an internal error occured.
16881 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
16882 xmlSchemaParticlePtr r,
16883 xmlSchemaParticlePtr b)
16885 /* TODO:Error codes (rcase-NSCompat). */
16887 * SPEC "For an element declaration particle to be a �valid restriction�
16888 * of a wildcard particle all of the following must be true:"
16890 * SPEC (1) "The element declaration's {target namespace} is �valid�
16891 * with respect to the wildcard's {namespace constraint} as defined by
16892 * Wildcard allows Namespace Name (�3.10.4)."
16894 if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
16895 ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
16898 * SPEC (2) "R's occurrence range is a valid restriction of B's
16899 * occurrence range as defined by Occurrence Range OK (�3.9.6)."
16901 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16902 b->minOccurs, b->maxOccurs) != 0)
16909 * xmlSchemaCheckRCaseRecurseAsIfGroup:
16910 * @ctxt: the schema parser context
16911 * @r: the restricting element declaration particle
16912 * @b: the base model group particle
16914 * (3.9.6) Constraints on Particle Schema Components
16915 * Schema Component Constraint:
16916 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
16917 * (rcase-RecurseAsIfGroup)
16921 * Returns 0 if the constraints are satisfied, a positive
16922 * error code if not and -1 if an internal error occured.
16925 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
16926 xmlSchemaParticlePtr r,
16927 xmlSchemaParticlePtr b)
16929 /* TODO: Error codes (rcase-RecurseAsIfGroup). */
16935 * xmlSchemaCheckRCaseNSSubset:
16936 * @ctxt: the schema parser context
16937 * @r: the restricting wildcard particle
16938 * @b: the base wildcard particle
16940 * (3.9.6) Constraints on Particle Schema Components
16941 * Schema Component Constraint:
16942 * Particle Derivation OK (Any:Any -- NSSubset)
16947 * Returns 0 if the constraints are satisfied, a positive
16948 * error code if not and -1 if an internal error occured.
16951 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
16952 xmlSchemaParticlePtr r,
16953 xmlSchemaParticlePtr b,
16956 /* TODO: Error codes (rcase-NSSubset). */
16958 * SPEC (1) "R's occurrence range is a valid restriction of B's
16959 * occurrence range as defined by Occurrence Range OK (�3.9.6)."
16961 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16962 b->minOccurs, b->maxOccurs))
16965 * SPEC (2) "R's {namespace constraint} must be an intensional subset
16966 * of B's {namespace constraint} as defined by Wildcard Subset (�3.10.6)."
16968 if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
16969 (xmlSchemaWildcardPtr) b->children))
16972 * SPEC (3) "Unless B is the content model wildcard of the �ur-type
16973 * definition�, R's {process contents} must be identical to or stronger
16974 * than B's {process contents}, where strict is stronger than lax is
16975 * stronger than skip."
16977 if (! isAnyTypeBase) {
16978 if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
16979 ((xmlSchemaWildcardPtr) b->children)->processContents)
16987 * xmlSchemaCheckCOSParticleRestrict:
16988 * @ctxt: the schema parser context
16989 * @type: the complex type definition
16991 * (3.9.6) Constraints on Particle Schema Components
16992 * Schema Component Constraint:
16993 * Particle Valid (Restriction) (cos-particle-restrict)
16997 * Returns 0 if the constraints are satisfied, a positive
16998 * error code if not and -1 if an internal error occured.
17001 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
17002 xmlSchemaParticlePtr r,
17003 xmlSchemaParticlePtr b)
17007 /*part = WXS_TYPE_PARTICLE(type);
17008 basePart = WXS_TYPE_PARTICLE(base);
17014 * SPEC (1) "They are the same particle."
17025 * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
17026 * @ctxt: the schema parser context
17027 * @r: the model group particle
17028 * @b: the base wildcard particle
17030 * (3.9.6) Constraints on Particle Schema Components
17031 * Schema Component Constraint:
17032 * Particle Derivation OK (All/Choice/Sequence:Any --
17033 * NSRecurseCheckCardinality)
17034 * (rcase-NSRecurseCheckCardinality)
17036 * STATUS: TODO: subst-groups
17038 * Returns 0 if the constraints are satisfied, a positive
17039 * error code if not and -1 if an internal error occured.
17042 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
17043 xmlSchemaParticlePtr r,
17044 xmlSchemaParticlePtr b)
17046 xmlSchemaParticlePtr part;
17047 /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
17048 if ((r->children == NULL) || (r->children->children == NULL))
17051 * SPEC "For a group particle to be a �valid restriction� of a
17052 * wildcard particle..."
17054 * SPEC (1) "Every member of the {particles} of the group is a �valid
17055 * restriction� of the wildcard as defined by
17056 * Particle Valid (Restriction) (�3.9.6)."
17058 part = (xmlSchemaParticlePtr) r->children->children;
17060 if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
17062 part = (xmlSchemaParticlePtr) part->next;
17063 } while (part != NULL);
17065 * SPEC (2) "The effective total range of the group [...] is a
17066 * valid restriction of B's occurrence range as defined by
17067 * Occurrence Range OK (�3.9.6)."
17069 if (xmlSchemaCheckParticleRangeOK(
17070 xmlSchemaGetParticleTotalRangeMin(r),
17071 xmlSchemaGetParticleTotalRangeMax(r),
17072 b->minOccurs, b->maxOccurs) != 0)
17079 * xmlSchemaCheckRCaseRecurse:
17080 * @ctxt: the schema parser context
17081 * @r: the <all> or <sequence> model group particle
17082 * @b: the base <all> or <sequence> model group particle
17084 * (3.9.6) Constraints on Particle Schema Components
17085 * Schema Component Constraint:
17086 * Particle Derivation OK (All:All,Sequence:Sequence --
17091 * TODO: subst-groups
17093 * Returns 0 if the constraints are satisfied, a positive
17094 * error code if not and -1 if an internal error occured.
17097 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
17098 xmlSchemaParticlePtr r,
17099 xmlSchemaParticlePtr b)
17101 /* xmlSchemaParticlePtr part; */
17102 /* TODO: Error codes (rcase-Recurse). */
17103 if ((r->children == NULL) || (b->children == NULL) ||
17104 (r->children->type != b->children->type))
17107 * SPEC "For an all or sequence group particle to be a �valid
17108 * restriction� of another group particle with the same {compositor}..."
17110 * SPEC (1) "R's occurrence range is a valid restriction of B's
17111 * occurrence range as defined by Occurrence Range OK (�3.9.6)."
17113 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17114 b->minOccurs, b->maxOccurs))
17123 #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
17124 xmlSchemaPCustomErrExt(pctxt, \
17125 XML_SCHEMAP_INVALID_FACET_VALUE, \
17126 WXS_BASIC_CAST fac1, fac1->node, \
17127 "It is an error for both '%s' and '%s' to be specified on the "\
17128 "same type definition", \
17129 BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
17130 BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
17132 #define FACET_RESTR_ERR(fac1, msg) \
17133 xmlSchemaPCustomErr(pctxt, \
17134 XML_SCHEMAP_INVALID_FACET_VALUE, \
17135 WXS_BASIC_CAST fac1, fac1->node, \
17138 #define FACET_RESTR_FIXED_ERR(fac) \
17139 xmlSchemaPCustomErr(pctxt, \
17140 XML_SCHEMAP_INVALID_FACET_VALUE, \
17141 WXS_BASIC_CAST fac, fac->node, \
17142 "The base type's facet is 'fixed', thus the value must not " \
17146 xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
17147 xmlSchemaFacetPtr facet1,
17148 xmlSchemaFacetPtr facet2,
17153 xmlChar *msg = NULL;
17155 msg = xmlStrdup(BAD_CAST "'");
17156 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
17157 msg = xmlStrcat(msg, BAD_CAST "' has to be");
17158 if (lessGreater == 0)
17159 msg = xmlStrcat(msg, BAD_CAST " equal to");
17160 if (lessGreater == 1)
17161 msg = xmlStrcat(msg, BAD_CAST " greater than");
17163 msg = xmlStrcat(msg, BAD_CAST " less than");
17166 msg = xmlStrcat(msg, BAD_CAST " or equal to");
17167 msg = xmlStrcat(msg, BAD_CAST " '");
17168 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
17170 msg = xmlStrcat(msg, BAD_CAST "' of the base type");
17172 msg = xmlStrcat(msg, BAD_CAST "'");
17174 xmlSchemaPCustomErr(pctxt,
17175 XML_SCHEMAP_INVALID_FACET_VALUE,
17176 WXS_BASIC_CAST facet1, NULL,
17177 (const char *) msg, NULL);
17184 * xmlSchemaDeriveAndValidateFacets:
17186 * Schema Component Constraint: Simple Type Restriction (Facets)
17187 * (st-restrict-facets)
17190 xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
17191 xmlSchemaTypePtr type)
17193 xmlSchemaTypePtr base = type->baseType;
17194 xmlSchemaFacetLinkPtr link, cur, last = NULL;
17195 xmlSchemaFacetPtr facet, bfacet,
17196 flength = NULL, ftotdig = NULL, ffracdig = NULL,
17197 fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
17198 fmininc = NULL, fmaxinc = NULL,
17199 fminexc = NULL, fmaxexc = NULL,
17200 bflength = NULL, bftotdig = NULL, bffracdig = NULL,
17201 bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
17202 bfmininc = NULL, bfmaxinc = NULL,
17203 bfminexc = NULL, bfmaxexc = NULL;
17204 int res; /* err = 0, fixedErr; */
17207 * SPEC st-restrict-facets 1:
17208 * "The {variety} of R is the same as that of B."
17211 * SPEC st-restrict-facets 2:
17212 * "If {variety} is atomic, the {primitive type definition}
17213 * of R is the same as that of B."
17215 * NOTE: we leave 1 & 2 out for now, since this will be
17216 * satisfied by the derivation process.
17217 * CONSTRUCTION TODO: Maybe needed if using a construction API.
17220 * SPEC st-restrict-facets 3:
17221 * "The {facets} of R are the union of S and the {facets}
17222 * of B, eliminating duplicates. To eliminate duplicates,
17223 * when a facet of the same kind occurs in both S and the
17224 * {facets} of B, the one in the {facets} of B is not
17225 * included, with the exception of enumeration and pattern
17226 * facets, for which multiple occurrences with distinct values
17230 if ((type->facetSet == NULL) && (base->facetSet == NULL))
17233 last = type->facetSet;
17235 while (last->next != NULL)
17238 for (cur = type->facetSet; cur != NULL; cur = cur->next) {
17239 facet = cur->facet;
17240 switch (facet->type) {
17241 case XML_SCHEMA_FACET_LENGTH:
17242 flength = facet; break;
17243 case XML_SCHEMA_FACET_MINLENGTH:
17244 fminlen = facet; break;
17245 case XML_SCHEMA_FACET_MININCLUSIVE:
17246 fmininc = facet; break;
17247 case XML_SCHEMA_FACET_MINEXCLUSIVE:
17248 fminexc = facet; break;
17249 case XML_SCHEMA_FACET_MAXLENGTH:
17250 fmaxlen = facet; break;
17251 case XML_SCHEMA_FACET_MAXINCLUSIVE:
17252 fmaxinc = facet; break;
17253 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17254 fmaxexc = facet; break;
17255 case XML_SCHEMA_FACET_TOTALDIGITS:
17256 ftotdig = facet; break;
17257 case XML_SCHEMA_FACET_FRACTIONDIGITS:
17258 ffracdig = facet; break;
17263 for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17264 facet = cur->facet;
17265 switch (facet->type) {
17266 case XML_SCHEMA_FACET_LENGTH:
17267 bflength = facet; break;
17268 case XML_SCHEMA_FACET_MINLENGTH:
17269 bfminlen = facet; break;
17270 case XML_SCHEMA_FACET_MININCLUSIVE:
17271 bfmininc = facet; break;
17272 case XML_SCHEMA_FACET_MINEXCLUSIVE:
17273 bfminexc = facet; break;
17274 case XML_SCHEMA_FACET_MAXLENGTH:
17275 bfmaxlen = facet; break;
17276 case XML_SCHEMA_FACET_MAXINCLUSIVE:
17277 bfmaxinc = facet; break;
17278 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17279 bfmaxexc = facet; break;
17280 case XML_SCHEMA_FACET_TOTALDIGITS:
17281 bftotdig = facet; break;
17282 case XML_SCHEMA_FACET_FRACTIONDIGITS:
17283 bffracdig = facet; break;
17289 * length and minLength or maxLength (2.2) + (3.2)
17291 if (flength && (fminlen || fmaxlen)) {
17292 FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
17293 "either of 'minLength' or 'maxLength' to be specified on "
17294 "the same type definition")
17297 * Mutual exclusions in the same derivation step.
17299 if ((fmaxinc) && (fmaxexc)) {
17301 * SCC "maxInclusive and maxExclusive"
17303 FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
17305 if ((fmininc) && (fminexc)) {
17307 * SCC "minInclusive and minExclusive"
17309 FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
17312 if (flength && bflength) {
17314 * SCC "length valid restriction"
17315 * The values have to be equal.
17317 res = xmlSchemaCompareValues(flength->val, bflength->val);
17319 goto internal_error;
17321 xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
17322 if ((res != 0) && (bflength->fixed)) {
17323 FACET_RESTR_FIXED_ERR(flength)
17327 if (fminlen && bfminlen) {
17329 * SCC "minLength valid restriction"
17330 * minLength >= BASE minLength
17332 res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
17334 goto internal_error;
17336 xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
17337 if ((res != 0) && (bfminlen->fixed)) {
17338 FACET_RESTR_FIXED_ERR(fminlen)
17341 if (fmaxlen && bfmaxlen) {
17343 * SCC "maxLength valid restriction"
17344 * maxLength <= BASE minLength
17346 res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
17348 goto internal_error;
17350 xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
17351 if ((res != 0) && (bfmaxlen->fixed)) {
17352 FACET_RESTR_FIXED_ERR(fmaxlen)
17356 * SCC "length and minLength or maxLength"
17359 flength = bflength;
17362 fminlen = bfminlen;
17364 /* (1.1) length >= minLength */
17365 res = xmlSchemaCompareValues(flength->val, fminlen->val);
17367 goto internal_error;
17369 xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
17372 fmaxlen = bfmaxlen;
17374 /* (2.1) length <= maxLength */
17375 res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
17377 goto internal_error;
17379 xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
17387 /* SCC "maxInclusive >= minInclusive" */
17388 res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
17390 goto internal_error;
17392 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
17396 * SCC "maxInclusive valid restriction"
17399 /* maxInclusive <= BASE maxInclusive */
17400 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
17402 goto internal_error;
17404 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
17405 if ((res != 0) && (bfmaxinc->fixed)) {
17406 FACET_RESTR_FIXED_ERR(fmaxinc)
17410 /* maxInclusive < BASE maxExclusive */
17411 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
17413 goto internal_error;
17415 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
17419 /* maxInclusive >= BASE minInclusive */
17420 res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
17422 goto internal_error;
17424 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
17428 /* maxInclusive > BASE minExclusive */
17429 res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
17431 goto internal_error;
17433 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
17439 * "maxExclusive >= minExclusive"
17442 res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
17444 goto internal_error;
17446 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
17450 * "maxExclusive valid restriction"
17453 /* maxExclusive <= BASE maxExclusive */
17454 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
17456 goto internal_error;
17458 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
17460 if ((res != 0) && (bfmaxexc->fixed)) {
17461 FACET_RESTR_FIXED_ERR(fmaxexc)
17465 /* maxExclusive <= BASE maxInclusive */
17466 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
17468 goto internal_error;
17470 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
17474 /* maxExclusive > BASE minInclusive */
17475 res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
17477 goto internal_error;
17479 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
17483 /* maxExclusive > BASE minExclusive */
17484 res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
17486 goto internal_error;
17488 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
17494 * "minExclusive < maxInclusive"
17497 res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
17499 goto internal_error;
17501 xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
17505 * "minExclusive valid restriction"
17508 /* minExclusive >= BASE minExclusive */
17509 res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
17511 goto internal_error;
17513 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
17515 if ((res != 0) && (bfminexc->fixed)) {
17516 FACET_RESTR_FIXED_ERR(fminexc)
17520 /* minExclusive <= BASE maxInclusive */
17521 res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
17523 goto internal_error;
17525 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
17529 /* minExclusive >= BASE minInclusive */
17530 res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
17532 goto internal_error;
17534 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
17538 /* minExclusive < BASE maxExclusive */
17539 res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
17541 goto internal_error;
17543 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
17549 * "minInclusive < maxExclusive"
17552 res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
17554 goto internal_error;
17556 xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
17560 * "minExclusive valid restriction"
17563 /* minInclusive >= BASE minInclusive */
17564 res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
17566 goto internal_error;
17568 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
17570 if ((res != 0) && (bfmininc->fixed)) {
17571 FACET_RESTR_FIXED_ERR(fmininc)
17575 /* minInclusive <= BASE maxInclusive */
17576 res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
17578 goto internal_error;
17580 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
17584 /* minInclusive > BASE minExclusive */
17585 res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
17587 goto internal_error;
17589 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
17592 /* minInclusive < BASE maxExclusive */
17593 res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
17595 goto internal_error;
17597 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
17600 if (ftotdig && bftotdig) {
17602 * SCC " totalDigits valid restriction"
17603 * totalDigits <= BASE totalDigits
17605 res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
17607 goto internal_error;
17609 xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
17611 if ((res != 0) && (bftotdig->fixed)) {
17612 FACET_RESTR_FIXED_ERR(ftotdig)
17615 if (ffracdig && bffracdig) {
17617 * SCC "fractionDigits valid restriction"
17618 * fractionDigits <= BASE fractionDigits
17620 res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
17622 goto internal_error;
17624 xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
17626 if ((res != 0) && (bffracdig->fixed)) {
17627 FACET_RESTR_FIXED_ERR(ffracdig)
17631 * SCC "fractionDigits less than or equal to totalDigits"
17634 ftotdig = bftotdig;
17636 ffracdig = bffracdig;
17637 if (ftotdig && ffracdig) {
17638 res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
17640 goto internal_error;
17642 xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
17646 * *Enumerations* won' be added here, since only the first set
17647 * of enumerations in the ancestor-or-self axis is used
17648 * for validation, plus we need to use the base type of those
17649 * enumerations for whitespace.
17651 * *Patterns*: won't be add here, since they are ORed at
17652 * type level and ANDed at ancestor level. This will
17653 * happed during validation by walking the base axis
17656 for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17657 bfacet = cur->facet;
17659 * Special handling of enumerations and patterns.
17660 * TODO: hmm, they should not appear in the set, so remove this.
17662 if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
17663 (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
17666 * Search for a duplicate facet in the current type.
17668 link = type->facetSet;
17670 /* fixedErr = 0; */
17671 while (link != NULL) {
17672 facet = link->facet;
17673 if (facet->type == bfacet->type) {
17674 switch (facet->type) {
17675 case XML_SCHEMA_FACET_WHITESPACE:
17677 * The whitespace must be stronger.
17679 if (facet->whitespace < bfacet->whitespace) {
17680 FACET_RESTR_ERR(facet,
17681 "The 'whitespace' value has to be equal to "
17682 "or stronger than the 'whitespace' value of "
17685 if ((bfacet->fixed) &&
17686 (facet->whitespace != bfacet->whitespace)) {
17687 FACET_RESTR_FIXED_ERR(facet)
17693 /* Duplicate found. */
17699 * If no duplicate was found: add the base types's facet
17702 if (link == NULL) {
17703 link = (xmlSchemaFacetLinkPtr)
17704 xmlMalloc(sizeof(xmlSchemaFacetLink));
17705 if (link == NULL) {
17706 xmlSchemaPErrMemory(pctxt,
17707 "deriving facets, creating a facet link", NULL);
17710 link->facet = cur->facet;
17713 type->facetSet = link;
17723 PERROR_INT("xmlSchemaDeriveAndValidateFacets",
17724 "an error occured");
17729 xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
17730 xmlSchemaTypePtr type)
17732 xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
17734 * The actual value is then formed by replacing any union type
17735 * definition in the �explicit members� with the members of their
17736 * {member type definitions}, in order.
17738 * TODO: There's a bug entry at
17739 * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
17740 * which indicates that we'll keep the union types the future.
17742 link = type->memberTypes;
17743 while (link != NULL) {
17745 if (WXS_IS_TYPE_NOT_FIXED(link->type))
17746 xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
17748 if (WXS_IS_UNION(link->type)) {
17749 subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
17750 if (subLink != NULL) {
17751 link->type = subLink->type;
17752 if (subLink->next != NULL) {
17753 lastLink = link->next;
17754 subLink = subLink->next;
17756 while (subLink != NULL) {
17757 newLink = (xmlSchemaTypeLinkPtr)
17758 xmlMalloc(sizeof(xmlSchemaTypeLink));
17759 if (newLink == NULL) {
17760 xmlSchemaPErrMemory(pctxt, "allocating a type link",
17764 newLink->type = subLink->type;
17765 prevLink->next = newLink;
17766 prevLink = newLink;
17767 newLink->next = lastLink;
17769 subLink = subLink->next;
17780 xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
17782 int has = 0, needVal = 0, normVal = 0;
17784 has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
17786 needVal = (type->baseType->flags &
17787 XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
17788 normVal = (type->baseType->flags &
17789 XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
17791 if (type->facets != NULL) {
17792 xmlSchemaFacetPtr fac;
17794 for (fac = type->facets; fac != NULL; fac = fac->next) {
17795 switch (fac->type) {
17796 case XML_SCHEMA_FACET_WHITESPACE:
17798 case XML_SCHEMA_FACET_PATTERN:
17802 case XML_SCHEMA_FACET_ENUMERATION:
17814 type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
17816 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17818 type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
17820 if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
17821 xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
17823 * OPTIMIZE VAL TODO: Some facets need a computed value.
17825 if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
17826 (prim->builtInType != XML_SCHEMAS_STRING)) {
17827 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17833 xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
17838 * Evaluate the whitespace-facet value.
17840 if (WXS_IS_LIST(type)) {
17841 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17843 } else if (WXS_IS_UNION(type))
17846 if (type->facetSet != NULL) {
17847 xmlSchemaFacetLinkPtr lin;
17849 for (lin = type->facetSet; lin != NULL; lin = lin->next) {
17850 if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
17851 switch (lin->facet->whitespace) {
17852 case XML_SCHEMAS_FACET_PRESERVE:
17853 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17855 case XML_SCHEMAS_FACET_REPLACE:
17856 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17858 case XML_SCHEMAS_FACET_COLLAPSE:
17859 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17869 * For all �atomic� datatypes other than string (and types �derived�
17870 * by �restriction� from it) the value of whiteSpace is fixed to
17874 xmlSchemaTypePtr anc;
17876 for (anc = type->baseType; anc != NULL &&
17877 anc->builtInType != XML_SCHEMAS_ANYTYPE;
17878 anc = anc->baseType) {
17880 if (anc->type == XML_SCHEMA_TYPE_BASIC) {
17881 if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
17882 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17884 } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
17885 (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
17886 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17889 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17898 xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
17899 xmlSchemaTypePtr type)
17901 if (type->type != XML_SCHEMA_TYPE_SIMPLE)
17903 if (! WXS_IS_TYPE_NOT_FIXED_1(type))
17905 type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
17907 if (WXS_IS_LIST(type)) {
17909 * Corresponds to <simpleType><list>...
17911 if (type->subtypes == NULL) {
17913 * This one is really needed, so get out.
17915 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17916 "list type has no item-type assigned");
17919 } else if (WXS_IS_UNION(type)) {
17921 * Corresponds to <simpleType><union>...
17923 if (type->memberTypes == NULL) {
17925 * This one is really needed, so get out.
17927 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17928 "union type has no member-types assigned");
17933 * Corresponds to <simpleType><restriction>...
17935 if (type->baseType == NULL) {
17936 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17937 "type has no base-type assigned");
17940 if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
17941 if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
17945 * If the <restriction> alternative is chosen, then the
17946 * {variety} of the {base type definition}.
17948 if (WXS_IS_ATOMIC(type->baseType))
17949 type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
17950 else if (WXS_IS_LIST(type->baseType)) {
17951 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
17953 * Inherit the itemType.
17955 type->subtypes = type->baseType->subtypes;
17956 } else if (WXS_IS_UNION(type->baseType)) {
17957 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
17959 * NOTE that we won't assign the memberTypes of the base,
17960 * since this will make trouble when freeing them; we will
17961 * use a lookup function to access them instead.
17970 xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
17971 xmlSchemaTypePtr type)
17973 if (type->node != NULL) {
17974 xmlGenericError(xmlGenericErrorContext,
17975 "Type of %s : %s:%d :", name,
17976 type->node->doc->URL,
17977 xmlGetLineNo(type->node));
17979 xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
17981 if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
17982 switch (type->contentType) {
17983 case XML_SCHEMA_CONTENT_SIMPLE:
17984 xmlGenericError(xmlGenericErrorContext, "simple\n");
17986 case XML_SCHEMA_CONTENT_ELEMENTS:
17987 xmlGenericError(xmlGenericErrorContext, "elements\n");
17989 case XML_SCHEMA_CONTENT_UNKNOWN:
17990 xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
17992 case XML_SCHEMA_CONTENT_EMPTY:
17993 xmlGenericError(xmlGenericErrorContext, "empty\n");
17995 case XML_SCHEMA_CONTENT_MIXED:
17996 if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
17998 xmlGenericError(xmlGenericErrorContext,
17999 "mixed as emptiable particle\n");
18001 xmlGenericError(xmlGenericErrorContext, "mixed\n");
18003 /* Removed, since not used. */
18005 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
18006 xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
18009 case XML_SCHEMA_CONTENT_BASIC:
18010 xmlGenericError(xmlGenericErrorContext, "basic\n");
18013 xmlGenericError(xmlGenericErrorContext,
18014 "not registered !!!\n");
18022 * 3.14.6 Constraints on Simple Type Definition Schema Components
18025 xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
18026 xmlSchemaTypePtr type)
18028 int res, olderrs = pctxt->nberrors;
18030 if (type->type != XML_SCHEMA_TYPE_SIMPLE)
18033 if (! WXS_IS_TYPE_NOT_FIXED(type))
18036 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18037 type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
18039 if (type->baseType == NULL) {
18040 PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
18041 "missing baseType");
18044 if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
18045 xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
18047 * If a member type of a union is a union itself, we need to substitute
18048 * that member type for its member types.
18049 * NOTE that this might change in WXS 1.1; i.e. we will keep the union
18050 * types in WXS 1.1.
18052 if ((type->memberTypes != NULL) &&
18053 (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
18056 * SPEC src-simple-type 1
18057 * "The corresponding simple type definition, if any, must satisfy
18058 * the conditions set out in Constraints on Simple Type Definition
18059 * Schema Components (�3.14.6)."
18062 * Schema Component Constraint: Simple Type Definition Properties Correct
18063 * (st-props-correct)
18065 res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
18068 * Schema Component Constraint: Derivation Valid (Restriction, Simple)
18069 * (cos-st-restricts)
18071 res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
18074 * TODO: Removed the error report, since it got annoying to get an
18075 * extra error report, if anything failed until now.
18076 * Enable this if needed.
18078 * xmlSchemaPErr(ctxt, type->node,
18079 * XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
18080 * "Simple type '%s' does not satisfy the constraints "
18081 * "on simple type definitions.\n",
18082 * type->name, NULL);
18085 * Schema Component Constraint: Simple Type Restriction (Facets)
18086 * (st-restrict-facets)
18088 res = xmlSchemaCheckFacetValues(type, pctxt);
18090 if ((type->facetSet != NULL) ||
18091 (type->baseType->facetSet != NULL)) {
18092 res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
18096 * Whitespace value.
18098 res = xmlSchemaTypeFixupWhitespace(type);
18100 xmlSchemaTypeFixupOptimFacets(type);
18104 xmlSchemaDebugFixedType(pctxt, type);
18106 if (olderrs != pctxt->nberrors)
18107 return(pctxt->err);
18112 xmlSchemaDebugFixedType(pctxt, type);
18118 xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
18119 xmlSchemaTypePtr type)
18121 int res = 0, olderrs = pctxt->nberrors;
18122 xmlSchemaTypePtr baseType = type->baseType;
18124 if (! WXS_IS_TYPE_NOT_FIXED(type))
18126 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18127 if (baseType == NULL) {
18128 PERROR_INT("xmlSchemaFixupComplexType",
18129 "missing baseType");
18133 * Fixup the base type.
18135 if (WXS_IS_TYPE_NOT_FIXED(baseType))
18136 xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
18137 if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
18139 * Skip fixup if the base type is invalid.
18140 * TODO: Generate a warning!
18145 * This basically checks if the base type can be derived.
18147 res = xmlSchemaCheckSRCCT(pctxt, type);
18150 * Fixup the content type.
18152 if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
18154 * Corresponds to <complexType><simpleContent>...
18156 if ((WXS_IS_COMPLEX(baseType)) &&
18157 (baseType->contentTypeDef != NULL) &&
18158 (WXS_IS_RESTRICTION(type))) {
18159 xmlSchemaTypePtr contentBase, content;
18160 #ifdef ENABLE_NAMED_LOCALS
18162 const xmlChar *tmpname;
18165 * SPEC (1) If <restriction> + base type is <complexType>,
18166 * "whose own {content type} is a simple type..."
18168 if (type->contentTypeDef != NULL) {
18170 * SPEC (1.1) "the simple type definition corresponding to the
18171 * <simpleType> among the [children] of <restriction> if there
18173 * Note that this "<simpleType> among the [children]" was put
18174 * into ->contentTypeDef during parsing.
18176 contentBase = type->contentTypeDef;
18177 type->contentTypeDef = NULL;
18180 * (1.2) "...otherwise (<restriction> has no <simpleType>
18181 * among its [children]), the simple type definition which
18182 * is the {content type} of the ... base type."
18184 contentBase = baseType->contentTypeDef;
18188 * "... a simple type definition which restricts the simple
18189 * type definition identified in clause 1.1 or clause 1.2
18190 * with a set of facet components"
18192 * Create the anonymous simple type, which will be the content
18193 * type of the complex type.
18195 #ifdef ENABLE_NAMED_LOCALS
18196 snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
18197 tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
18198 content = xmlSchemaAddType(pctxt, pctxt->schema,
18199 XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
18202 content = xmlSchemaAddType(pctxt, pctxt->schema,
18203 XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
18206 if (content == NULL)
18209 * We will use the same node as for the <complexType>
18210 * to have it somehow anchored in the schema doc.
18212 content->type = XML_SCHEMA_TYPE_SIMPLE;
18213 content->baseType = contentBase;
18215 * Move the facets, previously anchored on the
18216 * complexType during parsing.
18218 content->facets = type->facets;
18219 type->facets = NULL;
18220 content->facetSet = type->facetSet;
18221 type->facetSet = NULL;
18223 type->contentTypeDef = content;
18224 if (WXS_IS_TYPE_NOT_FIXED(contentBase))
18225 xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
18227 * Fixup the newly created type. We don't need to check
18228 * for circularity here.
18230 res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
18232 res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
18235 } else if ((WXS_IS_COMPLEX(baseType)) &&
18236 (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
18237 (WXS_IS_RESTRICTION(type))) {
18239 * SPEC (2) If <restriction> + base is a mixed <complexType> with
18240 * an emptiable particle, then a simple type definition which
18241 * restricts the <restriction>'s <simpleType> child.
18243 if ((type->contentTypeDef == NULL) ||
18244 (type->contentTypeDef->baseType == NULL)) {
18246 * TODO: Check if this ever happens.
18248 xmlSchemaPCustomErr(pctxt,
18249 XML_SCHEMAP_INTERNAL,
18250 WXS_BASIC_CAST type, NULL,
18251 "Internal error: xmlSchemaTypeFixup, "
18252 "complex type '%s': the <simpleContent><restriction> "
18253 "is missing a <simpleType> child, but was not catched "
18254 "by xmlSchemaCheckSRCCT()", type->name);
18257 } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
18259 * SPEC (3) If <extension> + base is <complexType> with
18260 * <simpleType> content, "...then the {content type} of that
18261 * complex type definition"
18263 if (baseType->contentTypeDef == NULL) {
18265 * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
18266 * should have catched this already.
18268 xmlSchemaPCustomErr(pctxt,
18269 XML_SCHEMAP_INTERNAL,
18270 WXS_BASIC_CAST type, NULL,
18271 "Internal error: xmlSchemaTypeFixup, "
18272 "complex type '%s': the <extension>ed base type is "
18273 "a complex type with no simple content type",
18277 type->contentTypeDef = baseType->contentTypeDef;
18278 } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
18280 * SPEC (4) <extension> + base is <simpleType>
18281 * "... then that simple type definition"
18283 type->contentTypeDef = baseType;
18286 * TODO: Check if this ever happens.
18288 xmlSchemaPCustomErr(pctxt,
18289 XML_SCHEMAP_INTERNAL,
18290 WXS_BASIC_CAST type, NULL,
18291 "Internal error: xmlSchemaTypeFixup, "
18292 "complex type '%s' with <simpleContent>: unhandled "
18293 "derivation case", type->name);
18297 int dummySequence = 0;
18298 xmlSchemaParticlePtr particle =
18299 (xmlSchemaParticlePtr) type->subtypes;
18301 * Corresponds to <complexType><complexContent>...
18303 * NOTE that the effective mixed was already set during parsing of
18304 * <complexType> and <complexContent>; its flag value is
18305 * XML_SCHEMAS_TYPE_MIXED.
18307 * Compute the "effective content":
18308 * (2.1.1) + (2.1.2) + (2.1.3)
18310 if ((particle == NULL) ||
18311 ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
18312 ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
18313 (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
18314 ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
18315 (particle->minOccurs == 0))) &&
18316 ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
18317 if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
18319 * SPEC (2.1.4) "If the �effective mixed� is true, then
18320 * a particle whose properties are as follows:..."
18322 * Empty sequence model group with
18323 * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
18324 * NOTE that we sill assign it the <complexType> node to
18325 * somehow anchor it in the doc.
18327 if ((particle == NULL) ||
18328 (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
18330 * Create the particle.
18332 particle = xmlSchemaAddParticle(pctxt,
18334 if (particle == NULL)
18337 * Create the model group.
18338 */ /* URGENT TODO: avoid adding to pending items. */
18339 particle->children = (xmlSchemaTreeItemPtr)
18340 xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18341 XML_SCHEMA_TYPE_SEQUENCE, type->node);
18342 if (particle->children == NULL)
18345 type->subtypes = (xmlSchemaTypePtr) particle;
18348 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18351 * SPEC (2.1.5) "otherwise empty"
18353 type->contentType = XML_SCHEMA_CONTENT_EMPTY;
18357 * SPEC (2.2) "otherwise the particle corresponding to the
18358 * <all>, <choice>, <group> or <sequence> among the
18361 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18364 * Compute the "content type".
18366 if (WXS_IS_RESTRICTION(type)) {
18368 * SPEC (3.1) "If <restriction>..."
18369 * (3.1.1) + (3.1.2) */
18370 if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
18371 if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18372 type->contentType = XML_SCHEMA_CONTENT_MIXED;
18376 * SPEC (3.2) "If <extension>..."
18378 if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18381 * "If the �effective content� is empty, then the
18382 * {content type} of the [...] base ..."
18384 type->contentType = baseType->contentType;
18385 type->subtypes = baseType->subtypes;
18387 * Fixes bug #347316:
18388 * This is the case when the base type has a simple
18389 * type definition as content.
18391 type->contentTypeDef = baseType->contentTypeDef;
18393 * NOTE that the effective mixed is ignored here.
18395 } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18399 if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18400 type->contentType = XML_SCHEMA_CONTENT_MIXED;
18405 if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18406 type->contentType = XML_SCHEMA_CONTENT_MIXED;
18408 * "A model group whose {compositor} is sequence and whose
18409 * {particles} are..."
18411 if ((WXS_TYPE_PARTICLE(type) != NULL) &&
18412 (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
18413 ((WXS_TYPE_PARTICLE_TERM(type))->type ==
18414 XML_SCHEMA_TYPE_ALL))
18417 * SPEC cos-all-limited (1)
18419 xmlSchemaCustomErr(ACTXT_CAST pctxt,
18420 /* TODO: error code */
18421 XML_SCHEMAP_COS_ALL_LIMITED,
18422 WXS_ITEM_NODE(type), NULL,
18423 "The type has an 'all' model group in its "
18424 "{content type} and thus cannot be derived from "
18425 "a non-empty type, since this would produce a "
18426 "'sequence' model group containing the 'all' "
18427 "model group; 'all' model groups are not "
18428 "allowed to appear inside other model groups",
18431 } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
18432 (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
18433 ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
18434 XML_SCHEMA_TYPE_ALL))
18437 * SPEC cos-all-limited (1)
18439 xmlSchemaCustomErr(ACTXT_CAST pctxt,
18440 /* TODO: error code */
18441 XML_SCHEMAP_COS_ALL_LIMITED,
18442 WXS_ITEM_NODE(type), NULL,
18443 "A type cannot be derived by extension from a type "
18444 "which has an 'all' model group in its "
18445 "{content type}, since this would produce a "
18446 "'sequence' model group containing the 'all' "
18447 "model group; 'all' model groups are not "
18448 "allowed to appear inside other model groups",
18451 } else if (! dummySequence) {
18452 xmlSchemaTreeItemPtr effectiveContent =
18453 (xmlSchemaTreeItemPtr) type->subtypes;
18455 * Create the particle.
18457 particle = xmlSchemaAddParticle(pctxt,
18459 if (particle == NULL)
18462 * Create the "sequence" model group.
18464 particle->children = (xmlSchemaTreeItemPtr)
18465 xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18466 XML_SCHEMA_TYPE_SEQUENCE, type->node);
18467 if (particle->children == NULL)
18469 WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
18471 * SPEC "the particle of the {content type} of
18472 * the ... base ..."
18473 * Create a duplicate of the base type's particle
18474 * and assign its "term" to it.
18476 particle->children->children =
18477 (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
18479 ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
18480 ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
18481 if (particle->children->children == NULL)
18483 particle = (xmlSchemaParticlePtr)
18484 particle->children->children;
18485 particle->children =
18486 ((xmlSchemaParticlePtr) baseType->subtypes)->children;
18488 * SPEC "followed by the �effective content�."
18490 particle->next = effectiveContent;
18492 * This all will result in:
18494 * --> new-sequence(
18503 * This is the case when there is already an empty
18504 * <sequence> with minOccurs==maxOccurs==1.
18505 * Just add the base types's content type.
18506 * NOTE that, although we miss to add an intermediate
18507 * <sequence>, this should produce no difference to
18508 * neither the regex compilation of the content model,
18509 * nor to the complex type contraints.
18511 particle->children->children =
18512 (xmlSchemaTreeItemPtr) baseType->subtypes;
18518 * Now fixup attribute uses:
18519 * - expand attr. group references
18520 * - intersect attribute wildcards
18521 * - inherit attribute uses of the base type
18522 * - inherit or union attr. wildcards if extending
18523 * - apply attr. use prohibitions if restricting
18525 res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
18528 * Apply the complex type component constraints; this will not
18529 * check attributes, since this is done in
18530 * xmlSchemaFixupTypeAttributeUses().
18532 res = xmlSchemaCheckCTComponent(pctxt, type);
18536 xmlSchemaDebugFixedType(pctxt, type);
18538 if (olderrs != pctxt->nberrors)
18539 return(pctxt->err);
18544 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18546 xmlSchemaDebugFixedType(pctxt, type);
18548 return(pctxt->err);
18551 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18553 xmlSchemaDebugFixedType(pctxt, type);
18560 * xmlSchemaTypeFixup:
18561 * @typeDecl: the schema type definition
18562 * @ctxt: the schema parser context
18564 * Fixes the content model of the type.
18565 * URGENT TODO: We need an int result!
18568 xmlSchemaTypeFixup(xmlSchemaTypePtr type,
18569 xmlSchemaAbstractCtxtPtr actxt)
18573 if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
18574 AERROR_INT("xmlSchemaTypeFixup",
18575 "this function needs a parser context");
18578 if (! WXS_IS_TYPE_NOT_FIXED(type))
18580 if (type->type == XML_SCHEMA_TYPE_COMPLEX)
18581 return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
18582 else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
18583 return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
18588 * xmlSchemaCheckFacet:
18589 * @facet: the facet
18590 * @typeDecl: the schema type definition
18591 * @pctxt: the schema parser context or NULL
18592 * @name: the optional name of the type
18594 * Checks and computes the values of facets.
18596 * Returns 0 if valid, a positive error code if not valid and
18597 * -1 in case of an internal or API error.
18600 xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
18601 xmlSchemaTypePtr typeDecl,
18602 xmlSchemaParserCtxtPtr pctxt,
18603 const xmlChar * name ATTRIBUTE_UNUSED)
18605 int ret = 0, ctxtGiven;
18607 if ((facet == NULL) || (typeDecl == NULL))
18610 * TODO: will the parser context be given if used from
18611 * the relaxNG module?
18618 switch (facet->type) {
18619 case XML_SCHEMA_FACET_MININCLUSIVE:
18620 case XML_SCHEMA_FACET_MINEXCLUSIVE:
18621 case XML_SCHEMA_FACET_MAXINCLUSIVE:
18622 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
18623 case XML_SCHEMA_FACET_ENUMERATION: {
18625 * Okay we need to validate the value
18628 xmlSchemaTypePtr base;
18630 /* 4.3.5.5 Constraints on enumeration Schema Components
18631 * Schema Component Constraint: enumeration valid restriction
18632 * It is an �error� if any member of {value} is not in the
18633 * �value space� of {base type definition}.
18635 * minInclusive, maxInclusive, minExclusive, maxExclusive:
18636 * The value �must� be in the
18637 * �value space� of the �base type�.
18640 * This function is intended to deliver a compiled value
18641 * on the facet. In this implementation of XML Schemata the
18642 * type holding a facet, won't be a built-in type.
18643 * Thus to ensure that other API
18644 * calls (relaxng) do work, if the given type is a built-in
18645 * type, we will assume that the given built-in type *is
18646 * already* the base type.
18648 if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
18649 base = typeDecl->baseType;
18650 if (base == NULL) {
18651 PERROR_INT("xmlSchemaCheckFacet",
18652 "a type user derived type has no base type");
18660 * A context is needed if called from RelaxNG.
18662 pctxt = xmlSchemaNewParserCtxt("*");
18667 * NOTE: This call does not check the content nodes,
18668 * since they are not available:
18669 * facet->node is just the node holding the facet
18670 * definition, *not* the attribute holding the *value*
18673 ret = xmlSchemaVCheckCVCSimpleType(
18674 ACTXT_CAST pctxt, facet->node, base,
18675 facet->value, &(facet->val), 1, 1, 0);
18678 /* No error message for RelaxNG. */
18680 xmlSchemaCustomErr(ACTXT_CAST pctxt,
18681 XML_SCHEMAP_INTERNAL, facet->node, NULL,
18682 "Internal error: xmlSchemaCheckFacet, "
18683 "failed to validate the value '%s' of the "
18684 "facet '%s' against the base type",
18685 facet->value, xmlSchemaFacetTypeToString(facet->type));
18687 goto internal_error;
18689 ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18690 /* No error message for RelaxNG. */
18692 xmlChar *str = NULL;
18694 xmlSchemaCustomErr(ACTXT_CAST pctxt,
18695 ret, facet->node, WXS_BASIC_CAST facet,
18696 "The value '%s' of the facet does not validate "
18697 "against the base type '%s'",
18699 xmlSchemaFormatQName(&str,
18700 base->targetNamespace, base->name));
18701 FREE_AND_NULL(str);
18704 } else if (facet->val == NULL) {
18706 PERROR_INT("xmlSchemaCheckFacet",
18707 "value was not computed");
18713 case XML_SCHEMA_FACET_PATTERN:
18714 facet->regexp = xmlRegexpCompile(facet->value);
18715 if (facet->regexp == NULL) {
18716 ret = XML_SCHEMAP_REGEXP_INVALID;
18717 /* No error message for RelaxNG. */
18719 xmlSchemaCustomErr(ACTXT_CAST pctxt,
18720 ret, facet->node, WXS_BASIC_CAST typeDecl,
18721 "The value '%s' of the facet 'pattern' is not a "
18722 "valid regular expression",
18723 facet->value, NULL);
18727 case XML_SCHEMA_FACET_TOTALDIGITS:
18728 case XML_SCHEMA_FACET_FRACTIONDIGITS:
18729 case XML_SCHEMA_FACET_LENGTH:
18730 case XML_SCHEMA_FACET_MAXLENGTH:
18731 case XML_SCHEMA_FACET_MINLENGTH:
18733 if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
18734 ret = xmlSchemaValidatePredefinedType(
18735 xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
18736 facet->value, &(facet->val));
18738 ret = xmlSchemaValidatePredefinedType(
18739 xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
18740 facet->value, &(facet->val));
18744 /* No error message for RelaxNG. */
18746 PERROR_INT("xmlSchemaCheckFacet",
18747 "validating facet value");
18749 goto internal_error;
18751 ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18752 /* No error message for RelaxNG. */
18755 xmlSchemaCustomErr4(ACTXT_CAST pctxt,
18756 ret, facet->node, WXS_BASIC_CAST typeDecl,
18757 "The value '%s' of the facet '%s' is not a valid '%s'",
18759 xmlSchemaFacetTypeToString(facet->type),
18760 (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
18761 BAD_CAST "nonNegativeInteger" :
18762 BAD_CAST "positiveInteger",
18768 case XML_SCHEMA_FACET_WHITESPACE:{
18769 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
18770 facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
18771 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
18772 facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
18773 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
18774 facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
18776 ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18777 /* No error message for RelaxNG. */
18779 /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
18780 xmlSchemaCustomErr(ACTXT_CAST pctxt,
18781 ret, facet->node, WXS_BASIC_CAST typeDecl,
18782 "The value '%s' of the facet 'whitespace' is not "
18783 "valid", facet->value, NULL);
18791 if ((! ctxtGiven) && (pctxt != NULL))
18792 xmlSchemaFreeParserCtxt(pctxt);
18795 if ((! ctxtGiven) && (pctxt != NULL))
18796 xmlSchemaFreeParserCtxt(pctxt);
18801 * xmlSchemaCheckFacetValues:
18802 * @typeDecl: the schema type definition
18803 * @ctxt: the schema parser context
18805 * Checks the default values types, especially for facets
18808 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
18809 xmlSchemaParserCtxtPtr pctxt)
18811 int res, olderrs = pctxt->nberrors;
18812 const xmlChar *name = typeDecl->name;
18814 * NOTE: It is intended to use the facets list, instead
18817 if (typeDecl->facets != NULL) {
18818 xmlSchemaFacetPtr facet = typeDecl->facets;
18821 * Temporarily assign the "schema" to the validation context
18822 * of the parser context. This is needed for NOTATION validation.
18824 if (pctxt->vctxt == NULL) {
18825 if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
18828 pctxt->vctxt->schema = pctxt->schema;
18829 while (facet != NULL) {
18830 res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
18832 facet = facet->next;
18834 pctxt->vctxt->schema = NULL;
18836 if (olderrs != pctxt->nberrors)
18837 return(pctxt->err);
18844 * xmlSchemaGetCircModelGrDefRef:
18845 * @ctxtMGroup: the searched model group
18846 * @selfMGroup: the second searched model group
18847 * @particle: the first particle
18849 * This one is intended to be used by
18850 * xmlSchemaCheckGroupDefCircular only.
18852 * Returns the particle with the circular model group definition reference,
18855 static xmlSchemaTreeItemPtr
18856 xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
18857 xmlSchemaTreeItemPtr particle)
18859 xmlSchemaTreeItemPtr circ = NULL;
18860 xmlSchemaTreeItemPtr term;
18861 xmlSchemaModelGroupDefPtr gdef;
18863 for (; particle != NULL; particle = particle->next) {
18864 term = particle->children;
18867 switch (term->type) {
18868 case XML_SCHEMA_TYPE_GROUP:
18869 gdef = (xmlSchemaModelGroupDefPtr) term;
18870 if (gdef == groupDef)
18873 * Mark this model group definition to avoid infinite
18874 * recursion on circular references not yet examined.
18876 if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
18878 if (gdef->children != NULL) {
18879 gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18880 circ = xmlSchemaGetCircModelGrDefRef(groupDef,
18881 gdef->children->children);
18882 gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18887 case XML_SCHEMA_TYPE_SEQUENCE:
18888 case XML_SCHEMA_TYPE_CHOICE:
18889 case XML_SCHEMA_TYPE_ALL:
18890 circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
18902 * xmlSchemaCheckGroupDefCircular:
18903 * @item: the model group definition
18904 * @ctxt: the parser context
18907 * Checks for circular references to model group definitions.
18910 xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
18911 xmlSchemaParserCtxtPtr ctxt)
18914 * Schema Component Constraint: Model Group Correct
18915 * 2 Circular groups are disallowed. That is, within the {particles}
18916 * of a group there must not be at any depth a particle whose {term}
18917 * is the group itself.
18919 if ((item == NULL) ||
18920 (item->type != XML_SCHEMA_TYPE_GROUP) ||
18921 (item->children == NULL))
18924 xmlSchemaTreeItemPtr circ;
18926 circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
18927 if (circ != NULL) {
18928 xmlChar *str = NULL;
18930 * TODO: The error report is not adequate: this constraint
18931 * is defined for model groups but not definitions, but since
18932 * there cannot be any circular model groups without a model group
18933 * definition (if not using a construction API), we check those
18936 xmlSchemaPCustomErr(ctxt,
18937 XML_SCHEMAP_MG_PROPS_CORRECT_2,
18938 NULL, WXS_ITEM_NODE(circ),
18939 "Circular reference to the model group definition '%s' "
18940 "defined", xmlSchemaFormatQName(&str,
18941 item->targetNamespace, item->name));
18944 * NOTE: We will cut the reference to avoid further
18945 * confusion of the processor. This is a fatal error.
18947 circ->children = NULL;
18953 * xmlSchemaModelGroupToModelGroupDefFixup:
18954 * @ctxt: the parser context
18955 * @mg: the model group
18957 * Assigns the model group of model group definitions to the "term"
18958 * of the referencing particle.
18959 * In xmlSchemaResolveModelGroupParticleReferences the model group
18960 * definitions were assigned to the "term", since needed for the
18961 * circularity check.
18963 * Schema Component Constraint:
18964 * All Group Limited (cos-all-limited) (1.2)
18967 xmlSchemaModelGroupToModelGroupDefFixup(
18968 xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
18969 xmlSchemaModelGroupPtr mg)
18971 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
18973 while (particle != NULL) {
18974 if ((WXS_PARTICLE_TERM(particle) == NULL) ||
18975 ((WXS_PARTICLE_TERM(particle))->type !=
18976 XML_SCHEMA_TYPE_GROUP))
18978 particle = WXS_PTC_CAST particle->next;
18981 if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
18983 * TODO: Remove the particle.
18985 WXS_PARTICLE_TERM(particle) = NULL;
18986 particle = WXS_PTC_CAST particle->next;
18990 * Assign the model group to the {term} of the particle.
18992 WXS_PARTICLE_TERM(particle) =
18993 WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
18995 particle = WXS_PTC_CAST particle->next;
19000 * xmlSchemaCheckAttrGroupCircularRecur:
19001 * @ctxtGr: the searched attribute group
19002 * @attr: the current attribute list to be processed
19004 * This one is intended to be used by
19005 * xmlSchemaCheckAttrGroupCircular only.
19007 * Returns the circular attribute grou reference, otherwise NULL.
19009 static xmlSchemaQNameRefPtr
19010 xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
19011 xmlSchemaItemListPtr list)
19013 xmlSchemaAttributeGroupPtr gr;
19014 xmlSchemaQNameRefPtr ref, circ;
19017 * We will search for an attribute group reference which
19018 * references the context attribute group.
19020 for (i = 0; i < list->nbItems; i++) {
19021 ref = list->items[i];
19022 if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19023 (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
19024 (ref->item != NULL))
19026 gr = WXS_ATTR_GROUP_CAST ref->item;
19029 if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
19032 * Mark as visited to avoid infinite recursion on
19033 * circular references not yet examined.
19035 if ((gr->attrUses) &&
19036 (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
19038 gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
19039 circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
19040 (xmlSchemaItemListPtr) gr->attrUses);
19041 gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
19052 * xmlSchemaCheckAttrGroupCircular:
19053 * attrGr: the attribute group definition
19054 * @ctxt: the parser context
19057 * Checks for circular references of attribute groups.
19060 xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
19061 xmlSchemaParserCtxtPtr ctxt)
19064 * Schema Representation Constraint:
19065 * Attribute Group Definition Representation OK
19066 * 3 Circular group reference is disallowed outside <redefine>.
19067 * That is, unless this element information item's parent is
19068 * <redefine>, then among the [children], if any, there must
19069 * not be an <attributeGroup> with ref [attribute] which resolves
19070 * to the component corresponding to this <attributeGroup>. Indirect
19071 * circularity is also ruled out. That is, when QName resolution
19072 * (Schema Document) (�3.15.3) is applied to a �QName� arising from
19073 * any <attributeGroup>s with a ref [attribute] among the [children],
19074 * it must not be the case that a �QName� is encountered at any depth
19075 * which resolves to the component corresponding to this <attributeGroup>.
19077 if (attrGr->attrUses == NULL)
19079 else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
19082 xmlSchemaQNameRefPtr circ;
19084 circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
19085 (xmlSchemaItemListPtr) attrGr->attrUses);
19086 if (circ != NULL) {
19087 xmlChar *str = NULL;
19089 * TODO: Report the referenced attr group as QName.
19091 xmlSchemaPCustomErr(ctxt,
19092 XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
19093 NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
19094 "Circular reference to the attribute group '%s' "
19095 "defined", xmlSchemaGetComponentQName(&str, attrGr));
19096 FREE_AND_NULL(str);
19098 * NOTE: We will cut the reference to avoid further
19099 * confusion of the processor.
19100 * BADSPEC TODO: The spec should define how to process in this case.
19110 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19111 xmlSchemaAttributeGroupPtr attrGr);
19114 * xmlSchemaExpandAttributeGroupRefs:
19115 * @pctxt: the parser context
19116 * @node: the node of the component holding the attribute uses
19117 * @completeWild: the intersected wildcard to be returned
19118 * @list: the attribute uses
19120 * Substitutes contained attribute group references
19121 * for their attribute uses. Wilcards are intersected.
19122 * Attribute use prohibitions are removed from the list
19123 * and returned via the @prohibs list.
19124 * Pointlessness of attr. prohibs, if a matching attr. decl
19125 * is existent a well, are checked.
19128 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
19129 xmlSchemaBasicItemPtr item,
19130 xmlSchemaWildcardPtr *completeWild,
19131 xmlSchemaItemListPtr list,
19132 xmlSchemaItemListPtr prohibs)
19134 xmlSchemaAttributeGroupPtr gr;
19135 xmlSchemaAttributeUsePtr use;
19136 xmlSchemaItemListPtr sublist;
19138 int created = (*completeWild == NULL) ? 0 : 1;
19141 prohibs->nbItems = 0;
19143 for (i = 0; i < list->nbItems; i++) {
19144 use = list->items[i];
19146 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
19147 if (prohibs == NULL) {
19148 PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
19149 "unexpected attr prohibition found");
19153 * Remove from attribute uses.
19155 if (xmlSchemaItemListRemove(list, i) == -1)
19159 * Note that duplicate prohibitions were already
19160 * handled at parsing time.
19163 * Add to list of prohibitions.
19165 xmlSchemaItemListAddSize(prohibs, 2, use);
19168 if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19169 ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
19171 if ((WXS_QNAME_CAST use)->item == NULL)
19173 gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
19175 * Expand the referenced attr. group.
19176 * TODO: remove this, this is done in a previous step, so
19177 * already done here.
19179 if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
19180 if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
19184 * Build the 'complete' wildcard; i.e. intersect multiple
19187 if (gr->attributeWildcard != NULL) {
19188 if (*completeWild == NULL) {
19189 *completeWild = gr->attributeWildcard;
19192 xmlSchemaWildcardPtr tmpWild;
19195 * Copy the first encountered wildcard as context,
19196 * except for the annotation.
19198 * Although the complete wildcard might not correspond
19199 * to any node in the schema, we will anchor it on
19200 * the node of the owner component.
19202 tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema,
19203 XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
19204 WXS_ITEM_NODE(item));
19205 if (tmpWild == NULL)
19207 if (xmlSchemaCloneWildcardNsConstraints(pctxt,
19208 tmpWild, *completeWild) == -1)
19210 tmpWild->processContents = (*completeWild)->processContents;
19211 *completeWild = tmpWild;
19215 if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
19216 gr->attributeWildcard) == -1)
19221 * Just remove the reference if the referenced group does not
19222 * contain any attribute uses.
19224 sublist = ((xmlSchemaItemListPtr) gr->attrUses);
19225 if ((sublist == NULL) || sublist->nbItems == 0) {
19226 if (xmlSchemaItemListRemove(list, i) == -1)
19232 * Add the attribute uses.
19234 list->items[i] = sublist->items[0];
19235 if (sublist->nbItems != 1) {
19236 for (j = 1; j < sublist->nbItems; j++) {
19238 if (xmlSchemaItemListInsert(list,
19239 sublist->items[j], i) == -1)
19247 * Handle pointless prohibitions of declared attributes.
19249 if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
19250 xmlSchemaAttributeUseProhibPtr prohib;
19252 for (i = prohibs->nbItems -1; i >= 0; i--) {
19253 prohib = prohibs->items[i];
19254 for (j = 0; j < list->nbItems; j++) {
19255 use = list->items[j];
19257 if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
19258 (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
19260 xmlChar *str = NULL;
19262 xmlSchemaCustomWarning(ACTXT_CAST pctxt,
19263 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
19264 prohib->node, NULL,
19265 "Skipping pointless attribute use prohibition "
19266 "'%s', since a corresponding attribute use "
19267 "exists already in the type definition",
19268 xmlSchemaFormatQName(&str,
19269 prohib->targetNamespace, prohib->name),
19271 FREE_AND_NULL(str);
19273 * Remove the prohibition.
19275 if (xmlSchemaItemListRemove(prohibs, i) == -1)
19286 * xmlSchemaAttributeGroupExpandRefs:
19287 * @pctxt: the parser context
19288 * @attrGr: the attribute group definition
19291 * {attribute uses} property
19292 * {attribute wildcard} property
19294 * Substitutes contained attribute group references
19295 * for their attribute uses. Wilcards are intersected.
19298 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19299 xmlSchemaAttributeGroupPtr attrGr)
19301 if ((attrGr->attrUses == NULL) ||
19302 (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
19305 attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
19306 if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
19307 &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
19313 * xmlSchemaAttributeGroupExpandRefs:
19314 * @pctxt: the parser context
19315 * @attrGr: the attribute group definition
19317 * Substitutes contained attribute group references
19318 * for their attribute uses. Wilcards are intersected.
19320 * Schema Component Constraint:
19321 * Attribute Group Definition Properties Correct (ag-props-correct)
19324 xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19325 xmlSchemaAttributeGroupPtr attrGr)
19328 * SPEC ag-props-correct
19329 * (1) "The values of the properties of an attribute group definition
19330 * must be as described in the property tableau in The Attribute
19331 * Group Definition Schema Component (�3.6.1), modulo the impact of
19332 * Missing Sub-components (�5.3);"
19335 if ((attrGr->attrUses != NULL) &&
19336 (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
19338 xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
19339 xmlSchemaAttributeUsePtr use, tmp;
19340 int i, j, hasId = 0;
19342 for (i = uses->nbItems -1; i >= 0; i--) {
19343 use = uses->items[i];
19345 * SPEC ag-props-correct
19346 * (2) "Two distinct members of the {attribute uses} must not have
19347 * {attribute declaration}s both of whose {name}s match and whose
19348 * {target namespace}s are identical."
19351 for (j = i -1; j >= 0; j--) {
19352 tmp = uses->items[j];
19353 if ((WXS_ATTRUSE_DECL_NAME(use) ==
19354 WXS_ATTRUSE_DECL_NAME(tmp)) &&
19355 (WXS_ATTRUSE_DECL_TNS(use) ==
19356 WXS_ATTRUSE_DECL_TNS(tmp)))
19358 xmlChar *str = NULL;
19360 xmlSchemaCustomErr(ACTXT_CAST pctxt,
19361 XML_SCHEMAP_AG_PROPS_CORRECT,
19362 attrGr->node, WXS_BASIC_CAST attrGr,
19364 xmlSchemaGetComponentDesignation(&str, use),
19366 FREE_AND_NULL(str);
19368 * Remove the duplicate.
19370 if (xmlSchemaItemListRemove(uses, i) == -1)
19377 * SPEC ag-props-correct
19378 * (3) "Two distinct members of the {attribute uses} must not have
19379 * {attribute declaration}s both of whose {type definition}s are or
19380 * are derived from ID."
19381 * TODO: Does 'derived' include member-types of unions?
19383 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
19384 if (xmlSchemaIsDerivedFromBuiltInType(
19385 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
19388 xmlChar *str = NULL;
19390 xmlSchemaCustomErr(ACTXT_CAST pctxt,
19391 XML_SCHEMAP_AG_PROPS_CORRECT,
19392 attrGr->node, WXS_BASIC_CAST attrGr,
19393 "There must not exist more than one attribute "
19394 "declaration of type 'xs:ID' "
19395 "(or derived from 'xs:ID'). The %s violates this "
19397 xmlSchemaGetComponentDesignation(&str, use),
19399 FREE_AND_NULL(str);
19400 if (xmlSchemaItemListRemove(uses, i) == -1)
19413 * xmlSchemaResolveAttrGroupReferences:
19414 * @attrgrpDecl: the schema attribute definition
19415 * @ctxt: the schema parser context
19416 * @name: the attribute name
19418 * Resolves references to attribute group definitions.
19421 xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
19422 xmlSchemaParserCtxtPtr ctxt)
19424 xmlSchemaAttributeGroupPtr group;
19426 if (ref->item != NULL)
19428 group = xmlSchemaGetAttributeGroup(ctxt->schema,
19430 ref->targetNamespace);
19431 if (group == NULL) {
19432 xmlSchemaPResCompAttrErr(ctxt,
19433 XML_SCHEMAP_SRC_RESOLVE,
19435 "ref", ref->name, ref->targetNamespace,
19436 ref->itemType, NULL);
19439 ref->item = WXS_BASIC_CAST group;
19444 * xmlSchemaCheckAttrPropsCorrect:
19445 * @item: an schema attribute declaration/use
19446 * @ctxt: a schema parser context
19447 * @name: the name of the attribute
19450 * Schema Component Constraint:
19451 * Attribute Declaration Properties Correct (a-props-correct)
19453 * Validates the value constraints of an attribute declaration/use.
19454 * NOTE that this needs the simle type definitions to be already
19455 * builded and checked.
19458 xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19459 xmlSchemaAttributePtr attr)
19463 * SPEC a-props-correct (1)
19464 * "The values of the properties of an attribute declaration must
19465 * be as described in the property tableau in The Attribute
19466 * Declaration Schema Component (�3.2.1), modulo the impact of
19467 * Missing Sub-components (�5.3)."
19470 if (WXS_ATTR_TYPEDEF(attr) == NULL)
19473 if (attr->defValue != NULL) {
19477 * SPEC a-props-correct (3)
19478 * "If the {type definition} is or is derived from ID then there
19479 * must not be a {value constraint}."
19481 if (xmlSchemaIsDerivedFromBuiltInType(
19482 WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
19484 xmlSchemaCustomErr(ACTXT_CAST pctxt,
19485 XML_SCHEMAP_A_PROPS_CORRECT_3,
19486 NULL, WXS_BASIC_CAST attr,
19487 "Value constraints are not allowed if the type definition "
19488 "is or is derived from xs:ID",
19490 return(pctxt->err);
19493 * SPEC a-props-correct (2)
19494 * "if there is a {value constraint}, the canonical lexical
19495 * representation of its value must be �valid� with respect
19496 * to the {type definition} as defined in String Valid (�3.14.4)."
19497 * TODO: Don't care about the *cononical* stuff here, this requirement
19498 * will be removed in WXS 1.1 anyway.
19500 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
19501 attr->node, WXS_ATTR_TYPEDEF(attr),
19502 attr->defValue, &(attr->defVal),
19506 PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
19507 "calling xmlSchemaVCheckCVCSimpleType()");
19510 xmlSchemaCustomErr(ACTXT_CAST pctxt,
19511 XML_SCHEMAP_A_PROPS_CORRECT_2,
19512 NULL, WXS_BASIC_CAST attr,
19513 "The value of the value constraint is not valid",
19515 return(pctxt->err);
19522 static xmlSchemaElementPtr
19523 xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
19524 xmlSchemaElementPtr ancestor)
19526 xmlSchemaElementPtr ret;
19528 if (WXS_SUBST_HEAD(ancestor) == NULL)
19530 if (WXS_SUBST_HEAD(ancestor) == elemDecl)
19533 if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
19535 WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
19536 ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
19537 WXS_SUBST_HEAD(ancestor));
19538 WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
19544 * xmlSchemaCheckElemPropsCorrect:
19545 * @ctxt: a schema parser context
19546 * @decl: the element declaration
19547 * @name: the name of the attribute
19549 * Schema Component Constraint:
19550 * Element Declaration Properties Correct (e-props-correct)
19556 xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19557 xmlSchemaElementPtr elemDecl)
19560 xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
19562 * SPEC (1) "The values of the properties of an element declaration
19563 * must be as described in the property tableau in The Element
19564 * Declaration Schema Component (�3.3.1), modulo the impact of Missing
19565 * Sub-components (�5.3)."
19567 if (WXS_SUBST_HEAD(elemDecl) != NULL) {
19568 xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
19570 xmlSchemaCheckElementDeclComponent(head, pctxt);
19572 * SPEC (3) "If there is a non-�absent� {substitution group
19573 * affiliation}, then {scope} must be global."
19575 if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
19576 xmlSchemaPCustomErr(pctxt,
19577 XML_SCHEMAP_E_PROPS_CORRECT_3,
19578 WXS_BASIC_CAST elemDecl, NULL,
19579 "Only global element declarations can have a "
19580 "substitution group affiliation", NULL);
19581 ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
19584 * TODO: SPEC (6) "Circular substitution groups are disallowed.
19585 * That is, it must not be possible to return to an element declaration
19586 * by repeatedly following the {substitution group affiliation}
19589 if (head == elemDecl)
19591 else if (WXS_SUBST_HEAD(head) != NULL)
19592 circ = xmlSchemaCheckSubstGroupCircular(head, head);
19595 if (circ != NULL) {
19596 xmlChar *strA = NULL, *strB = NULL;
19598 xmlSchemaPCustomErrExt(pctxt,
19599 XML_SCHEMAP_E_PROPS_CORRECT_6,
19600 WXS_BASIC_CAST circ, NULL,
19601 "The element declaration '%s' defines a circular "
19602 "substitution group to element declaration '%s'",
19603 xmlSchemaGetComponentQName(&strA, circ),
19604 xmlSchemaGetComponentQName(&strB, head),
19606 FREE_AND_NULL(strA)
19607 FREE_AND_NULL(strB)
19608 ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
19611 * SPEC (4) "If there is a {substitution group affiliation},
19612 * the {type definition}
19613 * of the element declaration must be validly derived from the {type
19614 * definition} of the {substitution group affiliation}, given the value
19615 * of the {substitution group exclusions} of the {substitution group
19616 * affiliation}, as defined in Type Derivation OK (Complex) (�3.4.6)
19617 * (if the {type definition} is complex) or as defined in
19618 * Type Derivation OK (Simple) (�3.14.6) (if the {type definition} is
19621 * NOTE: {substitution group exclusions} means the values of the
19622 * attribute "final".
19625 if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
19628 if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
19629 set |= SUBSET_EXTENSION;
19630 if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
19631 set |= SUBSET_RESTRICTION;
19633 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
19634 WXS_ELEM_TYPEDEF(head), set) != 0) {
19635 xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
19637 ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
19638 xmlSchemaPCustomErrExt(pctxt,
19639 XML_SCHEMAP_E_PROPS_CORRECT_4,
19640 WXS_BASIC_CAST elemDecl, NULL,
19641 "The type definition '%s' was "
19642 "either rejected by the substitution group "
19643 "affiliation '%s', or not validly derived from its type "
19645 xmlSchemaGetComponentQName(&strA, typeDef),
19646 xmlSchemaGetComponentQName(&strB, head),
19647 xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
19648 FREE_AND_NULL(strA)
19649 FREE_AND_NULL(strB)
19650 FREE_AND_NULL(strC)
19655 * SPEC (5) "If the {type definition} or {type definition}'s
19657 * is or is derived from ID then there must not be a {value constraint}.
19658 * Note: The use of ID as a type definition for elements goes beyond
19659 * XML 1.0, and should be avoided if backwards compatibility is desired"
19661 if ((elemDecl->value != NULL) &&
19662 ((WXS_IS_SIMPLE(typeDef) &&
19663 xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
19664 (WXS_IS_COMPLEX(typeDef) &&
19665 WXS_HAS_SIMPLE_CONTENT(typeDef) &&
19666 xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
19667 XML_SCHEMAS_ID)))) {
19669 ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
19670 xmlSchemaPCustomErr(pctxt,
19671 XML_SCHEMAP_E_PROPS_CORRECT_5,
19672 WXS_BASIC_CAST elemDecl, NULL,
19673 "The type definition (or type definition's content type) is or "
19674 "is derived from ID; value constraints are not allowed in "
19675 "conjunction with such a type definition", NULL);
19676 } else if (elemDecl->value != NULL) {
19678 xmlNodePtr node = NULL;
19681 * SPEC (2) "If there is a {value constraint}, the canonical lexical
19682 * representation of its value must be �valid� with respect to the
19683 * {type definition} as defined in Element Default Valid (Immediate)
19686 if (typeDef == NULL) {
19687 xmlSchemaPErr(pctxt, elemDecl->node,
19688 XML_SCHEMAP_INTERNAL,
19689 "Internal error: xmlSchemaCheckElemPropsCorrect, "
19690 "type is missing... skipping validation of "
19691 "the value constraint", NULL, NULL);
19694 if (elemDecl->node != NULL) {
19695 if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
19696 node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19699 node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19700 BAD_CAST "default");
19702 vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
19703 typeDef, elemDecl->value, &(elemDecl->defVal));
19706 PERROR_INT("xmlSchemaElemCheckValConstr",
19707 "failed to validate the value constraint of an "
19708 "element declaration");
19719 * xmlSchemaCheckElemSubstGroup:
19720 * @ctxt: a schema parser context
19721 * @decl: the element declaration
19722 * @name: the name of the attribute
19724 * Schema Component Constraint:
19725 * Substitution Group (cos-equiv-class)
19727 * In Libxml2 the subst. groups will be precomputed, in terms of that
19728 * a list will be built for each subst. group head, holding all direct
19729 * referents to this head.
19730 * NOTE that this function needs:
19731 * 1. circular subst. groups to be checked beforehand
19732 * 2. the declaration's type to be derived from the head's type
19738 xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
19739 xmlSchemaElementPtr elemDecl)
19741 if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
19742 /* SPEC (1) "Its {abstract} is false." */
19743 (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
19746 xmlSchemaElementPtr head;
19747 xmlSchemaTypePtr headType, type;
19750 * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
19751 * {disallowed substitutions} as the blocking constraint, as defined in
19752 * Substitution Group OK (Transitive) (�3.3.6)."
19754 for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
19755 head = WXS_SUBST_HEAD(head)) {
19759 * The blocking constraints.
19761 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
19763 headType = head->subtypes;
19764 type = elemDecl->subtypes;
19765 if (headType == type)
19767 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
19768 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19769 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
19770 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19772 * SPEC: Substitution Group OK (Transitive) (2.3)
19773 * "The set of all {derivation method}s involved in the
19774 * derivation of D's {type definition} from C's {type definition}
19775 * does not intersect with the union of the blocking constraint,
19776 * C's {prohibited substitutions} (if C is complex, otherwise the
19777 * empty set) and the {prohibited substitutions} (respectively the
19778 * empty set) of any intermediate {type definition}s in the
19779 * derivation of D's {type definition} from C's {type definition}."
19782 * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
19783 * subst.head axis, the methSet does not need to be computed for
19784 * the full depth over and over.
19787 * The set of all {derivation method}s involved in the derivation
19789 while ((type != NULL) && (type != headType)) {
19790 if ((WXS_IS_EXTENSION(type)) &&
19791 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19792 methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19794 if (WXS_IS_RESTRICTION(type) &&
19795 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19796 methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19798 type = type->baseType;
19801 * The {prohibited substitutions} of all intermediate types +
19804 type = elemDecl->subtypes->baseType;
19805 while (type != NULL) {
19806 if (WXS_IS_COMPLEX(type)) {
19808 XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19809 ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
19810 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19812 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19813 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19814 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19817 if (type == headType)
19819 type = type->baseType;
19822 (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19823 (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
19824 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19825 (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
19829 xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
19830 if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
19831 head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
19836 #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
19838 * xmlSchemaCheckElementDeclComponent
19839 * @pctxt: the schema parser context
19840 * @ctxtComponent: the context component (an element declaration)
19841 * @ctxtParticle: the first particle of the context component
19842 * @searchParticle: the element declaration particle to be analysed
19844 * Schema Component Constraint: Element Declarations Consistent
19847 xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
19848 xmlSchemaBasicItemPtr ctxtComponent,
19849 xmlSchemaParticlePtr ctxtParticle,
19850 xmlSchemaParticlePtr searchParticle,
19851 xmlSchemaParticlePtr curParticle,
19857 xmlSchemaParticlePtr cur = curParticle;
19858 if (curParticle == NULL) {
19861 if (WXS_PARTICLE_TERM(curParticle) == NULL) {
19863 * Just return in this case. A missing "term" of the particle
19864 * might arise due to an invalid "term" component.
19868 while (cur != NULL) {
19869 switch (WXS_PARTICLE_TERM(cur)->type) {
19870 case XML_SCHEMA_TYPE_ANY:
19872 case XML_SCHEMA_TYPE_ELEMENT:
19874 ret = xmlSchemaCheckElementDeclConsistent(pctxt,
19875 ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
19879 xmlSchemaElementPtr elem =
19880 WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
19882 * SPEC Element Declarations Consistent:
19883 * "If the {particles} contains, either directly,
19884 * indirectly (that is, within the {particles} of a
19885 * contained model group, recursively) or �implicitly�
19886 * two or more element declaration particles with
19887 * the same {name} and {target namespace}, then
19888 * all their type definitions must be the same
19889 * top-level definition [...]"
19891 if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
19892 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
19893 xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19894 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
19896 xmlChar *strA = NULL, *strB = NULL;
19898 xmlSchemaCustomErr(ACTXT_CAST pctxt,
19899 /* TODO: error code */
19900 XML_SCHEMAP_COS_NONAMBIG,
19901 WXS_ITEM_NODE(cur), NULL,
19902 "In the content model of %s, there are multiple "
19903 "element declarations for '%s' with different "
19904 "type definitions",
19905 xmlSchemaGetComponentDesignation(&strA,
19907 xmlSchemaFormatQName(&strB,
19908 WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19909 WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
19910 FREE_AND_NULL(strA);
19911 FREE_AND_NULL(strB);
19912 return(XML_SCHEMAP_COS_NONAMBIG);
19916 case XML_SCHEMA_TYPE_SEQUENCE: {
19919 case XML_SCHEMA_TYPE_CHOICE:{
19921 xmlSchemaTreeItemPtr sub;
19923 sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr)
19924 while (sub != NULL) {
19925 ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
19926 ctxtParticle, ctxtElem);
19934 case XML_SCHEMA_TYPE_ALL:
19936 case XML_SCHEMA_TYPE_GROUP:
19939 xmlSchemaInternalErr2(ACTXT_CAST pctxt,
19940 "xmlSchemaCheckElementDeclConsistent",
19941 "found unexpected term of type '%s' in content model",
19942 WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
19945 cur = (xmlSchemaParticlePtr) cur->next;
19954 * xmlSchemaCheckElementDeclComponent
19955 * @item: an schema element declaration/particle
19956 * @ctxt: a schema parser context
19957 * @name: the name of the attribute
19959 * Validates the value constraints of an element declaration.
19960 * Adds substitution group members.
19963 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
19964 xmlSchemaParserCtxtPtr ctxt)
19966 if (elemDecl == NULL)
19968 if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
19970 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
19971 if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
19973 * Adds substitution group members.
19975 xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
19980 * xmlSchemaResolveModelGroupParticleReferences:
19981 * @particle: a particle component
19982 * @ctxt: a parser context
19984 * Resolves references of a model group's {particles} to
19985 * model group definitions and to element declarations.
19988 xmlSchemaResolveModelGroupParticleReferences(
19989 xmlSchemaParserCtxtPtr ctxt,
19990 xmlSchemaModelGroupPtr mg)
19992 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
19993 xmlSchemaQNameRefPtr ref;
19994 xmlSchemaBasicItemPtr refItem;
19997 * URGENT TODO: Test this.
19999 while (particle != NULL) {
20000 if ((WXS_PARTICLE_TERM(particle) == NULL) ||
20001 ((WXS_PARTICLE_TERM(particle))->type !=
20002 XML_SCHEMA_EXTRA_QNAMEREF))
20004 goto next_particle;
20006 ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
20008 * Resolve the reference.
20009 * NULL the {term} by default.
20011 particle->children = NULL;
20013 refItem = xmlSchemaGetNamedComponent(ctxt->schema,
20014 ref->itemType, ref->name, ref->targetNamespace);
20015 if (refItem == NULL) {
20016 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
20017 NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
20018 ref->targetNamespace, ref->itemType, NULL);
20019 /* TODO: remove the particle. */
20020 goto next_particle;
20022 if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
20023 if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
20024 /* TODO: remove the particle. */
20025 goto next_particle;
20027 * NOTE that we will assign the model group definition
20028 * itself to the "term" of the particle. This will ease
20029 * the check for circular model group definitions. After
20030 * that the "term" will be assigned the model group of the
20031 * model group definition.
20033 if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
20034 XML_SCHEMA_TYPE_ALL) {
20036 * SPEC cos-all-limited (1)
20037 * SPEC cos-all-limited (1.2)
20038 * "It appears only as the value of one or both of the
20039 * following properties:"
20040 * (1.1) "the {model group} property of a model group
20042 * (1.2) "the {term} property of a particle [... of] the "
20043 * {content type} of a complex type definition."
20045 xmlSchemaCustomErr(ACTXT_CAST ctxt,
20046 /* TODO: error code */
20047 XML_SCHEMAP_COS_ALL_LIMITED,
20048 WXS_ITEM_NODE(particle), NULL,
20049 "A model group definition is referenced, but "
20050 "it contains an 'all' model group, which "
20051 "cannot be contained by model groups",
20053 /* TODO: remove the particle. */
20054 goto next_particle;
20056 particle->children = (xmlSchemaTreeItemPtr) refItem;
20059 * TODO: Are referenced element declarations the only
20060 * other components we expect here?
20062 particle->children = (xmlSchemaTreeItemPtr) refItem;
20065 particle = WXS_PTC_CAST particle->next;
20070 xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
20073 xmlSchemaTypePtr tx, ty, ptx, pty;
20076 while (x != NULL) {
20078 tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
20079 ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
20080 ptx = xmlSchemaGetPrimitiveType(tx);
20081 pty = xmlSchemaGetPrimitiveType(ty);
20083 * (1) if a datatype T' is �derived� by �restriction� from an
20084 * atomic datatype T then the �value space� of T' is a subset of
20085 * the �value space� of T. */
20087 * (2) if datatypes T' and T'' are �derived� by �restriction�
20088 * from a common atomic ancestor T then the �value space�s of T'
20089 * and T'' may overlap.
20094 * We assume computed values to be normalized, so do a fast
20095 * string comparison for string based types.
20097 if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
20098 WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
20100 xmlSchemaValueGetAsString(x),
20101 xmlSchemaValueGetAsString(y)))
20104 ret = xmlSchemaCompareValuesWhtsp(
20105 x, XML_SCHEMA_WHITESPACE_PRESERVE,
20106 y, XML_SCHEMA_WHITESPACE_PRESERVE);
20115 x = xmlSchemaValueGetNext(x);
20117 y = xmlSchemaValueGetNext(y);
20120 } else if (xmlSchemaValueGetNext(y) != NULL)
20129 * xmlSchemaResolveAttrUseReferences:
20130 * @item: an attribute use
20131 * @ctxt: a parser context
20133 * Resolves the referenced attribute declaration.
20136 xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
20137 xmlSchemaParserCtxtPtr ctxt)
20139 if ((ctxt == NULL) || (ause == NULL))
20141 if ((ause->attrDecl == NULL) ||
20142 (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
20146 xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
20149 * TODO: Evaluate, what errors could occur if the declaration is not
20152 ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
20153 ref->name, ref->targetNamespace);
20154 if (ause->attrDecl == NULL) {
20155 xmlSchemaPResCompAttrErr(ctxt,
20156 XML_SCHEMAP_SRC_RESOLVE,
20157 WXS_BASIC_CAST ause, ause->node,
20158 "ref", ref->name, ref->targetNamespace,
20159 XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20160 return(ctxt->err);;
20167 * xmlSchemaCheckAttrUsePropsCorrect:
20168 * @ctxt: a parser context
20169 * @use: an attribute use
20171 * Schema Component Constraint:
20172 * Attribute Use Correct (au-props-correct)
20176 xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
20177 xmlSchemaAttributeUsePtr use)
20179 if ((ctxt == NULL) || (use == NULL))
20181 if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
20182 ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
20186 * SPEC au-props-correct (1)
20187 * "The values of the properties of an attribute use must be as
20188 * described in the property tableau in The Attribute Use Schema
20189 * Component (�3.5.1), modulo the impact of Missing
20190 * Sub-components (�5.3)."
20193 if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
20194 ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
20195 ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20197 xmlSchemaPCustomErr(ctxt,
20198 XML_SCHEMAP_AU_PROPS_CORRECT_2,
20199 WXS_BASIC_CAST use, NULL,
20200 "The attribute declaration has a 'fixed' value constraint "
20201 ", thus the attribute use must also have a 'fixed' value "
20207 * Compute and check the value constraint's value.
20209 if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
20212 * TODO: The spec seems to be missing a check of the
20213 * value constraint of the attribute use. We will do it here.
20216 * SPEC a-props-correct (3)
20218 if (xmlSchemaIsDerivedFromBuiltInType(
20219 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
20221 xmlSchemaCustomErr(ACTXT_CAST ctxt,
20222 XML_SCHEMAP_AU_PROPS_CORRECT,
20223 NULL, WXS_BASIC_CAST use,
20224 "Value constraints are not allowed if the type definition "
20225 "is or is derived from xs:ID",
20230 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
20231 use->node, WXS_ATTRUSE_TYPEDEF(use),
20232 use->defValue, &(use->defVal),
20236 PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
20237 "calling xmlSchemaVCheckCVCSimpleType()");
20240 xmlSchemaCustomErr(ACTXT_CAST ctxt,
20241 XML_SCHEMAP_AU_PROPS_CORRECT,
20242 NULL, WXS_BASIC_CAST use,
20243 "The value of the value constraint is not valid",
20249 * SPEC au-props-correct (2)
20250 * "If the {attribute declaration} has a fixed
20251 * {value constraint}, then if the attribute use itself has a
20252 * {value constraint}, it must also be fixed and its value must match
20253 * that of the {attribute declaration}'s {value constraint}."
20255 if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
20256 (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20258 if (! xmlSchemaAreValuesEqual(use->defVal,
20259 (WXS_ATTRUSE_DECL(use))->defVal))
20261 xmlSchemaPCustomErr(ctxt,
20262 XML_SCHEMAP_AU_PROPS_CORRECT_2,
20263 WXS_BASIC_CAST use, NULL,
20264 "The 'fixed' value constraint of the attribute use "
20265 "must match the attribute declaration's value "
20267 (WXS_ATTRUSE_DECL(use))->defValue);
20278 * xmlSchemaResolveAttrTypeReferences:
20279 * @item: an attribute declaration
20280 * @ctxt: a parser context
20282 * Resolves the referenced type definition component.
20285 xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
20286 xmlSchemaParserCtxtPtr ctxt)
20289 * The simple type definition corresponding to the <simpleType> element
20290 * information item in the [children], if present, otherwise the simple
20291 * type definition �resolved� to by the �actual value� of the type
20292 * [attribute], if present, otherwise the �simple ur-type definition�.
20294 if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
20296 item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
20297 if (item->subtypes != NULL)
20299 if (item->typeName != NULL) {
20300 xmlSchemaTypePtr type;
20302 type = xmlSchemaGetType(ctxt->schema, item->typeName,
20304 if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
20305 xmlSchemaPResCompAttrErr(ctxt,
20306 XML_SCHEMAP_SRC_RESOLVE,
20307 WXS_BASIC_CAST item, item->node,
20308 "type", item->typeName, item->typeNs,
20309 XML_SCHEMA_TYPE_SIMPLE, NULL);
20312 item->subtypes = type;
20316 * The type defaults to the xs:anySimpleType.
20318 item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
20324 * xmlSchemaResolveIDCKeyReferences:
20325 * @idc: the identity-constraint definition
20326 * @ctxt: the schema parser context
20327 * @name: the attribute name
20329 * Resolve keyRef references to key/unique IDCs.
20330 * Schema Component Constraint:
20331 * Identity-constraint Definition Properties Correct (c-props-correct)
20334 xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
20335 xmlSchemaParserCtxtPtr pctxt)
20337 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
20339 if (idc->ref->name != NULL) {
20340 idc->ref->item = (xmlSchemaBasicItemPtr)
20341 xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
20342 idc->ref->targetNamespace);
20343 if (idc->ref->item == NULL) {
20345 * TODO: It is actually not an error to fail to resolve
20346 * at this stage. BUT we need to be that strict!
20348 xmlSchemaPResCompAttrErr(pctxt,
20349 XML_SCHEMAP_SRC_RESOLVE,
20350 WXS_BASIC_CAST idc, idc->node,
20351 "refer", idc->ref->name,
20352 idc->ref->targetNamespace,
20353 XML_SCHEMA_TYPE_IDC_KEY, NULL);
20354 return(pctxt->err);
20355 } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
20357 * SPEC c-props-correct (1)
20359 xmlSchemaCustomErr(ACTXT_CAST pctxt,
20360 XML_SCHEMAP_C_PROPS_CORRECT,
20361 NULL, WXS_BASIC_CAST idc,
20362 "The keyref references a keyref",
20364 idc->ref->item = NULL;
20365 return(pctxt->err);
20367 if (idc->nbFields !=
20368 ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
20369 xmlChar *str = NULL;
20370 xmlSchemaIDCPtr refer;
20372 refer = (xmlSchemaIDCPtr) idc->ref->item;
20374 * SPEC c-props-correct(2)
20375 * "If the {identity-constraint category} is keyref,
20376 * the cardinality of the {fields} must equal that of
20377 * the {fields} of the {referenced key}.
20379 xmlSchemaCustomErr(ACTXT_CAST pctxt,
20380 XML_SCHEMAP_C_PROPS_CORRECT,
20381 NULL, WXS_BASIC_CAST idc,
20382 "The cardinality of the keyref differs from the "
20383 "cardinality of the referenced key/unique '%s'",
20384 xmlSchemaFormatQName(&str, refer->targetNamespace,
20388 return(pctxt->err);
20396 xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
20397 xmlSchemaParserCtxtPtr pctxt)
20399 if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
20400 prohib->targetNamespace) == NULL) {
20402 xmlSchemaPResCompAttrErr(pctxt,
20403 XML_SCHEMAP_SRC_RESOLVE,
20404 NULL, prohib->node,
20405 "ref", prohib->name, prohib->targetNamespace,
20406 XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20407 return(XML_SCHEMAP_SRC_RESOLVE);
20412 #define WXS_REDEFINED_TYPE(c) \
20413 (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
20415 #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
20416 (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20418 #define WXS_REDEFINED_ATTR_GROUP(c) \
20419 (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
20422 xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
20425 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20426 xmlSchemaBasicItemPtr prev, item;
20433 item = redef->item;
20435 * First try to locate the redefined component in the
20436 * schema graph starting with the redefined schema.
20437 * NOTE: According to this schema bug entry:
20438 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
20439 * it's not clear if the referenced component needs to originate
20440 * from the <redefine>d schema _document_ or the schema; the latter
20441 * would include all imported and included sub-schemas of the
20442 * <redefine>d schema. Currenlty we latter approach is used.
20443 * SUPPLEMENT: It seems that the WG moves towards the latter
20444 * approach, so we are doing it right.
20447 prev = xmlSchemaFindRedefCompInGraph(
20448 redef->targetBucket, item->type,
20449 redef->refName, redef->refTargetNs);
20450 if (prev == NULL) {
20451 xmlChar *str = NULL;
20455 * SPEC src-redefine:
20456 * (6.2.1) "The �actual value� of its own name attribute plus
20457 * target namespace must successfully �resolve� to a model
20458 * group definition in I."
20459 * (7.2.1) "The �actual value� of its own name attribute plus
20460 * target namespace must successfully �resolve� to an attribute
20461 * group definition in I."
20464 * Note that, if we are redefining with the use of references
20465 * to components, the spec assumes the src-resolve to be used;
20466 * but this won't assure that we search only *inside* the
20467 * redefined schema.
20469 if (redef->reference)
20470 node = WXS_ITEM_NODE(redef->reference);
20472 node = WXS_ITEM_NODE(item);
20473 xmlSchemaCustomErr(ACTXT_CAST pctxt,
20475 * TODO: error code.
20476 * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
20479 XML_SCHEMAP_SRC_REDEFINE, node, NULL,
20480 "The %s '%s' to be redefined could not be found in "
20481 "the redefined schema",
20482 WXS_ITEM_TYPE_NAME(item),
20483 xmlSchemaFormatQName(&str, redef->refTargetNs,
20485 FREE_AND_NULL(str);
20487 redef = redef->next;
20491 * TODO: Obtaining and setting the redefinition state is really
20495 switch (item->type) {
20496 case XML_SCHEMA_TYPE_COMPLEX:
20497 case XML_SCHEMA_TYPE_SIMPLE:
20498 if ((WXS_TYPE_CAST prev)->flags &
20499 XML_SCHEMAS_TYPE_REDEFINED)
20504 /* Mark it as redefined. */
20505 (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
20507 * Assign the redefined type to the
20508 * base type of the redefining type.
20511 ((xmlSchemaTypePtr) item)->baseType =
20512 (xmlSchemaTypePtr) prev;
20514 case XML_SCHEMA_TYPE_GROUP:
20515 if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
20516 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20521 /* Mark it as redefined. */
20522 (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
20523 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
20524 if (redef->reference != NULL) {
20526 * Overwrite the QName-reference with the
20527 * referenced model group def.
20529 (WXS_PTC_CAST redef->reference)->children =
20530 WXS_TREE_CAST prev;
20532 redef->target = prev;
20534 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20535 if ((WXS_ATTR_GROUP_CAST prev)->flags &
20536 XML_SCHEMAS_ATTRGROUP_REDEFINED)
20541 (WXS_ATTR_GROUP_CAST prev)->flags |=
20542 XML_SCHEMAS_ATTRGROUP_REDEFINED;
20543 if (redef->reference != NULL) {
20545 * Assign the redefined attribute group to the
20546 * QName-reference component.
20547 * This is the easy case, since we will just
20548 * expand the redefined group.
20550 (WXS_QNAME_CAST redef->reference)->item = prev;
20551 redef->target = NULL;
20554 * This is the complicated case: we need
20555 * to apply src-redefine (7.2.2) at a later
20556 * stage, i.e. when attribute group references
20557 * have beed expanded and simple types have
20560 redef->target = prev;
20564 PERROR_INT("xmlSchemaResolveRedefReferences",
20565 "Unexpected redefined component type");
20568 if (wasRedefined) {
20569 xmlChar *str = NULL;
20572 if (redef->reference)
20573 node = WXS_ITEM_NODE(redef->reference);
20575 node = WXS_ITEM_NODE(redef->item);
20577 xmlSchemaCustomErr(ACTXT_CAST pctxt,
20578 /* TODO: error code. */
20579 XML_SCHEMAP_SRC_REDEFINE,
20581 "The referenced %s was already redefined. Multiple "
20582 "redefinition of the same component is not supported",
20583 xmlSchemaGetComponentDesignation(&str, prev),
20587 redef = redef->next;
20590 redef = redef->next;
20591 } while (redef != NULL);
20597 xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
20600 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20601 xmlSchemaBasicItemPtr item;
20607 if (redef->target == NULL) {
20608 redef = redef->next;
20611 item = redef->item;
20613 switch (item->type) {
20614 case XML_SCHEMA_TYPE_SIMPLE:
20615 case XML_SCHEMA_TYPE_COMPLEX:
20617 * Since the spec wants the {name} of the redefined
20618 * type to be 'absent', we'll NULL it.
20620 (WXS_TYPE_CAST redef->target)->name = NULL;
20623 * TODO: Seems like there's nothing more to do. The normal
20624 * inheritance mechanism is used. But not 100% sure.
20627 case XML_SCHEMA_TYPE_GROUP:
20630 * SPEC src-redefine:
20631 * (6.2.2) "The {model group} of the model group definition
20632 * which corresponds to it per XML Representation of Model
20633 * Group Definition Schema Components (�3.7.2) must be a
20634 * �valid restriction� of the {model group} of that model
20635 * group definition in I, as defined in Particle Valid
20636 * (Restriction) (�3.9.6)."
20639 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20641 * SPEC src-redefine:
20642 * (7.2.2) "The {attribute uses} and {attribute wildcard} of
20643 * the attribute group definition which corresponds to it
20644 * per XML Representation of Attribute Group Definition Schema
20645 * Components (�3.6.2) must be �valid restrictions� of the
20646 * {attribute uses} and {attribute wildcard} of that attribute
20647 * group definition in I, as defined in clause 2, clause 3 and
20648 * clause 4 of Derivation Valid (Restriction, Complex)
20649 * (�3.4.6) (where references to the base type definition are
20650 * understood as references to the attribute group definition
20653 err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
20654 XML_SCHEMA_ACTION_REDEFINE,
20655 item, redef->target,
20656 (WXS_ATTR_GROUP_CAST item)->attrUses,
20657 (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
20658 (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
20659 (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
20666 redef = redef->next;
20667 } while (redef != NULL);
20673 xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
20674 xmlSchemaBucketPtr bucket)
20676 xmlSchemaBasicItemPtr item;
20678 xmlHashTablePtr *table;
20679 const xmlChar *name;
20682 #define WXS_GET_GLOBAL_HASH(c, slot) { \
20683 if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
20684 table = &(WXS_IMPBUCKET((c))->schema->slot); \
20686 table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
20689 * Add global components to the schema's hash tables.
20690 * This is the place where duplicate components will be
20692 * TODO: I think normally we should support imports of the
20693 * same namespace from multiple locations. We don't do currently,
20694 * but if we do then according to:
20695 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
20696 * we would need, if imported directly, to import redefined
20697 * components as well to be able to catch clashing components.
20698 * (I hope I'll still know what this means after some months :-()
20700 if (bucket == NULL)
20702 if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
20704 bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
20706 for (i = 0; i < bucket->globals->nbItems; i++) {
20707 item = bucket->globals->items[i];
20709 switch (item->type) {
20710 case XML_SCHEMA_TYPE_COMPLEX:
20711 case XML_SCHEMA_TYPE_SIMPLE:
20712 if (WXS_REDEFINED_TYPE(item))
20714 name = (WXS_TYPE_CAST item)->name;
20715 WXS_GET_GLOBAL_HASH(bucket, typeDecl)
20717 case XML_SCHEMA_TYPE_ELEMENT:
20718 name = (WXS_ELEM_CAST item)->name;
20719 WXS_GET_GLOBAL_HASH(bucket, elemDecl)
20721 case XML_SCHEMA_TYPE_ATTRIBUTE:
20722 name = (WXS_ATTR_CAST item)->name;
20723 WXS_GET_GLOBAL_HASH(bucket, attrDecl)
20725 case XML_SCHEMA_TYPE_GROUP:
20726 if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
20728 name = (WXS_MODEL_GROUPDEF_CAST item)->name;
20729 WXS_GET_GLOBAL_HASH(bucket, groupDecl)
20731 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20732 if (WXS_REDEFINED_ATTR_GROUP(item))
20734 name = (WXS_ATTR_GROUP_CAST item)->name;
20735 WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
20737 case XML_SCHEMA_TYPE_IDC_KEY:
20738 case XML_SCHEMA_TYPE_IDC_UNIQUE:
20739 case XML_SCHEMA_TYPE_IDC_KEYREF:
20740 name = (WXS_IDC_CAST item)->name;
20741 WXS_GET_GLOBAL_HASH(bucket, idcDef)
20743 case XML_SCHEMA_TYPE_NOTATION:
20744 name = ((xmlSchemaNotationPtr) item)->name;
20745 WXS_GET_GLOBAL_HASH(bucket, notaDecl)
20748 PERROR_INT("xmlSchemaAddComponents",
20749 "Unexpected global component type");
20752 if (*table == NULL) {
20753 *table = xmlHashCreateDict(10, pctxt->dict);
20754 if (*table == NULL) {
20755 PERROR_INT("xmlSchemaAddComponents",
20756 "failed to create a component hash table");
20760 err = xmlHashAddEntry(*table, name, item);
20762 xmlChar *str = NULL;
20764 xmlSchemaCustomErr(ACTXT_CAST pctxt,
20765 XML_SCHEMAP_REDEFINED_TYPE,
20766 WXS_ITEM_NODE(item),
20767 WXS_BASIC_CAST item,
20768 "A global %s '%s' does already exist",
20769 WXS_ITEM_TYPE_NAME(item),
20770 xmlSchemaGetComponentQName(&str, item));
20771 FREE_AND_NULL(str);
20775 * Process imported/included schemas.
20777 if (bucket->relations != NULL) {
20778 xmlSchemaSchemaRelationPtr rel = bucket->relations;
20780 if ((rel->bucket != NULL) &&
20781 ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
20782 if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
20786 } while (rel != NULL);
20792 xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
20793 xmlSchemaBucketPtr rootBucket)
20795 xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
20796 xmlSchemaTreeItemPtr item, *items;
20797 int nbItems, i, ret = 0;
20798 xmlSchemaBucketPtr oldbucket = con->bucket;
20799 xmlSchemaElementPtr elemDecl;
20801 #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
20803 if ((con->pending == NULL) ||
20804 (con->pending->nbItems == 0))
20808 * Since xmlSchemaFixupComplexType() will create new particles
20809 * (local components), and those particle components need a bucket
20810 * on the constructor, we'll assure here that the constructor has
20812 * TODO: Think about storing locals _only_ on the main bucket.
20814 if (con->bucket == NULL)
20815 con->bucket = rootBucket;
20818 * SPEC (src-redefine):
20819 * (6.2) "If it has no such self-reference, then all of the
20820 * following must be true:"
20822 * (6.2.2) The {model group} of the model group definition which
20823 * corresponds to it per XML Representation of Model Group
20824 * Definition Schema Components (�3.7.2) must be a �valid
20825 * restriction� of the {model group} of that model group definition
20826 * in I, as defined in Particle Valid (Restriction) (�3.9.6)."
20828 xmlSchemaCheckSRCRedefineFirst(pctxt);
20831 * Add global components to the schemata's hash tables.
20833 xmlSchemaAddComponents(pctxt, rootBucket);
20835 pctxt->ctxtType = NULL;
20836 items = (xmlSchemaTreeItemPtr *) con->pending->items;
20837 nbItems = con->pending->nbItems;
20839 * Now that we have parsed *all* the schema document(s) and converted
20840 * them to schema components, we can resolve references, apply component
20841 * constraints, create the FSA from the content model, etc.
20844 * Resolve references of..
20846 * 1. element declarations:
20847 * - the type definition
20848 * - the substitution group affiliation
20849 * 2. simple/complex types:
20850 * - the base type definition
20851 * - the memberTypes of union types
20852 * - the itemType of list types
20853 * 3. attributes declarations and attribute uses:
20854 * - the type definition
20855 * - if an attribute use, then the attribute declaration
20856 * 4. attribute group references:
20857 * - the attribute group definition
20859 * - the term of the particle (e.g. a model group)
20860 * 6. IDC key-references:
20861 * - the referenced IDC 'key' or 'unique' definition
20862 * 7. Attribute prohibitions which had a "ref" attribute.
20864 for (i = 0; i < nbItems; i++) {
20866 switch (item->type) {
20867 case XML_SCHEMA_TYPE_ELEMENT:
20868 xmlSchemaResolveElementReferences(
20869 (xmlSchemaElementPtr) item, pctxt);
20872 case XML_SCHEMA_TYPE_COMPLEX:
20873 case XML_SCHEMA_TYPE_SIMPLE:
20874 xmlSchemaResolveTypeReferences(
20875 (xmlSchemaTypePtr) item, pctxt);
20878 case XML_SCHEMA_TYPE_ATTRIBUTE:
20879 xmlSchemaResolveAttrTypeReferences(
20880 (xmlSchemaAttributePtr) item, pctxt);
20883 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
20884 xmlSchemaResolveAttrUseReferences(
20885 (xmlSchemaAttributeUsePtr) item, pctxt);
20888 case XML_SCHEMA_EXTRA_QNAMEREF:
20889 if ((WXS_QNAME_CAST item)->itemType ==
20890 XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
20892 xmlSchemaResolveAttrGroupReferences(
20893 WXS_QNAME_CAST item, pctxt);
20897 case XML_SCHEMA_TYPE_SEQUENCE:
20898 case XML_SCHEMA_TYPE_CHOICE:
20899 case XML_SCHEMA_TYPE_ALL:
20900 xmlSchemaResolveModelGroupParticleReferences(pctxt,
20901 WXS_MODEL_GROUP_CAST item);
20904 case XML_SCHEMA_TYPE_IDC_KEY:
20905 case XML_SCHEMA_TYPE_IDC_UNIQUE:
20906 case XML_SCHEMA_TYPE_IDC_KEYREF:
20907 xmlSchemaResolveIDCKeyReferences(
20908 (xmlSchemaIDCPtr) item, pctxt);
20911 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
20913 * Handle attribue prohibition which had a
20916 xmlSchemaResolveAttrUseProhibReferences(
20917 WXS_ATTR_PROHIB_CAST item, pctxt);
20924 if (pctxt->nberrors != 0)
20928 * Now that all references are resolved we
20929 * can check for circularity of...
20930 * 1. the base axis of type definitions
20931 * 2. nested model group definitions
20932 * 3. nested attribute group definitions
20933 * TODO: check for circual substitution groups.
20935 for (i = 0; i < nbItems; i++) {
20938 * Let's better stop on the first error here.
20940 switch (item->type) {
20941 case XML_SCHEMA_TYPE_COMPLEX:
20942 case XML_SCHEMA_TYPE_SIMPLE:
20943 xmlSchemaCheckTypeDefCircular(
20944 (xmlSchemaTypePtr) item, pctxt);
20946 if (pctxt->nberrors != 0)
20949 case XML_SCHEMA_TYPE_GROUP:
20950 xmlSchemaCheckGroupDefCircular(
20951 (xmlSchemaModelGroupDefPtr) item, pctxt);
20953 if (pctxt->nberrors != 0)
20956 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20957 xmlSchemaCheckAttrGroupCircular(
20958 (xmlSchemaAttributeGroupPtr) item, pctxt);
20960 if (pctxt->nberrors != 0)
20967 if (pctxt->nberrors != 0)
20970 * Model group definition references:
20971 * Such a reference is reflected by a particle at the component
20972 * level. Until now the 'term' of such particles pointed
20973 * to the model group definition; this was done, in order to
20974 * ease circularity checks. Now we need to set the 'term' of
20975 * such particles to the model group of the model group definition.
20977 for (i = 0; i < nbItems; i++) {
20979 switch (item->type) {
20980 case XML_SCHEMA_TYPE_SEQUENCE:
20981 case XML_SCHEMA_TYPE_CHOICE:
20982 xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
20983 WXS_MODEL_GROUP_CAST item);
20989 if (pctxt->nberrors != 0)
20992 * Expand attribute group references of attribute group definitions.
20994 for (i = 0; i < nbItems; i++) {
20996 switch (item->type) {
20997 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20998 if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
20999 WXS_ATTR_GROUP_HAS_REFS(item))
21001 xmlSchemaAttributeGroupExpandRefs(pctxt,
21002 WXS_ATTR_GROUP_CAST item);
21010 if (pctxt->nberrors != 0)
21013 * First compute the variety of simple types. This is needed as
21014 * a seperate step, since otherwise we won't be able to detect
21015 * circular union types in all cases.
21017 for (i = 0; i < nbItems; i++) {
21019 switch (item->type) {
21020 case XML_SCHEMA_TYPE_SIMPLE:
21021 if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
21022 xmlSchemaFixupSimpleTypeStageOne(pctxt,
21023 (xmlSchemaTypePtr) item);
21031 if (pctxt->nberrors != 0)
21034 * Detect circular union types. Note that this needs the variety to
21035 * be already computed.
21037 for (i = 0; i < nbItems; i++) {
21039 switch (item->type) {
21040 case XML_SCHEMA_TYPE_SIMPLE:
21041 if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
21042 xmlSchemaCheckUnionTypeDefCircular(pctxt,
21043 (xmlSchemaTypePtr) item);
21051 if (pctxt->nberrors != 0)
21055 * Do the complete type fixup for simple types.
21057 for (i = 0; i < nbItems; i++) {
21059 switch (item->type) {
21060 case XML_SCHEMA_TYPE_SIMPLE:
21061 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21062 xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
21070 if (pctxt->nberrors != 0)
21073 * At this point we need build and check all simple types.
21076 * Apply contraints for attribute declarations.
21078 for (i = 0; i < nbItems; i++) {
21080 switch (item->type) {
21081 case XML_SCHEMA_TYPE_ATTRIBUTE:
21082 xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
21089 if (pctxt->nberrors != 0)
21092 * Apply constraints for attribute uses.
21094 for (i = 0; i < nbItems; i++) {
21096 switch (item->type) {
21097 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
21098 if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
21099 xmlSchemaCheckAttrUsePropsCorrect(pctxt,
21100 WXS_ATTR_USE_CAST item);
21108 if (pctxt->nberrors != 0)
21112 * Apply constraints for attribute group definitions.
21114 for (i = 0; i < nbItems; i++) {
21116 switch (item->type) {
21117 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21118 if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
21119 ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
21121 xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
21129 if (pctxt->nberrors != 0)
21133 * Apply constraints for redefinitions.
21135 if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
21136 xmlSchemaCheckSRCRedefineSecond(pctxt);
21137 if (pctxt->nberrors != 0)
21141 * Complex types are builded and checked.
21143 for (i = 0; i < nbItems; i++) {
21144 item = con->pending->items[i];
21145 switch (item->type) {
21146 case XML_SCHEMA_TYPE_COMPLEX:
21147 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21148 xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
21156 if (pctxt->nberrors != 0)
21160 * The list could have changed, since xmlSchemaFixupComplexType()
21161 * will create particles and model groups in some cases.
21163 items = (xmlSchemaTreeItemPtr *) con->pending->items;
21164 nbItems = con->pending->nbItems;
21167 * Apply some constraints for element declarations.
21169 for (i = 0; i < nbItems; i++) {
21171 switch (item->type) {
21172 case XML_SCHEMA_TYPE_ELEMENT:
21173 elemDecl = (xmlSchemaElementPtr) item;
21175 if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
21177 xmlSchemaCheckElementDeclComponent(
21178 (xmlSchemaElementPtr) elemDecl, pctxt);
21182 #ifdef WXS_ELEM_DECL_CONS_ENABLED
21184 * Schema Component Constraint: Element Declarations Consistent
21185 * Apply this constraint to local types of element declarations.
21187 if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
21188 (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
21189 (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
21191 xmlSchemaCheckElementDeclConsistent(pctxt,
21192 WXS_BASIC_CAST elemDecl,
21193 WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
21202 if (pctxt->nberrors != 0)
21206 * Finally we can build the automaton from the content model of
21210 for (i = 0; i < nbItems; i++) {
21212 switch (item->type) {
21213 case XML_SCHEMA_TYPE_COMPLEX:
21214 xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
21221 if (pctxt->nberrors != 0)
21224 * URGENT TODO: cos-element-consistent
21237 * Reset the constructor. This is needed for XSI acquisition, since
21238 * those items will be processed over and over again for every XSI
21239 * if not cleared here.
21241 con->bucket = oldbucket;
21242 con->pending->nbItems = 0;
21243 if (con->substGroups != NULL) {
21244 xmlHashFree(con->substGroups,
21245 (xmlHashDeallocator) xmlSchemaSubstGroupFree);
21246 con->substGroups = NULL;
21248 if (con->redefs != NULL) {
21249 xmlSchemaRedefListFree(con->redefs);
21250 con->redefs = NULL;
21256 * @ctxt: a schema validation context
21258 * parse a schema definition resource and build an internal
21259 * XML Shema struture which can be used to validate instances.
21261 * Returns the internal XML Schema structure built from the resource or
21262 * NULL in case of error
21265 xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
21267 xmlSchemaPtr mainSchema = NULL;
21268 xmlSchemaBucketPtr bucket = NULL;
21272 * This one is used if the schema to be parsed was specified via
21273 * the API; i.e. not automatically by the validated instance document.
21276 xmlSchemaInitTypes();
21281 /* TODO: Init the context. Is this all we need?*/
21282 ctxt->nberrors = 0;
21286 /* Create the *main* schema. */
21287 mainSchema = xmlSchemaNewSchema(ctxt);
21288 if (mainSchema == NULL)
21291 * Create the schema constructor.
21293 if (ctxt->constructor == NULL) {
21294 ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
21295 if (ctxt->constructor == NULL)
21297 /* Take ownership of the constructor to be able to free it. */
21298 ctxt->ownsConstructor = 1;
21300 ctxt->constructor->mainSchema = mainSchema;
21302 * Locate and add the schema document.
21304 res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
21305 ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
21306 NULL, NULL, &bucket);
21312 if (bucket == NULL) {
21313 /* TODO: Error code, actually we failed to *locate* the schema. */
21315 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21317 "Failed to locate the main schema resource at '%s'",
21320 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21322 "Failed to locate the main schema resource",
21326 /* Then do the parsing for good. */
21327 if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
21329 if (ctxt->nberrors != 0)
21332 mainSchema->doc = bucket->doc;
21333 mainSchema->preserve = ctxt->preserve;
21335 ctxt->schema = mainSchema;
21337 if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
21341 * TODO: This is not nice, since we cannot distinguish from the
21342 * result if there was an internal error or not.
21345 if (ctxt->nberrors != 0) {
21347 xmlSchemaFree(mainSchema);
21350 if (ctxt->constructor) {
21351 xmlSchemaConstructionCtxtFree(ctxt->constructor);
21352 ctxt->constructor = NULL;
21353 ctxt->ownsConstructor = 0;
21356 ctxt->schema = NULL;
21357 return(mainSchema);
21360 * Quite verbose, but should catch internal errors, which were
21361 * not communitated.
21364 xmlSchemaFree(mainSchema);
21367 if (ctxt->constructor) {
21368 xmlSchemaConstructionCtxtFree(ctxt->constructor);
21369 ctxt->constructor = NULL;
21370 ctxt->ownsConstructor = 0;
21372 PERROR_INT2("xmlSchemaParse",
21373 "An internal error occured");
21374 ctxt->schema = NULL;
21379 * xmlSchemaSetParserErrors:
21380 * @ctxt: a schema validation context
21381 * @err: the error callback
21382 * @warn: the warning callback
21383 * @ctx: contextual data for the callbacks
21385 * Set the callback functions used to handle errors for a validation context
21388 xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21389 xmlSchemaValidityErrorFunc err,
21390 xmlSchemaValidityWarningFunc warn, void *ctx)
21395 ctxt->warning = warn;
21396 ctxt->errCtxt = ctx;
21397 if (ctxt->vctxt != NULL)
21398 xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
21402 * xmlSchemaSetParserStructuredErrors:
21403 * @ctxt: a schema parser context
21404 * @serror: the structured error function
21405 * @ctx: the functions context
21407 * Set the structured error callback
21410 xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
21411 xmlStructuredErrorFunc serror,
21416 ctxt->serror = serror;
21417 ctxt->errCtxt = ctx;
21418 if (ctxt->vctxt != NULL)
21419 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
21423 * xmlSchemaGetParserErrors:
21424 * @ctxt: a XMl-Schema parser context
21425 * @err: the error callback result
21426 * @warn: the warning callback result
21427 * @ctx: contextual data for the callbacks result
21429 * Get the callback information used to handle errors for a parser context
21431 * Returns -1 in case of failure, 0 otherwise
21434 xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21435 xmlSchemaValidityErrorFunc * err,
21436 xmlSchemaValidityWarningFunc * warn, void **ctx)
21441 *err = ctxt->error;
21443 *warn = ctxt->warning;
21445 *ctx = ctxt->errCtxt;
21450 * xmlSchemaFacetTypeToString:
21451 * @type: the facet type
21453 * Convert the xmlSchemaTypeType to a char string.
21455 * Returns the char string representation of the facet type if the
21456 * type is a facet and an "Internal Error" string otherwise.
21458 static const xmlChar *
21459 xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
21462 case XML_SCHEMA_FACET_PATTERN:
21463 return (BAD_CAST "pattern");
21464 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
21465 return (BAD_CAST "maxExclusive");
21466 case XML_SCHEMA_FACET_MAXINCLUSIVE:
21467 return (BAD_CAST "maxInclusive");
21468 case XML_SCHEMA_FACET_MINEXCLUSIVE:
21469 return (BAD_CAST "minExclusive");
21470 case XML_SCHEMA_FACET_MININCLUSIVE:
21471 return (BAD_CAST "minInclusive");
21472 case XML_SCHEMA_FACET_WHITESPACE:
21473 return (BAD_CAST "whiteSpace");
21474 case XML_SCHEMA_FACET_ENUMERATION:
21475 return (BAD_CAST "enumeration");
21476 case XML_SCHEMA_FACET_LENGTH:
21477 return (BAD_CAST "length");
21478 case XML_SCHEMA_FACET_MAXLENGTH:
21479 return (BAD_CAST "maxLength");
21480 case XML_SCHEMA_FACET_MINLENGTH:
21481 return (BAD_CAST "minLength");
21482 case XML_SCHEMA_FACET_TOTALDIGITS:
21483 return (BAD_CAST "totalDigits");
21484 case XML_SCHEMA_FACET_FRACTIONDIGITS:
21485 return (BAD_CAST "fractionDigits");
21489 return (BAD_CAST "Internal Error");
21492 static xmlSchemaWhitespaceValueType
21493 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
21496 * The normalization type can be changed only for types which are derived
21499 if (type->type == XML_SCHEMA_TYPE_BASIC) {
21501 * Note that we assume a whitespace of preserve for anySimpleType.
21503 if ((type->builtInType == XML_SCHEMAS_STRING) ||
21504 (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
21505 return(XML_SCHEMA_WHITESPACE_PRESERVE);
21506 else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
21507 return(XML_SCHEMA_WHITESPACE_REPLACE);
21510 * For all �atomic� datatypes other than string (and types �derived�
21511 * by �restriction� from it) the value of whiteSpace is fixed to
21513 * Note that this includes built-in list datatypes.
21515 return(XML_SCHEMA_WHITESPACE_COLLAPSE);
21517 } else if (WXS_IS_LIST(type)) {
21519 * For list types the facet "whiteSpace" is fixed to "collapse".
21521 return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21522 } else if (WXS_IS_UNION(type)) {
21523 return (XML_SCHEMA_WHITESPACE_UNKNOWN);
21524 } else if (WXS_IS_ATOMIC(type)) {
21525 if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
21526 return (XML_SCHEMA_WHITESPACE_PRESERVE);
21527 else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
21528 return (XML_SCHEMA_WHITESPACE_REPLACE);
21530 return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21535 /************************************************************************
21537 * Simple type validation *
21539 ************************************************************************/
21542 /************************************************************************
21544 * DOM Validation code *
21546 ************************************************************************/
21549 * xmlSchemaAssembleByLocation:
21550 * @pctxt: a schema parser context
21551 * @vctxt: a schema validation context
21552 * @schema: the existing schema
21553 * @node: the node that fired the assembling
21554 * @nsName: the namespace name of the new schema
21555 * @location: the location of the schema
21557 * Expands an existing schema by an additional schema.
21559 * Returns 0 if the new schema is correct, a positive error code
21560 * number otherwise and -1 in case of an internal or API error.
21563 xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
21564 xmlSchemaPtr schema,
21566 const xmlChar *nsName,
21567 const xmlChar *location)
21570 xmlSchemaParserCtxtPtr pctxt;
21571 xmlSchemaBucketPtr bucket = NULL;
21573 if ((vctxt == NULL) || (schema == NULL))
21576 if (vctxt->pctxt == NULL) {
21577 VERROR_INT("xmlSchemaAssembleByLocation",
21578 "no parser context available");
21581 pctxt = vctxt->pctxt;
21582 if (pctxt->constructor == NULL) {
21583 PERROR_INT("xmlSchemaAssembleByLocation",
21588 * Acquire the schema document.
21590 location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
21593 * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
21594 * the process will automatically change this to
21595 * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
21597 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
21598 location, NULL, NULL, 0, node, NULL, nsName,
21602 if (bucket == NULL) {
21604 * Generate a warning that the document could not be located.
21606 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21608 "The document at location '%s' could not be acquired",
21609 location, NULL, NULL);
21613 * The first located schema will be handled as if all other
21614 * schemas imported by XSI were imported by this first schema.
21616 if ((bucket != NULL) &&
21617 (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
21618 WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
21620 * TODO: Is this handled like an import? I.e. is it not an error
21621 * if the schema cannot be located?
21623 if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
21626 * We will reuse the parser context for every schema imported
21627 * directly via XSI. So reset the context.
21629 pctxt->nberrors = 0;
21631 pctxt->doc = bucket->doc;
21633 ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
21638 /* Paranoid error channelling. */
21639 if ((ret == 0) && (pctxt->nberrors != 0))
21641 if (pctxt->nberrors == 0) {
21643 * Only bother to fixup pending components, if there was
21645 * For every XSI acquired schema (and its sub-schemata) we will
21646 * fixup the components.
21648 xmlSchemaFixupComponents(pctxt, bucket);
21651 * Not nice, but we need somehow to channel the schema parser
21652 * error to the validation context.
21654 if ((ret != 0) && (vctxt->err == 0))
21656 vctxt->nberrors += pctxt->nberrors;
21658 /* Add to validation error sum. */
21659 vctxt->nberrors += pctxt->nberrors;
21668 static xmlSchemaAttrInfoPtr
21669 xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
21672 if (vctxt->nbAttrInfos == 0)
21676 xmlSchemaAttrInfoPtr iattr;
21678 for (i = 0; i < vctxt->nbAttrInfos; i++) {
21679 iattr = vctxt->attrInfos[i];
21680 if (iattr->metaType == metaType)
21689 * xmlSchemaAssembleByXSI:
21690 * @vctxt: a schema validation context
21692 * Expands an existing schema by an additional schema using
21693 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
21694 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
21695 * must be set to 1.
21697 * Returns 0 if the new schema is correct, a positive error code
21698 * number otherwise and -1 in case of an internal or API error.
21701 xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
21703 const xmlChar *cur, *end;
21704 const xmlChar *nsname = NULL, *location;
21707 xmlSchemaAttrInfoPtr iattr;
21710 * Parse the value; we will assume an even number of values
21711 * to be given (this is how Xerces and XSV work).
21713 * URGENT TODO: !! This needs to work for both
21714 * @noNamespaceSchemaLocation AND @schemaLocation on the same
21717 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21718 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
21720 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21721 XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
21724 cur = iattr->value;
21727 * TODO: Move the string parsing mechanism away from here.
21729 if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
21731 * Get the namespace name.
21733 while (IS_BLANK_CH(*cur))
21736 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21740 count++; /* TODO: Don't use the schema's dict. */
21741 nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21747 while (IS_BLANK_CH(*cur))
21750 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21753 if (iattr->metaType ==
21754 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
21757 * If using @schemaLocation then tuples are expected.
21758 * I.e. the namespace name *and* the document's URI.
21760 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21762 "The value must consist of tuples: the target namespace "
21763 "name and the document's URI", NULL, NULL, NULL);
21767 count++; /* TODO: Don't use the schema's dict. */
21768 location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21770 ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
21771 iattr->node, nsname, location);
21773 VERROR_INT("xmlSchemaAssembleByXSI",
21774 "assembling schemata");
21777 } while (*cur != 0);
21781 static const xmlChar *
21782 xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
21783 const xmlChar *prefix)
21785 if (vctxt->sax != NULL) {
21787 xmlSchemaNodeInfoPtr inode;
21789 for (i = vctxt->depth; i >= 0; i--) {
21790 if (vctxt->elemInfos[i]->nbNsBindings != 0) {
21791 inode = vctxt->elemInfos[i];
21792 for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
21793 if (((prefix == NULL) &&
21794 (inode->nsBindings[j] == NULL)) ||
21795 ((prefix != NULL) && xmlStrEqual(prefix,
21796 inode->nsBindings[j]))) {
21799 * Note that the namespace bindings are already
21800 * in a string dict.
21802 return (inode->nsBindings[j+1]);
21808 #ifdef LIBXML_READER_ENABLED
21809 } else if (vctxt->reader != NULL) {
21812 nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
21813 if (nsName != NULL) {
21814 const xmlChar *ret;
21816 ret = xmlDictLookup(vctxt->dict, nsName, -1);
21825 if ((vctxt->inode->node == NULL) ||
21826 (vctxt->inode->node->doc == NULL)) {
21827 VERROR_INT("xmlSchemaLookupNamespace",
21828 "no node or node's doc avaliable");
21831 ns = xmlSearchNs(vctxt->inode->node->doc,
21832 vctxt->inode->node, prefix);
21840 * This one works on the schema of the validation context.
21843 xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
21844 xmlSchemaPtr schema,
21846 const xmlChar *value,
21847 xmlSchemaValPtr *val,
21852 if (vctxt && (vctxt->schema == NULL)) {
21853 VERROR_INT("xmlSchemaValidateNotation",
21854 "a schema is needed on the validation context");
21857 ret = xmlValidateQName(value, 1);
21861 xmlChar *localName = NULL;
21862 xmlChar *prefix = NULL;
21864 localName = xmlSplitQName2(value, &prefix);
21865 if (prefix != NULL) {
21866 const xmlChar *nsName = NULL;
21869 nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
21870 else if (node != NULL) {
21871 xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
21876 xmlFree(localName);
21879 if (nsName == NULL) {
21881 xmlFree(localName);
21884 if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
21885 if ((valNeeded) && (val != NULL)) {
21886 (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
21887 xmlStrdup(nsName));
21894 xmlFree(localName);
21896 if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
21897 if (valNeeded && (val != NULL)) {
21898 (*val) = xmlSchemaNewNOTATIONValue(
21899 BAD_CAST xmlStrdup(value), NULL);
21911 xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
21912 const xmlChar* lname,
21913 const xmlChar* nsname)
21917 lname = xmlDictLookup(vctxt->dict, lname, -1);
21920 if (nsname != NULL) {
21921 nsname = xmlDictLookup(vctxt->dict, nsname, -1);
21922 if (nsname == NULL)
21925 for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
21926 if ((vctxt->nodeQNames->items [i] == lname) &&
21927 (vctxt->nodeQNames->items[i +1] == nsname))
21928 /* Already there */
21931 /* Add new entry. */
21932 i = vctxt->nodeQNames->nbItems;
21933 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
21934 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
21938 /************************************************************************
21940 * Validation of identity-constraints (IDC) *
21942 ************************************************************************/
21945 * xmlSchemaAugmentIDC:
21946 * @idcDef: the IDC definition
21948 * Creates an augmented IDC definition item.
21950 * Returns the item, or NULL on internal errors.
21953 xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef,
21954 xmlSchemaValidCtxtPtr vctxt)
21956 xmlSchemaIDCAugPtr aidc;
21958 aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
21959 if (aidc == NULL) {
21960 xmlSchemaVErrMemory(vctxt,
21961 "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
21965 aidc->keyrefDepth = -1;
21966 aidc->def = idcDef;
21968 if (vctxt->aidcs == NULL)
21969 vctxt->aidcs = aidc;
21971 aidc->next = vctxt->aidcs;
21972 vctxt->aidcs = aidc;
21975 * Save if we have keyrefs at all.
21977 if ((vctxt->hasKeyrefs == 0) &&
21978 (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
21979 vctxt->hasKeyrefs = 1;
21983 * xmlSchemaAugmentImportedIDC:
21984 * @imported: the imported schema
21986 * Creates an augmented IDC definition for the imported schema.
21989 xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) {
21990 if (imported->schema->idcDef != NULL) {
21991 xmlHashScan(imported->schema->idcDef ,
21992 (xmlHashScanner) xmlSchemaAugmentIDC, vctxt);
21997 * xmlSchemaIDCNewBinding:
21998 * @idcDef: the IDC definition of this binding
22000 * Creates a new IDC binding.
22002 * Returns the new IDC binding, NULL on internal errors.
22004 static xmlSchemaPSVIIDCBindingPtr
22005 xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
22007 xmlSchemaPSVIIDCBindingPtr ret;
22009 ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
22010 sizeof(xmlSchemaPSVIIDCBinding));
22012 xmlSchemaVErrMemory(NULL,
22013 "allocating a PSVI IDC binding item", NULL);
22016 memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
22017 ret->definition = idcDef;
22022 * xmlSchemaIDCStoreNodeTableItem:
22023 * @vctxt: the WXS validation context
22024 * @item: the IDC node table item
22026 * The validation context is used to store IDC node table items.
22027 * They are stored to avoid copying them if IDC node-tables are merged
22028 * with corresponding parent IDC node-tables (bubbling).
22030 * Returns 0 if succeeded, -1 on internal errors.
22033 xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
22034 xmlSchemaPSVIIDCNodePtr item)
22037 * Add to gobal list.
22039 if (vctxt->idcNodes == NULL) {
22040 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22041 xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
22042 if (vctxt->idcNodes == NULL) {
22043 xmlSchemaVErrMemory(vctxt,
22044 "allocating the IDC node table item list", NULL);
22047 vctxt->sizeIdcNodes = 20;
22048 } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
22049 vctxt->sizeIdcNodes *= 2;
22050 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22051 xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
22052 sizeof(xmlSchemaPSVIIDCNodePtr));
22053 if (vctxt->idcNodes == NULL) {
22054 xmlSchemaVErrMemory(vctxt,
22055 "re-allocating the IDC node table item list", NULL);
22059 vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
22065 * xmlSchemaIDCStoreKey:
22066 * @vctxt: the WXS validation context
22067 * @item: the IDC key
22069 * The validation context is used to store an IDC key.
22071 * Returns 0 if succeeded, -1 on internal errors.
22074 xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
22075 xmlSchemaPSVIIDCKeyPtr key)
22078 * Add to gobal list.
22080 if (vctxt->idcKeys == NULL) {
22081 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22082 xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
22083 if (vctxt->idcKeys == NULL) {
22084 xmlSchemaVErrMemory(vctxt,
22085 "allocating the IDC key storage list", NULL);
22088 vctxt->sizeIdcKeys = 40;
22089 } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
22090 vctxt->sizeIdcKeys *= 2;
22091 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22092 xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
22093 sizeof(xmlSchemaPSVIIDCKeyPtr));
22094 if (vctxt->idcKeys == NULL) {
22095 xmlSchemaVErrMemory(vctxt,
22096 "re-allocating the IDC key storage list", NULL);
22100 vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
22106 * xmlSchemaIDCAppendNodeTableItem:
22107 * @bind: the IDC binding
22108 * @ntItem: the node-table item
22110 * Appends the IDC node-table item to the binding.
22112 * Returns 0 on success and -1 on internal errors.
22115 xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
22116 xmlSchemaPSVIIDCNodePtr ntItem)
22118 if (bind->nodeTable == NULL) {
22119 bind->sizeNodes = 10;
22120 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22121 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
22122 if (bind->nodeTable == NULL) {
22123 xmlSchemaVErrMemory(NULL,
22124 "allocating an array of IDC node-table items", NULL);
22127 } else if (bind->sizeNodes <= bind->nbNodes) {
22128 bind->sizeNodes *= 2;
22129 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22130 xmlRealloc(bind->nodeTable, bind->sizeNodes *
22131 sizeof(xmlSchemaPSVIIDCNodePtr));
22132 if (bind->nodeTable == NULL) {
22133 xmlSchemaVErrMemory(NULL,
22134 "re-allocating an array of IDC node-table items", NULL);
22138 bind->nodeTable[bind->nbNodes++] = ntItem;
22143 * xmlSchemaIDCAcquireBinding:
22144 * @vctxt: the WXS validation context
22145 * @matcher: the IDC matcher
22147 * Looks up an PSVI IDC binding, for the IDC definition and
22148 * of the given matcher. If none found, a new one is created
22149 * and added to the IDC table.
22151 * Returns an IDC binding or NULL on internal errors.
22153 static xmlSchemaPSVIIDCBindingPtr
22154 xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
22155 xmlSchemaIDCMatcherPtr matcher)
22157 xmlSchemaNodeInfoPtr ielem;
22159 ielem = vctxt->elemInfos[matcher->depth];
22161 if (ielem->idcTable == NULL) {
22162 ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
22163 if (ielem->idcTable == NULL)
22165 return(ielem->idcTable);
22167 xmlSchemaPSVIIDCBindingPtr bind = NULL;
22169 bind = ielem->idcTable;
22171 if (bind->definition == matcher->aidc->def)
22173 if (bind->next == NULL) {
22174 bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
22175 if (bind->next == NULL)
22177 return(bind->next);
22180 } while (bind != NULL);
22185 static xmlSchemaItemListPtr
22186 xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
22187 xmlSchemaIDCMatcherPtr matcher)
22189 if (matcher->targets == NULL)
22190 matcher->targets = xmlSchemaItemListCreate();
22191 return(matcher->targets);
22195 * xmlSchemaIDCFreeKey:
22196 * @key: the IDC key
22198 * Frees an IDC key together with its compiled value.
22201 xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
22203 if (key->val != NULL)
22204 xmlSchemaFreeValue(key->val);
22209 * xmlSchemaIDCFreeBinding:
22211 * Frees an IDC binding. Note that the node table-items
22215 xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
22217 if (bind->nodeTable != NULL)
22218 xmlFree(bind->nodeTable);
22219 if (bind->dupls != NULL)
22220 xmlSchemaItemListFree(bind->dupls);
22225 * xmlSchemaIDCFreeIDCTable:
22226 * @bind: the first IDC binding in the list
22228 * Frees an IDC table, i.e. all the IDC bindings in the list.
22231 xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
22233 xmlSchemaPSVIIDCBindingPtr prev;
22235 while (bind != NULL) {
22238 xmlSchemaIDCFreeBinding(prev);
22243 * xmlSchemaIDCFreeMatcherList:
22244 * @matcher: the first IDC matcher in the list
22246 * Frees a list of IDC matchers.
22249 xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
22251 xmlSchemaIDCMatcherPtr next;
22253 while (matcher != NULL) {
22254 next = matcher->next;
22255 if (matcher->keySeqs != NULL) {
22257 for (i = 0; i < matcher->sizeKeySeqs; i++)
22258 if (matcher->keySeqs[i] != NULL)
22259 xmlFree(matcher->keySeqs[i]);
22260 xmlFree(matcher->keySeqs);
22262 if (matcher->targets != NULL) {
22263 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22265 xmlSchemaPSVIIDCNodePtr idcNode;
22267 * Node-table items for keyrefs are not stored globally
22268 * to the validation context, since they are not bubbled.
22269 * We need to free them here.
22271 for (i = 0; i < matcher->targets->nbItems; i++) {
22273 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22274 xmlFree(idcNode->keys);
22278 xmlSchemaItemListFree(matcher->targets);
22286 * xmlSchemaIDCReleaseMatcherList:
22287 * @vctxt: the WXS validation context
22288 * @matcher: the first IDC matcher in the list
22290 * Caches a list of IDC matchers for reuse.
22293 xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
22294 xmlSchemaIDCMatcherPtr matcher)
22296 xmlSchemaIDCMatcherPtr next;
22298 while (matcher != NULL) {
22299 next = matcher->next;
22300 if (matcher->keySeqs != NULL) {
22303 * Don't free the array, but only the content.
22305 for (i = 0; i < matcher->sizeKeySeqs; i++)
22306 if (matcher->keySeqs[i] != NULL) {
22307 xmlFree(matcher->keySeqs[i]);
22308 matcher->keySeqs[i] = NULL;
22311 if (matcher->targets) {
22312 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22314 xmlSchemaPSVIIDCNodePtr idcNode;
22316 * Node-table items for keyrefs are not stored globally
22317 * to the validation context, since they are not bubbled.
22318 * We need to free them here.
22320 for (i = 0; i < matcher->targets->nbItems; i++) {
22322 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22323 xmlFree(idcNode->keys);
22327 xmlSchemaItemListFree(matcher->targets);
22328 matcher->targets = NULL;
22330 matcher->next = NULL;
22332 * Cache the matcher.
22334 if (vctxt->idcMatcherCache != NULL)
22335 matcher->nextCached = vctxt->idcMatcherCache;
22336 vctxt->idcMatcherCache = matcher;
22343 * xmlSchemaIDCAddStateObject:
22344 * @vctxt: the WXS validation context
22345 * @matcher: the IDC matcher
22346 * @sel: the XPath information
22347 * @parent: the parent "selector" state object if any
22348 * @type: "selector" or "field"
22350 * Creates/reuses and activates state objects for the given
22351 * XPath information; if the XPath expression consists of unions,
22352 * multiple state objects are created for every unioned expression.
22354 * Returns 0 on success and -1 on internal errors.
22357 xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
22358 xmlSchemaIDCMatcherPtr matcher,
22359 xmlSchemaIDCSelectPtr sel,
22362 xmlSchemaIDCStateObjPtr sto;
22365 * Reuse the state objects from the pool.
22367 if (vctxt->xpathStatePool != NULL) {
22368 sto = vctxt->xpathStatePool;
22369 vctxt->xpathStatePool = sto->next;
22373 * Create a new state object.
22375 sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
22377 xmlSchemaVErrMemory(NULL,
22378 "allocating an IDC state object", NULL);
22381 memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
22384 * Add to global list.
22386 if (vctxt->xpathStates != NULL)
22387 sto->next = vctxt->xpathStates;
22388 vctxt->xpathStates = sto;
22391 * Free the old xpath validation context.
22393 if (sto->xpathCtxt != NULL)
22394 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
22397 * Create a new XPath (pattern) validation context.
22399 sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
22400 (xmlPatternPtr) sel->xpathComp);
22401 if (sto->xpathCtxt == NULL) {
22402 VERROR_INT("xmlSchemaIDCAddStateObject",
22403 "failed to create an XPath validation context");
22407 sto->depth = vctxt->depth;
22408 sto->matcher = matcher;
22410 sto->nbHistory = 0;
22413 xmlGenericError(xmlGenericErrorContext, "IDC: STO push '%s'\n",
22420 * xmlSchemaXPathEvaluate:
22421 * @vctxt: the WXS validation context
22422 * @nodeType: the nodeType of the current node
22424 * Evaluates all active XPath state objects.
22426 * Returns the number of IC "field" state objects which resolved to
22427 * this node, 0 if none resolved and -1 on internal errors.
22430 xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
22431 xmlElementType nodeType)
22433 xmlSchemaIDCStateObjPtr sto, head = NULL, first;
22434 int res, resolved = 0, depth = vctxt->depth;
22436 if (vctxt->xpathStates == NULL)
22439 if (nodeType == XML_ATTRIBUTE_NODE)
22443 xmlChar *str = NULL;
22444 xmlGenericError(xmlGenericErrorContext,
22445 "IDC: EVAL on %s, depth %d, type %d\n",
22446 xmlSchemaFormatQName(&str, vctxt->inode->nsName,
22447 vctxt->inode->localName), depth, nodeType);
22452 * Process all active XPath state objects.
22454 first = vctxt->xpathStates;
22456 while (sto != head) {
22458 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
22459 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] selector '%s'\n",
22460 sto->matcher->aidc->def->name, sto->sel->xpath);
22462 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] field '%s'\n",
22463 sto->matcher->aidc->def->name, sto->sel->xpath);
22465 if (nodeType == XML_ELEMENT_NODE)
22466 res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
22467 vctxt->inode->localName, vctxt->inode->nsName);
22469 res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
22470 vctxt->inode->localName, vctxt->inode->nsName);
22473 VERROR_INT("xmlSchemaXPathEvaluate",
22474 "calling xmlStreamPush()");
22483 xmlGenericError(xmlGenericErrorContext, "IDC: "
22487 * Register a match in the state object history.
22489 if (sto->history == NULL) {
22490 sto->history = (int *) xmlMalloc(5 * sizeof(int));
22491 if (sto->history == NULL) {
22492 xmlSchemaVErrMemory(NULL,
22493 "allocating the state object history", NULL);
22496 sto->sizeHistory = 5;
22497 } else if (sto->sizeHistory <= sto->nbHistory) {
22498 sto->sizeHistory *= 2;
22499 sto->history = (int *) xmlRealloc(sto->history,
22500 sto->sizeHistory * sizeof(int));
22501 if (sto->history == NULL) {
22502 xmlSchemaVErrMemory(NULL,
22503 "re-allocating the state object history", NULL);
22507 sto->history[sto->nbHistory++] = depth;
22510 xmlGenericError(xmlGenericErrorContext, "IDC: push match '%d'\n",
22514 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22515 xmlSchemaIDCSelectPtr sel;
22517 * Activate state objects for the IDC fields of
22518 * the IDC selector.
22521 xmlGenericError(xmlGenericErrorContext, "IDC: "
22522 "activating field states\n");
22524 sel = sto->matcher->aidc->def->fields;
22525 while (sel != NULL) {
22526 if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
22527 sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
22531 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22533 * An IDC key node was found by the IDC field.
22536 xmlGenericError(xmlGenericErrorContext,
22537 "IDC: key found\n");
22540 * Notify that the character value of this node is
22543 if (resolved == 0) {
22544 if ((vctxt->inode->flags &
22545 XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
22546 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
22551 if (sto->next == NULL) {
22553 * Evaluate field state objects created on this node as well.
22556 sto = vctxt->xpathStates;
22563 static const xmlChar *
22564 xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
22566 xmlSchemaPSVIIDCKeyPtr *seq,
22570 xmlChar *value = NULL;
22572 *buf = xmlStrdup(BAD_CAST "[");
22573 for (i = 0; i < count; i++) {
22574 *buf = xmlStrcat(*buf, BAD_CAST "'");
22575 res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
22576 xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
22579 *buf = xmlStrcat(*buf, BAD_CAST value);
22581 VERROR_INT("xmlSchemaFormatIDCKeySequence",
22582 "failed to compute a canonical value");
22583 *buf = xmlStrcat(*buf, BAD_CAST "???");
22586 *buf = xmlStrcat(*buf, BAD_CAST "', ");
22588 *buf = xmlStrcat(*buf, BAD_CAST "'");
22589 if (value != NULL) {
22594 *buf = xmlStrcat(*buf, BAD_CAST "]");
22596 return (BAD_CAST *buf);
22600 * xmlSchemaXPathPop:
22601 * @vctxt: the WXS validation context
22603 * Pops all XPath states.
22605 * Returns 0 on success and -1 on internal errors.
22608 xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
22610 xmlSchemaIDCStateObjPtr sto;
22613 if (vctxt->xpathStates == NULL)
22615 sto = vctxt->xpathStates;
22617 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22621 } while (sto != NULL);
22626 * xmlSchemaXPathProcessHistory:
22627 * @vctxt: the WXS validation context
22628 * @type: the simple/complex type of the current node if any at all
22629 * @val: the precompiled value
22631 * Processes and pops the history items of the IDC state objects.
22632 * IDC key-sequences are validated/created on IDC bindings.
22634 * Returns 0 on success and -1 on internal errors.
22637 xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
22640 xmlSchemaIDCStateObjPtr sto, nextsto;
22641 int res, matchDepth;
22642 xmlSchemaPSVIIDCKeyPtr key = NULL;
22643 xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
22645 if (vctxt->xpathStates == NULL)
22647 sto = vctxt->xpathStates;
22651 xmlChar *str = NULL;
22652 xmlGenericError(xmlGenericErrorContext,
22653 "IDC: BACK on %s, depth %d\n",
22654 xmlSchemaFormatQName(&str, vctxt->inode->nsName,
22655 vctxt->inode->localName), vctxt->depth);
22660 * Evaluate the state objects.
22662 while (sto != NULL) {
22663 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22665 VERROR_INT("xmlSchemaXPathProcessHistory",
22666 "calling xmlStreamPop()");
22670 xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n",
22673 if (sto->nbHistory == 0)
22674 goto deregister_check;
22676 matchDepth = sto->history[sto->nbHistory -1];
22679 * Only matches at the current depth are of interest.
22681 if (matchDepth != depth) {
22685 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22687 * NOTE: According to
22688 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
22689 * ... the simple-content of complex types is also allowed.
22692 if (WXS_IS_COMPLEX(type)) {
22693 if (WXS_HAS_SIMPLE_CONTENT(type)) {
22695 * Sanity check for complex types with simple content.
22697 simpleType = type->contentTypeDef;
22698 if (simpleType == NULL) {
22699 VERROR_INT("xmlSchemaXPathProcessHistory",
22700 "field resolves to a CT with simple content "
22701 "but the CT is missing the ST definition");
22708 if (simpleType == NULL) {
22709 xmlChar *str = NULL;
22712 * Not qualified if the field resolves to a node of non
22715 xmlSchemaCustomErr(ACTXT_CAST vctxt,
22716 XML_SCHEMAV_CVC_IDC, NULL,
22717 WXS_BASIC_CAST sto->matcher->aidc->def,
22718 "The XPath '%s' of a field of %s does evaluate to a node of "
22721 xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
22722 FREE_AND_NULL(str);
22724 goto deregister_check;
22727 if ((key == NULL) && (vctxt->inode->val == NULL)) {
22729 * Failed to provide the normalized value; maybe
22730 * the value was invalid.
22732 VERROR(XML_SCHEMAV_CVC_IDC,
22733 WXS_BASIC_CAST sto->matcher->aidc->def,
22734 "Warning: No precomputed value available, the value "
22735 "was either invalid or something strange happend");
22737 goto deregister_check;
22739 xmlSchemaIDCMatcherPtr matcher = sto->matcher;
22740 xmlSchemaPSVIIDCKeyPtr *keySeq;
22744 * The key will be anchored on the matcher's list of
22745 * key-sequences. The position in this list is determined
22746 * by the target node's depth relative to the matcher's
22747 * depth of creation (i.e. the depth of the scope element).
22749 * Element Depth Pos List-entries
22752 * <target/> 2 2 target
22756 * The size of the list is only dependant on the depth of
22758 * An entry will be NULLed in selector_leave, i.e. when
22759 * we hit the target's
22761 pos = sto->depth - matcher->depth;
22762 idx = sto->sel->index;
22765 * Create/grow the array of key-sequences.
22767 if (matcher->keySeqs == NULL) {
22769 matcher->sizeKeySeqs = pos * 2;
22771 matcher->sizeKeySeqs = 10;
22772 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22773 xmlMalloc(matcher->sizeKeySeqs *
22774 sizeof(xmlSchemaPSVIIDCKeyPtr *));
22775 if (matcher->keySeqs == NULL) {
22776 xmlSchemaVErrMemory(NULL,
22777 "allocating an array of key-sequences",
22781 memset(matcher->keySeqs, 0,
22782 matcher->sizeKeySeqs *
22783 sizeof(xmlSchemaPSVIIDCKeyPtr *));
22784 } else if (pos >= matcher->sizeKeySeqs) {
22785 int i = matcher->sizeKeySeqs;
22787 matcher->sizeKeySeqs *= 2;
22788 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22789 xmlRealloc(matcher->keySeqs,
22790 matcher->sizeKeySeqs *
22791 sizeof(xmlSchemaPSVIIDCKeyPtr *));
22792 if (matcher->keySeqs == NULL) {
22793 xmlSchemaVErrMemory(NULL,
22794 "reallocating an array of key-sequences",
22799 * The array needs to be NULLed.
22800 * TODO: Use memset?
22802 for (; i < matcher->sizeKeySeqs; i++)
22803 matcher->keySeqs[i] = NULL;
22807 * Get/create the key-sequence.
22809 keySeq = matcher->keySeqs[pos];
22810 if (keySeq == NULL) {
22811 goto create_sequence;
22812 } else if (keySeq[idx] != NULL) {
22813 xmlChar *str = NULL;
22815 * cvc-identity-constraint:
22816 * 3 For each node in the �target node set� all
22817 * of the {fields}, with that node as the context
22818 * node, evaluate to either an empty node-set or
22819 * a node-set with exactly one member, which must
22820 * have a simple type.
22822 * The key was already set; report an error.
22824 xmlSchemaCustomErr(ACTXT_CAST vctxt,
22825 XML_SCHEMAV_CVC_IDC, NULL,
22826 WXS_BASIC_CAST matcher->aidc->def,
22827 "The XPath '%s' of a field of %s evaluates to a "
22828 "node-set with more than one member",
22830 xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
22831 FREE_AND_NULL(str);
22833 goto deregister_check;
22839 * Create a key-sequence.
22841 keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
22842 matcher->aidc->def->nbFields *
22843 sizeof(xmlSchemaPSVIIDCKeyPtr));
22844 if (keySeq == NULL) {
22845 xmlSchemaVErrMemory(NULL,
22846 "allocating an IDC key-sequence", NULL);
22849 memset(keySeq, 0, matcher->aidc->def->nbFields *
22850 sizeof(xmlSchemaPSVIIDCKeyPtr));
22851 matcher->keySeqs[pos] = keySeq;
22854 * Create a key once per node only.
22857 key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
22858 sizeof(xmlSchemaPSVIIDCKey));
22860 xmlSchemaVErrMemory(NULL,
22861 "allocating a IDC key", NULL);
22863 matcher->keySeqs[pos] = NULL;
22867 * Consume the compiled value.
22869 key->type = simpleType;
22870 key->val = vctxt->inode->val;
22871 vctxt->inode->val = NULL;
22873 * Store the key in a global list.
22875 if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
22876 xmlSchemaIDCFreeKey(key);
22882 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22884 xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
22885 /* xmlSchemaPSVIIDCBindingPtr bind; */
22886 xmlSchemaPSVIIDCNodePtr ntItem;
22887 xmlSchemaIDCMatcherPtr matcher;
22888 xmlSchemaIDCPtr idc;
22889 xmlSchemaItemListPtr targets;
22890 int pos, i, j, nbKeys;
22892 * Here we have the following scenario:
22893 * An IDC 'selector' state object resolved to a target node,
22894 * during the time this target node was in the
22895 * ancestor-or-self axis, the 'field' state object(s) looked
22896 * out for matching nodes to create a key-sequence for this
22897 * target node. Now we are back to this target node and need
22898 * to put the key-sequence, together with the target node
22899 * itself, into the node-table of the corresponding IDC
22902 matcher = sto->matcher;
22903 idc = matcher->aidc->def;
22904 nbKeys = idc->nbFields;
22905 pos = depth - matcher->depth;
22907 * Check if the matcher has any key-sequences at all, plus
22908 * if it has a key-sequence for the current target node.
22910 if ((matcher->keySeqs == NULL) ||
22911 (matcher->sizeKeySeqs <= pos)) {
22912 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22913 goto selector_key_error;
22915 goto selector_leave;
22918 keySeq = &(matcher->keySeqs[pos]);
22919 if (*keySeq == NULL) {
22920 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22921 goto selector_key_error;
22923 goto selector_leave;
22926 for (i = 0; i < nbKeys; i++) {
22927 if ((*keySeq)[i] == NULL) {
22929 * Not qualified, if not all fields did resolve.
22931 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
22933 * All fields of a "key" IDC must resolve.
22935 goto selector_key_error;
22937 goto selector_leave;
22941 * All fields did resolve.
22945 * 4.1 If the {identity-constraint category} is unique(/key),
22946 * then no two members of the �qualified node set� have
22947 * �key-sequences� whose members are pairwise equal, as
22948 * defined by Equal in [XML Schemas: Datatypes].
22950 * Get the IDC binding from the matcher and check for
22951 * duplicate key-sequences.
22954 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
22956 targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
22957 if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
22958 (targets->nbItems != 0)) {
22959 xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
22964 * Compare the key-sequences, key by key.
22968 ((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys;
22969 for (j = 0; j < nbKeys; j++) {
22970 ckey = (*keySeq)[j];
22972 res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
22975 } else if (res == 0) {
22977 * One of the keys differs, so the key-sequence
22978 * won't be equal; get out.
22985 * Duplicate key-sequence found.
22990 } while (i < targets->nbItems);
22991 if (i != targets->nbItems) {
22992 xmlChar *str = NULL, *strB = NULL;
22994 * TODO: Try to report the key-sequence.
22996 xmlSchemaCustomErr(ACTXT_CAST vctxt,
22997 XML_SCHEMAV_CVC_IDC, NULL,
22998 WXS_BASIC_CAST idc,
22999 "Duplicate key-sequence %s in %s",
23000 xmlSchemaFormatIDCKeySequence(vctxt, &str,
23001 (*keySeq), nbKeys),
23002 xmlSchemaGetIDCDesignation(&strB, idc));
23003 FREE_AND_NULL(str);
23004 FREE_AND_NULL(strB);
23005 goto selector_leave;
23009 * Add a node-table item to the IDC binding.
23011 ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
23012 sizeof(xmlSchemaPSVIIDCNode));
23013 if (ntItem == NULL) {
23014 xmlSchemaVErrMemory(NULL,
23015 "allocating an IDC node-table item", NULL);
23020 memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
23023 * Store the node-table item in a global list.
23025 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
23026 if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
23032 ntItem->nodeQNameID = -1;
23035 * Save a cached QName for this node on the IDC node, to be
23036 * able to report it, even if the node is not saved.
23038 ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
23039 vctxt->inode->localName, vctxt->inode->nsName);
23040 if (ntItem->nodeQNameID == -1) {
23048 * Init the node-table item: Save the node, position and
23049 * consume the key-sequence.
23051 ntItem->node = vctxt->node;
23052 ntItem->nodeLine = vctxt->inode->nodeLine;
23053 ntItem->keys = *keySeq;
23056 if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
23058 if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
23059 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23061 * Free the item, since keyref items won't be
23062 * put on a global list.
23064 xmlFree(ntItem->keys);
23070 goto selector_leave;
23071 selector_key_error:
23073 xmlChar *str = NULL;
23075 * 4.2.1 (KEY) The �target node set� and the
23076 * �qualified node set� are equal, that is, every
23077 * member of the �target node set� is also a member
23078 * of the �qualified node set� and vice versa.
23080 xmlSchemaCustomErr(ACTXT_CAST vctxt,
23081 XML_SCHEMAV_CVC_IDC, NULL,
23082 WXS_BASIC_CAST idc,
23083 "Not all fields of %s evaluate to a node",
23084 xmlSchemaGetIDCDesignation(&str, idc), NULL);
23085 FREE_AND_NULL(str);
23089 * Free the key-sequence if not added to the IDC table.
23091 if ((keySeq != NULL) && (*keySeq != NULL)) {
23095 } /* if selector */
23101 * Deregister state objects if they reach the depth of creation.
23103 if ((sto->nbHistory == 0) && (sto->depth == depth)) {
23105 xmlGenericError(xmlGenericErrorContext, "IDC: STO pop '%s'\n",
23108 if (vctxt->xpathStates != sto) {
23109 VERROR_INT("xmlSchemaXPathProcessHistory",
23110 "The state object to be removed is not the first "
23113 nextsto = sto->next;
23115 * Unlink from the list of active XPath state objects.
23117 vctxt->xpathStates = sto->next;
23118 sto->next = vctxt->xpathStatePool;
23120 * Link it to the pool of reusable state objects.
23122 vctxt->xpathStatePool = sto;
23126 } /* while (sto != NULL) */
23131 * xmlSchemaIDCRegisterMatchers:
23132 * @vctxt: the WXS validation context
23133 * @elemDecl: the element declaration
23135 * Creates helper objects to evaluate IDC selectors/fields
23138 * Returns 0 if OK and -1 on internal errors.
23141 xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
23142 xmlSchemaElementPtr elemDecl)
23144 xmlSchemaIDCMatcherPtr matcher, last = NULL;
23145 xmlSchemaIDCPtr idc, refIdc;
23146 xmlSchemaIDCAugPtr aidc;
23148 idc = (xmlSchemaIDCPtr) elemDecl->idcs;
23154 xmlChar *str = NULL;
23155 xmlGenericError(xmlGenericErrorContext,
23156 "IDC: REGISTER on %s, depth %d\n",
23157 (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
23158 vctxt->inode->localName), vctxt->depth);
23162 if (vctxt->inode->idcMatchers != NULL) {
23163 VERROR_INT("xmlSchemaIDCRegisterMatchers",
23164 "The chain of IDC matchers is expected to be empty");
23168 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23170 * Since IDCs bubbles are expensive we need to know the
23171 * depth at which the bubbles should stop; this will be
23172 * the depth of the top-most keyref IDC. If no keyref
23173 * references a key/unique IDC, the keyrefDepth will
23174 * be -1, indicating that no bubbles are needed.
23176 refIdc = (xmlSchemaIDCPtr) idc->ref->item;
23177 if (refIdc != NULL) {
23179 * Remember that we have keyrefs on this node.
23181 vctxt->inode->hasKeyrefs = 1;
23183 * Lookup the referenced augmented IDC info.
23185 aidc = vctxt->aidcs;
23186 while (aidc != NULL) {
23187 if (aidc->def == refIdc)
23191 if (aidc == NULL) {
23192 VERROR_INT("xmlSchemaIDCRegisterMatchers",
23193 "Could not find an augmented IDC item for an IDC "
23197 if ((aidc->keyrefDepth == -1) ||
23198 (vctxt->depth < aidc->keyrefDepth))
23199 aidc->keyrefDepth = vctxt->depth;
23203 * Lookup the augmented IDC item for the IDC definition.
23205 aidc = vctxt->aidcs;
23206 while (aidc != NULL) {
23207 if (aidc->def == idc)
23211 if (aidc == NULL) {
23212 VERROR_INT("xmlSchemaIDCRegisterMatchers",
23213 "Could not find an augmented IDC item for an IDC definition");
23217 * Create an IDC matcher for every IDC definition.
23219 if (vctxt->idcMatcherCache != NULL) {
23221 * Reuse a cached matcher.
23223 matcher = vctxt->idcMatcherCache;
23224 vctxt->idcMatcherCache = matcher->nextCached;
23225 matcher->nextCached = NULL;
23227 matcher = (xmlSchemaIDCMatcherPtr)
23228 xmlMalloc(sizeof(xmlSchemaIDCMatcher));
23229 if (matcher == NULL) {
23230 xmlSchemaVErrMemory(vctxt,
23231 "allocating an IDC matcher", NULL);
23234 memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
23237 vctxt->inode->idcMatchers = matcher;
23239 last->next = matcher;
23242 matcher->type = IDC_MATCHER;
23243 matcher->depth = vctxt->depth;
23244 matcher->aidc = aidc;
23245 matcher->idcType = aidc->def->type;
23247 xmlGenericError(xmlGenericErrorContext, "IDC: register matcher\n");
23250 * Init the automaton state object.
23252 if (xmlSchemaIDCAddStateObject(vctxt, matcher,
23253 idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
23257 } while (idc != NULL);
23262 xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
23263 xmlSchemaNodeInfoPtr ielem)
23265 xmlSchemaPSVIIDCBindingPtr bind;
23266 int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
23267 xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
23268 xmlSchemaPSVIIDCNodePtr *targets, *dupls;
23270 xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
23271 /* vctxt->createIDCNodeTables */
23272 while (matcher != NULL) {
23274 * Skip keyref IDCs and empty IDC target-lists.
23276 if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
23277 WXS_ILIST_IS_EMPTY(matcher->targets))
23279 matcher = matcher->next;
23283 * If we _want_ the IDC node-table to be created in any case
23284 * then do so. Otherwise create them only if keyrefs need them.
23286 if ((! vctxt->createIDCNodeTables) &&
23287 ((matcher->aidc->keyrefDepth == -1) ||
23288 (matcher->aidc->keyrefDepth > vctxt->depth)))
23290 matcher = matcher->next;
23294 * Get/create the IDC binding on this element for the IDC definition.
23296 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
23298 if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
23299 dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
23300 nbDupls = bind->dupls->nbItems;
23305 if (bind->nodeTable != NULL) {
23306 nbNodeTable = bind->nbNodes;
23311 if ((nbNodeTable == 0) && (nbDupls == 0)) {
23313 * Transfer all IDC target-nodes to the IDC node-table.
23316 (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23317 bind->sizeNodes = matcher->targets->sizeItems;
23318 bind->nbNodes = matcher->targets->nbItems;
23320 matcher->targets->items = NULL;
23321 matcher->targets->sizeItems = 0;
23322 matcher->targets->nbItems = 0;
23325 * Compare the key-sequences and add to the IDC node-table.
23327 nbTargets = matcher->targets->nbItems;
23328 targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23329 nbFields = matcher->aidc->def->nbFields;
23332 keys = targets[i]->keys;
23335 * Search in already found duplicates first.
23339 if (nbFields == 1) {
23340 res = xmlSchemaAreValuesEqual(keys[0]->val,
23341 dupls[j]->keys[0]->val);
23343 goto internal_error;
23346 * Equal key-sequence.
23352 ntkeys = dupls[j]->keys;
23353 for (k = 0; k < nbFields; k++) {
23354 res = xmlSchemaAreValuesEqual(keys[k]->val,
23357 goto internal_error;
23360 * One of the keys differs.
23367 * Equal key-sequence found.
23373 } while (j < nbDupls);
23378 if (nbFields == 1) {
23379 res = xmlSchemaAreValuesEqual(keys[0]->val,
23380 bind->nodeTable[j]->keys[0]->val);
23382 goto internal_error;
23385 * The key-sequence differs.
23387 goto next_node_table_entry;
23391 ntkeys = bind->nodeTable[j]->keys;
23392 for (k = 0; k < nbFields; k++) {
23393 res = xmlSchemaAreValuesEqual(keys[k]->val,
23396 goto internal_error;
23399 * One of the keys differs.
23401 goto next_node_table_entry;
23406 * Add the duplicate to the list of duplicates.
23408 if (bind->dupls == NULL) {
23409 bind->dupls = xmlSchemaItemListCreate();
23410 if (bind->dupls == NULL)
23411 goto internal_error;
23413 if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
23414 goto internal_error;
23416 * Remove the duplicate entry from the IDC node-table.
23418 bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
23423 next_node_table_entry:
23425 } while (j < nbNodeTable);
23428 * If everything is fine, then add the IDC target-node to
23429 * the IDC node-table.
23431 if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
23432 goto internal_error;
23436 } while (i < nbTargets);
23438 matcher = matcher->next;
23447 * xmlSchemaBubbleIDCNodeTables:
23448 * @depth: the current tree depth
23450 * Merges IDC bindings of an element at @depth into the corresponding IDC
23451 * bindings of its parent element. If a duplicate note-table entry is found,
23452 * both, the parent node-table entry and child entry are discarded from the
23453 * node-table of the parent.
23455 * Returns 0 if OK and -1 on internal errors.
23458 xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
23460 xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
23461 xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
23462 xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
23463 xmlSchemaIDCAugPtr aidc;
23464 int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
23466 bind = vctxt->inode->idcTable;
23467 if (bind == NULL) {
23468 /* Fine, no table, no bubbles. */
23472 parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
23474 * Walk all bindings; create new or add to existing bindings.
23475 * Remove duplicate key-sequences.
23477 while (bind != NULL) {
23479 if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
23482 * Check if the key/unique IDC table needs to be bubbled.
23484 if (! vctxt->createIDCNodeTables) {
23485 aidc = vctxt->aidcs;
23487 if (aidc->def == bind->definition) {
23488 if ((aidc->keyrefDepth == -1) ||
23489 (aidc->keyrefDepth >= vctxt->depth)) {
23495 } while (aidc != NULL);
23498 if (parTable != NULL)
23499 parBind = *parTable;
23501 * Search a matching parent binding for the
23504 while (parBind != NULL) {
23505 if (parBind->definition == bind->definition)
23507 parBind = parBind->next;
23510 if (parBind != NULL) {
23512 * Compare every node-table entry of the child node,
23513 * i.e. the key-sequence within, ...
23515 oldNum = parBind->nbNodes; /* Skip newly added items. */
23517 if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
23518 oldDupls = parBind->dupls->nbItems;
23519 dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
23525 parNodes = parBind->nodeTable;
23526 nbFields = bind->definition->nbFields;
23528 for (i = 0; i < bind->nbNodes; i++) {
23529 node = bind->nodeTable[i];
23533 * ...with every key-sequence of the parent node, already
23534 * evaluated to be a duplicate key-sequence.
23538 while (j < oldDupls) {
23539 if (nbFields == 1) {
23540 ret = xmlSchemaAreValuesEqual(
23541 node->keys[0]->val,
23542 dupls[j]->keys[0]->val);
23544 goto internal_error;
23550 parNode = dupls[j];
23551 for (k = 0; k < nbFields; k++) {
23552 ret = xmlSchemaAreValuesEqual(
23553 node->keys[k]->val,
23554 parNode->keys[k]->val);
23556 goto internal_error;
23562 /* Duplicate found. */
23566 if (j != oldDupls) {
23567 /* Duplicate found. Skip this entry. */
23572 * ... and with every key-sequence of the parent node.
23576 while (j < oldNum) {
23577 parNode = parNodes[j];
23578 if (nbFields == 1) {
23579 ret = xmlSchemaAreValuesEqual(
23580 node->keys[0]->val,
23581 parNode->keys[0]->val);
23583 goto internal_error;
23589 for (k = 0; k < nbFields; k++) {
23590 ret = xmlSchemaAreValuesEqual(
23591 node->keys[k]->val,
23592 parNode->keys[k]->val);
23594 goto internal_error;
23600 /* Duplicate found. */
23606 * Handle duplicates. Move the duplicate in
23607 * the parent's node-table to the list of
23611 parBind->nbNodes--;
23613 * Move last old item to pos of duplicate.
23615 parNodes[j] = parNodes[oldNum];
23617 if (parBind->nbNodes != oldNum) {
23619 * If new items exist, move last new item to
23620 * last of old items.
23623 parNodes[parBind->nbNodes];
23625 if (parBind->dupls == NULL) {
23626 parBind->dupls = xmlSchemaItemListCreate();
23627 if (parBind->dupls == NULL)
23628 goto internal_error;
23630 xmlSchemaItemListAdd(parBind->dupls, parNode);
23633 * Add the node-table entry (node and key-sequence) of
23634 * the child node to the node table of the parent node.
23636 if (parBind->nodeTable == NULL) {
23637 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23638 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
23639 if (parBind->nodeTable == NULL) {
23640 xmlSchemaVErrMemory(NULL,
23641 "allocating IDC list of node-table items", NULL);
23642 goto internal_error;
23644 parBind->sizeNodes = 1;
23645 } else if (parBind->nbNodes >= parBind->sizeNodes) {
23646 parBind->sizeNodes *= 2;
23647 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23648 xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
23649 sizeof(xmlSchemaPSVIIDCNodePtr));
23650 if (parBind->nodeTable == NULL) {
23651 xmlSchemaVErrMemory(NULL,
23652 "re-allocating IDC list of node-table items", NULL);
23653 goto internal_error;
23656 parNodes = parBind->nodeTable;
23658 * Append the new node-table entry to the 'new node-table
23659 * entries' section.
23661 parNodes[parBind->nbNodes++] = node;
23669 * No binding for the IDC was found: create a new one and
23670 * copy all node-tables.
23672 parBind = xmlSchemaIDCNewBinding(bind->definition);
23673 if (parBind == NULL)
23674 goto internal_error;
23677 * TODO: Hmm, how to optimize the initial number of
23678 * allocated entries?
23680 if (bind->nbNodes != 0) {
23682 * Add all IDC node-table entries.
23684 if (! vctxt->psviExposeIDCNodeTables) {
23686 * Just move the entries.
23687 * NOTE: this is quite save here, since
23688 * all the keyref lookups have already been
23691 parBind->nodeTable = bind->nodeTable;
23692 bind->nodeTable = NULL;
23693 parBind->sizeNodes = bind->sizeNodes;
23694 bind->sizeNodes = 0;
23695 parBind->nbNodes = bind->nbNodes;
23699 * Copy the entries.
23701 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23702 xmlMalloc(bind->nbNodes *
23703 sizeof(xmlSchemaPSVIIDCNodePtr));
23704 if (parBind->nodeTable == NULL) {
23705 xmlSchemaVErrMemory(NULL,
23706 "allocating an array of IDC node-table "
23708 xmlSchemaIDCFreeBinding(parBind);
23709 goto internal_error;
23711 parBind->sizeNodes = bind->nbNodes;
23712 parBind->nbNodes = bind->nbNodes;
23713 memcpy(parBind->nodeTable, bind->nodeTable,
23714 bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
23719 * Move the duplicates.
23721 if (parBind->dupls != NULL)
23722 xmlSchemaItemListFree(parBind->dupls);
23723 parBind->dupls = bind->dupls;
23724 bind->dupls = NULL;
23726 if (parTable != NULL) {
23727 if (*parTable == NULL)
23728 *parTable = parBind;
23730 parBind->next = *parTable;
23731 *parTable = parBind;
23746 * xmlSchemaCheckCVCIDCKeyRef:
23747 * @vctxt: the WXS validation context
23748 * @elemDecl: the element declaration
23750 * Check the cvc-idc-keyref constraints.
23753 xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
23755 xmlSchemaIDCMatcherPtr matcher;
23756 xmlSchemaPSVIIDCBindingPtr bind;
23758 matcher = vctxt->inode->idcMatchers;
23762 while (matcher != NULL) {
23763 if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
23764 matcher->targets &&
23765 matcher->targets->nbItems)
23767 int i, j, k, res, nbFields, hasDupls;
23768 xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
23769 xmlSchemaPSVIIDCNodePtr refNode = NULL;
23771 nbFields = matcher->aidc->def->nbFields;
23774 * Find the IDC node-table for the referenced IDC key/unique.
23776 bind = vctxt->inode->idcTable;
23777 while (bind != NULL) {
23778 if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
23783 hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
23785 * Search for a matching key-sequences.
23787 for (i = 0; i < matcher->targets->nbItems; i++) {
23789 refNode = matcher->targets->items[i];
23790 if (bind != NULL) {
23791 refKeys = refNode->keys;
23792 for (j = 0; j < bind->nbNodes; j++) {
23793 keys = bind->nodeTable[j]->keys;
23794 for (k = 0; k < nbFields; k++) {
23795 res = xmlSchemaAreValuesEqual(keys[k]->val,
23799 else if (res == -1) {
23810 if ((res == 0) && hasDupls) {
23812 * Search in duplicates
23814 for (j = 0; j < bind->dupls->nbItems; j++) {
23815 keys = ((xmlSchemaPSVIIDCNodePtr)
23816 bind->dupls->items[j])->keys;
23817 for (k = 0; k < nbFields; k++) {
23818 res = xmlSchemaAreValuesEqual(keys[k]->val,
23822 else if (res == -1) {
23828 * Match in duplicates found.
23830 xmlChar *str = NULL, *strB = NULL;
23831 xmlSchemaKeyrefErr(vctxt,
23832 XML_SCHEMAV_CVC_IDC, refNode,
23833 (xmlSchemaTypePtr) matcher->aidc->def,
23834 "More than one match found for "
23835 "key-sequence %s of keyref '%s'",
23836 xmlSchemaFormatIDCKeySequence(vctxt, &str,
23837 refNode->keys, nbFields),
23838 xmlSchemaGetComponentQName(&strB,
23839 matcher->aidc->def));
23840 FREE_AND_NULL(str);
23841 FREE_AND_NULL(strB);
23849 xmlChar *str = NULL, *strB = NULL;
23850 xmlSchemaKeyrefErr(vctxt,
23851 XML_SCHEMAV_CVC_IDC, refNode,
23852 (xmlSchemaTypePtr) matcher->aidc->def,
23853 "No match found for key-sequence %s of keyref '%s'",
23854 xmlSchemaFormatIDCKeySequence(vctxt, &str,
23855 refNode->keys, nbFields),
23856 xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
23857 FREE_AND_NULL(str);
23858 FREE_AND_NULL(strB);
23862 matcher = matcher->next;
23864 /* TODO: Return an error if any error encountered. */
23868 /************************************************************************
23870 * XML Reader validation code *
23872 ************************************************************************/
23874 static xmlSchemaAttrInfoPtr
23875 xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
23877 xmlSchemaAttrInfoPtr iattr;
23879 * Grow/create list of attribute infos.
23881 if (vctxt->attrInfos == NULL) {
23882 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23883 xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
23884 vctxt->sizeAttrInfos = 1;
23885 if (vctxt->attrInfos == NULL) {
23886 xmlSchemaVErrMemory(vctxt,
23887 "allocating attribute info list", NULL);
23890 } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
23891 vctxt->sizeAttrInfos++;
23892 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23893 xmlRealloc(vctxt->attrInfos,
23894 vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
23895 if (vctxt->attrInfos == NULL) {
23896 xmlSchemaVErrMemory(vctxt,
23897 "re-allocating attribute info list", NULL);
23901 iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
23902 if (iattr->localName != NULL) {
23903 VERROR_INT("xmlSchemaGetFreshAttrInfo",
23904 "attr info not cleared");
23907 iattr->nodeType = XML_ATTRIBUTE_NODE;
23911 * Create an attribute info.
23913 iattr = (xmlSchemaAttrInfoPtr)
23914 xmlMalloc(sizeof(xmlSchemaAttrInfo));
23915 if (iattr == NULL) {
23916 xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
23919 memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
23920 iattr->nodeType = XML_ATTRIBUTE_NODE;
23921 vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
23927 xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
23928 xmlNodePtr attrNode,
23930 const xmlChar *localName,
23931 const xmlChar *nsName,
23936 xmlSchemaAttrInfoPtr attr;
23938 attr = xmlSchemaGetFreshAttrInfo(vctxt);
23939 if (attr == NULL) {
23940 VERROR_INT("xmlSchemaPushAttribute",
23941 "calling xmlSchemaGetFreshAttrInfo()");
23944 attr->node = attrNode;
23945 attr->nodeLine = nodeLine;
23946 attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
23947 attr->localName = localName;
23948 attr->nsName = nsName;
23950 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
23952 * Evaluate if it's an XSI attribute.
23954 if (nsName != NULL) {
23955 if (xmlStrEqual(localName, BAD_CAST "nil")) {
23956 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23957 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
23959 } else if (xmlStrEqual(localName, BAD_CAST "type")) {
23960 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23961 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
23963 } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
23964 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23965 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
23967 } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
23968 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23969 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
23971 } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
23972 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
23975 attr->value = value;
23977 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
23978 if (attr->metaType != 0)
23979 attr->state = XML_SCHEMAS_ATTR_META;
23984 * xmlSchemaClearElemInfo:
23985 * @vctxt: the WXS validation context
23986 * @ielem: the element information item
23989 xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
23990 xmlSchemaNodeInfoPtr ielem)
23992 ielem->hasKeyrefs = 0;
23993 ielem->appliedXPath = 0;
23994 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
23995 FREE_AND_NULL(ielem->localName);
23996 FREE_AND_NULL(ielem->nsName);
23998 ielem->localName = NULL;
23999 ielem->nsName = NULL;
24001 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
24002 FREE_AND_NULL(ielem->value);
24004 ielem->value = NULL;
24006 if (ielem->val != NULL) {
24008 * PSVI TODO: Be careful not to free it when the value is
24009 * exposed via PSVI.
24011 xmlSchemaFreeValue(ielem->val);
24014 if (ielem->idcMatchers != NULL) {
24016 * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
24019 xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
24021 xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
24023 ielem->idcMatchers = NULL;
24025 if (ielem->idcTable != NULL) {
24027 * OPTIMIZE TODO: Use a pool of IDC tables??.
24029 xmlSchemaIDCFreeIDCTable(ielem->idcTable);
24030 ielem->idcTable = NULL;
24032 if (ielem->regexCtxt != NULL) {
24033 xmlRegFreeExecCtxt(ielem->regexCtxt);
24034 ielem->regexCtxt = NULL;
24036 if (ielem->nsBindings != NULL) {
24037 xmlFree((xmlChar **)ielem->nsBindings);
24038 ielem->nsBindings = NULL;
24039 ielem->nbNsBindings = 0;
24040 ielem->sizeNsBindings = 0;
24045 * xmlSchemaGetFreshElemInfo:
24046 * @vctxt: the schema validation context
24048 * Creates/reuses and initializes the element info item for
24049 * the currect tree depth.
24051 * Returns the element info item or NULL on API or internal errors.
24053 static xmlSchemaNodeInfoPtr
24054 xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
24056 xmlSchemaNodeInfoPtr info = NULL;
24058 if (vctxt->depth > vctxt->sizeElemInfos) {
24059 VERROR_INT("xmlSchemaGetFreshElemInfo",
24060 "inconsistent depth encountered");
24063 if (vctxt->elemInfos == NULL) {
24064 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24065 xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
24066 if (vctxt->elemInfos == NULL) {
24067 xmlSchemaVErrMemory(vctxt,
24068 "allocating the element info array", NULL);
24071 memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
24072 vctxt->sizeElemInfos = 10;
24073 } else if (vctxt->sizeElemInfos <= vctxt->depth) {
24074 int i = vctxt->sizeElemInfos;
24076 vctxt->sizeElemInfos *= 2;
24077 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24078 xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
24079 sizeof(xmlSchemaNodeInfoPtr));
24080 if (vctxt->elemInfos == NULL) {
24081 xmlSchemaVErrMemory(vctxt,
24082 "re-allocating the element info array", NULL);
24086 * We need the new memory to be NULLed.
24087 * TODO: Use memset instead?
24089 for (; i < vctxt->sizeElemInfos; i++)
24090 vctxt->elemInfos[i] = NULL;
24092 info = vctxt->elemInfos[vctxt->depth];
24094 if (info == NULL) {
24095 info = (xmlSchemaNodeInfoPtr)
24096 xmlMalloc(sizeof(xmlSchemaNodeInfo));
24097 if (info == NULL) {
24098 xmlSchemaVErrMemory(vctxt,
24099 "allocating an element info", NULL);
24102 vctxt->elemInfos[vctxt->depth] = info;
24104 if (info->localName != NULL) {
24105 VERROR_INT("xmlSchemaGetFreshElemInfo",
24106 "elem info has not been cleared");
24110 memset(info, 0, sizeof(xmlSchemaNodeInfo));
24111 info->nodeType = XML_ELEMENT_NODE;
24112 info->depth = vctxt->depth;
24117 #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
24118 #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
24119 #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
24122 xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
24124 xmlSchemaTypePtr type,
24125 xmlSchemaValType valType,
24126 const xmlChar * value,
24127 xmlSchemaValPtr val,
24128 unsigned long length,
24131 int ret, error = 0;
24133 xmlSchemaTypePtr tmpType;
24134 xmlSchemaFacetLinkPtr facetLink;
24135 xmlSchemaFacetPtr facet;
24136 unsigned long len = 0;
24137 xmlSchemaWhitespaceValueType ws;
24140 * In Libxml2, derived built-in types have currently no explicit facets.
24142 if (type->type == XML_SCHEMA_TYPE_BASIC)
24146 * NOTE: Do not jump away, if the facetSet of the given type is
24147 * empty: until now, "pattern" and "enumeration" facets of the
24148 * *base types* need to be checked as well.
24150 if (type->facetSet == NULL)
24151 goto pattern_and_enum;
24153 if (! WXS_IS_ATOMIC(type)) {
24154 if (WXS_IS_LIST(type))
24157 goto pattern_and_enum;
24160 * Whitespace handling is only of importance for string-based
24163 tmpType = xmlSchemaGetPrimitiveType(type);
24164 if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
24165 WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
24166 ws = xmlSchemaGetWhiteSpaceFacetValue(type);
24168 ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
24170 * If the value was not computed (for string or
24171 * anySimpleType based types), then use the provided
24177 valType = xmlSchemaGetValType(val);
24180 for (facetLink = type->facetSet; facetLink != NULL;
24181 facetLink = facetLink->next) {
24183 * Skip the pattern "whiteSpace": it is used to
24184 * format the character content beforehand.
24186 switch (facetLink->facet->type) {
24187 case XML_SCHEMA_FACET_WHITESPACE:
24188 case XML_SCHEMA_FACET_PATTERN:
24189 case XML_SCHEMA_FACET_ENUMERATION:
24191 case XML_SCHEMA_FACET_LENGTH:
24192 case XML_SCHEMA_FACET_MINLENGTH:
24193 case XML_SCHEMA_FACET_MAXLENGTH:
24194 ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
24195 valType, value, val, &len, ws);
24198 ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
24199 valType, value, val, ws);
24203 AERROR_INT("xmlSchemaValidateFacets",
24204 "validating against a atomic type facet");
24206 } else if (ret > 0) {
24208 xmlSchemaFacetErr(actxt, ret, node,
24209 value, len, type, facetLink->facet, NULL, NULL, NULL);
24219 if (! WXS_IS_LIST(type))
24220 goto pattern_and_enum;
24222 * "length", "minLength" and "maxLength" of list types.
24225 for (facetLink = type->facetSet; facetLink != NULL;
24226 facetLink = facetLink->next) {
24228 switch (facetLink->facet->type) {
24229 case XML_SCHEMA_FACET_LENGTH:
24230 case XML_SCHEMA_FACET_MINLENGTH:
24231 case XML_SCHEMA_FACET_MAXLENGTH:
24232 ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
24233 value, length, NULL);
24239 AERROR_INT("xmlSchemaValidateFacets",
24240 "validating against a list type facet");
24242 } else if (ret > 0) {
24244 xmlSchemaFacetErr(actxt, ret, node,
24245 value, length, type, facetLink->facet, NULL, NULL, NULL);
24258 * Process enumerations. Facet values are in the value space
24259 * of the defining type's base type. This seems to be a bug in the
24260 * XML Schema 1.0 spec. Use the whitespace type of the base type.
24261 * Only the first set of enumerations in the ancestor-or-self axis
24262 * is used for validation.
24267 for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
24268 if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
24271 ret = xmlSchemaAreValuesEqual(facet->val, val);
24274 else if (ret < 0) {
24275 AERROR_INT("xmlSchemaValidateFacets",
24276 "validating against an enumeration facet");
24283 * Break on the first set of enumerations. Any additional
24284 * enumerations which might be existent on the ancestors
24285 * of the current type are restricted by this set; thus
24286 * *must* *not* be taken into account.
24290 tmpType = tmpType->baseType;
24291 } while ((tmpType != NULL) &&
24292 (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24293 if (found && (ret == 0)) {
24294 ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
24296 xmlSchemaFacetErr(actxt, ret, node,
24297 value, 0, type, NULL, NULL, NULL, NULL);
24308 * Process patters. Pattern facets are ORed at type level
24309 * and ANDed if derived. Walk the base type axis.
24315 for (facetLink = tmpType->facetSet; facetLink != NULL;
24316 facetLink = facetLink->next) {
24317 if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
24321 * NOTE that for patterns, @value needs to be the
24322 * normalized vaule.
24324 ret = xmlRegexpExec(facetLink->facet->regexp, value);
24327 else if (ret < 0) {
24328 AERROR_INT("xmlSchemaValidateFacets",
24329 "validating against a pattern facet");
24333 * Save the last non-validating facet.
24335 facet = facetLink->facet;
24338 if (found && (ret != 1)) {
24339 ret = XML_SCHEMAV_CVC_PATTERN_VALID;
24341 xmlSchemaFacetErr(actxt, ret, node,
24342 value, 0, type, facet, NULL, NULL, NULL);
24349 tmpType = tmpType->baseType;
24350 } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24357 xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
24358 const xmlChar *value)
24360 switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
24361 case XML_SCHEMA_WHITESPACE_COLLAPSE:
24362 return (xmlSchemaCollapseString(value));
24363 case XML_SCHEMA_WHITESPACE_REPLACE:
24364 return (xmlSchemaWhiteSpaceReplace(value));
24371 xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
24372 const xmlChar *value,
24373 xmlSchemaValPtr *val,
24377 const xmlChar *nsName;
24378 xmlChar *local, *prefix = NULL;
24380 ret = xmlValidateQName(value, 1);
24383 VERROR_INT("xmlSchemaValidateQName",
24384 "calling xmlValidateQName()");
24387 return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
24390 * NOTE: xmlSplitQName2 will always return a duplicated
24393 local = xmlSplitQName2(value, &prefix);
24395 local = xmlStrdup(value);
24397 * OPTIMIZE TODO: Use flags for:
24398 * - is there any namespace binding?
24399 * - is there a default namespace?
24401 nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24403 if (prefix != NULL) {
24406 * A namespace must be found if the prefix is
24409 if (nsName == NULL) {
24410 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24411 xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
24412 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24413 "The QName value '%s' has no "
24414 "corresponding namespace declaration in "
24415 "scope", value, NULL);
24421 if (valNeeded && val) {
24422 if (nsName != NULL)
24423 *val = xmlSchemaNewQNameValue(
24424 BAD_CAST xmlStrdup(nsName), BAD_CAST local);
24426 *val = xmlSchemaNewQNameValue(NULL,
24437 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
24439 xmlSchemaTypePtr type,
24440 const xmlChar *value,
24441 xmlSchemaValPtr *retVal,
24446 int ret = 0, valNeeded = (retVal) ? 1 : 0;
24447 xmlSchemaValPtr val = NULL;
24448 /* xmlSchemaWhitespaceValueType ws; */
24449 xmlChar *normValue = NULL;
24451 #define NORMALIZE(atype) \
24452 if ((! isNormalized) && \
24453 (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
24454 normValue = xmlSchemaNormalizeValue(atype, value); \
24455 if (normValue != NULL) \
24456 value = normValue; \
24457 isNormalized = 1; \
24460 if ((retVal != NULL) && (*retVal != NULL)) {
24461 xmlSchemaFreeValue(*retVal);
24465 * 3.14.4 Simple Type Definition Validation Rules
24466 * Validation Rule: String Valid
24469 * 1 It is schema-valid with respect to that definition as defined
24470 * by Datatype Valid in [XML Schemas: Datatypes].
24473 * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
24474 * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6), then
24475 * the string must be a �declared entity name�.
24478 * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
24479 * given the empty set, as defined in Type Derivation OK (Simple) (�3.14.6),
24480 * then every whitespace-delimited substring of the string must be a �declared
24484 * 2.3 otherwise no further condition applies.
24486 if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
24489 value = BAD_CAST "";
24490 if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
24491 xmlSchemaTypePtr biType; /* The built-in type. */
24493 * SPEC (1.2.1) "if {variety} is �atomic� then the string must �match�
24494 * a literal in the �lexical space� of {base type definition}"
24497 * Whitespace-normalize.
24500 if (type->type != XML_SCHEMA_TYPE_BASIC) {
24502 * Get the built-in type.
24504 biType = type->baseType;
24505 while ((biType != NULL) &&
24506 (biType->type != XML_SCHEMA_TYPE_BASIC))
24507 biType = biType->baseType;
24509 if (biType == NULL) {
24510 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24511 "could not get the built-in type");
24512 goto internal_error;
24517 * NOTATIONs need to be processed here, since they need
24518 * to lookup in the hashtable of NOTATION declarations of the schema.
24520 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
24521 switch (biType->builtInType) {
24522 case XML_SCHEMAS_NOTATION:
24523 ret = xmlSchemaValidateNotation(
24524 (xmlSchemaValidCtxtPtr) actxt,
24525 ((xmlSchemaValidCtxtPtr) actxt)->schema,
24526 NULL, value, &val, valNeeded);
24528 case XML_SCHEMAS_QNAME:
24529 ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
24530 value, &val, valNeeded);
24533 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24535 ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24536 value, &val, node);
24538 ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24539 value, NULL, node);
24542 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
24543 switch (biType->builtInType) {
24544 case XML_SCHEMAS_NOTATION:
24545 ret = xmlSchemaValidateNotation(NULL,
24546 ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
24547 value, &val, valNeeded);
24550 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24552 ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24553 value, &val, node);
24555 ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24556 value, NULL, node);
24561 * Validation via a public API is not implemented yet.
24564 goto internal_error;
24568 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24569 "validating against a built-in type");
24570 goto internal_error;
24572 if (WXS_IS_LIST(type))
24573 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24575 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24577 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24581 ret = xmlSchemaValidateFacets(actxt, node, type,
24582 (xmlSchemaValType) biType->builtInType, value, val,
24586 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24587 "validating facets of atomic simple type");
24588 goto internal_error;
24590 if (WXS_IS_LIST(type))
24591 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24593 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24596 if (fireErrors && (ret > 0))
24597 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24598 } else if (WXS_IS_LIST(type)) {
24600 xmlSchemaTypePtr itemType;
24601 const xmlChar *cur, *end;
24602 xmlChar *tmpValue = NULL;
24603 unsigned long len = 0;
24604 xmlSchemaValPtr prevVal = NULL, curVal = NULL;
24605 /* 1.2.2 if {variety} is �list� then the string must be a sequence
24606 * of white space separated tokens, each of which �match�es a literal
24607 * in the �lexical space� of {item type definition}
24610 * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
24611 * the list type has an enum or pattern facet.
24615 * VAL TODO: Optimize validation of empty values.
24616 * VAL TODO: We do not have computed values for lists.
24618 itemType = WXS_LIST_ITEMTYPE(type);
24621 while (IS_BLANK_CH(*cur))
24624 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
24628 tmpValue = xmlStrndup(cur, end - cur);
24632 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24633 tmpValue, &curVal, fireErrors, 0, 1);
24635 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24636 tmpValue, NULL, fireErrors, 0, 1);
24637 FREE_AND_NULL(tmpValue);
24638 if (curVal != NULL) {
24640 * Add to list of computed values.
24645 xmlSchemaValueAppend(prevVal, curVal);
24651 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24652 "validating an item of list simple type");
24653 goto internal_error;
24655 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24659 } while (*cur != 0);
24660 FREE_AND_NULL(tmpValue);
24661 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24663 * Apply facets (pattern, enumeration).
24665 ret = xmlSchemaValidateFacets(actxt, node, type,
24666 XML_SCHEMAS_UNKNOWN, value, val,
24670 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24671 "validating facets of list simple type");
24672 goto internal_error;
24674 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24677 if (fireErrors && (ret > 0)) {
24679 * Report the normalized value.
24683 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24685 } else if (WXS_IS_UNION(type)) {
24686 xmlSchemaTypeLinkPtr memberLink;
24688 * TODO: For all datatypes �derived� by �union� whiteSpace does
24689 * not apply directly; however, the normalization behavior of �union�
24690 * types is controlled by the value of whiteSpace on that one of the
24691 * �memberTypes� against which the �union� is successfully validated.
24693 * This means that the value is normalized by the first validating
24694 * member type, then the facets of the union type are applied. This
24695 * needs changing of the value!
24699 * 1.2.3 if {variety} is �union� then the string must �match� a
24700 * literal in the �lexical space� of at least one member of
24701 * {member type definitions}
24703 memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
24704 if (memberLink == NULL) {
24705 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24706 "union simple type has no member types");
24707 goto internal_error;
24710 * Always normalize union type values, since we currently
24711 * cannot store the whitespace information with the value
24712 * itself; otherwise a later value-comparison would be
24715 while (memberLink != NULL) {
24717 ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24718 memberLink->type, value, &val, 0, 1, 0);
24720 ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24721 memberLink->type, value, NULL, 0, 1, 0);
24724 memberLink = memberLink->next;
24728 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24729 "validating members of union simple type");
24730 goto internal_error;
24732 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24735 * Apply facets (pattern, enumeration).
24737 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24739 * The normalization behavior of �union� types is controlled by
24740 * the value of whiteSpace on that one of the �memberTypes�
24741 * against which the �union� is successfully validated.
24743 NORMALIZE(memberLink->type);
24744 ret = xmlSchemaValidateFacets(actxt, node, type,
24745 XML_SCHEMAS_UNKNOWN, value, val,
24749 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24750 "validating facets of union simple type");
24751 goto internal_error;
24753 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24756 if (fireErrors && (ret > 0))
24757 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24760 if (normValue != NULL)
24761 xmlFree(normValue);
24763 if (retVal != NULL)
24765 else if (val != NULL)
24766 xmlSchemaFreeValue(val);
24767 } else if (val != NULL)
24768 xmlSchemaFreeValue(val);
24771 if (normValue != NULL)
24772 xmlFree(normValue);
24774 xmlSchemaFreeValue(val);
24779 xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
24780 const xmlChar *value,
24781 const xmlChar **nsName,
24782 const xmlChar **localName)
24786 if ((nsName == NULL) || (localName == NULL))
24791 ret = xmlValidateQName(value, 1);
24795 xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
24796 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24797 value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
24801 xmlChar *local = NULL;
24805 * NOTE: xmlSplitQName2 will return a duplicated
24808 local = xmlSplitQName2(value, &prefix);
24810 *localName = xmlDictLookup(vctxt->dict, value, -1);
24812 *localName = xmlDictLookup(vctxt->dict, local, -1);
24816 *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24818 if (prefix != NULL) {
24821 * A namespace must be found if the prefix is NOT NULL.
24823 if (*nsName == NULL) {
24824 xmlSchemaCustomErr(ACTXT_CAST vctxt,
24825 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24826 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24827 "The QName value '%s' has no "
24828 "corresponding namespace declaration in scope",
24838 xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
24839 xmlSchemaAttrInfoPtr iattr,
24840 xmlSchemaTypePtr *localType,
24841 xmlSchemaElementPtr elemDecl)
24845 * cvc-elt (3.3.4) : (4)
24847 * Schema-Validity Assessment (Element) (cvc-assess-elt)
24848 * (1.2.1.2.1) - (1.2.1.2.4)
24849 * Handle 'xsi:type'.
24851 if (localType == NULL)
24857 const xmlChar *nsName = NULL, *local = NULL;
24859 * TODO: We should report a *warning* that the type was overriden
24862 ACTIVATE_ATTRIBUTE(iattr);
24864 * (cvc-elt) (3.3.4) : (4.1)
24865 * (cvc-assess-elt) (1.2.1.2.2)
24867 ret = xmlSchemaVExpandQName(vctxt, iattr->value,
24871 VERROR_INT("xmlSchemaValidateElementByDeclaration",
24872 "calling xmlSchemaQNameExpand() to validate the "
24873 "attribute 'xsi:type'");
24874 goto internal_error;
24879 * (cvc-elt) (3.3.4) : (4.2)
24880 * (cvc-assess-elt) (1.2.1.2.3)
24882 *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
24883 if (*localType == NULL) {
24884 xmlChar *str = NULL;
24886 xmlSchemaCustomErr(ACTXT_CAST vctxt,
24887 XML_SCHEMAV_CVC_ELT_4_2, NULL,
24888 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24889 "The QName value '%s' of the xsi:type attribute does not "
24890 "resolve to a type definition",
24891 xmlSchemaFormatQName(&str, nsName, local), NULL);
24892 FREE_AND_NULL(str);
24896 if (elemDecl != NULL) {
24900 * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
24901 * "The �local type definition� must be validly
24902 * derived from the {type definition} given the union of
24903 * the {disallowed substitutions} and the {type definition}'s
24904 * {prohibited substitutions}, as defined in
24905 * Type Derivation OK (Complex) (�3.4.6)
24906 * (if it is a complex type definition),
24907 * or given {disallowed substitutions} as defined in Type
24908 * Derivation OK (Simple) (�3.14.6) (if it is a simple type
24911 * {disallowed substitutions}: the "block" on the element decl.
24912 * {prohibited substitutions}: the "block" on the type def.
24915 * OPTIMIZE TODO: We could map types already evaluated
24916 * to be validly derived from other types to avoid checking
24917 * this over and over for the same types.
24919 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
24920 (elemDecl->subtypes->flags &
24921 XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
24922 set |= SUBSET_EXTENSION;
24924 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
24925 (elemDecl->subtypes->flags &
24926 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
24927 set |= SUBSET_RESTRICTION;
24930 * REMOVED and CHANGED since this produced a parser context
24931 * which adds to the string dict of the schema. So this would
24932 * change the schema and we don't want this. We don't need
24933 * the parser context anymore.
24935 * if ((vctxt->pctxt == NULL) &&
24936 * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
24940 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
24941 elemDecl->subtypes, set) != 0) {
24942 xmlChar *str = NULL;
24944 xmlSchemaCustomErr(ACTXT_CAST vctxt,
24945 XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
24946 "The type definition '%s', specified by xsi:type, is "
24947 "blocked or not validly derived from the type definition "
24948 "of the element declaration",
24949 xmlSchemaFormatQName(&str,
24950 (*localType)->targetNamespace,
24951 (*localType)->name),
24953 FREE_AND_NULL(str);
24968 xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
24970 xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
24971 xmlSchemaTypePtr actualType;
24974 * cvc-elt (3.3.4) : 1
24976 if (elemDecl == NULL) {
24977 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
24978 "No matching declaration available");
24979 return (vctxt->err);
24981 actualType = WXS_ELEM_TYPEDEF(elemDecl);
24983 * cvc-elt (3.3.4) : 2
24985 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
24986 VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
24987 "The element declaration is abstract");
24988 return (vctxt->err);
24990 if (actualType == NULL) {
24991 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
24992 "The type definition is absent");
24993 return (XML_SCHEMAV_CVC_TYPE_1);
24995 if (vctxt->nbAttrInfos != 0) {
24997 xmlSchemaAttrInfoPtr iattr;
24999 * cvc-elt (3.3.4) : 3
25000 * Handle 'xsi:nil'.
25002 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25003 XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
25005 ACTIVATE_ATTRIBUTE(iattr);
25007 * Validate the value.
25009 ret = xmlSchemaVCheckCVCSimpleType(
25010 ACTXT_CAST vctxt, NULL,
25011 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
25012 iattr->value, &(iattr->val), 1, 0, 0);
25015 VERROR_INT("xmlSchemaValidateElemDecl",
25016 "calling xmlSchemaVCheckCVCSimpleType() to "
25017 "validate the attribute 'xsi:nil'");
25021 if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
25023 * cvc-elt (3.3.4) : 3.1
25025 VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
25026 "The element is not 'nillable'");
25027 /* Does not return an error on purpose. */
25029 if (xmlSchemaValueGetAsBoolean(iattr->val)) {
25031 * cvc-elt (3.3.4) : 3.2.2
25033 if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
25034 (elemDecl->value != NULL)) {
25035 VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
25036 "The element cannot be 'nilled' because "
25037 "there is a fixed value constraint defined "
25039 /* Does not return an error on purpose. */
25041 vctxt->inode->flags |=
25042 XML_SCHEMA_ELEM_INFO_NILLED;
25048 * cvc-elt (3.3.4) : 4
25049 * Handle 'xsi:type'.
25051 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25052 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25054 xmlSchemaTypePtr localType = NULL;
25056 ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
25060 VERROR_INT("xmlSchemaValidateElemDecl",
25061 "calling xmlSchemaProcessXSIType() to "
25062 "process the attribute 'xsi:type'");
25065 /* Does not return an error on purpose. */
25067 if (localType != NULL) {
25068 vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
25069 actualType = localType;
25074 * IDC: Register identity-constraint XPath matchers.
25076 if ((elemDecl->idcs != NULL) &&
25077 (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
25080 * No actual type definition.
25082 if (actualType == NULL) {
25083 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
25084 "The type definition is absent");
25085 return (XML_SCHEMAV_CVC_TYPE_1);
25088 * Remember the actual type definition.
25090 vctxt->inode->typeDef = actualType;
25096 xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
25098 xmlSchemaAttrInfoPtr iattr;
25102 * SPEC cvc-type (3.1.1)
25103 * "The attributes of must be empty, excepting those whose namespace
25104 * name is identical to http://www.w3.org/2001/XMLSchema-instance and
25105 * whose local name is one of type, nil, schemaLocation or
25106 * noNamespaceSchemaLocation."
25108 if (vctxt->nbAttrInfos == 0)
25110 for (i = 0; i < vctxt->nbAttrInfos; i++) {
25111 iattr = vctxt->attrInfos[i];
25112 if (! iattr->metaType) {
25113 ACTIVATE_ATTRIBUTE(iattr)
25114 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25115 XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
25116 ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
25124 * Cleanup currently used attribute infos.
25127 xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
25130 xmlSchemaAttrInfoPtr attr;
25132 if (vctxt->nbAttrInfos == 0)
25134 for (i = 0; i < vctxt->nbAttrInfos; i++) {
25135 attr = vctxt->attrInfos[i];
25136 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
25137 if (attr->localName != NULL)
25138 xmlFree((xmlChar *) attr->localName);
25139 if (attr->nsName != NULL)
25140 xmlFree((xmlChar *) attr->nsName);
25142 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
25143 if (attr->value != NULL)
25144 xmlFree((xmlChar *) attr->value);
25146 if (attr->val != NULL) {
25147 xmlSchemaFreeValue(attr->val);
25150 memset(attr, 0, sizeof(xmlSchemaAttrInfo));
25152 vctxt->nbAttrInfos = 0;
25156 * 3.4.4 Complex Type Definition Validation Rules
25157 * Element Locally Valid (Complex Type) (cvc-complex-type)
25158 * 3.2.4 Attribute Declaration Validation Rules
25159 * Validation Rule: Attribute Locally Valid (cvc-attribute)
25160 * Attribute Locally Valid (Use) (cvc-au)
25162 * Only "assessed" attribute information items will be visible to
25163 * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
25166 xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
25168 xmlSchemaTypePtr type = vctxt->inode->typeDef;
25169 xmlSchemaItemListPtr attrUseList;
25170 xmlSchemaAttributeUsePtr attrUse = NULL;
25171 xmlSchemaAttributePtr attrDecl = NULL;
25172 xmlSchemaAttrInfoPtr iattr, tmpiattr;
25173 int i, j, found, nbAttrs, nbUses;
25174 int xpathRes = 0, res, wildIDs = 0, fixed;
25175 xmlNodePtr defAttrOwnerElem = NULL;
25178 * SPEC (cvc-attribute)
25179 * (1) "The declaration must not be �absent� (see Missing
25180 * Sub-components (�5.3) for how this can fail to be
25182 * (2) "Its {type definition} must not be absent."
25184 * NOTE (1) + (2): This is not handled here, since we currently do not
25185 * allow validation against schemas which have missing sub-components.
25187 * SPEC (cvc-complex-type)
25188 * (3) "For each attribute information item in the element information
25189 * item's [attributes] excepting those whose [namespace name] is
25190 * identical to http://www.w3.org/2001/XMLSchema-instance and whose
25191 * [local name] is one of type, nil, schemaLocation or
25192 * noNamespaceSchemaLocation, the appropriate case among the following
25196 attrUseList = (xmlSchemaItemListPtr) type->attrUses;
25198 * @nbAttrs is the number of attributes present in the instance.
25200 nbAttrs = vctxt->nbAttrInfos;
25201 if (attrUseList != NULL)
25202 nbUses = attrUseList->nbItems;
25205 for (i = 0; i < nbUses; i++) {
25207 attrUse = attrUseList->items[i];
25208 attrDecl = WXS_ATTRUSE_DECL(attrUse);
25209 for (j = 0; j < nbAttrs; j++) {
25210 iattr = vctxt->attrInfos[j];
25212 * SPEC (cvc-complex-type) (3)
25213 * Skip meta attributes.
25215 if (iattr->metaType)
25217 if (iattr->localName[0] != attrDecl->name[0])
25219 if (!xmlStrEqual(iattr->localName, attrDecl->name))
25221 if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
25225 * SPEC (cvc-complex-type)
25226 * (3.1) "If there is among the {attribute uses} an attribute
25227 * use with an {attribute declaration} whose {name} matches
25228 * the attribute information item's [local name] and whose
25229 * {target namespace} is identical to the attribute information
25230 * item's [namespace name] (where an �absent� {target namespace}
25231 * is taken to be identical to a [namespace name] with no value),
25232 * then the attribute information must be �valid� with respect
25233 * to that attribute use as per Attribute Locally Valid (Use)
25234 * (�3.5.4). In this case the {attribute declaration} of that
25235 * attribute use is the �context-determined declaration� for the
25236 * attribute information item with respect to Schema-Validity
25237 * Assessment (Attribute) (�3.2.4) and
25238 * Assessment Outcome (Attribute) (�3.2.5).
25240 iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25241 iattr->use = attrUse;
25243 * Context-determined declaration.
25245 iattr->decl = attrDecl;
25246 iattr->typeDef = attrDecl->subtypes;
25253 if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
25255 * Handle non-existent, required attributes.
25257 * SPEC (cvc-complex-type)
25258 * (4) "The {attribute declaration} of each attribute use in
25259 * the {attribute uses} whose {required} is true matches one
25260 * of the attribute information items in the element information
25261 * item's [attributes] as per clause 3.1 above."
25263 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25264 if (tmpiattr == NULL) {
25266 "xmlSchemaVAttributesComplex",
25267 "calling xmlSchemaGetFreshAttrInfo()");
25270 tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
25271 tmpiattr->use = attrUse;
25272 tmpiattr->decl = attrDecl;
25273 } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
25274 ((attrUse->defValue != NULL) ||
25275 (attrDecl->defValue != NULL))) {
25277 * Handle non-existent, optional, default/fixed attributes.
25279 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25280 if (tmpiattr == NULL) {
25282 "xmlSchemaVAttributesComplex",
25283 "calling xmlSchemaGetFreshAttrInfo()");
25286 tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
25287 tmpiattr->use = attrUse;
25288 tmpiattr->decl = attrDecl;
25289 tmpiattr->typeDef = attrDecl->subtypes;
25290 tmpiattr->localName = attrDecl->name;
25291 tmpiattr->nsName = attrDecl->targetNamespace;
25295 if (vctxt->nbAttrInfos == 0)
25298 * Validate against the wildcard.
25300 if (type->attributeWildcard != NULL) {
25302 * SPEC (cvc-complex-type)
25303 * (3.2.1) "There must be an {attribute wildcard}."
25305 for (i = 0; i < nbAttrs; i++) {
25306 iattr = vctxt->attrInfos[i];
25308 * SPEC (cvc-complex-type) (3)
25309 * Skip meta attributes.
25311 if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
25314 * SPEC (cvc-complex-type)
25315 * (3.2.2) "The attribute information item must be �valid� with
25316 * respect to it as defined in Item Valid (Wildcard) (�3.10.4)."
25318 * SPEC Item Valid (Wildcard) (cvc-wildcard)
25319 * "... its [namespace name] must be �valid� with respect to
25320 * the wildcard constraint, as defined in Wildcard allows
25321 * Namespace Name (�3.10.4)."
25323 if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
25324 iattr->nsName) == 0) {
25326 * Handle processContents.
25328 * SPEC (cvc-wildcard):
25329 * processContents | context-determined declaration:
25330 * "strict" "mustFind"
25334 if (type->attributeWildcard->processContents ==
25335 XML_SCHEMAS_ANY_SKIP) {
25337 * context-determined declaration = "skip"
25339 * SPEC PSVI Assessment Outcome (Attribute)
25340 * [validity] = "notKnown"
25341 * [validation attempted] = "none"
25343 iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
25347 * Find an attribute declaration.
25349 iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
25350 iattr->localName, iattr->nsName);
25351 if (iattr->decl != NULL) {
25352 iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25354 * SPEC (cvc-complex-type)
25355 * (5) "Let [Definition:] the wild IDs be the set of
25356 * all attribute information item to which clause 3.2
25357 * applied and whose �validation� resulted in a
25358 * �context-determined declaration� of mustFind or no
25359 * �context-determined declaration� at all, and whose
25360 * [local name] and [namespace name] resolve (as
25361 * defined by QName resolution (Instance) (�3.15.4)) to
25362 * an attribute declaration whose {type definition} is
25363 * or is derived from ID. Then all of the following
25366 iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
25367 if (xmlSchemaIsDerivedFromBuiltInType(
25368 iattr->typeDef, XML_SCHEMAS_ID)) {
25370 * SPEC (5.1) "There must be no more than one
25371 * item in �wild IDs�."
25373 if (wildIDs != 0) {
25375 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
25381 * SPEC (cvc-complex-type)
25382 * (5.2) "If �wild IDs� is non-empty, there must not
25383 * be any attribute uses among the {attribute uses}
25384 * whose {attribute declaration}'s {type definition}
25385 * is or is derived from ID."
25387 if (attrUseList != NULL) {
25388 for (j = 0; j < attrUseList->nbItems; j++) {
25389 if (xmlSchemaIsDerivedFromBuiltInType(
25390 WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
25392 /* URGENT VAL TODO: implement */
25393 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
25400 } else if (type->attributeWildcard->processContents ==
25401 XML_SCHEMAS_ANY_LAX) {
25402 iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
25404 * SPEC PSVI Assessment Outcome (Attribute)
25405 * [validity] = "notKnown"
25406 * [validation attempted] = "none"
25409 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
25415 if (vctxt->nbAttrInfos == 0)
25419 * Get the owner element; needed for creation of default attributes.
25420 * This fixes bug #341337, reported by David Grohmann.
25422 if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
25423 xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
25424 if (ielem && ielem->node && ielem->node->doc)
25425 defAttrOwnerElem = ielem->node;
25428 * Validate values, create default attributes, evaluate IDCs.
25430 for (i = 0; i < vctxt->nbAttrInfos; i++) {
25431 iattr = vctxt->attrInfos[i];
25433 * VAL TODO: Note that we won't try to resolve IDCs to
25434 * "lax" and "skip" validated attributes. Check what to
25437 if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
25438 (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
25441 * VAL TODO: What to do if the type definition is missing?
25443 if (iattr->typeDef == NULL) {
25444 iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
25448 ACTIVATE_ATTRIBUTE(iattr);
25452 if (vctxt->xpathStates != NULL) {
25456 xpathRes = xmlSchemaXPathEvaluate(vctxt,
25457 XML_ATTRIBUTE_NODE);
25458 if (xpathRes == -1) {
25459 VERROR_INT("xmlSchemaVAttributesComplex",
25460 "calling xmlSchemaXPathEvaluate()");
25461 goto internal_error;
25465 if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
25467 * Default/fixed attributes.
25468 * We need the value only if we need to resolve IDCs or
25469 * will create default attributes.
25471 if ((xpathRes) || (defAttrOwnerElem)) {
25472 if (iattr->use->defValue != NULL) {
25473 iattr->value = (xmlChar *) iattr->use->defValue;
25474 iattr->val = iattr->use->defVal;
25476 iattr->value = (xmlChar *) iattr->decl->defValue;
25477 iattr->val = iattr->decl->defVal;
25480 * IDCs will consume the precomputed default value,
25481 * so we need to clone it.
25483 if (iattr->val == NULL) {
25484 VERROR_INT("xmlSchemaVAttributesComplex",
25485 "default/fixed value on an attribute use was "
25486 "not precomputed");
25487 goto internal_error;
25489 iattr->val = xmlSchemaCopyValue(iattr->val);
25490 if (iattr->val == NULL) {
25491 VERROR_INT("xmlSchemaVAttributesComplex",
25492 "calling xmlSchemaCopyValue()");
25493 goto internal_error;
25497 * PSVI: Add the default attribute to the current element.
25498 * VAL TODO: Should we use the *normalized* value? This currently
25499 * uses the *initial* value.
25502 if (defAttrOwnerElem) {
25503 xmlChar *normValue;
25504 const xmlChar *value;
25506 value = iattr->value;
25508 * Normalize the value.
25510 normValue = xmlSchemaNormalizeValue(iattr->typeDef,
25512 if (normValue != NULL)
25513 value = BAD_CAST normValue;
25515 if (iattr->nsName == NULL) {
25516 if (xmlNewProp(defAttrOwnerElem,
25517 iattr->localName, value) == NULL) {
25518 VERROR_INT("xmlSchemaVAttributesComplex",
25519 "callling xmlNewProp()");
25520 if (normValue != NULL)
25521 xmlFree(normValue);
25522 goto internal_error;
25527 ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
25528 defAttrOwnerElem, iattr->nsName);
25530 xmlChar prefix[12];
25534 * Create a namespace declaration on the validation
25535 * root node if no namespace declaration is in scope.
25538 snprintf((char *) prefix, 12, "p%d", counter++);
25539 ns = xmlSearchNs(defAttrOwnerElem->doc,
25540 defAttrOwnerElem, BAD_CAST prefix);
25541 if (counter > 1000) {
25543 "xmlSchemaVAttributesComplex",
25544 "could not compute a ns prefix for a "
25545 "default/fixed attribute");
25546 if (normValue != NULL)
25547 xmlFree(normValue);
25548 goto internal_error;
25550 } while (ns != NULL);
25551 ns = xmlNewNs(vctxt->validationRoot,
25552 iattr->nsName, BAD_CAST prefix);
25556 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
25557 * If we have QNames: do we need to ensure there's a
25558 * prefix defined for the QName?
25560 xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
25562 if (normValue != NULL)
25563 xmlFree(normValue);
25566 * Go directly to IDC evaluation.
25571 * Validate the value.
25573 if (vctxt->value != NULL) {
25575 * Free last computed value; just for safety reasons.
25577 xmlSchemaFreeValue(vctxt->value);
25578 vctxt->value = NULL;
25581 * Note that the attribute *use* can be unavailable, if
25582 * the attribute was a wild attribute.
25584 if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
25585 ((iattr->use != NULL) &&
25586 (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
25591 * SPEC (cvc-attribute)
25592 * (3) "The item's �normalized value� must be locally �valid�
25593 * with respect to that {type definition} as per
25594 * String Valid (�3.14.4)."
25596 * VAL TODO: Do we already have the
25597 * "normalized attribute value" here?
25599 if (xpathRes || fixed) {
25600 iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
25602 * Request a computed value.
25604 res = xmlSchemaVCheckCVCSimpleType(
25606 iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
25609 res = xmlSchemaVCheckCVCSimpleType(
25611 iattr->node, iattr->typeDef, iattr->value, NULL,
25617 VERROR_INT("xmlSchemaVAttributesComplex",
25618 "calling xmlSchemaStreamValidateSimpleTypeValue()");
25619 goto internal_error;
25621 iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
25623 * SPEC PSVI Assessment Outcome (Attribute)
25624 * [validity] = "invalid"
25631 * SPEC Attribute Locally Valid (Use) (cvc-au)
25632 * "For an attribute information item to be�valid�
25633 * with respect to an attribute use its *normalized*
25634 * value� must match the *canonical* lexical
25635 * representation of the attribute use's {value
25636 * constraint}value, if it is present and fixed."
25638 * VAL TODO: The requirement for the *canonical* value
25639 * will be removed in XML Schema 1.1.
25642 * SPEC Attribute Locally Valid (cvc-attribute)
25643 * (4) "The item's *actual* value� must match the *value* of
25644 * the {value constraint}, if it is present and fixed."
25646 if (iattr->val == NULL) {
25647 /* VAL TODO: A value was not precomputed. */
25651 if ((iattr->use != NULL) &&
25652 (iattr->use->defValue != NULL)) {
25653 if (iattr->use->defVal == NULL) {
25654 /* VAL TODO: A default value was not precomputed. */
25658 iattr->vcValue = iattr->use->defValue;
25660 if (xmlSchemaCompareValuesWhtsp(attr->val,
25661 (xmlSchemaWhitespaceValueType) ws,
25663 (xmlSchemaWhitespaceValueType) ws) != 0) {
25665 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
25666 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25668 if (iattr->decl->defVal == NULL) {
25669 /* VAL TODO: A default value was not precomputed. */
25673 iattr->vcValue = iattr->decl->defValue;
25675 if (xmlSchemaCompareValuesWhtsp(attr->val,
25676 (xmlSchemaWhitespaceValueType) ws,
25678 (xmlSchemaWhitespaceValueType) ws) != 0) {
25680 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
25681 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25684 * [validity] = "valid"
25692 if (xmlSchemaXPathProcessHistory(vctxt,
25693 vctxt->depth +1) == -1) {
25694 VERROR_INT("xmlSchemaVAttributesComplex",
25695 "calling xmlSchemaXPathEvaluate()");
25696 goto internal_error;
25698 } else if (vctxt->xpathStates != NULL)
25699 xmlSchemaXPathPop(vctxt);
25705 for (i = 0; i < vctxt->nbAttrInfos; i++) {
25706 iattr = vctxt->attrInfos[i];
25707 if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
25708 (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
25709 (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
25710 (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
25712 ACTIVATE_ATTRIBUTE(iattr);
25713 switch (iattr->state) {
25714 case XML_SCHEMAS_ATTR_ERR_MISSING: {
25715 xmlChar *str = NULL;
25717 xmlSchemaCustomErr(ACTXT_CAST vctxt,
25718 XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
25719 "The attribute '%s' is required but missing",
25720 xmlSchemaFormatQName(&str,
25721 iattr->decl->targetNamespace,
25722 iattr->decl->name),
25727 case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
25728 VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
25729 "The type definition is absent");
25731 case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
25732 xmlSchemaCustomErr(ACTXT_CAST vctxt,
25733 XML_SCHEMAV_CVC_AU, NULL, NULL,
25734 "The value '%s' does not match the fixed "
25735 "value constraint '%s'",
25736 iattr->value, iattr->vcValue);
25738 case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
25739 VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
25740 "No matching global attribute declaration available, but "
25741 "demanded by the strict wildcard");
25743 case XML_SCHEMAS_ATTR_UNKNOWN:
25744 if (iattr->metaType)
25747 * MAYBE VAL TODO: One might report different error messages
25748 * for the following errors.
25750 if (type->attributeWildcard == NULL) {
25751 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25752 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
25754 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25755 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
25771 xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
25774 xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
25776 * The namespace of the element was already identified to be
25777 * matching the wildcard.
25779 if ((skip == NULL) || (wild == NULL) ||
25780 (wild->type != XML_SCHEMA_TYPE_ANY)) {
25781 VERROR_INT("xmlSchemaValidateElemWildcard",
25786 if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
25788 * URGENT VAL TODO: Either we need to position the stream to the
25789 * next sibling, or walk the whole subtree.
25795 xmlSchemaElementPtr decl = NULL;
25797 decl = xmlSchemaGetElem(vctxt->schema,
25798 vctxt->inode->localName, vctxt->inode->nsName);
25799 if (decl != NULL) {
25800 vctxt->inode->decl = decl;
25804 if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
25805 /* VAL TODO: Change to proper error code. */
25806 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
25807 "No matching global element declaration available, but "
25808 "demanded by the strict wildcard");
25809 return (vctxt->err);
25811 if (vctxt->nbAttrInfos != 0) {
25812 xmlSchemaAttrInfoPtr iattr;
25814 * SPEC Validation Rule: Schema-Validity Assessment (Element)
25815 * (1.2.1.2.1) - (1.2.1.2.3 )
25817 * Use the xsi:type attribute for the type definition.
25819 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25820 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25821 if (iattr != NULL) {
25822 if (xmlSchemaProcessXSIType(vctxt, iattr,
25823 &(vctxt->inode->typeDef), NULL) == -1) {
25824 VERROR_INT("xmlSchemaValidateElemWildcard",
25825 "calling xmlSchemaProcessXSIType() to "
25826 "process the attribute 'xsi:nil'");
25830 * Don't return an error on purpose.
25836 * SPEC Validation Rule: Schema-Validity Assessment (Element)
25838 * Fallback to "anyType".
25840 vctxt->inode->typeDef =
25841 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
25846 * xmlSchemaCheckCOSValidDefault:
25848 * This will be called if: not nilled, no content and a default/fixed
25849 * value is provided.
25853 xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
25854 const xmlChar *value,
25855 xmlSchemaValPtr *val)
25858 xmlSchemaNodeInfoPtr inode = vctxt->inode;
25861 * cos-valid-default:
25862 * Schema Component Constraint: Element Default Valid (Immediate)
25863 * For a string to be a valid default with respect to a type
25864 * definition the appropriate case among the following must be true:
25866 if WXS_IS_COMPLEX(inode->typeDef) {
25870 * SPEC (2.1) "its {content type} must be a simple type definition
25872 * SPEC (2.2.2) "If the {content type} is mixed, then the {content
25873 * type}'s particle must be �emptiable� as defined by
25874 * Particle Emptiable (�3.9.6)."
25876 if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
25877 ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
25878 (! WXS_EMPTIABLE(inode->typeDef)))) {
25879 ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
25880 /* NOTE that this covers (2.2.2) as well. */
25882 "For a string to be a valid default, the type definition "
25883 "must be a simple type or a complex type with simple content "
25884 "or mixed content and a particle emptiable");
25889 * 1 If the type definition is a simple type definition, then the string
25890 * must be �valid� with respect to that definition as defined by String
25891 * Valid (�3.14.4).
25895 * 2.2.1 If the {content type} is a simple type definition, then the
25896 * string must be �valid� with respect to that simple type definition
25897 * as defined by String Valid (�3.14.4).
25899 if (WXS_IS_SIMPLE(inode->typeDef)) {
25901 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25902 NULL, inode->typeDef, value, val, 1, 1, 0);
25904 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
25906 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25907 NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
25910 VERROR_INT("xmlSchemaCheckCOSValidDefault",
25911 "calling xmlSchemaVCheckCVCSimpleType()");
25917 xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
25918 const xmlChar * name ATTRIBUTE_UNUSED,
25919 xmlSchemaElementPtr item,
25920 xmlSchemaNodeInfoPtr inode)
25922 inode->decl = item;
25923 #ifdef DEBUG_CONTENT
25925 xmlChar *str = NULL;
25927 if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
25928 xmlGenericError(xmlGenericErrorContext,
25929 "AUTOMATON callback for '%s' [declaration]\n",
25930 xmlSchemaFormatQName(&str,
25931 inode->localName, inode->nsName));
25933 xmlGenericError(xmlGenericErrorContext,
25934 "AUTOMATON callback for '%s' [wildcard]\n",
25935 xmlSchemaFormatQName(&str,
25936 inode->localName, inode->nsName));
25945 xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
25947 vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
25948 if (vctxt->inode == NULL) {
25949 VERROR_INT("xmlSchemaValidatorPushElem",
25950 "calling xmlSchemaGetFreshElemInfo()");
25953 vctxt->nbAttrInfos = 0;
25958 xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
25959 xmlSchemaNodeInfoPtr inode,
25960 xmlSchemaTypePtr type,
25961 const xmlChar *value)
25963 if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
25964 return (xmlSchemaVCheckCVCSimpleType(
25965 ACTXT_CAST vctxt, NULL,
25966 type, value, &(inode->val), 1, 1, 0));
25968 return (xmlSchemaVCheckCVCSimpleType(
25969 ACTXT_CAST vctxt, NULL,
25970 type, value, NULL, 1, 0, 0));
25976 * Process END of element.
25979 xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
25982 xmlSchemaNodeInfoPtr inode = vctxt->inode;
25984 if (vctxt->nbAttrInfos != 0)
25985 xmlSchemaClearAttrInfos(vctxt);
25986 if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
25988 * This element was not expected;
25989 * we will not validate child elements of broken parents.
25990 * Skip validation of all content of the parent.
25992 vctxt->skipDepth = vctxt->depth -1;
25995 if ((inode->typeDef == NULL) ||
25996 (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
25998 * 1. the type definition might be missing if the element was
26000 * 2. it might be abstract.
26005 * Check the content model.
26007 if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
26008 (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
26011 * Workaround for "anyType".
26013 if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
26014 goto character_content;
26016 if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
26017 xmlChar *values[10];
26018 int terminal, nbval = 10, nbneg;
26020 if (inode->regexCtxt == NULL) {
26022 * Create the regex context.
26025 xmlRegNewExecCtxt(inode->typeDef->contModel,
26026 (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
26028 if (inode->regexCtxt == NULL) {
26029 VERROR_INT("xmlSchemaValidatorPopElem",
26030 "failed to create a regex context");
26031 goto internal_error;
26033 #ifdef DEBUG_AUTOMATA
26034 xmlGenericError(xmlGenericErrorContext,
26035 "AUTOMATON create on '%s'\n", inode->localName);
26039 * Get hold of the still expected content, since a further
26040 * call to xmlRegExecPushString() will loose this information.
26042 xmlRegExecNextValues(inode->regexCtxt,
26043 &nbval, &nbneg, &values[0], &terminal);
26044 ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
26045 if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
26047 * Still missing something.
26051 XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26052 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26053 XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
26054 "Missing child element(s)",
26055 nbval, nbneg, values);
26056 #ifdef DEBUG_AUTOMATA
26057 xmlGenericError(xmlGenericErrorContext,
26058 "AUTOMATON missing ERROR on '%s'\n",
26063 * Content model is satisfied.
26066 #ifdef DEBUG_AUTOMATA
26067 xmlGenericError(xmlGenericErrorContext,
26068 "AUTOMATON succeeded on '%s'\n",
26075 if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
26080 if (vctxt->value != NULL) {
26081 xmlSchemaFreeValue(vctxt->value);
26082 vctxt->value = NULL;
26085 * Check character content.
26087 if (inode->decl == NULL) {
26089 * Speedup if no declaration exists.
26091 if (WXS_IS_SIMPLE(inode->typeDef)) {
26092 ret = xmlSchemaVCheckINodeDataType(vctxt,
26093 inode, inode->typeDef, inode->value);
26094 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26095 ret = xmlSchemaVCheckINodeDataType(vctxt,
26096 inode, inode->typeDef->contentTypeDef,
26100 VERROR_INT("xmlSchemaValidatorPopElem",
26101 "calling xmlSchemaVCheckCVCSimpleType()");
26102 goto internal_error;
26107 * cvc-elt (3.3.4) : 5
26108 * The appropriate case among the following must be true:
26111 * cvc-elt (3.3.4) : 5.1
26112 * If the declaration has a {value constraint},
26113 * the item has neither element nor character [children] and
26114 * clause 3.2 has not applied, then all of the following must be true:
26116 if ((inode->decl->value != NULL) &&
26117 (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
26118 (! INODE_NILLED(inode))) {
26120 * cvc-elt (3.3.4) : 5.1.1
26121 * If the �actual type definition� is a �local type definition�
26122 * then the canonical lexical representation of the {value constraint}
26123 * value must be a valid default for the �actual type definition� as
26124 * defined in Element Default Valid (Immediate) (�3.3.6).
26127 * NOTE: 'local' above means types acquired by xsi:type.
26128 * NOTE: Although the *canonical* value is stated, it is not
26129 * relevant if canonical or not. Additionally XML Schema 1.1
26130 * will removed this requirement as well.
26132 if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
26134 ret = xmlSchemaCheckCOSValidDefault(vctxt,
26135 inode->decl->value, &(inode->val));
26138 VERROR_INT("xmlSchemaValidatorPopElem",
26139 "calling xmlSchemaCheckCOSValidDefault()");
26140 goto internal_error;
26145 * Stop here, to avoid redundant validation of the value
26151 * cvc-elt (3.3.4) : 5.1.2
26152 * The element information item with the canonical lexical
26153 * representation of the {value constraint} value used as its
26154 * �normalized value� must be �valid� with respect to the
26155 * �actual type definition� as defined by Element Locally Valid (Type)
26158 if (WXS_IS_SIMPLE(inode->typeDef)) {
26159 ret = xmlSchemaVCheckINodeDataType(vctxt,
26160 inode, inode->typeDef, inode->decl->value);
26161 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26162 ret = xmlSchemaVCheckINodeDataType(vctxt,
26163 inode, inode->typeDef->contentTypeDef,
26164 inode->decl->value);
26168 VERROR_INT("xmlSchemaValidatorPopElem",
26169 "calling xmlSchemaVCheckCVCSimpleType()");
26170 goto internal_error;
26177 * PSVI: Create a text node on the instance element.
26179 if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
26180 (inode->node != NULL)) {
26181 xmlNodePtr textChild;
26182 xmlChar *normValue;
26184 * VAL TODO: Normalize the value.
26186 normValue = xmlSchemaNormalizeValue(inode->typeDef,
26187 inode->decl->value);
26188 if (normValue != NULL) {
26189 textChild = xmlNewText(BAD_CAST normValue);
26190 xmlFree(normValue);
26192 textChild = xmlNewText(inode->decl->value);
26193 if (textChild == NULL) {
26194 VERROR_INT("xmlSchemaValidatorPopElem",
26195 "calling xmlNewText()");
26196 goto internal_error;
26198 xmlAddChild(inode->node, textChild);
26201 } else if (! INODE_NILLED(inode)) {
26203 * 5.2.1 The element information item must be �valid� with respect
26204 * to the �actual type definition� as defined by Element Locally
26205 * Valid (Type) (�3.3.4).
26207 if (WXS_IS_SIMPLE(inode->typeDef)) {
26209 * SPEC (cvc-type) (3.1)
26210 * "If the type definition is a simple type definition, ..."
26211 * (3.1.3) "If clause 3.2 of Element Locally Valid
26212 * (Element) (�3.3.4) did not apply, then the �normalized value�
26213 * must be �valid� with respect to the type definition as defined
26214 * by String Valid (�3.14.4).
26216 ret = xmlSchemaVCheckINodeDataType(vctxt,
26217 inode, inode->typeDef, inode->value);
26218 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26220 * SPEC (cvc-type) (3.2) "If the type definition is a complex type
26221 * definition, then the element information item must be
26222 * �valid� with respect to the type definition as per
26223 * Element Locally Valid (Complex Type) (�3.4.4);"
26225 * SPEC (cvc-complex-type) (2.2)
26226 * "If the {content type} is a simple type definition, ...
26227 * the �normalized value� of the element information item is
26228 * �valid� with respect to that simple type definition as
26229 * defined by String Valid (�3.14.4)."
26231 ret = xmlSchemaVCheckINodeDataType(vctxt,
26232 inode, inode->typeDef->contentTypeDef, inode->value);
26236 VERROR_INT("xmlSchemaValidatorPopElem",
26237 "calling xmlSchemaVCheckCVCSimpleType()");
26238 goto internal_error;
26243 * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
26244 * not applied, all of the following must be true:
26246 if ((inode->decl->value != NULL) &&
26247 (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
26250 * TODO: We will need a computed value, when comparison is
26251 * done on computed values.
26254 * 5.2.2.1 The element information item must have no element
26255 * information item [children].
26258 XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
26259 ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
26261 "The content must not containt element nodes since "
26262 "there is a fixed value constraint");
26266 * 5.2.2.2 The appropriate case among the following must
26269 if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
26271 * 5.2.2.2.1 If the {content type} of the �actual type
26272 * definition� is mixed, then the *initial value* of the
26273 * item must match the canonical lexical representation
26274 * of the {value constraint} value.
26276 * ... the *initial value* of an element information
26277 * item is the string composed of, in order, the
26278 * [character code] of each character information item in
26279 * the [children] of that element information item.
26281 if (! xmlStrEqual(inode->value, inode->decl->value)){
26283 * VAL TODO: Report invalid & expected values as well.
26284 * VAL TODO: Implement the canonical stuff.
26286 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
26287 xmlSchemaCustomErr(ACTXT_CAST vctxt,
26289 "The initial value '%s' does not match the fixed "
26290 "value constraint '%s'",
26291 inode->value, inode->decl->value);
26294 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26296 * 5.2.2.2.2 If the {content type} of the �actual type
26297 * definition� is a simple type definition, then the
26298 * *actual value* of the item must match the canonical
26299 * lexical representation of the {value constraint} value.
26302 * VAL TODO: *actual value* is the normalized value, impl.
26304 * VAL TODO: Report invalid & expected values as well.
26305 * VAL TODO: Implement a comparison with the computed values.
26307 if (! xmlStrEqual(inode->value,
26308 inode->decl->value)) {
26309 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
26310 xmlSchemaCustomErr(ACTXT_CAST vctxt,
26312 "The actual value '%s' does not match the fixed "
26313 "value constraint '%s'",
26315 inode->decl->value);
26324 if (vctxt->depth < 0) {
26325 /* TODO: raise error? */
26328 if (vctxt->depth == vctxt->skipDepth)
26329 vctxt->skipDepth = -1;
26331 * Evaluate the history of XPath state objects.
26333 if (inode->appliedXPath &&
26334 (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
26335 goto internal_error;
26338 * SPEC (6) "The element information item must be �valid� with
26339 * respect to each of the {identity-constraint definitions} as per
26340 * Identity-constraint Satisfied (�3.11.4)."
26343 * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
26344 * need to be built in any case.
26345 * We will currently build IDC node-tables and bubble them only if
26346 * keyrefs do exist.
26350 * Add the current IDC target-nodes to the IDC node-tables.
26352 if ((inode->idcMatchers != NULL) &&
26353 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26355 if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
26356 goto internal_error;
26359 * Validate IDC keyrefs.
26361 if (vctxt->inode->hasKeyrefs)
26362 if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
26363 goto internal_error;
26365 * Merge/free the IDC table.
26367 if (inode->idcTable != NULL) {
26368 #ifdef DEBUG_IDC_NODE_TABLE
26369 xmlSchemaDebugDumpIDCTable(stdout,
26374 if ((vctxt->depth > 0) &&
26375 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26378 * Merge the IDC node table with the table of the parent node.
26380 if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
26381 goto internal_error;
26385 * Clear the current ielem.
26386 * VAL TODO: Don't free the PSVI IDC tables if they are
26387 * requested for the PSVI.
26389 xmlSchemaClearElemInfo(vctxt, inode);
26391 * Skip further processing if we are on the validation root.
26393 if (vctxt->depth == 0) {
26395 vctxt->inode = NULL;
26399 * Reset the keyrefDepth if needed.
26401 if (vctxt->aidcs != NULL) {
26402 xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
26404 if (aidc->keyrefDepth == vctxt->depth) {
26406 * A 'keyrefDepth' of a key/unique IDC matches the current
26407 * depth, this means that we are leaving the scope of the
26408 * top-most keyref IDC which refers to this IDC.
26410 aidc->keyrefDepth = -1;
26413 } while (aidc != NULL);
26416 vctxt->inode = vctxt->elemInfos[vctxt->depth];
26418 * VAL TODO: 7 If the element information item is the �validation root�, it must be
26419 * �valid� per Validation Root Valid (ID/IDREF) (�3.3.4).
26429 * 3.4.4 Complex Type Definition Validation Rules
26430 * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
26433 xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
26435 xmlSchemaNodeInfoPtr pielem;
26436 xmlSchemaTypePtr ptype;
26439 if (vctxt->depth <= 0) {
26440 VERROR_INT("xmlSchemaValidateChildElem",
26441 "not intended for the validation root");
26444 pielem = vctxt->elemInfos[vctxt->depth -1];
26445 if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
26446 pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
26448 * Handle 'nilled' elements.
26450 if (INODE_NILLED(pielem)) {
26452 * SPEC (cvc-elt) (3.3.4) : (3.2.1)
26454 ACTIVATE_PARENT_ELEM;
26455 ret = XML_SCHEMAV_CVC_ELT_3_2_1;
26457 "Neither character nor element content is allowed, "
26458 "because the element was 'nilled'");
26460 goto unexpected_elem;
26463 ptype = pielem->typeDef;
26465 if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
26467 * Workaround for "anyType": we have currently no content model
26468 * assigned for "anyType", so handle it explicitely.
26469 * "anyType" has an unbounded, lax "any" wildcard.
26471 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26472 vctxt->inode->localName,
26473 vctxt->inode->nsName);
26475 if (vctxt->inode->decl == NULL) {
26476 xmlSchemaAttrInfoPtr iattr;
26478 * Process "xsi:type".
26479 * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
26481 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
26482 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
26483 if (iattr != NULL) {
26484 ret = xmlSchemaProcessXSIType(vctxt, iattr,
26485 &(vctxt->inode->typeDef), NULL);
26488 VERROR_INT("xmlSchemaValidateChildElem",
26489 "calling xmlSchemaProcessXSIType() to "
26490 "process the attribute 'xsi:nil'");
26497 * Fallback to "anyType".
26499 * SPEC (cvc-assess-elt)
26500 * "If the item cannot be �strictly assessed�, [...]
26501 * an element information item's schema validity may be laxly
26502 * assessed if its �context-determined declaration� is not
26503 * skip by �validating� with respect to the �ur-type
26504 * definition� as per Element Locally Valid (Type) (�3.3.4)."
26506 vctxt->inode->typeDef =
26507 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
26513 switch (ptype->contentType) {
26514 case XML_SCHEMA_CONTENT_EMPTY:
26516 * SPEC (2.1) "If the {content type} is empty, then the
26517 * element information item has no character or element
26518 * information item [children]."
26520 ACTIVATE_PARENT_ELEM
26521 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
26523 "Element content is not allowed, "
26524 "because the content type is empty");
26526 goto unexpected_elem;
26529 case XML_SCHEMA_CONTENT_MIXED:
26530 case XML_SCHEMA_CONTENT_ELEMENTS: {
26531 xmlRegExecCtxtPtr regexCtxt;
26532 xmlChar *values[10];
26533 int terminal, nbval = 10, nbneg;
26535 /* VAL TODO: Optimized "anyType" validation.*/
26537 if (ptype->contModel == NULL) {
26538 VERROR_INT("xmlSchemaValidateChildElem",
26539 "type has elem content but no content model");
26543 * Safety belf for evaluation if the cont. model was already
26544 * examined to be invalid.
26546 if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
26547 VERROR_INT("xmlSchemaValidateChildElem",
26548 "validating elem, but elem content is already invalid");
26552 regexCtxt = pielem->regexCtxt;
26553 if (regexCtxt == NULL) {
26555 * Create the regex context.
26557 regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
26558 (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
26560 if (regexCtxt == NULL) {
26561 VERROR_INT("xmlSchemaValidateChildElem",
26562 "failed to create a regex context");
26565 pielem->regexCtxt = regexCtxt;
26566 #ifdef DEBUG_AUTOMATA
26567 xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
26568 pielem->localName);
26573 * SPEC (2.4) "If the {content type} is element-only or mixed,
26574 * then the sequence of the element information item's
26575 * element information item [children], if any, taken in
26576 * order, is �valid� with respect to the {content type}'s
26577 * particle, as defined in Element Sequence Locally Valid
26578 * (Particle) (�3.9.4)."
26580 ret = xmlRegExecPushString2(regexCtxt,
26581 vctxt->inode->localName,
26582 vctxt->inode->nsName,
26584 #ifdef DEBUG_AUTOMATA
26586 xmlGenericError(xmlGenericErrorContext,
26587 "AUTOMATON push ERROR for '%s' on '%s'\n",
26588 vctxt->inode->localName, pielem->localName);
26590 xmlGenericError(xmlGenericErrorContext,
26591 "AUTOMATON push OK for '%s' on '%s'\n",
26592 vctxt->inode->localName, pielem->localName);
26594 if (vctxt->err == XML_SCHEMAV_INTERNAL) {
26595 VERROR_INT("xmlSchemaValidateChildElem",
26596 "calling xmlRegExecPushString2()");
26600 xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
26601 &values[0], &terminal);
26602 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26603 XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
26604 "This element is not expected",
26605 nbval, nbneg, values);
26607 goto unexpected_elem;
26612 case XML_SCHEMA_CONTENT_SIMPLE:
26613 case XML_SCHEMA_CONTENT_BASIC:
26614 ACTIVATE_PARENT_ELEM
26615 if (WXS_IS_COMPLEX(ptype)) {
26617 * SPEC (cvc-complex-type) (2.2)
26618 * "If the {content type} is a simple type definition, then
26619 * the element information item has no element information
26620 * item [children], ..."
26622 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
26623 VERROR(ret, NULL, "Element content is not allowed, "
26624 "because the content type is a simple type definition");
26627 * SPEC (cvc-type) (3.1.2) "The element information item must
26628 * have no element information item [children]."
26630 ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
26631 VERROR(ret, NULL, "Element content is not allowed, "
26632 "because the type definition is simple");
26636 goto unexpected_elem;
26645 * Pop this element and set the skipDepth to skip
26646 * all further content of the parent element.
26648 vctxt->skipDepth = vctxt->depth;
26649 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
26650 pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26654 #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
26655 #define XML_SCHEMA_PUSH_TEXT_CREATED 2
26656 #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
26659 xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
26660 int nodeType, const xmlChar *value, int len,
26661 int mode, int *consumed)
26664 * Unfortunately we have to duplicate the text sometimes.
26665 * OPTIMIZE: Maybe we could skip it, if:
26666 * 1. content type is simple
26667 * 2. whitespace is "collapse"
26668 * 3. it consists of whitespace only
26670 * Process character content.
26672 if (consumed != NULL)
26674 if (INODE_NILLED(vctxt->inode)) {
26676 * SPEC cvc-elt (3.3.4 - 3.2.1)
26677 * "The element information item must have no character or
26678 * element information item [children]."
26680 VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
26681 "Neither character nor element content is allowed "
26682 "because the element is 'nilled'");
26683 return (vctxt->err);
26686 * SPEC (2.1) "If the {content type} is empty, then the
26687 * element information item has no character or element
26688 * information item [children]."
26690 if (vctxt->inode->typeDef->contentType ==
26691 XML_SCHEMA_CONTENT_EMPTY) {
26692 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
26693 "Character content is not allowed, "
26694 "because the content type is empty");
26695 return (vctxt->err);
26698 if (vctxt->inode->typeDef->contentType ==
26699 XML_SCHEMA_CONTENT_ELEMENTS) {
26700 if ((nodeType != XML_TEXT_NODE) ||
26701 (! xmlSchemaIsBlank((xmlChar *) value, len))) {
26703 * SPEC cvc-complex-type (2.3)
26704 * "If the {content type} is element-only, then the
26705 * element information item has no character information
26706 * item [children] other than those whose [character
26707 * code] is defined as a white space in [XML 1.0 (Second
26710 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
26711 "Character content other than whitespace is not allowed "
26712 "because the content type is 'element-only'");
26713 return (vctxt->err);
26718 if ((value == NULL) || (value[0] == 0))
26722 * NOTE that even if the content type is *mixed*, we need the
26723 * *initial value* for default/fixed value constraints.
26725 if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
26726 ((vctxt->inode->decl == NULL) ||
26727 (vctxt->inode->decl->value == NULL)))
26730 if (vctxt->inode->value == NULL) {
26735 case XML_SCHEMA_PUSH_TEXT_PERSIST:
26737 * When working on a tree.
26739 vctxt->inode->value = value;
26741 case XML_SCHEMA_PUSH_TEXT_CREATED:
26743 * When working with the reader.
26744 * The value will be freed by the element info.
26746 vctxt->inode->value = value;
26747 if (consumed != NULL)
26749 vctxt->inode->flags |=
26750 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26752 case XML_SCHEMA_PUSH_TEXT_VOLATILE:
26754 * When working with SAX.
26755 * The value will be freed by the element info.
26758 vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
26760 vctxt->inode->value = BAD_CAST xmlStrdup(value);
26761 vctxt->inode->flags |=
26762 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26769 len = xmlStrlen(value);
26771 * Concat the value.
26773 if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
26774 vctxt->inode->value = BAD_CAST xmlStrncat(
26775 (xmlChar *) vctxt->inode->value, value, len);
26777 vctxt->inode->value =
26778 BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
26779 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26787 xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
26791 if ((vctxt->skipDepth != -1) &&
26792 (vctxt->depth >= vctxt->skipDepth)) {
26793 VERROR_INT("xmlSchemaValidateElem",
26795 goto internal_error;
26797 if (vctxt->xsiAssemble) {
26799 * We will stop validation if there was an error during
26800 * dynamic schema construction.
26801 * Note that we simply set @skipDepth to 0, this could
26802 * mean that a streaming document via SAX would be
26803 * still read to the end but it won't be validated any more.
26804 * TODO: If we are sure how to stop the validation at once
26805 * for all input scenarios, then this should be changed to
26806 * instantly stop the validation.
26808 ret = xmlSchemaAssembleByXSI(vctxt);
26811 goto internal_error;
26812 vctxt->skipDepth = 0;
26816 * Augment the IDC definitions for the main schema and all imported ones
26817 * NOTE: main schema is the first in the imported list
26819 xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
26821 if (vctxt->depth > 0) {
26823 * Validate this element against the content model
26826 ret = xmlSchemaValidateChildElem(vctxt);
26829 VERROR_INT("xmlSchemaValidateElem",
26830 "calling xmlSchemaStreamValidateChildElement()");
26831 goto internal_error;
26835 if (vctxt->depth == vctxt->skipDepth)
26837 if ((vctxt->inode->decl == NULL) &&
26838 (vctxt->inode->typeDef == NULL)) {
26839 VERROR_INT("xmlSchemaValidateElem",
26840 "the child element was valid but neither the "
26841 "declaration nor the type was set");
26842 goto internal_error;
26846 * Get the declaration of the validation root.
26848 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26849 vctxt->inode->localName,
26850 vctxt->inode->nsName);
26851 if (vctxt->inode->decl == NULL) {
26852 ret = XML_SCHEMAV_CVC_ELT_1;
26854 "No matching global declaration available "
26855 "for the validation root");
26860 if (vctxt->inode->decl == NULL)
26861 goto type_validation;
26863 if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
26868 ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
26871 VERROR_INT("xmlSchemaValidateElem",
26872 "calling xmlSchemaValidateElemWildcard()");
26873 goto internal_error;
26878 vctxt->skipDepth = vctxt->depth;
26882 * The declaration might be set by the wildcard validation,
26883 * when the processContents is "lax" or "strict".
26885 if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
26887 * Clear the "decl" field to not confuse further processing.
26889 vctxt->inode->decl = NULL;
26890 goto type_validation;
26894 * Validate against the declaration.
26896 ret = xmlSchemaValidateElemDecl(vctxt);
26899 VERROR_INT("xmlSchemaValidateElem",
26900 "calling xmlSchemaValidateElemDecl()");
26901 goto internal_error;
26906 * Validate against the type definition.
26910 if (vctxt->inode->typeDef == NULL) {
26911 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26912 ret = XML_SCHEMAV_CVC_TYPE_1;
26914 "The type definition is absent");
26917 if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
26918 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26919 ret = XML_SCHEMAV_CVC_TYPE_2;
26921 "The type definition is abstract");
26925 * Evaluate IDCs. Do it here, since new IDC matchers are registered
26926 * during validation against the declaration. This must be done
26927 * _before_ attribute validation.
26929 if (vctxt->xpathStates != NULL) {
26930 ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
26931 vctxt->inode->appliedXPath = 1;
26933 VERROR_INT("xmlSchemaValidateElem",
26934 "calling xmlSchemaXPathEvaluate()");
26935 goto internal_error;
26939 * Validate attributes.
26941 if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
26942 if ((vctxt->nbAttrInfos != 0) ||
26943 (vctxt->inode->typeDef->attrUses != NULL)) {
26945 ret = xmlSchemaVAttributesComplex(vctxt);
26947 } else if (vctxt->nbAttrInfos != 0) {
26949 ret = xmlSchemaVAttributesSimple(vctxt);
26952 * Clear registered attributes.
26954 if (vctxt->nbAttrInfos != 0)
26955 xmlSchemaClearAttrInfos(vctxt);
26957 VERROR_INT("xmlSchemaValidateElem",
26958 "calling attributes validation");
26959 goto internal_error;
26962 * Don't return an error if attributes are invalid on purpose.
26968 vctxt->skipDepth = vctxt->depth;
26974 #ifdef XML_SCHEMA_READER_ENABLED
26976 xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
26978 const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
26979 int depth, nodeType, ret = 0, consumed;
26980 xmlSchemaNodeInfoPtr ielem;
26983 ret = xmlTextReaderRead(vctxt->reader);
26985 * Move to the document element.
26988 nodeType = xmlTextReaderNodeType(vctxt->reader);
26989 if (nodeType == XML_ELEMENT_NODE)
26991 ret = xmlTextReaderRead(vctxt->reader);
26998 depth = xmlTextReaderDepth(vctxt->reader);
26999 nodeType = xmlTextReaderNodeType(vctxt->reader);
27001 if (nodeType == XML_ELEMENT_NODE) {
27004 if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27005 VERROR_INT("xmlSchemaVReaderWalk",
27006 "calling xmlSchemaValidatorPushElem()");
27007 goto internal_error;
27009 ielem = vctxt->inode;
27010 ielem->localName = xmlTextReaderLocalName(vctxt->reader);
27011 ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
27012 ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
27014 * Is the element empty?
27016 ret = xmlTextReaderIsEmptyElement(vctxt->reader);
27018 VERROR_INT("xmlSchemaVReaderWalk",
27019 "calling xmlTextReaderIsEmptyElement()");
27020 goto internal_error;
27023 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27026 * Register attributes.
27028 vctxt->nbAttrInfos = 0;
27029 ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
27031 VERROR_INT("xmlSchemaVReaderWalk",
27032 "calling xmlTextReaderMoveToFirstAttribute()");
27033 goto internal_error;
27038 * VAL TODO: How do we know that the reader works on a
27039 * node tree, to be able to pass a node here?
27041 if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
27042 (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
27043 xmlTextReaderNamespaceUri(vctxt->reader), 1,
27044 xmlTextReaderValue(vctxt->reader), 1) == -1) {
27046 VERROR_INT("xmlSchemaVReaderWalk",
27047 "calling xmlSchemaValidatorPushAttribute()");
27048 goto internal_error;
27050 ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
27052 VERROR_INT("xmlSchemaVReaderWalk",
27053 "calling xmlTextReaderMoveToFirstAttribute()");
27054 goto internal_error;
27056 } while (ret == 1);
27058 * Back to element position.
27060 ret = xmlTextReaderMoveToElement(vctxt->reader);
27062 VERROR_INT("xmlSchemaVReaderWalk",
27063 "calling xmlTextReaderMoveToElement()");
27064 goto internal_error;
27068 * Validate the element.
27070 ret= xmlSchemaValidateElem(vctxt);
27073 VERROR_INT("xmlSchemaVReaderWalk",
27074 "calling xmlSchemaValidateElem()");
27075 goto internal_error;
27079 if (vctxt->depth == vctxt->skipDepth) {
27082 * Skip all content.
27084 if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
27085 ret = xmlTextReaderRead(vctxt->reader);
27086 curDepth = xmlTextReaderDepth(vctxt->reader);
27087 while ((ret == 1) && (curDepth != depth)) {
27088 ret = xmlTextReaderRead(vctxt->reader);
27089 curDepth = xmlTextReaderDepth(vctxt->reader);
27093 * VAL TODO: A reader error occured; what to do here?
27102 * READER VAL TODO: Is an END_ELEM really never called
27103 * if the elem is empty?
27105 if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27107 } else if (nodeType == END_ELEM) {
27109 * Process END of element.
27112 ret = xmlSchemaValidatorPopElem(vctxt);
27115 VERROR_INT("xmlSchemaVReaderWalk",
27116 "calling xmlSchemaValidatorPopElem()");
27117 goto internal_error;
27121 if (vctxt->depth >= 0)
27122 ielem = vctxt->inode;
27125 } else if ((nodeType == XML_TEXT_NODE) ||
27126 (nodeType == XML_CDATA_SECTION_NODE) ||
27127 (nodeType == WHTSP) ||
27128 (nodeType == SIGN_WHTSP)) {
27130 * Process character content.
27134 if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
27135 nodeType = XML_TEXT_NODE;
27137 value = xmlTextReaderValue(vctxt->reader);
27138 ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
27139 -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
27143 VERROR_INT("xmlSchemaVReaderWalk",
27144 "calling xmlSchemaVPushText()");
27145 goto internal_error;
27147 } else if ((nodeType == XML_ENTITY_NODE) ||
27148 (nodeType == XML_ENTITY_REF_NODE)) {
27150 * VAL TODO: What to do with entities?
27157 ret = xmlTextReaderRead(vctxt->reader);
27158 } while (ret == 1);
27167 /************************************************************************
27169 * SAX validation handlers *
27171 ************************************************************************/
27174 * Process text content.
27177 xmlSchemaSAXHandleText(void *ctx,
27178 const xmlChar * ch,
27181 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27183 if (vctxt->depth < 0)
27185 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27187 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27188 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27189 if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
27190 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27191 VERROR_INT("xmlSchemaSAXHandleCDataSection",
27192 "calling xmlSchemaVPushText()");
27194 xmlStopParser(vctxt->parserCtxt);
27199 * Process CDATA content.
27202 xmlSchemaSAXHandleCDataSection(void *ctx,
27203 const xmlChar * ch,
27206 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27208 if (vctxt->depth < 0)
27210 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27212 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27213 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27214 if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
27215 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27216 VERROR_INT("xmlSchemaSAXHandleCDataSection",
27217 "calling xmlSchemaVPushText()");
27219 xmlStopParser(vctxt->parserCtxt);
27224 xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
27225 const xmlChar * name ATTRIBUTE_UNUSED)
27227 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27229 if (vctxt->depth < 0)
27231 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27233 /* SAX VAL TODO: What to do here? */
27238 xmlSchemaSAXHandleStartElementNs(void *ctx,
27239 const xmlChar * localname,
27240 const xmlChar * prefix ATTRIBUTE_UNUSED,
27241 const xmlChar * URI,
27243 const xmlChar ** namespaces,
27245 int nb_defaulted ATTRIBUTE_UNUSED,
27246 const xmlChar ** attributes)
27248 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27250 xmlSchemaNodeInfoPtr ielem;
27254 * SAX VAL TODO: What to do with nb_defaulted?
27257 * Skip elements if inside a "skip" wildcard or invalid.
27260 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27263 * Push the element.
27265 if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27266 VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27267 "calling xmlSchemaValidatorPushElem()");
27268 goto internal_error;
27270 ielem = vctxt->inode;
27272 * TODO: Is this OK?
27274 ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
27275 ielem->localName = localname;
27276 ielem->nsName = URI;
27277 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27279 * Register namespaces on the elem info.
27281 if (nb_namespaces != 0) {
27283 * Although the parser builds its own namespace list,
27284 * we have no access to it, so we'll use an own one.
27286 for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
27288 * Store prefix and namespace name.
27290 if (ielem->nsBindings == NULL) {
27291 ielem->nsBindings =
27292 (const xmlChar **) xmlMalloc(10 *
27293 sizeof(const xmlChar *));
27294 if (ielem->nsBindings == NULL) {
27295 xmlSchemaVErrMemory(vctxt,
27296 "allocating namespace bindings for SAX validation",
27298 goto internal_error;
27300 ielem->nbNsBindings = 0;
27301 ielem->sizeNsBindings = 5;
27302 } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
27303 ielem->sizeNsBindings *= 2;
27304 ielem->nsBindings =
27305 (const xmlChar **) xmlRealloc(
27306 (void *) ielem->nsBindings,
27307 ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
27308 if (ielem->nsBindings == NULL) {
27309 xmlSchemaVErrMemory(vctxt,
27310 "re-allocating namespace bindings for SAX validation",
27312 goto internal_error;
27316 ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
27317 if (namespaces[j+1][0] == 0) {
27321 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
27323 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
27325 ielem->nbNsBindings++;
27329 * Register attributes.
27330 * SAX VAL TODO: We are not adding namespace declaration
27333 if (nb_attributes != 0) {
27336 for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
27338 * Duplicate the value.
27340 value = xmlStrndup(attributes[j+3],
27341 attributes[j+4] - attributes[j+3]);
27343 * TODO: Set the node line.
27345 ret = xmlSchemaValidatorPushAttribute(vctxt,
27346 NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
27349 VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27350 "calling xmlSchemaValidatorPushAttribute()");
27351 goto internal_error;
27356 * Validate the element.
27358 ret = xmlSchemaValidateElem(vctxt);
27361 VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27362 "calling xmlSchemaValidateElem()");
27363 goto internal_error;
27372 xmlStopParser(vctxt->parserCtxt);
27377 xmlSchemaSAXHandleEndElementNs(void *ctx,
27378 const xmlChar * localname ATTRIBUTE_UNUSED,
27379 const xmlChar * prefix ATTRIBUTE_UNUSED,
27380 const xmlChar * URI ATTRIBUTE_UNUSED)
27382 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27386 * Skip elements if inside a "skip" wildcard or if invalid.
27388 if (vctxt->skipDepth != -1) {
27389 if (vctxt->depth > vctxt->skipDepth) {
27393 vctxt->skipDepth = -1;
27396 * SAX VAL TODO: Just a temporary check.
27398 if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
27399 (!xmlStrEqual(vctxt->inode->nsName, URI))) {
27400 VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27401 "elem pop mismatch");
27403 res = xmlSchemaValidatorPopElem(vctxt);
27406 VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27407 "calling xmlSchemaValidatorPopElem()");
27408 goto internal_error;
27416 xmlStopParser(vctxt->parserCtxt);
27420 /************************************************************************
27422 * Validation interfaces *
27424 ************************************************************************/
27427 * xmlSchemaNewValidCtxt:
27428 * @schema: a precompiled XML Schemas
27430 * Create an XML Schemas validation context based on the given schema.
27432 * Returns the validation context or NULL in case of error
27434 xmlSchemaValidCtxtPtr
27435 xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
27437 xmlSchemaValidCtxtPtr ret;
27439 ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
27441 xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
27444 memset(ret, 0, sizeof(xmlSchemaValidCtxt));
27445 ret->type = XML_SCHEMA_CTXT_VALIDATOR;
27446 ret->dict = xmlDictCreate();
27447 ret->nodeQNames = xmlSchemaItemListCreate();
27448 ret->schema = schema;
27453 * xmlSchemaClearValidCtxt:
27454 * @ctxt: the schema validation context
27456 * Free the resources associated to the schema validation context;
27457 * leaves some fields alive intended for reuse of the context.
27460 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
27466 * TODO: Should we clear the flags?
27467 * Might be problematic if one reuses the context
27468 * and assumes that the options remain the same.
27471 vctxt->validationRoot = NULL;
27473 #ifdef LIBXML_READER_ENABLED
27474 vctxt->reader = NULL;
27476 vctxt->hasKeyrefs = 0;
27478 if (vctxt->value != NULL) {
27479 xmlSchemaFreeValue(vctxt->value);
27480 vctxt->value = NULL;
27483 * Augmented IDC information.
27485 if (vctxt->aidcs != NULL) {
27486 xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
27491 } while (cur != NULL);
27492 vctxt->aidcs = NULL;
27494 if (vctxt->idcMatcherCache != NULL) {
27495 xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
27499 matcher = matcher->nextCached;
27500 xmlSchemaIDCFreeMatcherList(tmp);
27502 vctxt->idcMatcherCache = NULL;
27506 if (vctxt->idcNodes != NULL) {
27508 xmlSchemaPSVIIDCNodePtr item;
27510 for (i = 0; i < vctxt->nbIdcNodes; i++) {
27511 item = vctxt->idcNodes[i];
27512 xmlFree(item->keys);
27515 xmlFree(vctxt->idcNodes);
27516 vctxt->idcNodes = NULL;
27517 vctxt->nbIdcNodes = 0;
27518 vctxt->sizeIdcNodes = 0;
27521 * Note that we won't delete the XPath state pool here.
27523 if (vctxt->xpathStates != NULL) {
27524 xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
27525 vctxt->xpathStates = NULL;
27530 if (vctxt->nbAttrInfos != 0) {
27531 xmlSchemaClearAttrInfos(vctxt);
27536 if (vctxt->elemInfos != NULL) {
27538 xmlSchemaNodeInfoPtr ei;
27540 for (i = 0; i < vctxt->sizeElemInfos; i++) {
27541 ei = vctxt->elemInfos[i];
27544 xmlSchemaClearElemInfo(vctxt, ei);
27547 xmlSchemaItemListClear(vctxt->nodeQNames);
27548 /* Recreate the dict. */
27549 xmlDictFree(vctxt->dict);
27551 * TODO: Is is save to recreate it? Do we have a scenario
27552 * where the user provides the dict?
27554 vctxt->dict = xmlDictCreate();
27558 * xmlSchemaFreeValidCtxt:
27559 * @ctxt: the schema validation context
27561 * Free the resources associated to the schema validation context
27564 xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
27568 if (ctxt->value != NULL)
27569 xmlSchemaFreeValue(ctxt->value);
27570 if (ctxt->pctxt != NULL)
27571 xmlSchemaFreeParserCtxt(ctxt->pctxt);
27572 if (ctxt->idcNodes != NULL) {
27574 xmlSchemaPSVIIDCNodePtr item;
27576 for (i = 0; i < ctxt->nbIdcNodes; i++) {
27577 item = ctxt->idcNodes[i];
27578 xmlFree(item->keys);
27581 xmlFree(ctxt->idcNodes);
27583 if (ctxt->idcKeys != NULL) {
27585 for (i = 0; i < ctxt->nbIdcKeys; i++)
27586 xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
27587 xmlFree(ctxt->idcKeys);
27590 if (ctxt->xpathStates != NULL) {
27591 xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
27592 ctxt->xpathStates = NULL;
27594 if (ctxt->xpathStatePool != NULL) {
27595 xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
27596 ctxt->xpathStatePool = NULL;
27600 * Augmented IDC information.
27602 if (ctxt->aidcs != NULL) {
27603 xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
27608 } while (cur != NULL);
27610 if (ctxt->attrInfos != NULL) {
27612 xmlSchemaAttrInfoPtr attr;
27614 /* Just a paranoid call to the cleanup. */
27615 if (ctxt->nbAttrInfos != 0)
27616 xmlSchemaClearAttrInfos(ctxt);
27617 for (i = 0; i < ctxt->sizeAttrInfos; i++) {
27618 attr = ctxt->attrInfos[i];
27621 xmlFree(ctxt->attrInfos);
27623 if (ctxt->elemInfos != NULL) {
27625 xmlSchemaNodeInfoPtr ei;
27627 for (i = 0; i < ctxt->sizeElemInfos; i++) {
27628 ei = ctxt->elemInfos[i];
27631 xmlSchemaClearElemInfo(ctxt, ei);
27634 xmlFree(ctxt->elemInfos);
27636 if (ctxt->nodeQNames != NULL)
27637 xmlSchemaItemListFree(ctxt->nodeQNames);
27638 if (ctxt->dict != NULL)
27639 xmlDictFree(ctxt->dict);
27644 * xmlSchemaIsValid:
27645 * @ctxt: the schema validation context
27647 * Check if any error was detected during validation.
27649 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
27650 * of internal error.
27653 xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
27657 return(ctxt->err == 0);
27661 * xmlSchemaSetValidErrors:
27662 * @ctxt: a schema validation context
27663 * @err: the error function
27664 * @warn: the warning function
27665 * @ctx: the functions context
27667 * Set the error and warning callback informations
27670 xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27671 xmlSchemaValidityErrorFunc err,
27672 xmlSchemaValidityWarningFunc warn, void *ctx)
27677 ctxt->warning = warn;
27678 ctxt->errCtxt = ctx;
27679 if (ctxt->pctxt != NULL)
27680 xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
27684 * xmlSchemaSetValidStructuredErrors:
27685 * @ctxt: a schema validation context
27686 * @serror: the structured error function
27687 * @ctx: the functions context
27689 * Set the structured error callback
27692 xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
27693 xmlStructuredErrorFunc serror, void *ctx)
27697 ctxt->serror = serror;
27698 ctxt->error = NULL;
27699 ctxt->warning = NULL;
27700 ctxt->errCtxt = ctx;
27701 if (ctxt->pctxt != NULL)
27702 xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
27706 * xmlSchemaGetValidErrors:
27707 * @ctxt: a XML-Schema validation context
27708 * @err: the error function result
27709 * @warn: the warning function result
27710 * @ctx: the functions context result
27712 * Get the error and warning callback informations
27714 * Returns -1 in case of error and 0 otherwise
27717 xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27718 xmlSchemaValidityErrorFunc * err,
27719 xmlSchemaValidityWarningFunc * warn, void **ctx)
27724 *err = ctxt->error;
27726 *warn = ctxt->warning;
27728 *ctx = ctxt->errCtxt;
27734 * xmlSchemaSetValidOptions:
27735 * @ctxt: a schema validation context
27736 * @options: a combination of xmlSchemaValidOption
27738 * Sets the options to be used during the validation.
27740 * Returns 0 in case of success, -1 in case of an
27744 xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
27753 * WARNING: Change the start value if adding to the
27754 * xmlSchemaValidOption.
27755 * TODO: Is there an other, more easy to maintain,
27758 for (i = 1; i < (int) sizeof(int) * 8; i++) {
27759 if (options & 1<<i)
27762 ctxt->options = options;
27767 * xmlSchemaValidCtxtGetOptions:
27768 * @ctxt: a schema validation context
27770 * Get the validation context options.
27772 * Returns the option combination or -1 on error.
27775 xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
27781 return (ctxt->options);
27785 xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
27789 xmlSchemaNodeInfoPtr ielem = NULL;
27790 xmlNodePtr node, valRoot;
27791 const xmlChar *nsName;
27793 /* DOC VAL TODO: Move this to the start function. */
27794 valRoot = xmlDocGetRootElement(vctxt->doc);
27795 if (valRoot == NULL) {
27796 /* VAL TODO: Error code? */
27797 VERROR(1, NULL, "The document has no document element");
27801 vctxt->validationRoot = valRoot;
27803 while (node != NULL) {
27804 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27806 if (node->type == XML_ELEMENT_NODE) {
27809 * Init the node-info.
27812 if (xmlSchemaValidatorPushElem(vctxt) == -1)
27813 goto internal_error;
27814 ielem = vctxt->inode;
27815 ielem->node = node;
27816 ielem->nodeLine = node->line;
27817 ielem->localName = node->name;
27818 if (node->ns != NULL)
27819 ielem->nsName = node->ns->href;
27820 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27822 * Register attributes.
27823 * DOC VAL TODO: We do not register namespace declaration
27826 vctxt->nbAttrInfos = 0;
27827 if (node->properties != NULL) {
27828 attr = node->properties;
27830 if (attr->ns != NULL)
27831 nsName = attr->ns->href;
27834 ret = xmlSchemaValidatorPushAttribute(vctxt,
27837 * Note that we give it the line number of the
27841 attr->name, nsName, 0,
27842 xmlNodeListGetString(attr->doc, attr->children, 1), 1);
27844 VERROR_INT("xmlSchemaDocWalk",
27845 "calling xmlSchemaValidatorPushAttribute()");
27846 goto internal_error;
27852 * Validate the element.
27854 ret = xmlSchemaValidateElem(vctxt);
27857 VERROR_INT("xmlSchemaDocWalk",
27858 "calling xmlSchemaValidateElem()");
27859 goto internal_error;
27862 * Don't stop validation; just skip the content
27867 if ((vctxt->skipDepth != -1) &&
27868 (vctxt->depth >= vctxt->skipDepth))
27870 } else if ((node->type == XML_TEXT_NODE) ||
27871 (node->type == XML_CDATA_SECTION_NODE)) {
27873 * Process character content.
27875 if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
27876 ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27877 ret = xmlSchemaVPushText(vctxt, node->type, node->content,
27878 -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
27880 VERROR_INT("xmlSchemaVDocWalk",
27881 "calling xmlSchemaVPushText()");
27882 goto internal_error;
27885 * DOC VAL TODO: Should we skip further validation of the
27886 * element content here?
27888 } else if ((node->type == XML_ENTITY_NODE) ||
27889 (node->type == XML_ENTITY_REF_NODE)) {
27891 * DOC VAL TODO: What to do with entities?
27893 VERROR_INT("xmlSchemaVDocWalk",
27894 "there is at least one entity reference in the node-tree "
27895 "currently being validated. Processing of entities with "
27896 "this XML Schema processor is not supported (yet). Please "
27897 "substitute entities before validation.");
27898 goto internal_error;
27902 * DOC VAL TODO: XInclude nodes, etc.
27908 if (node->children != NULL) {
27909 node = node->children;
27913 if (node->type == XML_ELEMENT_NODE) {
27915 * Leaving the scope of an element.
27917 if (node != vctxt->inode->node) {
27918 VERROR_INT("xmlSchemaVDocWalk",
27919 "element position mismatch");
27920 goto internal_error;
27922 ret = xmlSchemaValidatorPopElem(vctxt);
27925 VERROR_INT("xmlSchemaVDocWalk",
27926 "calling xmlSchemaValidatorPopElem()");
27927 goto internal_error;
27930 if (node == valRoot)
27934 if (node->next != NULL)
27937 node = node->parent;
27949 xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
27951 * Some initialization.
27954 vctxt->nberrors = 0;
27956 vctxt->skipDepth = -1;
27957 vctxt->xsiAssemble = 0;
27958 vctxt->hasKeyrefs = 0;
27959 #ifdef ENABLE_IDC_NODE_TABLES_TEST
27960 vctxt->createIDCNodeTables = 1;
27962 vctxt->createIDCNodeTables = 0;
27965 * Create a schema + parser if necessary.
27967 if (vctxt->schema == NULL) {
27968 xmlSchemaParserCtxtPtr pctxt;
27970 vctxt->xsiAssemble = 1;
27972 * If not schema was given then we will create a schema
27973 * dynamically using XSI schema locations.
27975 * Create the schema parser context.
27977 if ((vctxt->pctxt == NULL) &&
27978 (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
27980 pctxt = vctxt->pctxt;
27981 pctxt->xsiAssemble = 1;
27983 * Create the schema.
27985 vctxt->schema = xmlSchemaNewSchema(pctxt);
27986 if (vctxt->schema == NULL)
27989 * Create the schema construction context.
27991 pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
27992 if (pctxt->constructor == NULL)
27994 pctxt->constructor->mainSchema = vctxt->schema;
27996 * Take ownership of the constructor to be able to free it.
27998 pctxt->ownsConstructor = 1;
28001 * Augment the IDC definitions for the main schema and all imported ones
28002 * NOTE: main schema if the first in the imported list
28004 xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
28010 xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
28011 if (vctxt->xsiAssemble) {
28012 if (vctxt->schema != NULL) {
28013 xmlSchemaFree(vctxt->schema);
28014 vctxt->schema = NULL;
28017 xmlSchemaClearValidCtxt(vctxt);
28021 xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
28025 if (xmlSchemaPreRun(vctxt) < 0)
28028 if (vctxt->doc != NULL) {
28032 ret = xmlSchemaVDocWalk(vctxt);
28033 #ifdef LIBXML_READER_ENABLED
28034 } else if (vctxt->reader != NULL) {
28036 * XML Reader validation.
28038 #ifdef XML_SCHEMA_READER_ENABLED
28039 ret = xmlSchemaVReaderWalk(vctxt);
28042 } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
28046 ret = xmlParseDocument(vctxt->parserCtxt);
28048 VERROR_INT("xmlSchemaVStart",
28049 "no instance to validate");
28053 xmlSchemaPostRun(vctxt);
28060 * xmlSchemaValidateOneElement:
28061 * @ctxt: a schema validation context
28062 * @elem: an element node
28064 * Validate a branch of a tree, starting with the given @elem.
28066 * Returns 0 if the element and its subtree is valid, a positive error
28067 * code number otherwise and -1 in case of an internal or API error.
28070 xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
28072 if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
28075 if (ctxt->schema == NULL)
28078 ctxt->doc = elem->doc;
28080 ctxt->validationRoot = elem;
28081 return(xmlSchemaVStart(ctxt));
28085 * xmlSchemaValidateDoc:
28086 * @ctxt: a schema validation context
28087 * @doc: a parsed document tree
28089 * Validate a document tree in memory.
28091 * Returns 0 if the document is schemas valid, a positive error code
28092 * number otherwise and -1 in case of internal or API error.
28095 xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
28097 if ((ctxt == NULL) || (doc == NULL))
28101 ctxt->node = xmlDocGetRootElement(doc);
28102 if (ctxt->node == NULL) {
28103 xmlSchemaCustomErr(ACTXT_CAST ctxt,
28104 XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
28105 (xmlNodePtr) doc, NULL,
28106 "The document has no document element", NULL, NULL);
28107 return (ctxt->err);
28109 ctxt->validationRoot = ctxt->node;
28110 return (xmlSchemaVStart(ctxt));
28114 /************************************************************************
28116 * Function and data for SAX streaming API *
28118 ************************************************************************/
28119 typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
28120 typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
28122 struct _xmlSchemaSplitSAXData {
28123 xmlSAXHandlerPtr user_sax;
28125 xmlSchemaValidCtxtPtr ctxt;
28126 xmlSAXHandlerPtr schemas_sax;
28129 #define XML_SAX_PLUG_MAGIC 0xdc43ba21
28131 struct _xmlSchemaSAXPlug {
28132 unsigned int magic;
28134 /* the original callbacks informations */
28135 xmlSAXHandlerPtr *user_sax_ptr;
28136 xmlSAXHandlerPtr user_sax;
28137 void **user_data_ptr;
28140 /* the block plugged back and validation informations */
28141 xmlSAXHandler schemas_sax;
28142 xmlSchemaValidCtxtPtr ctxt;
28145 /* All those functions just bounces to the user provided SAX handlers */
28147 internalSubsetSplit(void *ctx, const xmlChar *name,
28148 const xmlChar *ExternalID, const xmlChar *SystemID)
28150 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28151 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28152 (ctxt->user_sax->internalSubset != NULL))
28153 ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
28158 isStandaloneSplit(void *ctx)
28160 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28161 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28162 (ctxt->user_sax->isStandalone != NULL))
28163 return(ctxt->user_sax->isStandalone(ctxt->user_data));
28168 hasInternalSubsetSplit(void *ctx)
28170 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28171 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28172 (ctxt->user_sax->hasInternalSubset != NULL))
28173 return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
28178 hasExternalSubsetSplit(void *ctx)
28180 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28181 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28182 (ctxt->user_sax->hasExternalSubset != NULL))
28183 return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
28188 externalSubsetSplit(void *ctx, const xmlChar *name,
28189 const xmlChar *ExternalID, const xmlChar *SystemID)
28191 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28192 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28193 (ctxt->user_sax->externalSubset != NULL))
28194 ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
28198 static xmlParserInputPtr
28199 resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
28201 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28202 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28203 (ctxt->user_sax->resolveEntity != NULL))
28204 return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
28209 static xmlEntityPtr
28210 getEntitySplit(void *ctx, const xmlChar *name)
28212 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28213 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28214 (ctxt->user_sax->getEntity != NULL))
28215 return(ctxt->user_sax->getEntity(ctxt->user_data, name));
28219 static xmlEntityPtr
28220 getParameterEntitySplit(void *ctx, const xmlChar *name)
28222 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28223 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28224 (ctxt->user_sax->getParameterEntity != NULL))
28225 return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
28231 entityDeclSplit(void *ctx, const xmlChar *name, int type,
28232 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
28234 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28235 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28236 (ctxt->user_sax->entityDecl != NULL))
28237 ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
28238 systemId, content);
28242 attributeDeclSplit(void *ctx, const xmlChar * elem,
28243 const xmlChar * name, int type, int def,
28244 const xmlChar * defaultValue, xmlEnumerationPtr tree)
28246 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28247 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28248 (ctxt->user_sax->attributeDecl != NULL)) {
28249 ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
28250 def, defaultValue, tree);
28252 xmlFreeEnumeration(tree);
28257 elementDeclSplit(void *ctx, const xmlChar *name, int type,
28258 xmlElementContentPtr content)
28260 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28261 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28262 (ctxt->user_sax->elementDecl != NULL))
28263 ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
28267 notationDeclSplit(void *ctx, const xmlChar *name,
28268 const xmlChar *publicId, const xmlChar *systemId)
28270 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28271 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28272 (ctxt->user_sax->notationDecl != NULL))
28273 ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
28278 unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
28279 const xmlChar *publicId, const xmlChar *systemId,
28280 const xmlChar *notationName)
28282 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28283 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28284 (ctxt->user_sax->unparsedEntityDecl != NULL))
28285 ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
28286 systemId, notationName);
28290 setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
28292 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28293 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28294 (ctxt->user_sax->setDocumentLocator != NULL))
28295 ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
28299 startDocumentSplit(void *ctx)
28301 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28302 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28303 (ctxt->user_sax->startDocument != NULL))
28304 ctxt->user_sax->startDocument(ctxt->user_data);
28308 endDocumentSplit(void *ctx)
28310 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28311 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28312 (ctxt->user_sax->endDocument != NULL))
28313 ctxt->user_sax->endDocument(ctxt->user_data);
28317 processingInstructionSplit(void *ctx, const xmlChar *target,
28318 const xmlChar *data)
28320 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28321 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28322 (ctxt->user_sax->processingInstruction != NULL))
28323 ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
28327 commentSplit(void *ctx, const xmlChar *value)
28329 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28330 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28331 (ctxt->user_sax->comment != NULL))
28332 ctxt->user_sax->comment(ctxt->user_data, value);
28336 * Varargs error callbacks to the user application, harder ...
28339 static void XMLCDECL
28340 warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28341 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28342 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28343 (ctxt->user_sax->warning != NULL)) {
28347 static void XMLCDECL
28348 errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28349 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28350 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28351 (ctxt->user_sax->error != NULL)) {
28355 static void XMLCDECL
28356 fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28357 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28358 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28359 (ctxt->user_sax->fatalError != NULL)) {
28365 * Those are function where both the user handler and the schemas handler
28366 * need to be called.
28369 charactersSplit(void *ctx, const xmlChar *ch, int len)
28371 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28374 if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
28375 ctxt->user_sax->characters(ctxt->user_data, ch, len);
28376 if (ctxt->ctxt != NULL)
28377 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28381 ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
28383 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28386 if ((ctxt->user_sax != NULL) &&
28387 (ctxt->user_sax->ignorableWhitespace != NULL))
28388 ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
28389 if (ctxt->ctxt != NULL)
28390 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28394 cdataBlockSplit(void *ctx, const xmlChar *value, int len)
28396 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28399 if ((ctxt->user_sax != NULL) &&
28400 (ctxt->user_sax->cdataBlock != NULL))
28401 ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
28402 if (ctxt->ctxt != NULL)
28403 xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
28407 referenceSplit(void *ctx, const xmlChar *name)
28409 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28412 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28413 (ctxt->user_sax->reference != NULL))
28414 ctxt->user_sax->reference(ctxt->user_data, name);
28415 if (ctxt->ctxt != NULL)
28416 xmlSchemaSAXHandleReference(ctxt->user_data, name);
28420 startElementNsSplit(void *ctx, const xmlChar * localname,
28421 const xmlChar * prefix, const xmlChar * URI,
28422 int nb_namespaces, const xmlChar ** namespaces,
28423 int nb_attributes, int nb_defaulted,
28424 const xmlChar ** attributes) {
28425 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28428 if ((ctxt->user_sax != NULL) &&
28429 (ctxt->user_sax->startElementNs != NULL))
28430 ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
28431 URI, nb_namespaces, namespaces,
28432 nb_attributes, nb_defaulted,
28434 if (ctxt->ctxt != NULL)
28435 xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
28436 URI, nb_namespaces, namespaces,
28437 nb_attributes, nb_defaulted,
28442 endElementNsSplit(void *ctx, const xmlChar * localname,
28443 const xmlChar * prefix, const xmlChar * URI) {
28444 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28447 if ((ctxt->user_sax != NULL) &&
28448 (ctxt->user_sax->endElementNs != NULL))
28449 ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
28450 if (ctxt->ctxt != NULL)
28451 xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
28455 * xmlSchemaSAXPlug:
28456 * @ctxt: a schema validation context
28457 * @sax: a pointer to the original xmlSAXHandlerPtr
28458 * @user_data: a pointer to the original SAX user data pointer
28460 * Plug a SAX based validation layer in a SAX parsing event flow.
28461 * The original @saxptr and @dataptr data are replaced by new pointers
28462 * but the calls to the original will be maintained.
28464 * Returns a pointer to a data structure needed to unplug the validation layer
28465 * or NULL in case of errors.
28467 xmlSchemaSAXPlugPtr
28468 xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
28469 xmlSAXHandlerPtr *sax, void **user_data)
28471 xmlSchemaSAXPlugPtr ret;
28472 xmlSAXHandlerPtr old_sax;
28474 if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
28478 * We only allow to plug into SAX2 event streams
28481 if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
28483 if ((old_sax != NULL) &&
28484 (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
28485 ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
28489 * everything seems right allocate the local data needed for that layer
28491 ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
28495 memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
28496 ret->magic = XML_SAX_PLUG_MAGIC;
28497 ret->schemas_sax.initialized = XML_SAX2_MAGIC;
28499 ret->user_sax_ptr = sax;
28500 ret->user_sax = old_sax;
28501 if (old_sax == NULL) {
28503 * go direct, no need for the split block and functions.
28505 ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
28506 ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
28508 * Note that we use the same text-function for both, to prevent
28509 * the parser from testing for ignorable whitespace.
28511 ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
28512 ret->schemas_sax.characters = xmlSchemaSAXHandleText;
28514 ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
28515 ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
28517 ret->user_data = ctxt;
28521 * for each callback unused by Schemas initialize it to the Split
28522 * routine only if non NULL in the user block, this can speed up
28523 * things at the SAX level.
28525 if (old_sax->internalSubset != NULL)
28526 ret->schemas_sax.internalSubset = internalSubsetSplit;
28527 if (old_sax->isStandalone != NULL)
28528 ret->schemas_sax.isStandalone = isStandaloneSplit;
28529 if (old_sax->hasInternalSubset != NULL)
28530 ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
28531 if (old_sax->hasExternalSubset != NULL)
28532 ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
28533 if (old_sax->resolveEntity != NULL)
28534 ret->schemas_sax.resolveEntity = resolveEntitySplit;
28535 if (old_sax->getEntity != NULL)
28536 ret->schemas_sax.getEntity = getEntitySplit;
28537 if (old_sax->entityDecl != NULL)
28538 ret->schemas_sax.entityDecl = entityDeclSplit;
28539 if (old_sax->notationDecl != NULL)
28540 ret->schemas_sax.notationDecl = notationDeclSplit;
28541 if (old_sax->attributeDecl != NULL)
28542 ret->schemas_sax.attributeDecl = attributeDeclSplit;
28543 if (old_sax->elementDecl != NULL)
28544 ret->schemas_sax.elementDecl = elementDeclSplit;
28545 if (old_sax->unparsedEntityDecl != NULL)
28546 ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
28547 if (old_sax->setDocumentLocator != NULL)
28548 ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
28549 if (old_sax->startDocument != NULL)
28550 ret->schemas_sax.startDocument = startDocumentSplit;
28551 if (old_sax->endDocument != NULL)
28552 ret->schemas_sax.endDocument = endDocumentSplit;
28553 if (old_sax->processingInstruction != NULL)
28554 ret->schemas_sax.processingInstruction = processingInstructionSplit;
28555 if (old_sax->comment != NULL)
28556 ret->schemas_sax.comment = commentSplit;
28557 if (old_sax->warning != NULL)
28558 ret->schemas_sax.warning = warningSplit;
28559 if (old_sax->error != NULL)
28560 ret->schemas_sax.error = errorSplit;
28561 if (old_sax->fatalError != NULL)
28562 ret->schemas_sax.fatalError = fatalErrorSplit;
28563 if (old_sax->getParameterEntity != NULL)
28564 ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
28565 if (old_sax->externalSubset != NULL)
28566 ret->schemas_sax.externalSubset = externalSubsetSplit;
28569 * the 6 schemas callback have to go to the splitter functions
28570 * Note that we use the same text-function for ignorableWhitespace
28571 * if possible, to prevent the parser from testing for ignorable
28574 ret->schemas_sax.characters = charactersSplit;
28575 if ((old_sax->ignorableWhitespace != NULL) &&
28576 (old_sax->ignorableWhitespace != old_sax->characters))
28577 ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
28579 ret->schemas_sax.ignorableWhitespace = charactersSplit;
28580 ret->schemas_sax.cdataBlock = cdataBlockSplit;
28581 ret->schemas_sax.reference = referenceSplit;
28582 ret->schemas_sax.startElementNs = startElementNsSplit;
28583 ret->schemas_sax.endElementNs = endElementNsSplit;
28585 ret->user_data_ptr = user_data;
28586 ret->user_data = *user_data;
28591 * plug the pointers back.
28593 *sax = &(ret->schemas_sax);
28595 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28596 xmlSchemaPreRun(ctxt);
28601 * xmlSchemaSAXUnplug:
28602 * @plug: a data structure returned by xmlSchemaSAXPlug
28604 * Unplug a SAX based validation layer in a SAX parsing event flow.
28605 * The original pointers used in the call are restored.
28607 * Returns 0 in case of success and -1 in case of failure.
28610 xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
28612 xmlSAXHandlerPtr *sax;
28615 if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
28619 xmlSchemaPostRun(plug->ctxt);
28620 /* restore the data */
28621 sax = plug->user_sax_ptr;
28622 *sax = plug->user_sax;
28623 if (plug->user_sax != NULL) {
28624 user_data = plug->user_data_ptr;
28625 *user_data = plug->user_data;
28628 /* free and return */
28634 * xmlSchemaValidateStream:
28635 * @ctxt: a schema validation context
28636 * @input: the input to use for reading the data
28637 * @enc: an optional encoding information
28638 * @sax: a SAX handler for the resulting events
28639 * @user_data: the context to provide to the SAX handler.
28641 * Validate an input based on a flow of SAX event from the parser
28642 * and forward the events to the @sax handler with the provided @user_data
28643 * the user provided @sax handler must be a SAX2 one.
28645 * Returns 0 if the document is schemas valid, a positive error code
28646 * number otherwise and -1 in case of internal or API error.
28649 xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
28650 xmlParserInputBufferPtr input, xmlCharEncoding enc,
28651 xmlSAXHandlerPtr sax, void *user_data)
28653 xmlSchemaSAXPlugPtr plug = NULL;
28654 xmlSAXHandlerPtr old_sax = NULL;
28655 xmlParserCtxtPtr pctxt = NULL;
28656 xmlParserInputPtr inputStream = NULL;
28659 if ((ctxt == NULL) || (input == NULL))
28663 * prepare the parser
28665 pctxt = xmlNewParserCtxt();
28668 old_sax = pctxt->sax;
28670 pctxt->userData = user_data;
28673 xmlCtxtUseOptions(pctxt, options);
28675 pctxt->linenumbers = 1;
28677 inputStream = xmlNewIOInputStream(pctxt, input, enc);;
28678 if (inputStream == NULL) {
28682 inputPush(pctxt, inputStream);
28683 ctxt->parserCtxt = pctxt;
28684 ctxt->input = input;
28687 * Plug the validation and launch the parsing
28689 plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
28690 if (plug == NULL) {
28694 ctxt->input = input;
28696 ctxt->sax = pctxt->sax;
28697 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28698 ret = xmlSchemaVStart(ctxt);
28700 if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
28701 ret = ctxt->parserCtxt->errNo;
28707 ctxt->parserCtxt = NULL;
28709 ctxt->input = NULL;
28710 if (plug != NULL) {
28711 xmlSchemaSAXUnplug(plug);
28714 if (pctxt != NULL) {
28715 pctxt->sax = old_sax;
28716 xmlFreeParserCtxt(pctxt);
28722 * xmlSchemaValidateFile:
28723 * @ctxt: a schema validation context
28724 * @filename: the URI of the instance
28725 * @options: a future set of options, currently unused
28727 * Do a schemas validation of the given resource, it will use the
28728 * SAX streamable validation internally.
28730 * Returns 0 if the document is valid, a positive error code
28731 * number otherwise and -1 in case of an internal or API error.
28734 xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
28735 const char * filename,
28736 int options ATTRIBUTE_UNUSED)
28739 xmlParserInputBufferPtr input;
28741 if ((ctxt == NULL) || (filename == NULL))
28744 input = xmlParserInputBufferCreateFilename(filename,
28745 XML_CHAR_ENCODING_NONE);
28748 ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
28754 * xmlSchemaValidCtxtGetParserCtxt:
28755 * @ctxt: a schema validation context
28757 * allow access to the parser context of the schema validation context
28759 * Returns the parser context of the schema validation context or NULL
28760 * in case of error.
28763 xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
28767 return (ctxt->parserCtxt);
28770 #define bottom_xmlschemas
28771 #include "elfgcchack.h"
28772 #endif /* LIBXML_SCHEMAS_ENABLED */