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 * - Eliminated 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.
48 /* To avoid EBCDIC trouble when parsing on zOS */
50 #pragma convert("ISO8859-1")
56 #ifdef LIBXML_SCHEMAS_ENABLED
59 #include <libxml/xmlmemory.h>
60 #include <libxml/parser.h>
61 #include <libxml/parserInternals.h>
62 #include <libxml/hash.h>
63 #include <libxml/uri.h>
64 #include <libxml/xmlschemas.h>
65 #include <libxml/schemasInternals.h>
66 #include <libxml/xmlschemastypes.h>
67 #include <libxml/xmlautomata.h>
68 #include <libxml/xmlregexp.h>
69 #include <libxml/dict.h>
70 #include <libxml/encoding.h>
71 #include <libxml/xmlIO.h>
72 #ifdef LIBXML_PATTERN_ENABLED
73 #include <libxml/pattern.h>
75 #ifdef LIBXML_READER_ENABLED
76 #include <libxml/xmlreader.h>
79 #include "private/error.h"
80 #include "private/string.h"
84 /* #define DEBUG_CONTENT 1 */
86 /* #define DEBUG_TYPE 1 */
88 /* #define DEBUG_CONTENT_REGEXP 1 */
90 /* #define DEBUG_AUTOMATA 1 */
92 /* #define DEBUG_IDC */
94 /* #define DEBUG_IDC_NODE_TABLE */
96 /* #define WXS_ELEM_DECL_CONS_ENABLED */
99 #ifndef DEBUG_IDC_NODE_TABLE
100 #define DEBUG_IDC_NODE_TABLE
104 /* #define ENABLE_PARTICLE_RESTRICTION 1 */
106 #define ENABLE_REDEFINE
108 /* #define ENABLE_NAMED_LOCALS */
110 /* #define ENABLE_IDC_NODE_TABLES_TEST */
112 #define DUMP_CONTENT_MODEL
114 #ifdef LIBXML_READER_ENABLED
115 /* #define XML_SCHEMA_READER_ENABLED */
118 #define UNBOUNDED (1 << 30)
120 xmlGenericError(xmlGenericErrorContext, \
121 "Unimplemented block at %s:%d\n", \
124 #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
127 * The XML Schemas namespaces
129 static const xmlChar
*xmlSchemaNs
= (const xmlChar
*)
130 "http://www.w3.org/2001/XMLSchema";
132 static const xmlChar
*xmlSchemaInstanceNs
= (const xmlChar
*)
133 "http://www.w3.org/2001/XMLSchema-instance";
135 static const xmlChar
*xmlNamespaceNs
= (const xmlChar
*)
136 "http://www.w3.org/2000/xmlns/";
139 * Come casting macros.
141 #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
142 #define PCTXT_CAST (xmlSchemaParserCtxtPtr)
143 #define VCTXT_CAST (xmlSchemaValidCtxtPtr)
144 #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
145 #define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
146 #define WXS_PTC_CAST (xmlSchemaParticlePtr)
147 #define WXS_TYPE_CAST (xmlSchemaTypePtr)
148 #define WXS_ELEM_CAST (xmlSchemaElementPtr)
149 #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
150 #define WXS_ATTR_CAST (xmlSchemaAttributePtr)
151 #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
152 #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
153 #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
154 #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
155 #define WXS_IDC_CAST (xmlSchemaIDCPtr)
156 #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
157 #define WXS_LIST_CAST (xmlSchemaItemListPtr)
160 * Macros to query common properties of components.
162 #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
164 #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
166 * Macros for element declarations.
168 #define WXS_ELEM_TYPEDEF(e) (e)->subtypes
170 #define WXS_SUBST_HEAD(item) (item)->refDecl
172 * Macros for attribute declarations.
174 #define WXS_ATTR_TYPEDEF(a) (a)->subtypes
176 * Macros for attribute uses.
178 #define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl
180 #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
182 #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
184 #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
186 * Macros for attribute groups.
188 #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
189 #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
191 * Macros for particles.
193 #define WXS_PARTICLE(p) WXS_PTC_CAST (p)
195 #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
197 #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
199 #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
201 * Macros for model groups definitions.
203 #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
205 * Macros for model groups.
207 #define WXS_IS_MODEL_GROUP(i) \
208 (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
209 ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
210 ((i)->type == XML_SCHEMA_TYPE_ALL))
212 #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
214 * Macros for schema buckets.
216 #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
217 ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
219 #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
220 ((t) == XML_SCHEMA_SCHEMA_IMPORT))
222 #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
224 #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
226 * Macros for complex/simple types.
228 #define WXS_IS_ANYTYPE(i) \
229 (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
230 ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
232 #define WXS_IS_COMPLEX(i) \
233 (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
234 ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
236 #define WXS_IS_SIMPLE(item) \
237 ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
238 ((item->type == XML_SCHEMA_TYPE_BASIC) && \
239 (item->builtInType != XML_SCHEMAS_ANYTYPE)))
241 #define WXS_IS_ANY_SIMPLE_TYPE(i) \
242 (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
243 ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
245 #define WXS_IS_RESTRICTION(t) \
246 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
248 #define WXS_IS_EXTENSION(t) \
249 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
251 #define WXS_IS_TYPE_NOT_FIXED(i) \
252 (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
253 (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
255 #define WXS_IS_TYPE_NOT_FIXED_1(item) \
256 (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
257 (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
259 #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
261 #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
263 * Macros for exclusively for complex types.
265 #define WXS_HAS_COMPLEX_CONTENT(item) \
266 ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
267 (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
268 (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
270 #define WXS_HAS_SIMPLE_CONTENT(item) \
271 ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
272 (item->contentType == XML_SCHEMA_CONTENT_BASIC))
274 #define WXS_HAS_MIXED_CONTENT(item) \
275 (item->contentType == XML_SCHEMA_CONTENT_MIXED)
277 #define WXS_EMPTIABLE(t) \
278 (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
280 #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
282 #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
284 #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
286 * Macros for exclusively for simple types.
288 #define WXS_LIST_ITEMTYPE(t) (t)->subtypes
290 #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
292 #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
294 #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
296 * Misc parser context macros.
298 #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
300 #define WXS_HAS_BUCKETS(ctx) \
301 ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
302 (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
304 #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
306 #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
308 #define WXS_SCHEMA(ctx) (ctx)->schema
310 #define WXS_ADD_LOCAL(ctx, item) \
312 if (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item) < 0) { \
318 #define WXS_ADD_GLOBAL(ctx, item) \
320 if (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item) < 0) { \
326 #define WXS_ADD_PENDING(ctx, item) \
327 xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
329 * xmlSchemaItemList macros.
331 #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
335 #define IS_SCHEMA(node, type) \
336 ((node != NULL) && (node->ns != NULL) && \
337 (xmlStrEqual(node->name, (const xmlChar *) type)) && \
338 (xmlStrEqual(node->ns->href, xmlSchemaNs)))
340 #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
343 * Since we put the default/fixed values into the dict, we can
344 * use pointer comparison for those values.
345 * REMOVED: (xmlStrEqual((v1), (v2)))
347 #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
349 #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
351 #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
353 #define HFAILURE if (res == -1) goto exit_failure;
355 #define HERROR if (res != 0) goto exit_error;
357 #define HSTOP(ctx) if ((ctx)->stop) goto exit;
359 * Some flags used for various schema constraints.
361 #define SUBSET_RESTRICTION 1<<0
362 #define SUBSET_EXTENSION 1<<1
363 #define SUBSET_SUBSTITUTION 1<<2
364 #define SUBSET_LIST 1<<3
365 #define SUBSET_UNION 1<<4
367 typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo
;
368 typedef xmlSchemaNodeInfo
*xmlSchemaNodeInfoPtr
;
370 typedef struct _xmlSchemaItemList xmlSchemaItemList
;
371 typedef xmlSchemaItemList
*xmlSchemaItemListPtr
;
372 struct _xmlSchemaItemList
{
373 void **items
; /* used for dynamic addition of schemata */
374 int nbItems
; /* used for dynamic addition of schemata */
375 int sizeItems
; /* used for dynamic addition of schemata */
378 #define XML_SCHEMA_CTXT_PARSER 1
379 #define XML_SCHEMA_CTXT_VALIDATOR 2
381 typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt
;
382 typedef xmlSchemaAbstractCtxt
*xmlSchemaAbstractCtxtPtr
;
383 struct _xmlSchemaAbstractCtxt
{
384 int type
; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
385 void *dummy
; /* Fix alignment issues */
388 typedef struct _xmlSchemaBucket xmlSchemaBucket
;
389 typedef xmlSchemaBucket
*xmlSchemaBucketPtr
;
391 #define XML_SCHEMA_SCHEMA_MAIN 0
392 #define XML_SCHEMA_SCHEMA_IMPORT 1
393 #define XML_SCHEMA_SCHEMA_INCLUDE 2
394 #define XML_SCHEMA_SCHEMA_REDEFINE 3
397 * xmlSchemaSchemaRelation:
399 * Used to create a graph of schema relationships.
401 typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation
;
402 typedef xmlSchemaSchemaRelation
*xmlSchemaSchemaRelationPtr
;
403 struct _xmlSchemaSchemaRelation
{
404 xmlSchemaSchemaRelationPtr next
;
405 int type
; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
406 const xmlChar
*importNamespace
;
407 xmlSchemaBucketPtr bucket
;
410 #define XML_SCHEMA_BUCKET_MARKED 1<<0
411 #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
413 struct _xmlSchemaBucket
{
416 const xmlChar
*schemaLocation
;
417 const xmlChar
*origTargetNamespace
;
418 const xmlChar
*targetNamespace
;
420 xmlSchemaSchemaRelationPtr relations
;
425 xmlSchemaItemListPtr globals
; /* Global components. */
426 xmlSchemaItemListPtr locals
; /* Local components. */
431 * (extends xmlSchemaBucket)
433 * Reflects a schema. Holds some information
434 * about the schema and its toplevel components. Duplicate
435 * toplevel components are not checked at this level.
437 typedef struct _xmlSchemaImport xmlSchemaImport
;
438 typedef xmlSchemaImport
*xmlSchemaImportPtr
;
439 struct _xmlSchemaImport
{
440 int type
; /* Main OR import OR include. */
442 const xmlChar
*schemaLocation
; /* The URI of the schema document. */
443 /* For chameleon includes, @origTargetNamespace will be NULL */
444 const xmlChar
*origTargetNamespace
;
446 * For chameleon includes, @targetNamespace will be the
447 * targetNamespace of the including schema.
449 const xmlChar
*targetNamespace
;
450 xmlDocPtr doc
; /* The schema node-tree. */
451 /* @relations will hold any included/imported/redefined schemas. */
452 xmlSchemaSchemaRelationPtr relations
;
457 xmlSchemaItemListPtr globals
;
458 xmlSchemaItemListPtr locals
;
459 /* The imported schema. */
464 * (extends xmlSchemaBucket)
466 typedef struct _xmlSchemaInclude xmlSchemaInclude
;
467 typedef xmlSchemaInclude
*xmlSchemaIncludePtr
;
468 struct _xmlSchemaInclude
{
471 const xmlChar
*schemaLocation
;
472 const xmlChar
*origTargetNamespace
;
473 const xmlChar
*targetNamespace
;
475 xmlSchemaSchemaRelationPtr relations
;
480 xmlSchemaItemListPtr globals
; /* Global components. */
481 xmlSchemaItemListPtr locals
; /* Local components. */
483 /* The owning main or import schema bucket. */
484 xmlSchemaImportPtr ownerImport
;
488 * xmlSchemaBasicItem:
490 * The abstract base type for schema components.
492 typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem
;
493 typedef xmlSchemaBasicItem
*xmlSchemaBasicItemPtr
;
494 struct _xmlSchemaBasicItem
{
495 xmlSchemaTypeType type
;
496 void *dummy
; /* Fix alignment issues */
500 * xmlSchemaAnnotItem:
502 * The abstract base type for annotated schema components.
503 * (Extends xmlSchemaBasicItem)
505 typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem
;
506 typedef xmlSchemaAnnotItem
*xmlSchemaAnnotItemPtr
;
507 struct _xmlSchemaAnnotItem
{
508 xmlSchemaTypeType type
;
509 xmlSchemaAnnotPtr annot
;
515 * The abstract base type for tree-like structured schema components.
516 * (Extends xmlSchemaAnnotItem)
518 typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem
;
519 typedef xmlSchemaTreeItem
*xmlSchemaTreeItemPtr
;
520 struct _xmlSchemaTreeItem
{
521 xmlSchemaTypeType type
;
522 xmlSchemaAnnotPtr annot
;
523 xmlSchemaTreeItemPtr next
;
524 xmlSchemaTreeItemPtr children
;
528 #define XML_SCHEMA_ATTR_USE_FIXED 1<<0
530 * xmlSchemaAttributeUsePtr:
532 * The abstract base type for tree-like structured schema components.
533 * (Extends xmlSchemaTreeItem)
535 typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse
;
536 typedef xmlSchemaAttributeUse
*xmlSchemaAttributeUsePtr
;
537 struct _xmlSchemaAttributeUse
{
538 xmlSchemaTypeType type
;
539 xmlSchemaAnnotPtr annot
;
540 xmlSchemaAttributeUsePtr next
; /* The next attr. use. */
542 * The attr. decl. OR a QName-ref. to an attr. decl. OR
543 * a QName-ref. to an attribute group definition.
545 xmlSchemaAttributePtr attrDecl
;
549 int occurs
; /* required, optional */
550 const xmlChar
* defValue
;
551 xmlSchemaValPtr defVal
;
555 * xmlSchemaAttributeUseProhibPtr:
557 * A helper component to reflect attribute prohibitions.
558 * (Extends xmlSchemaBasicItem)
560 typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib
;
561 typedef xmlSchemaAttributeUseProhib
*xmlSchemaAttributeUseProhibPtr
;
562 struct _xmlSchemaAttributeUseProhib
{
563 xmlSchemaTypeType type
; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
566 const xmlChar
*targetNamespace
;
573 typedef struct _xmlSchemaRedef xmlSchemaRedef
;
574 typedef xmlSchemaRedef
*xmlSchemaRedefPtr
;
575 struct _xmlSchemaRedef
{
576 xmlSchemaRedefPtr next
;
577 xmlSchemaBasicItemPtr item
; /* The redefining component. */
578 xmlSchemaBasicItemPtr reference
; /* The referencing component. */
579 xmlSchemaBasicItemPtr target
; /* The to-be-redefined component. */
580 const xmlChar
*refName
; /* The name of the to-be-redefined component. */
581 const xmlChar
*refTargetNs
; /* The target namespace of the
582 to-be-redefined comp. */
583 xmlSchemaBucketPtr targetBucket
; /* The redefined schema. */
587 * xmlSchemaConstructionCtxt:
589 typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt
;
590 typedef xmlSchemaConstructionCtxt
*xmlSchemaConstructionCtxtPtr
;
591 struct _xmlSchemaConstructionCtxt
{
592 xmlSchemaPtr mainSchema
; /* The main schema. */
593 xmlSchemaBucketPtr mainBucket
; /* The main schema bucket */
595 xmlSchemaItemListPtr buckets
; /* List of schema buckets. */
596 /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
597 xmlSchemaBucketPtr bucket
; /* The current schema bucket */
598 xmlSchemaItemListPtr pending
; /* All Components of all schemas that
600 xmlHashTablePtr substGroups
;
601 xmlSchemaRedefPtr redefs
;
602 xmlSchemaRedefPtr lastRedef
;
605 #define XML_SCHEMAS_PARSE_ERROR 1
606 #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
608 struct _xmlSchemaParserCtxt
{
610 void *errCtxt
; /* user specific error context */
611 xmlSchemaValidityErrorFunc error
; /* the callback in case of errors */
612 xmlSchemaValidityWarningFunc warning
; /* the callback in case of warning */
615 xmlStructuredErrorFunc serror
;
617 xmlSchemaConstructionCtxtPtr constructor
;
618 int ownsConstructor
; /* TODO: Move this to parser *flags*. */
620 /* xmlSchemaPtr topschema; */
621 /* xmlHashTablePtr namespaces; */
623 xmlSchemaPtr schema
; /* The main schema in use */
628 int preserve
; /* Whether the doc should be freed */
634 * Used to build complex element content models
637 xmlAutomataStatePtr start
;
638 xmlAutomataStatePtr end
;
639 xmlAutomataStatePtr state
;
641 xmlDictPtr dict
; /* dictionary for interned string names */
642 xmlSchemaTypePtr ctxtType
; /* The current context simple/complex type */
644 xmlSchemaValidCtxtPtr vctxt
;
648 int stop
; /* If the parser should stop; i.e. a critical error. */
649 const xmlChar
*targetNamespace
;
650 xmlSchemaBucketPtr redefined
; /* The schema to be redefined. */
652 xmlSchemaRedefPtr redef
; /* Used for redefinitions. */
653 int redefCounter
; /* Used for redefinitions. */
654 xmlSchemaItemListPtr attrProhibs
;
660 * A component reference item (not a schema component)
661 * (Extends xmlSchemaBasicItem)
663 typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef
;
664 typedef xmlSchemaQNameRef
*xmlSchemaQNameRefPtr
;
665 struct _xmlSchemaQNameRef
{
666 xmlSchemaTypeType type
;
667 xmlSchemaBasicItemPtr item
; /* The resolved referenced item. */
668 xmlSchemaTypeType itemType
;
670 const xmlChar
*targetNamespace
;
677 * A particle component.
678 * (Extends xmlSchemaTreeItem)
680 typedef struct _xmlSchemaParticle xmlSchemaParticle
;
681 typedef xmlSchemaParticle
*xmlSchemaParticlePtr
;
682 struct _xmlSchemaParticle
{
683 xmlSchemaTypeType type
;
684 xmlSchemaAnnotPtr annot
;
685 xmlSchemaTreeItemPtr next
; /* next particle */
686 xmlSchemaTreeItemPtr children
; /* the "term" (e.g. a model group,
687 a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
695 * xmlSchemaModelGroup:
697 * A model group component.
698 * (Extends xmlSchemaTreeItem)
700 typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup
;
701 typedef xmlSchemaModelGroup
*xmlSchemaModelGroupPtr
;
702 struct _xmlSchemaModelGroup
{
703 xmlSchemaTypeType type
; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
704 xmlSchemaAnnotPtr annot
;
705 xmlSchemaTreeItemPtr next
; /* not used */
706 xmlSchemaTreeItemPtr children
; /* first particle (OR "element decl" OR "wildcard") */
710 #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
711 #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
713 * xmlSchemaModelGroupDef:
715 * A model group definition component.
716 * (Extends xmlSchemaTreeItem)
718 typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef
;
719 typedef xmlSchemaModelGroupDef
*xmlSchemaModelGroupDefPtr
;
720 struct _xmlSchemaModelGroupDef
{
721 xmlSchemaTypeType type
; /* XML_SCHEMA_TYPE_GROUP */
722 xmlSchemaAnnotPtr annot
;
723 xmlSchemaTreeItemPtr next
; /* not used */
724 xmlSchemaTreeItemPtr children
; /* the "model group" */
726 const xmlChar
*targetNamespace
;
731 typedef struct _xmlSchemaIDC xmlSchemaIDC
;
732 typedef xmlSchemaIDC
*xmlSchemaIDCPtr
;
735 * xmlSchemaIDCSelect:
737 * The identity-constraint "field" and "selector" item, holding the
740 typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect
;
741 typedef xmlSchemaIDCSelect
*xmlSchemaIDCSelectPtr
;
742 struct _xmlSchemaIDCSelect
{
743 xmlSchemaIDCSelectPtr next
;
745 int index
; /* an index position if significant for IDC key-sequences */
746 const xmlChar
*xpath
; /* the XPath expression */
747 void *xpathComp
; /* the compiled XPath expression */
753 * The identity-constraint definition component.
754 * (Extends xmlSchemaAnnotItem)
757 struct _xmlSchemaIDC
{
758 xmlSchemaTypeType type
;
759 xmlSchemaAnnotPtr annot
;
760 xmlSchemaIDCPtr next
;
763 const xmlChar
*targetNamespace
;
764 xmlSchemaIDCSelectPtr selector
;
765 xmlSchemaIDCSelectPtr fields
;
767 xmlSchemaQNameRefPtr ref
;
773 * The augmented IDC information used for validation.
775 typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug
;
776 typedef xmlSchemaIDCAug
*xmlSchemaIDCAugPtr
;
777 struct _xmlSchemaIDCAug
{
778 xmlSchemaIDCAugPtr next
; /* next in a list */
779 xmlSchemaIDCPtr def
; /* the IDC definition */
780 int keyrefDepth
; /* the lowest tree level to which IDC
781 tables need to be bubbled upwards */
785 * xmlSchemaPSVIIDCKeySequence:
787 * The key sequence of a node table item.
789 typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey
;
790 typedef xmlSchemaPSVIIDCKey
*xmlSchemaPSVIIDCKeyPtr
;
791 struct _xmlSchemaPSVIIDCKey
{
792 xmlSchemaTypePtr type
;
797 * xmlSchemaPSVIIDCNode:
799 * The node table item of a node table.
801 typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode
;
802 typedef xmlSchemaPSVIIDCNode
*xmlSchemaPSVIIDCNodePtr
;
803 struct _xmlSchemaPSVIIDCNode
{
805 xmlSchemaPSVIIDCKeyPtr
*keys
;
812 * xmlSchemaPSVIIDCBinding:
814 * The identity-constraint binding item of the [identity-constraint table].
816 typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding
;
817 typedef xmlSchemaPSVIIDCBinding
*xmlSchemaPSVIIDCBindingPtr
;
818 struct _xmlSchemaPSVIIDCBinding
{
819 xmlSchemaPSVIIDCBindingPtr next
; /* next binding of a specific node */
820 xmlSchemaIDCPtr definition
; /* the IDC definition */
821 xmlSchemaPSVIIDCNodePtr
*nodeTable
; /* array of key-sequences */
822 int nbNodes
; /* number of entries in the node table */
823 int sizeNodes
; /* size of the node table */
824 xmlSchemaItemListPtr dupls
;
828 #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
829 #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
831 #define XPATH_STATE_OBJ_MATCHES -2
832 #define XPATH_STATE_OBJ_BLOCKED -3
834 typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher
;
835 typedef xmlSchemaIDCMatcher
*xmlSchemaIDCMatcherPtr
;
838 * xmlSchemaIDCStateObj:
840 * The state object used to evaluate XPath expressions.
842 typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj
;
843 typedef xmlSchemaIDCStateObj
*xmlSchemaIDCStateObjPtr
;
844 struct _xmlSchemaIDCStateObj
{
846 xmlSchemaIDCStateObjPtr next
; /* next if in a list */
847 int depth
; /* depth of creation */
848 int *history
; /* list of (depth, state-id) tuples */
851 xmlSchemaIDCMatcherPtr matcher
; /* the correspondent field/selector
853 xmlSchemaIDCSelectPtr sel
;
857 #define IDC_MATCHER 0
860 * xmlSchemaIDCMatcher:
862 * Used to evaluate IDC selectors (and fields).
864 struct _xmlSchemaIDCMatcher
{
866 int depth
; /* the tree depth at creation time */
867 xmlSchemaIDCMatcherPtr next
; /* next in the list */
868 xmlSchemaIDCMatcherPtr nextCached
; /* next in the cache list */
869 xmlSchemaIDCAugPtr aidc
; /* the augmented IDC item */
871 xmlSchemaPSVIIDCKeyPtr
**keySeqs
; /* the key-sequences of the target
874 xmlSchemaItemListPtr targets
; /* list of target-node
875 (xmlSchemaPSVIIDCNodePtr) entries */
876 xmlHashTablePtr htab
;
880 * Element info flags.
882 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0
883 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
884 #define XML_SCHEMA_ELEM_INFO_NILLED 1<<2
885 #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3
887 #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4
888 #define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5
889 #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6
891 #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7
892 #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8
893 #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9
894 #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10
899 * Holds information of an element node.
901 struct _xmlSchemaNodeInfo
{
905 const xmlChar
*localName
;
906 const xmlChar
*nsName
;
907 const xmlChar
*value
;
908 xmlSchemaValPtr val
; /* the pre-computed value if any */
909 xmlSchemaTypePtr typeDef
; /* the complex/simple type definition if any */
911 int flags
; /* combination of node info flags */
916 xmlSchemaElementPtr decl
; /* the element/attribute declaration */
918 xmlSchemaPSVIIDCBindingPtr idcTable
; /* the table of PSVI IDC bindings
919 for the scope element*/
920 xmlSchemaIDCMatcherPtr idcMatchers
; /* the IDC matchers for the scope
922 xmlRegExecCtxtPtr regexCtxt
;
924 const xmlChar
**nsBindings
; /* Namespace bindings on this element */
929 int appliedXPath
; /* Indicates that an XPath has been applied. */
932 #define XML_SCHEMAS_ATTR_UNKNOWN 1
933 #define XML_SCHEMAS_ATTR_ASSESSED 2
934 #define XML_SCHEMAS_ATTR_PROHIBITED 3
935 #define XML_SCHEMAS_ATTR_ERR_MISSING 4
936 #define XML_SCHEMAS_ATTR_INVALID_VALUE 5
937 #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
938 #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
939 #define XML_SCHEMAS_ATTR_DEFAULT 8
940 #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
941 #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
942 #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
943 #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
944 #define XML_SCHEMAS_ATTR_WILD_SKIP 13
945 #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
946 #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
947 #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
948 #define XML_SCHEMAS_ATTR_META 17
950 * @metaType values of xmlSchemaAttrInfo.
952 #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
953 #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
954 #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
955 #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
956 #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
958 typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo
;
959 typedef xmlSchemaAttrInfo
*xmlSchemaAttrInfoPtr
;
960 struct _xmlSchemaAttrInfo
{
964 const xmlChar
*localName
;
965 const xmlChar
*nsName
;
966 const xmlChar
*value
;
967 xmlSchemaValPtr val
; /* the pre-computed value if any */
968 xmlSchemaTypePtr typeDef
; /* the complex/simple type definition if any */
969 int flags
; /* combination of node info flags */
971 xmlSchemaAttributePtr decl
; /* the attribute declaration */
972 xmlSchemaAttributeUsePtr use
; /* the attribute use */
975 const xmlChar
*vcValue
; /* the value constraint value */
976 xmlSchemaNodeInfoPtr parent
;
980 #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
982 * xmlSchemaValidCtxt:
984 * A Schemas validation context
986 struct _xmlSchemaValidCtxt
{
988 void *errCtxt
; /* user specific data block */
989 xmlSchemaValidityErrorFunc error
; /* the callback in case of errors */
990 xmlSchemaValidityWarningFunc warning
; /* the callback in case of warning */
991 xmlStructuredErrorFunc serror
;
993 xmlSchemaPtr schema
; /* The schema in use */
995 xmlParserInputBufferPtr input
;
997 xmlSAXHandlerPtr sax
;
998 xmlParserCtxtPtr parserCtxt
;
999 void *user_data
; /* TODO: What is this for? */
1007 /* xmlSchemaTypePtr type; */
1009 xmlRegExecCtxtPtr regexp
;
1010 xmlSchemaValPtr value
;
1014 xmlNodePtr validationRoot
;
1015 xmlSchemaParserCtxtPtr pctxt
;
1019 xmlSchemaNodeInfoPtr
*elemInfos
; /* array of element information */
1021 xmlSchemaNodeInfoPtr inode
; /* the current element information */
1023 xmlSchemaIDCAugPtr aidcs
; /* a list of augmented IDC information */
1025 xmlSchemaIDCStateObjPtr xpathStates
; /* first active state object. */
1026 xmlSchemaIDCStateObjPtr xpathStatePool
; /* first stored state object. */
1027 xmlSchemaIDCMatcherPtr idcMatcherCache
; /* Cache for IDC matcher objects. */
1029 xmlSchemaPSVIIDCNodePtr
*idcNodes
; /* list of all IDC node-table entries*/
1033 xmlSchemaPSVIIDCKeyPtr
*idcKeys
; /* list of all IDC node-table entries */
1041 #ifdef LIBXML_READER_ENABLED
1042 xmlTextReaderPtr reader
;
1045 xmlSchemaAttrInfoPtr
*attrInfos
;
1050 xmlSchemaItemListPtr nodeQNames
;
1052 int createIDCNodeTables
;
1053 int psviExposeIDCNodeTables
;
1055 /* Locator for error reporting in streaming mode */
1056 xmlSchemaValidityLocatorFunc locFunc
;
1061 * xmlSchemaSubstGroup:
1065 typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup
;
1066 typedef xmlSchemaSubstGroup
*xmlSchemaSubstGroupPtr
;
1067 struct _xmlSchemaSubstGroup
{
1068 xmlSchemaElementPtr head
;
1069 xmlSchemaItemListPtr members
;
1075 * an entry in hash tables to quickly look up keys/uniques
1077 typedef struct _xmlIDCHashEntry xmlIDCHashEntry
;
1078 typedef xmlIDCHashEntry
*xmlIDCHashEntryPtr
;
1079 struct _xmlIDCHashEntry
{
1080 xmlIDCHashEntryPtr next
; /* next item with same hash */
1081 int index
; /* index into associated item list */
1084 /************************************************************************
1086 * Some predeclarations *
1088 ************************************************************************/
1090 static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt
,
1091 xmlSchemaPtr schema
,
1093 static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt
,
1094 xmlSchemaPtr schema
,
1097 xmlSchemaTypeFixup(xmlSchemaTypePtr type
,
1098 xmlSchemaAbstractCtxtPtr ctxt
);
1099 static const xmlChar
*
1100 xmlSchemaFacetTypeToString(xmlSchemaTypeType type
);
1102 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
1105 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl
,
1106 xmlSchemaParserCtxtPtr ctxt
);
1108 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt
);
1109 static xmlSchemaWhitespaceValueType
1110 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type
);
1111 static xmlSchemaTreeItemPtr
1112 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
1113 xmlNodePtr node
, xmlSchemaTypeType type
,
1115 static const xmlChar
*
1116 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item
);
1117 static xmlSchemaTypeLinkPtr
1118 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type
);
1120 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt
,
1121 const char *funcName
,
1122 const char *message
) LIBXML_ATTR_FORMAT(3,0);
1124 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt
,
1125 xmlSchemaTypePtr type
,
1126 xmlSchemaTypePtr baseType
,
1129 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl
,
1130 xmlSchemaParserCtxtPtr ctxt
);
1132 xmlSchemaComponentListFree(xmlSchemaItemListPtr list
);
1133 static xmlSchemaQNameRefPtr
1134 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt
,
1135 xmlSchemaPtr schema
,
1138 /************************************************************************
1140 * Helper functions *
1142 ************************************************************************/
1145 * xmlSchemaItemTypeToStr:
1146 * @type: the type of the schema item
1148 * Returns the component name of a schema item.
1150 static const xmlChar
*
1151 xmlSchemaItemTypeToStr(xmlSchemaTypeType type
)
1154 case XML_SCHEMA_TYPE_BASIC
:
1155 return(BAD_CAST
"simple type definition");
1156 case XML_SCHEMA_TYPE_SIMPLE
:
1157 return(BAD_CAST
"simple type definition");
1158 case XML_SCHEMA_TYPE_COMPLEX
:
1159 return(BAD_CAST
"complex type definition");
1160 case XML_SCHEMA_TYPE_ELEMENT
:
1161 return(BAD_CAST
"element declaration");
1162 case XML_SCHEMA_TYPE_ATTRIBUTE_USE
:
1163 return(BAD_CAST
"attribute use");
1164 case XML_SCHEMA_TYPE_ATTRIBUTE
:
1165 return(BAD_CAST
"attribute declaration");
1166 case XML_SCHEMA_TYPE_GROUP
:
1167 return(BAD_CAST
"model group definition");
1168 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
1169 return(BAD_CAST
"attribute group definition");
1170 case XML_SCHEMA_TYPE_NOTATION
:
1171 return(BAD_CAST
"notation declaration");
1172 case XML_SCHEMA_TYPE_SEQUENCE
:
1173 return(BAD_CAST
"model group (sequence)");
1174 case XML_SCHEMA_TYPE_CHOICE
:
1175 return(BAD_CAST
"model group (choice)");
1176 case XML_SCHEMA_TYPE_ALL
:
1177 return(BAD_CAST
"model group (all)");
1178 case XML_SCHEMA_TYPE_PARTICLE
:
1179 return(BAD_CAST
"particle");
1180 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
1181 return(BAD_CAST
"unique identity-constraint");
1182 /* return(BAD_CAST "IDC (unique)"); */
1183 case XML_SCHEMA_TYPE_IDC_KEY
:
1184 return(BAD_CAST
"key identity-constraint");
1185 /* return(BAD_CAST "IDC (key)"); */
1186 case XML_SCHEMA_TYPE_IDC_KEYREF
:
1187 return(BAD_CAST
"keyref identity-constraint");
1188 /* return(BAD_CAST "IDC (keyref)"); */
1189 case XML_SCHEMA_TYPE_ANY
:
1190 return(BAD_CAST
"wildcard (any)");
1191 case XML_SCHEMA_EXTRA_QNAMEREF
:
1192 return(BAD_CAST
"[helper component] QName reference");
1193 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB
:
1194 return(BAD_CAST
"[helper component] attribute use prohibition");
1196 return(BAD_CAST
"Not a schema component");
1201 * xmlSchemaGetComponentTypeStr:
1202 * @type: the type of the schema item
1204 * Returns the component name of a schema item.
1206 static const xmlChar
*
1207 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item
)
1209 switch (item
->type
) {
1210 case XML_SCHEMA_TYPE_BASIC
:
1211 if (WXS_IS_COMPLEX(WXS_TYPE_CAST item
))
1212 return(BAD_CAST
"complex type definition");
1214 return(BAD_CAST
"simple type definition");
1216 return(xmlSchemaItemTypeToStr(item
->type
));
1221 * xmlSchemaGetComponentNode:
1222 * @item: a schema component
1224 * Returns node associated with the schema component.
1225 * NOTE that such a node need not be available; plus, a component's
1226 * node need not to reflect the component directly, since there is no
1227 * one-to-one relationship between the XML Schema representation and
1228 * the component representation.
1231 xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item
)
1233 switch (item
->type
) {
1234 case XML_SCHEMA_TYPE_ELEMENT
:
1235 return (((xmlSchemaElementPtr
) item
)->node
);
1236 case XML_SCHEMA_TYPE_ATTRIBUTE
:
1237 return (((xmlSchemaAttributePtr
) item
)->node
);
1238 case XML_SCHEMA_TYPE_COMPLEX
:
1239 case XML_SCHEMA_TYPE_SIMPLE
:
1240 return (((xmlSchemaTypePtr
) item
)->node
);
1241 case XML_SCHEMA_TYPE_ANY
:
1242 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE
:
1243 return (((xmlSchemaWildcardPtr
) item
)->node
);
1244 case XML_SCHEMA_TYPE_PARTICLE
:
1245 return (((xmlSchemaParticlePtr
) item
)->node
);
1246 case XML_SCHEMA_TYPE_SEQUENCE
:
1247 case XML_SCHEMA_TYPE_CHOICE
:
1248 case XML_SCHEMA_TYPE_ALL
:
1249 return (((xmlSchemaModelGroupPtr
) item
)->node
);
1250 case XML_SCHEMA_TYPE_GROUP
:
1251 return (((xmlSchemaModelGroupDefPtr
) item
)->node
);
1252 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
1253 return (((xmlSchemaAttributeGroupPtr
) item
)->node
);
1254 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
1255 case XML_SCHEMA_TYPE_IDC_KEY
:
1256 case XML_SCHEMA_TYPE_IDC_KEYREF
:
1257 return (((xmlSchemaIDCPtr
) item
)->node
);
1258 case XML_SCHEMA_EXTRA_QNAMEREF
:
1259 return(((xmlSchemaQNameRefPtr
) item
)->node
);
1260 /* TODO: What to do with NOTATIONs?
1261 case XML_SCHEMA_TYPE_NOTATION:
1262 return (((xmlSchemaNotationPtr) item)->node);
1264 case XML_SCHEMA_TYPE_ATTRIBUTE_USE
:
1265 return (((xmlSchemaAttributeUsePtr
) item
)->node
);
1273 * xmlSchemaGetNextComponent:
1274 * @item: a schema component
1276 * Returns the next sibling of the schema component.
1278 static xmlSchemaBasicItemPtr
1279 xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item
)
1281 switch (item
->type
) {
1282 case XML_SCHEMA_TYPE_ELEMENT
:
1283 return ((xmlSchemaBasicItemPtr
) ((xmlSchemaElementPtr
) item
)->next
);
1284 case XML_SCHEMA_TYPE_ATTRIBUTE
:
1285 return ((xmlSchemaBasicItemPtr
) ((xmlSchemaAttributePtr
) item
)->next
);
1286 case XML_SCHEMA_TYPE_COMPLEX
:
1287 case XML_SCHEMA_TYPE_SIMPLE
:
1288 return ((xmlSchemaBasicItemPtr
) ((xmlSchemaTypePtr
) item
)->next
);
1289 case XML_SCHEMA_TYPE_ANY
:
1290 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE
:
1292 case XML_SCHEMA_TYPE_PARTICLE
:
1293 return ((xmlSchemaBasicItemPtr
) ((xmlSchemaParticlePtr
) item
)->next
);
1294 case XML_SCHEMA_TYPE_SEQUENCE
:
1295 case XML_SCHEMA_TYPE_CHOICE
:
1296 case XML_SCHEMA_TYPE_ALL
:
1298 case XML_SCHEMA_TYPE_GROUP
:
1300 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
1301 return ((xmlSchemaBasicItemPtr
) ((xmlSchemaAttributeGroupPtr
) item
)->next
);
1302 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
1303 case XML_SCHEMA_TYPE_IDC_KEY
:
1304 case XML_SCHEMA_TYPE_IDC_KEYREF
:
1305 return ((xmlSchemaBasicItemPtr
) ((xmlSchemaIDCPtr
) item
)->next
);
1314 * xmlSchemaFormatQName:
1315 * @buf: the string buffer
1316 * @namespaceName: the namespace name
1317 * @localName: the local name
1319 * Returns the given QName in the format "{namespaceName}localName" or
1320 * just "localName" if @namespaceName is NULL.
1322 * Returns the localName if @namespaceName is NULL, a formatted
1325 static const xmlChar
*
1326 xmlSchemaFormatQName(xmlChar
**buf
,
1327 const xmlChar
*namespaceName
,
1328 const xmlChar
*localName
)
1331 if (namespaceName
!= NULL
) {
1332 *buf
= xmlStrdup(BAD_CAST
"{");
1333 *buf
= xmlStrcat(*buf
, namespaceName
);
1334 *buf
= xmlStrcat(*buf
, BAD_CAST
"}");
1336 if (localName
!= NULL
) {
1337 if (namespaceName
== NULL
)
1339 *buf
= xmlStrcat(*buf
, localName
);
1341 *buf
= xmlStrcat(*buf
, BAD_CAST
"(NULL)");
1343 return ((const xmlChar
*) *buf
);
1346 static const xmlChar
*
1347 xmlSchemaFormatQNameNs(xmlChar
**buf
, xmlNsPtr ns
, const xmlChar
*localName
)
1350 return (xmlSchemaFormatQName(buf
, ns
->href
, localName
));
1352 return (xmlSchemaFormatQName(buf
, NULL
, localName
));
1355 static const xmlChar
*
1356 xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item
)
1361 switch (item
->type
) {
1362 case XML_SCHEMA_TYPE_ELEMENT
:
1363 return (((xmlSchemaElementPtr
) item
)->name
);
1364 case XML_SCHEMA_TYPE_ATTRIBUTE
:
1365 return (((xmlSchemaAttributePtr
) item
)->name
);
1366 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
1367 return (((xmlSchemaAttributeGroupPtr
) item
)->name
);
1368 case XML_SCHEMA_TYPE_BASIC
:
1369 case XML_SCHEMA_TYPE_SIMPLE
:
1370 case XML_SCHEMA_TYPE_COMPLEX
:
1371 return (((xmlSchemaTypePtr
) item
)->name
);
1372 case XML_SCHEMA_TYPE_GROUP
:
1373 return (((xmlSchemaModelGroupDefPtr
) item
)->name
);
1374 case XML_SCHEMA_TYPE_IDC_KEY
:
1375 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
1376 case XML_SCHEMA_TYPE_IDC_KEYREF
:
1377 return (((xmlSchemaIDCPtr
) item
)->name
);
1378 case XML_SCHEMA_TYPE_ATTRIBUTE_USE
:
1379 if (WXS_ATTRUSE_DECL(item
) != NULL
) {
1380 return(xmlSchemaGetComponentName(
1381 WXS_BASIC_CAST
WXS_ATTRUSE_DECL(item
)));
1384 case XML_SCHEMA_EXTRA_QNAMEREF
:
1385 return (((xmlSchemaQNameRefPtr
) item
)->name
);
1386 case XML_SCHEMA_TYPE_NOTATION
:
1387 return (((xmlSchemaNotationPtr
) item
)->name
);
1390 * Other components cannot have names.
1397 #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
1398 #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
1400 static const xmlChar *
1401 xmlSchemaGetQNameRefName(void *ref)
1403 return(((xmlSchemaQNameRefPtr) ref)->name);
1406 static const xmlChar *
1407 xmlSchemaGetQNameRefTargetNs(void *ref)
1409 return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
1413 static const xmlChar
*
1414 xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item
)
1419 switch (item
->type
) {
1420 case XML_SCHEMA_TYPE_ELEMENT
:
1421 return (((xmlSchemaElementPtr
) item
)->targetNamespace
);
1422 case XML_SCHEMA_TYPE_ATTRIBUTE
:
1423 return (((xmlSchemaAttributePtr
) item
)->targetNamespace
);
1424 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
1425 return (((xmlSchemaAttributeGroupPtr
) item
)->targetNamespace
);
1426 case XML_SCHEMA_TYPE_BASIC
:
1427 return (BAD_CAST
"http://www.w3.org/2001/XMLSchema");
1428 case XML_SCHEMA_TYPE_SIMPLE
:
1429 case XML_SCHEMA_TYPE_COMPLEX
:
1430 return (((xmlSchemaTypePtr
) item
)->targetNamespace
);
1431 case XML_SCHEMA_TYPE_GROUP
:
1432 return (((xmlSchemaModelGroupDefPtr
) item
)->targetNamespace
);
1433 case XML_SCHEMA_TYPE_IDC_KEY
:
1434 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
1435 case XML_SCHEMA_TYPE_IDC_KEYREF
:
1436 return (((xmlSchemaIDCPtr
) item
)->targetNamespace
);
1437 case XML_SCHEMA_TYPE_ATTRIBUTE_USE
:
1438 if (WXS_ATTRUSE_DECL(item
) != NULL
) {
1439 return(xmlSchemaGetComponentTargetNs(
1440 WXS_BASIC_CAST
WXS_ATTRUSE_DECL(item
)));
1442 /* TODO: Will returning NULL break something? */
1444 case XML_SCHEMA_EXTRA_QNAMEREF
:
1445 return (((xmlSchemaQNameRefPtr
) item
)->targetNamespace
);
1446 case XML_SCHEMA_TYPE_NOTATION
:
1447 return (((xmlSchemaNotationPtr
) item
)->targetNamespace
);
1450 * Other components cannot have names.
1457 static const xmlChar
*
1458 xmlSchemaGetComponentQName(xmlChar
**buf
,
1461 return (xmlSchemaFormatQName(buf
,
1462 xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr
) item
),
1463 xmlSchemaGetComponentName((xmlSchemaBasicItemPtr
) item
)));
1466 static const xmlChar
*
1467 xmlSchemaGetComponentDesignation(xmlChar
**buf
, void *item
)
1469 xmlChar
*str
= NULL
;
1471 *buf
= xmlStrcat(*buf
, WXS_ITEM_TYPE_NAME(item
));
1472 *buf
= xmlStrcat(*buf
, BAD_CAST
" '");
1473 *buf
= xmlStrcat(*buf
, xmlSchemaGetComponentQName(&str
,
1474 (xmlSchemaBasicItemPtr
) item
));
1475 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1480 static const xmlChar
*
1481 xmlSchemaGetIDCDesignation(xmlChar
**buf
, xmlSchemaIDCPtr idc
)
1483 return(xmlSchemaGetComponentDesignation(buf
, idc
));
1487 * xmlSchemaWildcardPCToString:
1488 * @pc: the type of processContents
1490 * Returns a string representation of the type of
1493 static const xmlChar
*
1494 xmlSchemaWildcardPCToString(int pc
)
1497 case XML_SCHEMAS_ANY_SKIP
:
1498 return (BAD_CAST
"skip");
1499 case XML_SCHEMAS_ANY_LAX
:
1500 return (BAD_CAST
"lax");
1501 case XML_SCHEMAS_ANY_STRICT
:
1502 return (BAD_CAST
"strict");
1504 return (BAD_CAST
"invalid process contents");
1509 * xmlSchemaGetCanonValueWhtspExt:
1510 * @val: the precomputed value
1511 * @retValue: the returned value
1512 * @ws: the whitespace type of the value
1513 * @for_hash: non-zero if this is supposed to generate a string for hashing
1515 * Get a the canonical representation of the value.
1516 * The caller has to free the returned retValue.
1518 * Returns 0 if the value could be built and -1 in case of
1519 * API errors or if the value type is not supported yet.
1522 xmlSchemaGetCanonValueWhtspExt_1(xmlSchemaValPtr val
,
1523 xmlSchemaWhitespaceValueType ws
,
1528 xmlSchemaValType valType
;
1529 const xmlChar
*value
, *value2
= NULL
;
1532 if ((retValue
== NULL
) || (val
== NULL
))
1534 list
= xmlSchemaValueGetNext(val
) ? 1 : 0;
1538 valType
= xmlSchemaGetValType(val
);
1540 case XML_SCHEMAS_STRING
:
1541 case XML_SCHEMAS_NORMSTRING
:
1542 case XML_SCHEMAS_ANYSIMPLETYPE
:
1543 value
= xmlSchemaValueGetAsString(val
);
1544 if (value
!= NULL
) {
1545 if (ws
== XML_SCHEMA_WHITESPACE_COLLAPSE
)
1546 value2
= xmlSchemaCollapseString(value
);
1547 else if (ws
== XML_SCHEMA_WHITESPACE_REPLACE
)
1548 value2
= xmlSchemaWhiteSpaceReplace(value
);
1554 if (xmlSchemaGetCanonValue(val
, &value2
) == -1) {
1556 xmlFree((xmlChar
*) value2
);
1557 goto internal_error
;
1559 if (for_hash
&& valType
== XML_SCHEMAS_DECIMAL
) {
1560 /* We can mostly use the canonical value for hashing,
1561 except in the case of decimal. There the canonical
1562 representation requires a trailing '.0' even for
1563 non-fractional numbers, but for the derived integer
1564 types it forbids any decimal point. Nevertheless they
1565 compare equal if the value is equal. We need to generate
1566 the same hash value for this to work, and it's easiest
1567 to just cut off the useless '.0' suffix for the
1569 int len
= xmlStrlen(value2
);
1570 if (len
> 2 && value2
[len
-1] == '0' && value2
[len
-2] == '.')
1571 ((xmlChar
*)value2
)[len
-2] = 0;
1575 if (*retValue
== NULL
)
1576 if (value
== NULL
) {
1578 *retValue
= xmlStrdup(BAD_CAST
"");
1580 *retValue
= xmlStrdup(value
);
1581 else if (value
!= NULL
) {
1583 *retValue
= xmlStrcat((xmlChar
*) *retValue
, BAD_CAST
" ");
1584 *retValue
= xmlStrcat((xmlChar
*) *retValue
, value
);
1586 FREE_AND_NULL(value2
)
1587 val
= xmlSchemaValueGetNext(val
);
1588 } while (val
!= NULL
);
1592 if (*retValue
!= NULL
)
1593 xmlFree((xmlChar
*) (*retValue
));
1595 xmlFree((xmlChar
*) value2
);
1600 xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val
,
1601 xmlSchemaWhitespaceValueType ws
,
1604 return xmlSchemaGetCanonValueWhtspExt_1(val
, ws
, retValue
, 0);
1608 xmlSchemaGetCanonValueHash(xmlSchemaValPtr val
,
1611 return xmlSchemaGetCanonValueWhtspExt_1(val
, XML_SCHEMA_WHITESPACE_COLLAPSE
,
1616 * xmlSchemaFormatItemForReport:
1617 * @buf: the string buffer
1618 * @itemDes: the designation of the item
1619 * @itemName: the name of the item
1620 * @item: the item as an object
1621 * @itemNode: the node of the item
1622 * @local: the local name
1623 * @parsing: if the function is used during the parse
1625 * Returns a representation of the given item used
1626 * for error reports.
1628 * The following order is used to build the resulting
1629 * designation if the arguments are not NULL:
1630 * 1a. If itemDes not NULL -> itemDes
1631 * 1b. If (itemDes not NULL) and (itemName not NULL)
1632 * -> itemDes + itemName
1633 * 2. If the preceding was NULL and (item not NULL) -> item
1634 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
1636 * If the itemNode is an attribute node, the name of the attribute
1637 * will be appended to the result.
1639 * Returns the formatted string and sets @buf to the resulting value.
1642 xmlSchemaFormatItemForReport(xmlChar
**buf
,
1643 const xmlChar
*itemDes
,
1644 xmlSchemaBasicItemPtr item
,
1645 xmlNodePtr itemNode
)
1647 xmlChar
*str
= NULL
;
1655 if (itemDes
!= NULL
) {
1656 *buf
= xmlStrdup(itemDes
);
1657 } else if (item
!= NULL
) {
1658 switch (item
->type
) {
1659 case XML_SCHEMA_TYPE_BASIC
: {
1660 xmlSchemaTypePtr type
= WXS_TYPE_CAST item
;
1662 if (WXS_IS_ATOMIC(type
))
1663 *buf
= xmlStrdup(BAD_CAST
"atomic type 'xs:");
1664 else if (WXS_IS_LIST(type
))
1665 *buf
= xmlStrdup(BAD_CAST
"list type 'xs:");
1666 else if (WXS_IS_UNION(type
))
1667 *buf
= xmlStrdup(BAD_CAST
"union type 'xs:");
1669 *buf
= xmlStrdup(BAD_CAST
"simple type 'xs:");
1670 *buf
= xmlStrcat(*buf
, type
->name
);
1671 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1674 case XML_SCHEMA_TYPE_SIMPLE
: {
1675 xmlSchemaTypePtr type
= WXS_TYPE_CAST item
;
1677 if (type
->flags
& XML_SCHEMAS_TYPE_GLOBAL
) {
1678 *buf
= xmlStrdup(BAD_CAST
"");
1680 *buf
= xmlStrdup(BAD_CAST
"local ");
1682 if (WXS_IS_ATOMIC(type
))
1683 *buf
= xmlStrcat(*buf
, BAD_CAST
"atomic type");
1684 else if (WXS_IS_LIST(type
))
1685 *buf
= xmlStrcat(*buf
, BAD_CAST
"list type");
1686 else if (WXS_IS_UNION(type
))
1687 *buf
= xmlStrcat(*buf
, BAD_CAST
"union type");
1689 *buf
= xmlStrcat(*buf
, BAD_CAST
"simple type");
1690 if (type
->flags
& XML_SCHEMAS_TYPE_GLOBAL
) {
1691 *buf
= xmlStrcat(*buf
, BAD_CAST
" '");
1692 *buf
= xmlStrcat(*buf
, type
->name
);
1693 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1697 case XML_SCHEMA_TYPE_COMPLEX
: {
1698 xmlSchemaTypePtr type
= WXS_TYPE_CAST item
;
1700 if (type
->flags
& XML_SCHEMAS_TYPE_GLOBAL
)
1701 *buf
= xmlStrdup(BAD_CAST
"");
1703 *buf
= xmlStrdup(BAD_CAST
"local ");
1704 *buf
= xmlStrcat(*buf
, BAD_CAST
"complex type");
1705 if (type
->flags
& XML_SCHEMAS_TYPE_GLOBAL
) {
1706 *buf
= xmlStrcat(*buf
, BAD_CAST
" '");
1707 *buf
= xmlStrcat(*buf
, type
->name
);
1708 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1712 case XML_SCHEMA_TYPE_ATTRIBUTE_USE
: {
1713 xmlSchemaAttributeUsePtr ause
;
1715 ause
= WXS_ATTR_USE_CAST item
;
1716 *buf
= xmlStrdup(BAD_CAST
"attribute use ");
1717 if (WXS_ATTRUSE_DECL(ause
) != NULL
) {
1718 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1719 *buf
= xmlStrcat(*buf
,
1720 xmlSchemaGetComponentQName(&str
, WXS_ATTRUSE_DECL(ause
)));
1722 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1724 *buf
= xmlStrcat(*buf
, BAD_CAST
"(unknown)");
1728 case XML_SCHEMA_TYPE_ATTRIBUTE
: {
1729 xmlSchemaAttributePtr attr
;
1731 attr
= (xmlSchemaAttributePtr
) item
;
1732 *buf
= xmlStrdup(BAD_CAST
"attribute decl.");
1733 *buf
= xmlStrcat(*buf
, BAD_CAST
" '");
1734 *buf
= xmlStrcat(*buf
, xmlSchemaFormatQName(&str
,
1735 attr
->targetNamespace
, attr
->name
));
1737 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1740 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
1741 xmlSchemaGetComponentDesignation(buf
, item
);
1743 case XML_SCHEMA_TYPE_ELEMENT
: {
1744 xmlSchemaElementPtr elem
;
1746 elem
= (xmlSchemaElementPtr
) item
;
1747 *buf
= xmlStrdup(BAD_CAST
"element decl.");
1748 *buf
= xmlStrcat(*buf
, BAD_CAST
" '");
1749 *buf
= xmlStrcat(*buf
, xmlSchemaFormatQName(&str
,
1750 elem
->targetNamespace
, elem
->name
));
1751 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1754 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
1755 case XML_SCHEMA_TYPE_IDC_KEY
:
1756 case XML_SCHEMA_TYPE_IDC_KEYREF
:
1757 if (item
->type
== XML_SCHEMA_TYPE_IDC_UNIQUE
)
1758 *buf
= xmlStrdup(BAD_CAST
"unique '");
1759 else if (item
->type
== XML_SCHEMA_TYPE_IDC_KEY
)
1760 *buf
= xmlStrdup(BAD_CAST
"key '");
1762 *buf
= xmlStrdup(BAD_CAST
"keyRef '");
1763 *buf
= xmlStrcat(*buf
, ((xmlSchemaIDCPtr
) item
)->name
);
1764 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1766 case XML_SCHEMA_TYPE_ANY
:
1767 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE
:
1768 *buf
= xmlStrdup(xmlSchemaWildcardPCToString(
1769 ((xmlSchemaWildcardPtr
) item
)->processContents
));
1770 *buf
= xmlStrcat(*buf
, BAD_CAST
" wildcard");
1772 case XML_SCHEMA_FACET_MININCLUSIVE
:
1773 case XML_SCHEMA_FACET_MINEXCLUSIVE
:
1774 case XML_SCHEMA_FACET_MAXINCLUSIVE
:
1775 case XML_SCHEMA_FACET_MAXEXCLUSIVE
:
1776 case XML_SCHEMA_FACET_TOTALDIGITS
:
1777 case XML_SCHEMA_FACET_FRACTIONDIGITS
:
1778 case XML_SCHEMA_FACET_PATTERN
:
1779 case XML_SCHEMA_FACET_ENUMERATION
:
1780 case XML_SCHEMA_FACET_WHITESPACE
:
1781 case XML_SCHEMA_FACET_LENGTH
:
1782 case XML_SCHEMA_FACET_MAXLENGTH
:
1783 case XML_SCHEMA_FACET_MINLENGTH
:
1784 *buf
= xmlStrdup(BAD_CAST
"facet '");
1785 *buf
= xmlStrcat(*buf
, xmlSchemaFacetTypeToString(item
->type
));
1786 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1788 case XML_SCHEMA_TYPE_GROUP
: {
1789 *buf
= xmlStrdup(BAD_CAST
"model group def.");
1790 *buf
= xmlStrcat(*buf
, BAD_CAST
" '");
1791 *buf
= xmlStrcat(*buf
, xmlSchemaGetComponentQName(&str
, item
));
1792 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1796 case XML_SCHEMA_TYPE_SEQUENCE
:
1797 case XML_SCHEMA_TYPE_CHOICE
:
1798 case XML_SCHEMA_TYPE_ALL
:
1799 case XML_SCHEMA_TYPE_PARTICLE
:
1800 *buf
= xmlStrdup(WXS_ITEM_TYPE_NAME(item
));
1802 case XML_SCHEMA_TYPE_NOTATION
: {
1803 *buf
= xmlStrdup(WXS_ITEM_TYPE_NAME(item
));
1804 *buf
= xmlStrcat(*buf
, BAD_CAST
" '");
1805 *buf
= xmlStrcat(*buf
, xmlSchemaGetComponentQName(&str
, item
));
1806 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1809 /* Falls through. */
1816 if ((named
== 0) && (itemNode
!= NULL
)) {
1819 if (itemNode
->type
== XML_ATTRIBUTE_NODE
)
1820 elem
= itemNode
->parent
;
1823 *buf
= xmlStrdup(BAD_CAST
"Element '");
1824 if (elem
->ns
!= NULL
) {
1825 *buf
= xmlStrcat(*buf
,
1826 xmlSchemaFormatQName(&str
, elem
->ns
->href
, elem
->name
));
1829 *buf
= xmlStrcat(*buf
, elem
->name
);
1830 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1833 if ((itemNode
!= NULL
) && (itemNode
->type
== XML_ATTRIBUTE_NODE
)) {
1834 *buf
= xmlStrcat(*buf
, BAD_CAST
", attribute '");
1835 if (itemNode
->ns
!= NULL
) {
1836 *buf
= xmlStrcat(*buf
, xmlSchemaFormatQName(&str
,
1837 itemNode
->ns
->href
, itemNode
->name
));
1840 *buf
= xmlStrcat(*buf
, itemNode
->name
);
1841 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1845 return (xmlEscapeFormatString(buf
));
1849 * xmlSchemaFormatFacetEnumSet:
1850 * @buf: the string buffer
1851 * @type: the type holding the enumeration facets
1853 * Builds a string consisting of all enumeration elements.
1855 * Returns a string of all enumeration elements.
1857 static const xmlChar
*
1858 xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt
,
1859 xmlChar
**buf
, xmlSchemaTypePtr type
)
1861 xmlSchemaFacetPtr facet
;
1862 xmlSchemaWhitespaceValueType ws
;
1863 xmlChar
*value
= NULL
;
1872 * Use the whitespace type of the base type.
1874 ws
= xmlSchemaGetWhiteSpaceFacetValue(type
->baseType
);
1875 for (facet
= type
->facets
; facet
!= NULL
; facet
= facet
->next
) {
1876 if (facet
->type
!= XML_SCHEMA_FACET_ENUMERATION
)
1879 res
= xmlSchemaGetCanonValueWhtspExt(facet
->val
,
1882 xmlSchemaInternalErr(actxt
,
1883 "xmlSchemaFormatFacetEnumSet",
1884 "compute the canonical lexical representation");
1891 *buf
= xmlStrdup(BAD_CAST
"'");
1893 *buf
= xmlStrcat(*buf
, BAD_CAST
", '");
1894 *buf
= xmlStrcat(*buf
, BAD_CAST value
);
1895 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1896 if (value
!= NULL
) {
1897 xmlFree((xmlChar
*)value
);
1902 * The enumeration facet of a type restricts the enumeration
1903 * facet of the ancestor type; i.e., such restricted enumerations
1904 * do not belong to the set of the given type. Thus we break
1905 * on the first found enumeration.
1909 type
= type
->baseType
;
1910 } while ((type
!= NULL
) && (type
->type
!= XML_SCHEMA_TYPE_BASIC
));
1912 return ((const xmlChar
*) *buf
);
1915 /************************************************************************
1919 ************************************************************************/
1923 xmlSchemaErrMemory(const char *msg
)
1925 __xmlSimpleError(XML_FROM_SCHEMASP
, XML_ERR_NO_MEMORY
, NULL
, NULL
,
1931 xmlSchemaPSimpleErr(const char *msg
)
1933 __xmlSimpleError(XML_FROM_SCHEMASP
, XML_ERR_NO_MEMORY
, NULL
, NULL
,
1938 * xmlSchemaPErrMemory:
1939 * @node: a context node
1940 * @extra: extra information
1942 * Handle an out of memory condition
1945 xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt
,
1946 const char *extra
, xmlNodePtr node
)
1950 __xmlSimpleError(XML_FROM_SCHEMASP
, XML_ERR_NO_MEMORY
, node
, NULL
,
1956 * @ctxt: the parsing context
1957 * @node: the context node
1958 * @error: the error code
1959 * @msg: the error message
1963 * Handle a parser error
1965 static void LIBXML_ATTR_FORMAT(4,0)
1966 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
, int error
,
1967 const char *msg
, const xmlChar
* str1
, const xmlChar
* str2
)
1969 xmlGenericErrorFunc channel
= NULL
;
1970 xmlStructuredErrorFunc schannel
= NULL
;
1976 channel
= ctxt
->error
;
1977 data
= ctxt
->errCtxt
;
1978 schannel
= ctxt
->serror
;
1980 __xmlRaiseError(schannel
, channel
, data
, ctxt
, node
, XML_FROM_SCHEMASP
,
1981 error
, XML_ERR_ERROR
, NULL
, 0,
1982 (const char *) str1
, (const char *) str2
, NULL
, 0, 0,
1988 * @ctxt: the parsing context
1989 * @node: the context node
1990 * @node: the current child
1991 * @error: the error code
1992 * @msg: the error message
1996 * Handle a parser error
1998 static void LIBXML_ATTR_FORMAT(5,0)
1999 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
,
2000 xmlNodePtr child
, int error
,
2001 const char *msg
, const xmlChar
* str1
, const xmlChar
* str2
)
2004 xmlSchemaPErr(ctxt
, child
, error
, msg
, str1
, str2
);
2006 xmlSchemaPErr(ctxt
, node
, error
, msg
, str1
, str2
);
2012 * @ctxt: the parsing context
2013 * @node: the context node
2014 * @error: the error code
2015 * @strData1: extra data
2016 * @strData2: extra data
2017 * @strData3: extra data
2019 * @str1: extra parameter for the message display
2020 * @str2: extra parameter for the message display
2021 * @str3: extra parameter for the message display
2022 * @str4: extra parameter for the message display
2023 * @str5: extra parameter for the message display
2025 * Handle a parser error
2027 static void LIBXML_ATTR_FORMAT(7,0)
2028 xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
, int error
,
2029 const xmlChar
* strData1
, const xmlChar
* strData2
,
2030 const xmlChar
* strData3
, const char *msg
, const xmlChar
* str1
,
2031 const xmlChar
* str2
, const xmlChar
* str3
, const xmlChar
* str4
,
2032 const xmlChar
* str5
)
2035 xmlGenericErrorFunc channel
= NULL
;
2036 xmlStructuredErrorFunc schannel
= NULL
;
2042 channel
= ctxt
->error
;
2043 data
= ctxt
->errCtxt
;
2044 schannel
= ctxt
->serror
;
2046 __xmlRaiseError(schannel
, channel
, data
, ctxt
, node
, XML_FROM_SCHEMASP
,
2047 error
, XML_ERR_ERROR
, NULL
, 0,
2048 (const char *) strData1
, (const char *) strData2
,
2049 (const char *) strData3
, 0, 0, msg
, str1
, str2
,
2053 /************************************************************************
2055 * Allround error functions *
2057 ************************************************************************/
2060 * xmlSchemaVTypeErrMemory:
2061 * @node: a context node
2062 * @extra: extra information
2064 * Handle an out of memory condition
2067 xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt
,
2068 const char *extra
, xmlNodePtr node
)
2072 ctxt
->err
= XML_SCHEMAV_INTERNAL
;
2074 __xmlSimpleError(XML_FROM_SCHEMASV
, XML_ERR_NO_MEMORY
, node
, NULL
,
2078 static void LIBXML_ATTR_FORMAT(2,0)
2079 xmlSchemaPSimpleInternalErr(xmlNodePtr node
,
2080 const char *msg
, const xmlChar
*str
)
2082 __xmlSimpleError(XML_FROM_SCHEMASP
, XML_SCHEMAP_INTERNAL
, node
,
2083 msg
, (const char *) str
);
2086 #define WXS_ERROR_TYPE_ERROR 1
2087 #define WXS_ERROR_TYPE_WARNING 2
2089 * xmlSchemaErr4Line:
2090 * @ctxt: the validation context
2091 * @errorLevel: the error level
2092 * @error: the error code
2093 * @node: the context node
2094 * @line: the line number
2095 * @msg: the error message
2101 * Handle a validation error
2103 static void LIBXML_ATTR_FORMAT(6,0)
2104 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt
,
2105 xmlErrorLevel errorLevel
,
2106 int error
, xmlNodePtr node
, int line
, const char *msg
,
2107 const xmlChar
*str1
, const xmlChar
*str2
,
2108 const xmlChar
*str3
, const xmlChar
*str4
)
2110 xmlStructuredErrorFunc schannel
= NULL
;
2111 xmlGenericErrorFunc channel
= NULL
;
2115 if (ctxt
->type
== XML_SCHEMA_CTXT_VALIDATOR
) {
2116 xmlSchemaValidCtxtPtr vctxt
= (xmlSchemaValidCtxtPtr
) ctxt
;
2117 const char *file
= NULL
;
2119 if (errorLevel
!= XML_ERR_WARNING
) {
2122 channel
= vctxt
->error
;
2124 channel
= vctxt
->warning
;
2126 schannel
= vctxt
->serror
;
2127 data
= vctxt
->errCtxt
;
2130 * Error node. If we specify a line number, then
2131 * do not channel any node to the error function.
2134 if ((node
== NULL
) &&
2135 (vctxt
->depth
>= 0) &&
2136 (vctxt
->inode
!= NULL
)) {
2137 node
= vctxt
->inode
->node
;
2140 * Get filename and line if no node-tree.
2142 if ((node
== NULL
) &&
2143 (vctxt
->parserCtxt
!= NULL
) &&
2144 (vctxt
->parserCtxt
->input
!= NULL
)) {
2145 file
= vctxt
->parserCtxt
->input
->filename
;
2146 line
= vctxt
->parserCtxt
->input
->line
;
2147 col
= vctxt
->parserCtxt
->input
->col
;
2151 * Override the given node's (if any) position
2152 * and channel only the given line number.
2158 if (vctxt
->doc
!= NULL
)
2159 file
= (const char *) vctxt
->doc
->URL
;
2160 else if ((vctxt
->parserCtxt
!= NULL
) &&
2161 (vctxt
->parserCtxt
->input
!= NULL
))
2162 file
= vctxt
->parserCtxt
->input
->filename
;
2164 if (vctxt
->locFunc
!= NULL
) {
2165 if ((file
== NULL
) || (line
== 0)) {
2168 vctxt
->locFunc(vctxt
->locCtxt
, &f
, &l
);
2175 if ((file
== NULL
) && (vctxt
->filename
!= NULL
))
2176 file
= vctxt
->filename
;
2178 __xmlRaiseError(schannel
, channel
, data
, ctxt
,
2179 node
, XML_FROM_SCHEMASV
,
2180 error
, errorLevel
, file
, line
,
2181 (const char *) str1
, (const char *) str2
,
2182 (const char *) str3
, 0, col
, msg
, str1
, str2
, str3
, str4
);
2184 } else if (ctxt
->type
== XML_SCHEMA_CTXT_PARSER
) {
2185 xmlSchemaParserCtxtPtr pctxt
= (xmlSchemaParserCtxtPtr
) ctxt
;
2186 if (errorLevel
!= XML_ERR_WARNING
) {
2189 channel
= pctxt
->error
;
2191 channel
= pctxt
->warning
;
2193 schannel
= pctxt
->serror
;
2194 data
= pctxt
->errCtxt
;
2195 __xmlRaiseError(schannel
, channel
, data
, ctxt
,
2196 node
, XML_FROM_SCHEMASP
, error
,
2197 errorLevel
, NULL
, 0,
2198 (const char *) str1
, (const char *) str2
,
2199 (const char *) str3
, 0, 0, msg
, str1
, str2
, str3
, str4
);
2208 * @ctxt: the validation context
2209 * @node: the context node
2210 * @error: the error code
2211 * @msg: the error message
2216 * Handle a validation error
2218 static void LIBXML_ATTR_FORMAT(4,0)
2219 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt
,
2220 int error
, xmlNodePtr node
, const char *msg
,
2221 const xmlChar
*str1
, const xmlChar
*str2
, const xmlChar
*str3
)
2223 xmlSchemaErr4Line(actxt
, XML_ERR_ERROR
, error
, node
, 0,
2224 msg
, str1
, str2
, str3
, NULL
);
2227 static void LIBXML_ATTR_FORMAT(4,0)
2228 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt
,
2229 int error
, xmlNodePtr node
, const char *msg
,
2230 const xmlChar
*str1
, const xmlChar
*str2
,
2231 const xmlChar
*str3
, const xmlChar
*str4
)
2233 xmlSchemaErr4Line(actxt
, XML_ERR_ERROR
, error
, node
, 0,
2234 msg
, str1
, str2
, str3
, str4
);
2237 static void LIBXML_ATTR_FORMAT(4,0)
2238 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt
,
2239 int error
, xmlNodePtr node
, const char *msg
,
2240 const xmlChar
*str1
, const xmlChar
*str2
)
2242 xmlSchemaErr4(actxt
, error
, node
, msg
, str1
, str2
, NULL
, NULL
);
2246 xmlSchemaFormatNodeForError(xmlChar
** msg
,
2247 xmlSchemaAbstractCtxtPtr actxt
,
2250 xmlChar
*str
= NULL
;
2253 if ((node
!= NULL
) &&
2254 (node
->type
!= XML_ELEMENT_NODE
) &&
2255 (node
->type
!= XML_ATTRIBUTE_NODE
))
2258 * Don't try to format other nodes than element and
2260 * Play safe and return an empty string.
2262 *msg
= xmlStrdup(BAD_CAST
"");
2267 * Work on tree nodes.
2269 if (node
->type
== XML_ATTRIBUTE_NODE
) {
2270 xmlNodePtr elem
= node
->parent
;
2272 *msg
= xmlStrdup(BAD_CAST
"Element '");
2273 if (elem
->ns
!= NULL
)
2274 *msg
= xmlStrcat(*msg
, xmlSchemaFormatQName(&str
,
2275 elem
->ns
->href
, elem
->name
));
2277 *msg
= xmlStrcat(*msg
, xmlSchemaFormatQName(&str
,
2280 *msg
= xmlStrcat(*msg
, BAD_CAST
"', ");
2281 *msg
= xmlStrcat(*msg
, BAD_CAST
"attribute '");
2283 *msg
= xmlStrdup(BAD_CAST
"Element '");
2285 if (node
->ns
!= NULL
)
2286 *msg
= xmlStrcat(*msg
, xmlSchemaFormatQName(&str
,
2287 node
->ns
->href
, node
->name
));
2289 *msg
= xmlStrcat(*msg
, xmlSchemaFormatQName(&str
,
2292 *msg
= xmlStrcat(*msg
, BAD_CAST
"': ");
2293 } else if (actxt
->type
== XML_SCHEMA_CTXT_VALIDATOR
) {
2294 xmlSchemaValidCtxtPtr vctxt
= (xmlSchemaValidCtxtPtr
) actxt
;
2296 * Work on node infos.
2298 if (vctxt
->inode
->nodeType
== XML_ATTRIBUTE_NODE
) {
2299 xmlSchemaNodeInfoPtr ielem
=
2300 vctxt
->elemInfos
[vctxt
->depth
];
2302 *msg
= xmlStrdup(BAD_CAST
"Element '");
2303 *msg
= xmlStrcat(*msg
, xmlSchemaFormatQName(&str
,
2304 ielem
->nsName
, ielem
->localName
));
2306 *msg
= xmlStrcat(*msg
, BAD_CAST
"', ");
2307 *msg
= xmlStrcat(*msg
, BAD_CAST
"attribute '");
2309 *msg
= xmlStrdup(BAD_CAST
"Element '");
2311 *msg
= xmlStrcat(*msg
, xmlSchemaFormatQName(&str
,
2312 vctxt
->inode
->nsName
, vctxt
->inode
->localName
));
2314 *msg
= xmlStrcat(*msg
, BAD_CAST
"': ");
2315 } else if (actxt
->type
== XML_SCHEMA_CTXT_PARSER
) {
2317 * Hmm, no node while parsing?
2318 * Return an empty string, in case NULL will break something.
2320 *msg
= xmlStrdup(BAD_CAST
"");
2327 * xmlSchemaFormatItemForReport() also returns an escaped format
2328 * string, so do this before calling it below (in the future).
2330 xmlEscapeFormatString(msg
);
2333 * VAL TODO: The output of the given schema component is currently
2337 if ((type
!= NULL
) && (xmlSchemaIsGlobalItem(type
))) {
2338 *msg
= xmlStrcat(*msg
, BAD_CAST
" [");
2339 *msg
= xmlStrcat(*msg
, xmlSchemaFormatItemForReport(&str
,
2340 NULL
, type
, NULL
, 0));
2342 *msg
= xmlStrcat(*msg
, BAD_CAST
"]");
2348 static void LIBXML_ATTR_FORMAT(3,0)
2349 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt
,
2350 const char *funcName
,
2351 const char *message
,
2352 const xmlChar
*str1
,
2353 const xmlChar
*str2
)
2355 xmlChar
*msg
= NULL
;
2359 msg
= xmlStrdup(BAD_CAST
"Internal error: %s, ");
2360 msg
= xmlStrcat(msg
, BAD_CAST message
);
2361 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
2363 if (actxt
->type
== XML_SCHEMA_CTXT_VALIDATOR
)
2364 xmlSchemaErr3(actxt
, XML_SCHEMAV_INTERNAL
, NULL
,
2365 (const char *) msg
, (const xmlChar
*) funcName
, str1
, str2
);
2366 else if (actxt
->type
== XML_SCHEMA_CTXT_PARSER
)
2367 xmlSchemaErr3(actxt
, XML_SCHEMAP_INTERNAL
, NULL
,
2368 (const char *) msg
, (const xmlChar
*) funcName
, str1
, str2
);
2373 static void LIBXML_ATTR_FORMAT(3,0)
2374 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt
,
2375 const char *funcName
,
2376 const char *message
)
2378 xmlSchemaInternalErr2(actxt
, funcName
, message
, NULL
, NULL
);
2382 static void LIBXML_ATTR_FORMAT(3,0)
2383 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt
,
2384 const char *funcName
,
2385 const char *message
,
2386 const xmlChar
*str1
,
2387 const xmlChar
*str2
)
2389 xmlSchemaInternalErr2(ACTXT_CAST pctxt
, funcName
, message
,
2394 static void LIBXML_ATTR_FORMAT(5,0)
2395 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt
,
2396 xmlParserErrors error
,
2398 xmlSchemaBasicItemPtr item
,
2399 const char *message
,
2400 const xmlChar
*str1
, const xmlChar
*str2
,
2401 const xmlChar
*str3
, const xmlChar
*str4
)
2403 xmlChar
*msg
= NULL
;
2405 if ((node
== NULL
) && (item
!= NULL
) &&
2406 (actxt
->type
== XML_SCHEMA_CTXT_PARSER
)) {
2407 node
= WXS_ITEM_NODE(item
);
2408 xmlSchemaFormatItemForReport(&msg
, NULL
, item
, NULL
);
2409 msg
= xmlStrcat(msg
, BAD_CAST
": ");
2411 xmlSchemaFormatNodeForError(&msg
, actxt
, node
);
2412 msg
= xmlStrcat(msg
, (const xmlChar
*) message
);
2413 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
2414 xmlSchemaErr4(actxt
, error
, node
,
2415 (const char *) msg
, str1
, str2
, str3
, str4
);
2419 static void LIBXML_ATTR_FORMAT(5,0)
2420 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt
,
2421 xmlParserErrors error
,
2423 xmlSchemaBasicItemPtr item
,
2424 const char *message
,
2425 const xmlChar
*str1
,
2426 const xmlChar
*str2
)
2428 xmlSchemaCustomErr4(actxt
, error
, node
, item
,
2429 message
, str1
, str2
, NULL
, NULL
);
2434 static void LIBXML_ATTR_FORMAT(5,0)
2435 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt
,
2436 xmlParserErrors error
,
2438 xmlSchemaTypePtr type ATTRIBUTE_UNUSED
,
2439 const char *message
,
2440 const xmlChar
*str1
,
2441 const xmlChar
*str2
,
2442 const xmlChar
*str3
)
2444 xmlChar
*msg
= NULL
;
2446 xmlSchemaFormatNodeForError(&msg
, actxt
, node
);
2447 msg
= xmlStrcat(msg
, (const xmlChar
*) message
);
2448 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
2450 /* URGENT TODO: Set the error code to something sane. */
2451 xmlSchemaErr4Line(actxt
, XML_ERR_WARNING
, error
, node
, 0,
2452 (const char *) msg
, str1
, str2
, str3
, NULL
);
2459 static void LIBXML_ATTR_FORMAT(5,0)
2460 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt
,
2461 xmlParserErrors error
,
2462 xmlSchemaPSVIIDCNodePtr idcNode
,
2463 xmlSchemaTypePtr type ATTRIBUTE_UNUSED
,
2464 const char *message
,
2465 const xmlChar
*str1
,
2466 const xmlChar
*str2
)
2468 xmlChar
*msg
= NULL
, *qname
= NULL
;
2470 msg
= xmlStrdup(BAD_CAST
"Element '%s': ");
2471 msg
= xmlStrcat(msg
, (const xmlChar
*) message
);
2472 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
2473 xmlSchemaErr4Line(ACTXT_CAST vctxt
, XML_ERR_ERROR
,
2474 error
, NULL
, idcNode
->nodeLine
, (const char *) msg
,
2475 xmlSchemaFormatQName(&qname
,
2476 vctxt
->nodeQNames
->items
[idcNode
->nodeQNameID
+1],
2477 vctxt
->nodeQNames
->items
[idcNode
->nodeQNameID
]),
2479 FREE_AND_NULL(qname
);
2484 xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt
,
2488 return (node
->type
);
2489 if ((actxt
->type
== XML_SCHEMA_CTXT_VALIDATOR
) &&
2490 (((xmlSchemaValidCtxtPtr
) actxt
)->inode
!= NULL
))
2491 return ( ((xmlSchemaValidCtxtPtr
) actxt
)->inode
->nodeType
);
2496 xmlSchemaIsGlobalItem(xmlSchemaTypePtr item
)
2498 switch (item
->type
) {
2499 case XML_SCHEMA_TYPE_COMPLEX
:
2500 case XML_SCHEMA_TYPE_SIMPLE
:
2501 if (item
->flags
& XML_SCHEMAS_TYPE_GLOBAL
)
2504 case XML_SCHEMA_TYPE_GROUP
:
2506 case XML_SCHEMA_TYPE_ELEMENT
:
2507 if ( ((xmlSchemaElementPtr
) item
)->flags
&
2508 XML_SCHEMAS_ELEM_GLOBAL
)
2511 case XML_SCHEMA_TYPE_ATTRIBUTE
:
2512 if ( ((xmlSchemaAttributePtr
) item
)->flags
&
2513 XML_SCHEMAS_ATTR_GLOBAL
)
2516 /* Note that attribute groups are always global. */
2524 xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt
,
2525 xmlParserErrors error
,
2527 const xmlChar
*value
,
2528 xmlSchemaTypePtr type
,
2531 xmlChar
*msg
= NULL
;
2533 xmlSchemaFormatNodeForError(&msg
, actxt
, node
);
2535 if (displayValue
|| (xmlSchemaEvalErrorNodeType(actxt
, node
) ==
2536 XML_ATTRIBUTE_NODE
))
2537 msg
= xmlStrcat(msg
, BAD_CAST
"'%s' is not a valid value of ");
2539 msg
= xmlStrcat(msg
, BAD_CAST
"The character content is not a valid "
2542 if (! xmlSchemaIsGlobalItem(type
))
2543 msg
= xmlStrcat(msg
, BAD_CAST
"the local ");
2545 msg
= xmlStrcat(msg
, BAD_CAST
"the ");
2547 if (WXS_IS_ATOMIC(type
))
2548 msg
= xmlStrcat(msg
, BAD_CAST
"atomic type");
2549 else if (WXS_IS_LIST(type
))
2550 msg
= xmlStrcat(msg
, BAD_CAST
"list type");
2551 else if (WXS_IS_UNION(type
))
2552 msg
= xmlStrcat(msg
, BAD_CAST
"union type");
2554 if (xmlSchemaIsGlobalItem(type
)) {
2555 xmlChar
*str
= NULL
;
2556 msg
= xmlStrcat(msg
, BAD_CAST
" '");
2557 if (type
->builtInType
!= 0) {
2558 msg
= xmlStrcat(msg
, BAD_CAST
"xs:");
2559 str
= xmlStrdup(type
->name
);
2561 const xmlChar
*qName
= xmlSchemaFormatQName(&str
, type
->targetNamespace
, type
->name
);
2563 str
= xmlStrdup(qName
);
2565 msg
= xmlStrcat(msg
, xmlEscapeFormatString(&str
));
2566 msg
= xmlStrcat(msg
, BAD_CAST
"'");
2569 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
2570 if (displayValue
|| (xmlSchemaEvalErrorNodeType(actxt
, node
) ==
2571 XML_ATTRIBUTE_NODE
))
2572 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, value
, NULL
);
2574 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, NULL
, NULL
);
2578 static const xmlChar
*
2579 xmlSchemaFormatErrorNodeQName(xmlChar
** str
,
2580 xmlSchemaNodeInfoPtr ni
,
2584 if (node
->ns
!= NULL
)
2585 return (xmlSchemaFormatQName(str
, node
->ns
->href
, node
->name
));
2587 return (xmlSchemaFormatQName(str
, NULL
, node
->name
));
2588 } else if (ni
!= NULL
)
2589 return (xmlSchemaFormatQName(str
, ni
->nsName
, ni
->localName
));
2594 xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt
,
2595 xmlParserErrors error
,
2596 xmlSchemaAttrInfoPtr ni
,
2599 xmlChar
*msg
= NULL
, *str
= NULL
;
2601 xmlSchemaFormatNodeForError(&msg
, actxt
, node
);
2602 msg
= xmlStrcat(msg
, BAD_CAST
"The attribute '%s' is not allowed.\n");
2603 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
,
2604 xmlSchemaFormatErrorNodeQName(&str
, (xmlSchemaNodeInfoPtr
) ni
, node
),
2610 static void LIBXML_ATTR_FORMAT(5,0)
2611 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt
,
2612 xmlParserErrors error
,
2614 xmlSchemaTypePtr type ATTRIBUTE_UNUSED
,
2615 const char *message
,
2620 xmlChar
*str
= NULL
, *msg
= NULL
;
2621 xmlChar
*localName
, *nsName
;
2622 const xmlChar
*cur
, *end
;
2625 xmlSchemaFormatNodeForError(&msg
, actxt
, node
);
2626 msg
= xmlStrcat(msg
, (const xmlChar
*) message
);
2627 msg
= xmlStrcat(msg
, BAD_CAST
".");
2629 * Note that is does not make sense to report that we have a
2630 * wildcard here, since the wildcard might be unfolded into
2631 * multiple transitions.
2633 if (nbval
+ nbneg
> 0) {
2634 if (nbval
+ nbneg
> 1) {
2635 str
= xmlStrdup(BAD_CAST
" Expected is one of ( ");
2637 str
= xmlStrdup(BAD_CAST
" Expected is ( ");
2640 for (i
= 0; i
< nbval
+ nbneg
; i
++) {
2644 if ((cur
[0] == 'n') && (cur
[1] == 'o') && (cur
[2] == 't') &&
2647 str
= xmlStrcat(str
, BAD_CAST
"##other");
2650 * Get the local name.
2656 localName
= xmlStrdup(BAD_CAST
"*");
2659 while ((*end
!= 0) && (*end
!= '|'))
2661 localName
= xmlStrncat(localName
, BAD_CAST cur
, end
- cur
);
2666 * Skip "*|*" if they come with negated expressions, since
2667 * they represent the same negated wildcard.
2669 if ((nbneg
== 0) || (*end
!= '*') || (*localName
!= '*')) {
2671 * Get the namespace name.
2675 nsName
= xmlStrdup(BAD_CAST
"{*}");
2681 nsName
= xmlStrdup(BAD_CAST
"{##other:");
2683 nsName
= xmlStrdup(BAD_CAST
"{");
2685 nsName
= xmlStrncat(nsName
, BAD_CAST cur
, end
- cur
);
2686 nsName
= xmlStrcat(nsName
, BAD_CAST
"}");
2688 str
= xmlStrcat(str
, BAD_CAST nsName
);
2689 FREE_AND_NULL(nsName
)
2691 FREE_AND_NULL(localName
);
2695 str
= xmlStrcat(str
, BAD_CAST localName
);
2696 FREE_AND_NULL(localName
);
2698 if (i
< nbval
+ nbneg
-1)
2699 str
= xmlStrcat(str
, BAD_CAST
", ");
2701 str
= xmlStrcat(str
, BAD_CAST
" ).\n");
2702 msg
= xmlStrcat(msg
, xmlEscapeFormatString(&str
));
2705 msg
= xmlStrcat(msg
, BAD_CAST
"\n");
2706 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, NULL
, NULL
);
2710 static void LIBXML_ATTR_FORMAT(8,0)
2711 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt
,
2712 xmlParserErrors error
,
2714 const xmlChar
*value
,
2715 unsigned long length
,
2716 xmlSchemaTypePtr type
,
2717 xmlSchemaFacetPtr facet
,
2718 const char *message
,
2719 const xmlChar
*str1
,
2720 const xmlChar
*str2
)
2722 xmlChar
*str
= NULL
, *msg
= NULL
;
2723 xmlSchemaTypeType facetType
;
2724 int nodeType
= xmlSchemaEvalErrorNodeType(actxt
, node
);
2726 xmlSchemaFormatNodeForError(&msg
, actxt
, node
);
2727 if (error
== XML_SCHEMAV_CVC_ENUMERATION_VALID
) {
2728 facetType
= XML_SCHEMA_FACET_ENUMERATION
;
2730 * If enumerations are validated, one must not expect the
2731 * facet to be given.
2734 facetType
= facet
->type
;
2735 msg
= xmlStrcat(msg
, BAD_CAST
"[");
2736 msg
= xmlStrcat(msg
, BAD_CAST
"facet '");
2737 msg
= xmlStrcat(msg
, xmlSchemaFacetTypeToString(facetType
));
2738 msg
= xmlStrcat(msg
, BAD_CAST
"'] ");
2739 if (message
== NULL
) {
2741 * Use a default message.
2743 if ((facetType
== XML_SCHEMA_FACET_LENGTH
) ||
2744 (facetType
== XML_SCHEMA_FACET_MINLENGTH
) ||
2745 (facetType
== XML_SCHEMA_FACET_MAXLENGTH
)) {
2747 char len
[25], actLen
[25];
2749 /* FIXME, TODO: What is the max expected string length of the
2752 if (nodeType
== XML_ATTRIBUTE_NODE
)
2753 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' has a length of '%s'; ");
2755 msg
= xmlStrcat(msg
, BAD_CAST
"The value has a length of '%s'; ");
2757 snprintf(len
, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet
));
2758 snprintf(actLen
, 24, "%lu", length
);
2760 if (facetType
== XML_SCHEMA_FACET_LENGTH
)
2761 msg
= xmlStrcat(msg
,
2762 BAD_CAST
"this differs from the allowed length of '%s'.\n");
2763 else if (facetType
== XML_SCHEMA_FACET_MAXLENGTH
)
2764 msg
= xmlStrcat(msg
,
2765 BAD_CAST
"this exceeds the allowed maximum length of '%s'.\n");
2766 else if (facetType
== XML_SCHEMA_FACET_MINLENGTH
)
2767 msg
= xmlStrcat(msg
,
2768 BAD_CAST
"this underruns the allowed minimum length of '%s'.\n");
2770 if (nodeType
== XML_ATTRIBUTE_NODE
)
2771 xmlSchemaErr3(actxt
, error
, node
, (const char *) msg
,
2772 value
, (const xmlChar
*) actLen
, (const xmlChar
*) len
);
2774 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
,
2775 (const xmlChar
*) actLen
, (const xmlChar
*) len
);
2777 } else if (facetType
== XML_SCHEMA_FACET_ENUMERATION
) {
2778 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' is not an element "
2779 "of the set {%s}.\n");
2780 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, value
,
2781 xmlSchemaFormatFacetEnumSet(actxt
, &str
, type
));
2782 } else if (facetType
== XML_SCHEMA_FACET_PATTERN
) {
2783 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' is not accepted "
2784 "by the pattern '%s'.\n");
2785 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, value
,
2787 } else if (facetType
== XML_SCHEMA_FACET_MININCLUSIVE
) {
2788 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' is less than the "
2789 "minimum value allowed ('%s').\n");
2790 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, value
,
2792 } else if (facetType
== XML_SCHEMA_FACET_MAXINCLUSIVE
) {
2793 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' is greater than the "
2794 "maximum value allowed ('%s').\n");
2795 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, value
,
2797 } else if (facetType
== XML_SCHEMA_FACET_MINEXCLUSIVE
) {
2798 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' must be greater than "
2800 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, value
,
2802 } else if (facetType
== XML_SCHEMA_FACET_MAXEXCLUSIVE
) {
2803 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' must be less than "
2805 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, value
,
2807 } else if (facetType
== XML_SCHEMA_FACET_TOTALDIGITS
) {
2808 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' has more "
2809 "digits than are allowed ('%s').\n");
2810 xmlSchemaErr(actxt
, error
, node
, (const char*) msg
, value
,
2812 } else if (facetType
== XML_SCHEMA_FACET_FRACTIONDIGITS
) {
2813 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' has more fractional "
2814 "digits than are allowed ('%s').\n");
2815 xmlSchemaErr(actxt
, error
, node
, (const char*) msg
, value
,
2817 } else if (nodeType
== XML_ATTRIBUTE_NODE
) {
2818 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' is not facet-valid.\n");
2819 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, value
, NULL
);
2821 msg
= xmlStrcat(msg
, BAD_CAST
"The value is not facet-valid.\n");
2822 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, NULL
, NULL
);
2825 msg
= xmlStrcat(msg
, (const xmlChar
*) message
);
2826 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
2827 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, str1
, str2
);
2833 #define VERROR(err, type, msg) \
2834 xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
2836 #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
2838 #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
2839 #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
2841 #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
2845 * xmlSchemaPMissingAttrErr:
2846 * @ctxt: the schema validation context
2847 * @ownerItem: the owner as a schema object
2848 * @ownerElem: the owner as an element node
2849 * @node: the parent element node of the missing attribute node
2850 * @type: the corresponding type of the attribute node
2852 * Reports an illegal attribute.
2855 xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt
,
2856 xmlParserErrors error
,
2857 xmlSchemaBasicItemPtr ownerItem
,
2858 xmlNodePtr ownerElem
,
2860 const char *message
)
2862 xmlChar
*des
= NULL
;
2864 xmlSchemaFormatItemForReport(&des
, NULL
, ownerItem
, ownerElem
);
2866 if (message
!= NULL
)
2867 xmlSchemaPErr(ctxt
, ownerElem
, error
, "%s: %s.\n", BAD_CAST des
, BAD_CAST message
);
2869 xmlSchemaPErr(ctxt
, ownerElem
, error
,
2870 "%s: The attribute '%s' is required but missing.\n",
2871 BAD_CAST des
, BAD_CAST name
);
2877 * xmlSchemaPResCompAttrErr:
2878 * @ctxt: the schema validation context
2879 * @error: the error code
2880 * @ownerItem: the owner as a schema object
2881 * @ownerElem: the owner as an element node
2882 * @name: the name of the attribute holding the QName
2883 * @refName: the referenced local name
2884 * @refURI: the referenced namespace URI
2885 * @message: optional message
2887 * Used to report QName attribute values that failed to resolve
2888 * to schema components.
2891 xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt
,
2892 xmlParserErrors error
,
2893 xmlSchemaBasicItemPtr ownerItem
,
2894 xmlNodePtr ownerElem
,
2896 const xmlChar
*refName
,
2897 const xmlChar
*refURI
,
2898 xmlSchemaTypeType refType
,
2899 const char *refTypeStr
)
2901 xmlChar
*des
= NULL
, *strA
= NULL
;
2903 xmlSchemaFormatItemForReport(&des
, NULL
, ownerItem
, ownerElem
);
2904 if (refTypeStr
== NULL
)
2905 refTypeStr
= (const char *) xmlSchemaItemTypeToStr(refType
);
2906 xmlSchemaPErrExt(ctxt
, ownerElem
, error
,
2908 "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
2909 "%s.\n", BAD_CAST des
, BAD_CAST name
,
2910 xmlSchemaFormatQName(&strA
, refURI
, refName
),
2911 BAD_CAST refTypeStr
, NULL
);
2917 * xmlSchemaPCustomAttrErr:
2918 * @ctxt: the schema parser context
2919 * @error: the error code
2920 * @ownerDes: the designation of the owner
2921 * @ownerItem: the owner as a schema object
2922 * @attr: the illegal attribute node
2924 * Reports an illegal attribute during the parse.
2927 xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt
,
2928 xmlParserErrors error
,
2930 xmlSchemaBasicItemPtr ownerItem
,
2934 xmlChar
*des
= NULL
;
2936 if (ownerDes
== NULL
)
2937 xmlSchemaFormatItemForReport(&des
, NULL
, ownerItem
, attr
->parent
);
2938 else if (*ownerDes
== NULL
) {
2939 xmlSchemaFormatItemForReport(ownerDes
, NULL
, ownerItem
, attr
->parent
);
2944 xmlSchemaPErrExt(ctxt
, NULL
, error
, NULL
, NULL
, NULL
,
2945 "%s, attribute '%s': %s.\n",
2946 BAD_CAST des
, (const xmlChar
*) "Unknown",
2947 (const xmlChar
*) msg
, NULL
, NULL
);
2949 xmlSchemaPErrExt(ctxt
, (xmlNodePtr
) attr
, error
, NULL
, NULL
, NULL
,
2950 "%s, attribute '%s': %s.\n",
2951 BAD_CAST des
, attr
->name
, (const xmlChar
*) msg
, NULL
, NULL
);
2953 if (ownerDes
== NULL
)
2958 * xmlSchemaPIllegalAttrErr:
2959 * @ctxt: the schema parser context
2960 * @error: the error code
2961 * @ownerItem: the attribute's owner item
2962 * @attr: the illegal attribute node
2964 * Reports an illegal attribute during the parse.
2967 xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt
,
2968 xmlParserErrors error
,
2969 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED
,
2972 xmlChar
*strA
= NULL
, *strB
= NULL
;
2974 xmlSchemaFormatNodeForError(&strA
, ACTXT_CAST ctxt
, attr
->parent
);
2975 xmlSchemaErr4(ACTXT_CAST ctxt
, error
, (xmlNodePtr
) attr
,
2976 "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA
,
2977 xmlSchemaFormatQNameNs(&strB
, attr
->ns
, attr
->name
),
2979 FREE_AND_NULL(strA
);
2980 FREE_AND_NULL(strB
);
2984 * xmlSchemaPCustomErr:
2985 * @ctxt: the schema parser context
2986 * @error: the error code
2987 * @itemDes: the designation of the schema item
2988 * @item: the schema item
2989 * @itemElem: the node of the schema item
2990 * @message: the error message
2991 * @str1: an optional param for the error message
2992 * @str2: an optional param for the error message
2993 * @str3: an optional param for the error message
2995 * Reports an error during parsing.
2997 static void LIBXML_ATTR_FORMAT(5,0)
2998 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt
,
2999 xmlParserErrors error
,
3000 xmlSchemaBasicItemPtr item
,
3001 xmlNodePtr itemElem
,
3002 const char *message
,
3003 const xmlChar
*str1
,
3004 const xmlChar
*str2
,
3005 const xmlChar
*str3
)
3007 xmlChar
*des
= NULL
, *msg
= NULL
;
3009 xmlSchemaFormatItemForReport(&des
, NULL
, item
, itemElem
);
3010 msg
= xmlStrdup(BAD_CAST
"%s: ");
3011 msg
= xmlStrcat(msg
, (const xmlChar
*) message
);
3012 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
3013 if ((itemElem
== NULL
) && (item
!= NULL
))
3014 itemElem
= WXS_ITEM_NODE(item
);
3015 xmlSchemaPErrExt(ctxt
, itemElem
, error
, NULL
, NULL
, NULL
,
3016 (const char *) msg
, BAD_CAST des
, str1
, str2
, str3
, NULL
);
3022 * xmlSchemaPCustomErr:
3023 * @ctxt: the schema parser context
3024 * @error: the error code
3025 * @itemDes: the designation of the schema item
3026 * @item: the schema item
3027 * @itemElem: the node of the schema item
3028 * @message: the error message
3029 * @str1: the optional param for the error message
3031 * Reports an error during parsing.
3033 static void LIBXML_ATTR_FORMAT(5,0)
3034 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt
,
3035 xmlParserErrors error
,
3036 xmlSchemaBasicItemPtr item
,
3037 xmlNodePtr itemElem
,
3038 const char *message
,
3039 const xmlChar
*str1
)
3041 xmlSchemaPCustomErrExt(ctxt
, error
, item
, itemElem
, message
,
3046 * xmlSchemaPAttrUseErr:
3047 * @ctxt: the schema parser context
3048 * @error: the error code
3049 * @itemDes: the designation of the schema type
3050 * @item: the schema type
3051 * @itemElem: the node of the schema type
3052 * @attr: the invalid schema attribute
3053 * @message: the error message
3054 * @str1: the optional param for the error message
3056 * Reports an attribute use error during parsing.
3058 static void LIBXML_ATTR_FORMAT(6,0)
3059 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt
,
3060 xmlParserErrors error
,
3062 xmlSchemaBasicItemPtr ownerItem
,
3063 const xmlSchemaAttributeUsePtr attruse
,
3064 const char *message
,
3065 const xmlChar
*str1
, const xmlChar
*str2
,
3066 const xmlChar
*str3
,const xmlChar
*str4
)
3068 xmlChar
*str
= NULL
, *msg
= NULL
;
3070 xmlSchemaFormatItemForReport(&msg
, NULL
, ownerItem
, NULL
);
3071 msg
= xmlStrcat(msg
, BAD_CAST
", ");
3072 msg
= xmlStrcat(msg
,
3073 BAD_CAST
xmlSchemaFormatItemForReport(&str
, NULL
,
3074 WXS_BASIC_CAST attruse
, NULL
));
3076 msg
= xmlStrcat(msg
, BAD_CAST
": ");
3077 msg
= xmlStrcat(msg
, (const xmlChar
*) message
);
3078 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
3079 xmlSchemaErr4(ACTXT_CAST ctxt
, error
, node
,
3080 (const char *) msg
, str1
, str2
, str3
, str4
);
3085 * xmlSchemaPIllegalFacetAtomicErr:
3086 * @ctxt: the schema parser context
3087 * @error: the error code
3088 * @type: the schema type
3089 * @baseType: the base type of type
3090 * @facet: the illegal facet
3092 * Reports an illegal facet for atomic simple types.
3095 xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt
,
3096 xmlParserErrors error
,
3097 xmlSchemaTypePtr type
,
3098 xmlSchemaTypePtr baseType
,
3099 xmlSchemaFacetPtr facet
)
3101 xmlChar
*des
= NULL
, *strT
= NULL
;
3103 xmlSchemaFormatItemForReport(&des
, NULL
, WXS_BASIC_CAST type
, type
->node
);
3104 xmlSchemaPErrExt(ctxt
, type
->node
, error
, NULL
, NULL
, NULL
,
3105 "%s: The facet '%s' is not allowed on types derived from the "
3107 BAD_CAST des
, xmlSchemaFacetTypeToString(facet
->type
),
3108 xmlSchemaFormatItemForReport(&strT
, NULL
, WXS_BASIC_CAST baseType
, NULL
),
3111 FREE_AND_NULL(strT
);
3115 * xmlSchemaPIllegalFacetListUnionErr:
3116 * @ctxt: the schema parser context
3117 * @error: the error code
3118 * @itemDes: the designation of the schema item involved
3119 * @item: the schema item involved
3120 * @facet: the illegal facet
3122 * Reports an illegal facet for <list> and <union>.
3125 xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt
,
3126 xmlParserErrors error
,
3127 xmlSchemaTypePtr type
,
3128 xmlSchemaFacetPtr facet
)
3130 xmlChar
*des
= NULL
;
3132 xmlSchemaFormatItemForReport(&des
, NULL
, WXS_BASIC_CAST type
,
3134 xmlSchemaPErr(ctxt
, type
->node
, error
,
3135 "%s: The facet '%s' is not allowed.\n",
3136 BAD_CAST des
, xmlSchemaFacetTypeToString(facet
->type
));
3141 * xmlSchemaPMutualExclAttrErr:
3142 * @ctxt: the schema validation context
3143 * @error: the error code
3144 * @elemDes: the designation of the parent element node
3145 * @attr: the bad attribute node
3146 * @type: the corresponding type of the attribute node
3148 * Reports an illegal attribute.
3151 xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt
,
3152 xmlParserErrors error
,
3153 xmlSchemaBasicItemPtr ownerItem
,
3158 xmlChar
*des
= NULL
;
3160 xmlSchemaFormatItemForReport(&des
, NULL
, WXS_BASIC_CAST ownerItem
, attr
->parent
);
3161 xmlSchemaPErrExt(ctxt
, (xmlNodePtr
) attr
, error
, NULL
, NULL
, NULL
,
3162 "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
3163 BAD_CAST des
, BAD_CAST name1
, BAD_CAST name2
, NULL
, NULL
);
3168 * xmlSchemaPSimpleTypeErr:
3169 * @ctxt: the schema validation context
3170 * @error: the error code
3171 * @type: the type specifier
3172 * @ownerItem: the schema object if existent
3173 * @node: the validated node
3174 * @value: the validated value
3176 * Reports a simple type validation error.
3177 * TODO: Should this report the value of an element as well?
3179 static void LIBXML_ATTR_FORMAT(8,0)
3180 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt
,
3181 xmlParserErrors error
,
3182 xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED
,
3184 xmlSchemaTypePtr type
,
3185 const char *expected
,
3186 const xmlChar
*value
,
3187 const char *message
,
3188 const xmlChar
*str1
,
3189 const xmlChar
*str2
)
3191 xmlChar
*msg
= NULL
;
3193 xmlSchemaFormatNodeForError(&msg
, ACTXT_CAST ctxt
, node
);
3194 if (message
== NULL
) {
3196 * Use default messages.
3199 if (node
->type
== XML_ATTRIBUTE_NODE
)
3200 msg
= xmlStrcat(msg
, BAD_CAST
"'%s' is not a valid value of ");
3202 msg
= xmlStrcat(msg
, BAD_CAST
"The character content is not a "
3204 if (! xmlSchemaIsGlobalItem(type
))
3205 msg
= xmlStrcat(msg
, BAD_CAST
"the local ");
3207 msg
= xmlStrcat(msg
, BAD_CAST
"the ");
3209 if (WXS_IS_ATOMIC(type
))
3210 msg
= xmlStrcat(msg
, BAD_CAST
"atomic type");
3211 else if (WXS_IS_LIST(type
))
3212 msg
= xmlStrcat(msg
, BAD_CAST
"list type");
3213 else if (WXS_IS_UNION(type
))
3214 msg
= xmlStrcat(msg
, BAD_CAST
"union type");
3216 if (xmlSchemaIsGlobalItem(type
)) {
3217 xmlChar
*str
= NULL
;
3218 msg
= xmlStrcat(msg
, BAD_CAST
" '");
3219 if (type
->builtInType
!= 0) {
3220 msg
= xmlStrcat(msg
, BAD_CAST
"xs:");
3221 str
= xmlStrdup(type
->name
);
3223 const xmlChar
*qName
= xmlSchemaFormatQName(&str
, type
->targetNamespace
, type
->name
);
3225 str
= xmlStrdup(qName
);
3227 msg
= xmlStrcat(msg
, xmlEscapeFormatString(&str
));
3228 msg
= xmlStrcat(msg
, BAD_CAST
"'.");
3232 if (node
->type
== XML_ATTRIBUTE_NODE
)
3233 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' is not valid.");
3235 msg
= xmlStrcat(msg
, BAD_CAST
"The character content is not "
3239 xmlChar
*expectedEscaped
= xmlCharStrdup(expected
);
3240 msg
= xmlStrcat(msg
, BAD_CAST
" Expected is '");
3241 msg
= xmlStrcat(msg
, xmlEscapeFormatString(&expectedEscaped
));
3242 FREE_AND_NULL(expectedEscaped
);
3243 msg
= xmlStrcat(msg
, BAD_CAST
"'.\n");
3245 msg
= xmlStrcat(msg
, BAD_CAST
"\n");
3246 if (node
->type
== XML_ATTRIBUTE_NODE
)
3247 xmlSchemaPErr(ctxt
, node
, error
, (const char *) msg
, value
, NULL
);
3249 xmlSchemaPErr(ctxt
, node
, error
, (const char *) msg
, NULL
, NULL
);
3251 msg
= xmlStrcat(msg
, BAD_CAST message
);
3252 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
3253 xmlSchemaPErrExt(ctxt
, node
, error
, NULL
, NULL
, NULL
,
3254 (const char*) msg
, str1
, str2
, NULL
, NULL
, NULL
);
3261 * xmlSchemaPContentErr:
3262 * @ctxt: the schema parser context
3263 * @error: the error code
3264 * @ownerItem: the owner item of the holder of the content
3265 * @ownerElem: the node of the holder of the content
3266 * @child: the invalid child node
3267 * @message: the optional error message
3268 * @content: the optional string describing the correct content
3270 * Reports an error concerning the content of a schema element.
3273 xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt
,
3274 xmlParserErrors error
,
3275 xmlSchemaBasicItemPtr ownerItem
,
3276 xmlNodePtr ownerElem
,
3278 const char *message
,
3279 const char *content
)
3281 xmlChar
*des
= NULL
;
3283 xmlSchemaFormatItemForReport(&des
, NULL
, ownerItem
, ownerElem
);
3284 if (message
!= NULL
)
3285 xmlSchemaPErr2(ctxt
, ownerElem
, child
, error
,
3287 BAD_CAST des
, BAD_CAST message
);
3289 if (content
!= NULL
) {
3290 xmlSchemaPErr2(ctxt
, ownerElem
, child
, error
,
3291 "%s: The content is not valid. Expected is %s.\n",
3292 BAD_CAST des
, BAD_CAST content
);
3294 xmlSchemaPErr2(ctxt
, ownerElem
, child
, error
,
3295 "%s: The content is not valid.\n",
3296 BAD_CAST des
, NULL
);
3302 /************************************************************************
3304 * Streamable error functions *
3306 ************************************************************************/
3311 /************************************************************************
3313 * Validation helper functions *
3315 ************************************************************************/
3318 /************************************************************************
3320 * Allocation functions *
3322 ************************************************************************/
3325 * xmlSchemaNewSchemaForParserCtxt:
3326 * @ctxt: a schema validation context
3328 * Allocate a new Schema structure.
3330 * Returns the newly allocated structure or NULL in case or error
3333 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt
)
3337 ret
= (xmlSchemaPtr
) xmlMalloc(sizeof(xmlSchema
));
3339 xmlSchemaPErrMemory(ctxt
, "allocating schema", NULL
);
3342 memset(ret
, 0, sizeof(xmlSchema
));
3343 ret
->dict
= ctxt
->dict
;
3344 xmlDictReference(ret
->dict
);
3350 * xmlSchemaNewFacet:
3352 * Allocate a new Facet structure.
3354 * Returns the newly allocated structure or NULL in case or error
3357 xmlSchemaNewFacet(void)
3359 xmlSchemaFacetPtr ret
;
3361 ret
= (xmlSchemaFacetPtr
) xmlMalloc(sizeof(xmlSchemaFacet
));
3365 memset(ret
, 0, sizeof(xmlSchemaFacet
));
3371 * xmlSchemaNewAnnot:
3372 * @ctxt: a schema validation context
3375 * Allocate a new annotation structure.
3377 * Returns the newly allocated structure or NULL in case or error
3379 static xmlSchemaAnnotPtr
3380 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
)
3382 xmlSchemaAnnotPtr ret
;
3384 ret
= (xmlSchemaAnnotPtr
) xmlMalloc(sizeof(xmlSchemaAnnot
));
3386 xmlSchemaPErrMemory(ctxt
, "allocating annotation", node
);
3389 memset(ret
, 0, sizeof(xmlSchemaAnnot
));
3390 ret
->content
= node
;
3394 static xmlSchemaItemListPtr
3395 xmlSchemaItemListCreate(void)
3397 xmlSchemaItemListPtr ret
;
3399 ret
= xmlMalloc(sizeof(xmlSchemaItemList
));
3401 xmlSchemaPErrMemory(NULL
,
3402 "allocating an item list structure", NULL
);
3405 memset(ret
, 0, sizeof(xmlSchemaItemList
));
3410 xmlSchemaItemListClear(xmlSchemaItemListPtr list
)
3412 if (list
->items
!= NULL
) {
3413 xmlFree(list
->items
);
3417 list
->sizeItems
= 0;
3421 xmlSchemaItemListAdd(xmlSchemaItemListPtr list
, void *item
)
3423 if (list
->sizeItems
<= list
->nbItems
) {
3425 size_t newSize
= list
->sizeItems
== 0 ? 20 : list
->sizeItems
* 2;
3427 tmp
= (void **) xmlRealloc(list
->items
, newSize
* sizeof(void *));
3429 xmlSchemaPErrMemory(NULL
, "growing item list", NULL
);
3433 list
->sizeItems
= newSize
;
3435 list
->items
[list
->nbItems
++] = item
;
3440 xmlSchemaItemListAddSize(xmlSchemaItemListPtr list
,
3444 if (list
->items
== NULL
) {
3445 if (initialSize
<= 0)
3447 list
->items
= (void **) xmlMalloc(
3448 initialSize
* sizeof(void *));
3449 if (list
->items
== NULL
) {
3450 xmlSchemaPErrMemory(NULL
, "allocating new item list", NULL
);
3453 list
->sizeItems
= initialSize
;
3454 } else if (list
->sizeItems
<= list
->nbItems
) {
3457 list
->sizeItems
*= 2;
3458 tmp
= (void **) xmlRealloc(list
->items
,
3459 list
->sizeItems
* sizeof(void *));
3461 xmlSchemaPErrMemory(NULL
, "growing item list", NULL
);
3462 list
->sizeItems
/= 2;
3467 list
->items
[list
->nbItems
++] = item
;
3472 xmlSchemaItemListInsert(xmlSchemaItemListPtr list
, void *item
, int idx
)
3474 if (list
->sizeItems
<= list
->nbItems
) {
3476 size_t newSize
= list
->sizeItems
== 0 ? 20 : list
->sizeItems
* 2;
3478 tmp
= (void **) xmlRealloc(list
->items
, newSize
* sizeof(void *));
3480 xmlSchemaPErrMemory(NULL
, "growing item list", NULL
);
3484 list
->sizeItems
= newSize
;
3487 * Just append if the index is greater/equal than the item count.
3489 if (idx
>= list
->nbItems
) {
3490 list
->items
[list
->nbItems
++] = item
;
3493 for (i
= list
->nbItems
; i
> idx
; i
--)
3494 list
->items
[i
] = list
->items
[i
-1];
3495 list
->items
[idx
] = item
;
3501 #if 0 /* enable if ever needed */
3503 xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list
,
3508 if (list
->items
== NULL
) {
3509 if (initialSize
<= 0)
3511 list
->items
= (void **) xmlMalloc(
3512 initialSize
* sizeof(void *));
3513 if (list
->items
== NULL
) {
3514 xmlSchemaPErrMemory(NULL
, "allocating new item list", NULL
);
3517 list
->sizeItems
= initialSize
;
3518 } else if (list
->sizeItems
<= list
->nbItems
) {
3519 list
->sizeItems
*= 2;
3520 list
->items
= (void **) xmlRealloc(list
->items
,
3521 list
->sizeItems
* sizeof(void *));
3522 if (list
->items
== NULL
) {
3523 xmlSchemaPErrMemory(NULL
, "growing item list", NULL
);
3524 list
->sizeItems
= 0;
3529 * Just append if the index is greater/equal than the item count.
3531 if (idx
>= list
->nbItems
) {
3532 list
->items
[list
->nbItems
++] = item
;
3535 for (i
= list
->nbItems
; i
> idx
; i
--)
3536 list
->items
[i
] = list
->items
[i
-1];
3537 list
->items
[idx
] = item
;
3545 xmlSchemaItemListRemove(xmlSchemaItemListPtr list
, int idx
)
3548 if ((list
->items
== NULL
) || (idx
>= list
->nbItems
)) {
3549 xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
3554 if (list
->nbItems
== 1) {
3555 /* TODO: Really free the list? */
3556 xmlFree(list
->items
);
3559 list
->sizeItems
= 0;
3560 } else if (list
->nbItems
-1 == idx
) {
3563 for (i
= idx
; i
< list
->nbItems
-1; i
++)
3564 list
->items
[i
] = list
->items
[i
+1];
3571 * xmlSchemaItemListFree:
3572 * @annot: a schema type structure
3574 * Deallocate a annotation structure
3577 xmlSchemaItemListFree(xmlSchemaItemListPtr list
)
3581 if (list
->items
!= NULL
)
3582 xmlFree(list
->items
);
3587 xmlSchemaBucketFree(xmlSchemaBucketPtr bucket
)
3591 if (bucket
->globals
!= NULL
) {
3592 xmlSchemaComponentListFree(bucket
->globals
);
3593 xmlSchemaItemListFree(bucket
->globals
);
3595 if (bucket
->locals
!= NULL
) {
3596 xmlSchemaComponentListFree(bucket
->locals
);
3597 xmlSchemaItemListFree(bucket
->locals
);
3599 if (bucket
->relations
!= NULL
) {
3600 xmlSchemaSchemaRelationPtr prev
, cur
= bucket
->relations
;
3605 } while (cur
!= NULL
);
3607 if ((! bucket
->preserveDoc
) && (bucket
->doc
!= NULL
)) {
3608 xmlFreeDoc(bucket
->doc
);
3610 if (bucket
->type
== XML_SCHEMA_SCHEMA_IMPORT
) {
3611 if (WXS_IMPBUCKET(bucket
)->schema
!= NULL
)
3612 xmlSchemaFree(WXS_IMPBUCKET(bucket
)->schema
);
3618 xmlSchemaBucketFreeEntry(void *bucket
, const xmlChar
*name ATTRIBUTE_UNUSED
)
3620 xmlSchemaBucketFree((xmlSchemaBucketPtr
) bucket
);
3623 static xmlSchemaBucketPtr
3624 xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt
,
3625 int type
, const xmlChar
*targetNamespace
)
3627 xmlSchemaBucketPtr ret
;
3629 xmlSchemaPtr mainSchema
;
3631 if (WXS_CONSTRUCTOR(pctxt
)->mainSchema
== NULL
) {
3632 PERROR_INT("xmlSchemaBucketCreate",
3633 "no main schema on constructor");
3636 mainSchema
= WXS_CONSTRUCTOR(pctxt
)->mainSchema
;
3637 /* Create the schema bucket. */
3638 if (WXS_IS_BUCKET_INCREDEF(type
))
3639 size
= sizeof(xmlSchemaInclude
);
3641 size
= sizeof(xmlSchemaImport
);
3642 ret
= (xmlSchemaBucketPtr
) xmlMalloc(size
);
3644 xmlSchemaPErrMemory(NULL
, "allocating schema bucket", NULL
);
3647 memset(ret
, 0, size
);
3648 ret
->targetNamespace
= targetNamespace
;
3650 ret
->globals
= xmlSchemaItemListCreate();
3651 if (ret
->globals
== NULL
) {
3652 xmlSchemaBucketFree(ret
);
3655 ret
->locals
= xmlSchemaItemListCreate();
3656 if (ret
->locals
== NULL
) {
3657 xmlSchemaBucketFree(ret
);
3661 * The following will assure that only the first bucket is marked as
3662 * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
3663 * For each following import buckets an xmlSchema will be created.
3664 * An xmlSchema will be created for every distinct targetNamespace.
3665 * We assign the targetNamespace to the schemata here.
3667 if (! WXS_HAS_BUCKETS(pctxt
)) {
3668 if (WXS_IS_BUCKET_INCREDEF(type
)) {
3669 PERROR_INT("xmlSchemaBucketCreate",
3670 "first bucket but it's an include or redefine");
3671 xmlSchemaBucketFree(ret
);
3674 /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
3675 ret
->type
= XML_SCHEMA_SCHEMA_MAIN
;
3676 /* Point to the *main* schema. */
3677 WXS_CONSTRUCTOR(pctxt
)->mainBucket
= ret
;
3678 WXS_IMPBUCKET(ret
)->schema
= mainSchema
;
3680 * Ensure that the main schema gets a targetNamespace.
3682 mainSchema
->targetNamespace
= targetNamespace
;
3684 if (type
== XML_SCHEMA_SCHEMA_MAIN
) {
3685 PERROR_INT("xmlSchemaBucketCreate",
3686 "main bucket but it's not the first one");
3687 xmlSchemaBucketFree(ret
);
3689 } else if (type
== XML_SCHEMA_SCHEMA_IMPORT
) {
3691 * Create a schema for imports and assign the
3694 WXS_IMPBUCKET(ret
)->schema
= xmlSchemaNewSchema(pctxt
);
3695 if (WXS_IMPBUCKET(ret
)->schema
== NULL
) {
3696 xmlSchemaBucketFree(ret
);
3699 WXS_IMPBUCKET(ret
)->schema
->targetNamespace
= targetNamespace
;
3702 if (WXS_IS_BUCKET_IMPMAIN(type
)) {
3705 * Imports go into the "schemasImports" slot of the main *schema*.
3706 * Note that we create an import entry for the main schema as well; i.e.,
3707 * even if there's only one schema, we'll get an import.
3709 if (mainSchema
->schemasImports
== NULL
) {
3710 mainSchema
->schemasImports
= xmlHashCreateDict(5,
3711 WXS_CONSTRUCTOR(pctxt
)->dict
);
3712 if (mainSchema
->schemasImports
== NULL
) {
3713 xmlSchemaBucketFree(ret
);
3717 if (targetNamespace
== NULL
)
3718 res
= xmlHashAddEntry(mainSchema
->schemasImports
,
3719 XML_SCHEMAS_NO_NAMESPACE
, ret
);
3721 res
= xmlHashAddEntry(mainSchema
->schemasImports
,
3722 targetNamespace
, ret
);
3724 PERROR_INT("xmlSchemaBucketCreate",
3725 "failed to add the schema bucket to the hash");
3726 xmlSchemaBucketFree(ret
);
3730 /* Set the @ownerImport of an include bucket. */
3731 if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt
)->bucket
->type
))
3732 WXS_INCBUCKET(ret
)->ownerImport
=
3733 WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt
)->bucket
);
3735 WXS_INCBUCKET(ret
)->ownerImport
=
3736 WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt
)->bucket
)->ownerImport
;
3738 /* Includes got into the "includes" slot of the *main* schema. */
3739 if (mainSchema
->includes
== NULL
) {
3740 mainSchema
->includes
= xmlSchemaItemListCreate();
3741 if (mainSchema
->includes
== NULL
) {
3742 xmlSchemaBucketFree(ret
);
3746 if (xmlSchemaItemListAdd(mainSchema
->includes
, ret
) < 0) {
3747 xmlSchemaBucketFree(ret
);
3752 * Add to list of all buckets; this is used for lookup
3753 * during schema construction time only.
3755 if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt
)->buckets
, ret
) == -1)
3761 xmlSchemaAddItemSize(xmlSchemaItemListPtr
*list
, int initialSize
, void *item
)
3763 if (*list
== NULL
) {
3764 *list
= xmlSchemaItemListCreate();
3768 return(xmlSchemaItemListAddSize(*list
, initialSize
, item
));
3772 * xmlSchemaFreeAnnot:
3773 * @annot: a schema type structure
3775 * Deallocate a annotation structure
3778 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot
)
3782 if (annot
->next
== NULL
) {
3785 xmlSchemaAnnotPtr prev
;
3789 annot
= annot
->next
;
3791 } while (annot
!= NULL
);
3796 * xmlSchemaFreeNotation:
3797 * @schema: a schema notation structure
3799 * Deallocate a Schema Notation structure.
3802 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota
)
3810 * xmlSchemaFreeAttribute:
3811 * @attr: an attribute declaration
3813 * Deallocates an attribute declaration structure.
3816 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr
)
3820 if (attr
->annot
!= NULL
)
3821 xmlSchemaFreeAnnot(attr
->annot
);
3822 if (attr
->defVal
!= NULL
)
3823 xmlSchemaFreeValue(attr
->defVal
);
3828 * xmlSchemaFreeAttributeUse:
3829 * @use: an attribute use
3831 * Deallocates an attribute use structure.
3834 xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use
)
3838 if (use
->annot
!= NULL
)
3839 xmlSchemaFreeAnnot(use
->annot
);
3840 if (use
->defVal
!= NULL
)
3841 xmlSchemaFreeValue(use
->defVal
);
3846 * xmlSchemaFreeAttributeUseProhib:
3847 * @prohib: an attribute use prohibition
3849 * Deallocates an attribute use structure.
3852 xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib
)
3860 * xmlSchemaFreeWildcardNsSet:
3861 * set: a schema wildcard namespace
3863 * Deallocates a list of wildcard constraint structures.
3866 xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set
)
3868 xmlSchemaWildcardNsPtr next
;
3870 while (set
!= NULL
) {
3878 * xmlSchemaFreeWildcard:
3879 * @wildcard: a wildcard structure
3881 * Deallocates a wildcard structure.
3884 xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard
)
3886 if (wildcard
== NULL
)
3888 if (wildcard
->annot
!= NULL
)
3889 xmlSchemaFreeAnnot(wildcard
->annot
);
3890 if (wildcard
->nsSet
!= NULL
)
3891 xmlSchemaFreeWildcardNsSet(wildcard
->nsSet
);
3892 if (wildcard
->negNsSet
!= NULL
)
3893 xmlFree(wildcard
->negNsSet
);
3898 * xmlSchemaFreeAttributeGroup:
3899 * @schema: a schema attribute group structure
3901 * Deallocate a Schema Attribute Group structure.
3904 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr
)
3908 if (attrGr
->annot
!= NULL
)
3909 xmlSchemaFreeAnnot(attrGr
->annot
);
3910 if (attrGr
->attrUses
!= NULL
)
3911 xmlSchemaItemListFree(WXS_LIST_CAST attrGr
->attrUses
);
3916 * xmlSchemaFreeQNameRef:
3917 * @item: a QName reference structure
3919 * Deallocatea a QName reference structure.
3922 xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item
)
3928 * xmlSchemaFreeTypeLinkList:
3929 * @alink: a type link
3931 * Deallocate a list of types.
3934 xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link
)
3936 xmlSchemaTypeLinkPtr next
;
3938 while (link
!= NULL
) {
3946 xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto
)
3948 xmlSchemaIDCStateObjPtr next
;
3949 while (sto
!= NULL
) {
3951 if (sto
->history
!= NULL
)
3952 xmlFree(sto
->history
);
3953 if (sto
->xpathCtxt
!= NULL
)
3954 xmlFreeStreamCtxt((xmlStreamCtxtPtr
) sto
->xpathCtxt
);
3962 * @idc: a identity-constraint definition
3964 * Deallocates an identity-constraint definition.
3967 xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef
)
3969 xmlSchemaIDCSelectPtr cur
, prev
;
3973 if (idcDef
->annot
!= NULL
)
3974 xmlSchemaFreeAnnot(idcDef
->annot
);
3976 if (idcDef
->selector
!= NULL
) {
3977 if (idcDef
->selector
->xpathComp
!= NULL
)
3978 xmlFreePattern((xmlPatternPtr
) idcDef
->selector
->xpathComp
);
3979 xmlFree(idcDef
->selector
);
3982 if (idcDef
->fields
!= NULL
) {
3983 cur
= idcDef
->fields
;
3987 if (prev
->xpathComp
!= NULL
)
3988 xmlFreePattern((xmlPatternPtr
) prev
->xpathComp
);
3990 } while (cur
!= NULL
);
3996 * xmlSchemaFreeElement:
3997 * @schema: a schema element structure
3999 * Deallocate a Schema Element structure.
4002 xmlSchemaFreeElement(xmlSchemaElementPtr elem
)
4006 if (elem
->annot
!= NULL
)
4007 xmlSchemaFreeAnnot(elem
->annot
);
4008 if (elem
->contModel
!= NULL
)
4009 xmlRegFreeRegexp(elem
->contModel
);
4010 if (elem
->defVal
!= NULL
)
4011 xmlSchemaFreeValue(elem
->defVal
);
4016 * xmlSchemaFreeFacet:
4017 * @facet: a schema facet structure
4019 * Deallocate a Schema Facet structure.
4022 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet
)
4026 if (facet
->val
!= NULL
)
4027 xmlSchemaFreeValue(facet
->val
);
4028 if (facet
->regexp
!= NULL
)
4029 xmlRegFreeRegexp(facet
->regexp
);
4030 if (facet
->annot
!= NULL
)
4031 xmlSchemaFreeAnnot(facet
->annot
);
4036 * xmlSchemaFreeType:
4037 * @type: a schema type structure
4039 * Deallocate a Schema Type structure.
4042 xmlSchemaFreeType(xmlSchemaTypePtr type
)
4046 if (type
->annot
!= NULL
)
4047 xmlSchemaFreeAnnot(type
->annot
);
4048 if (type
->facets
!= NULL
) {
4049 xmlSchemaFacetPtr facet
, next
;
4051 facet
= type
->facets
;
4052 while (facet
!= NULL
) {
4054 xmlSchemaFreeFacet(facet
);
4058 if (type
->attrUses
!= NULL
)
4059 xmlSchemaItemListFree((xmlSchemaItemListPtr
) type
->attrUses
);
4060 if (type
->memberTypes
!= NULL
)
4061 xmlSchemaFreeTypeLinkList(type
->memberTypes
);
4062 if (type
->facetSet
!= NULL
) {
4063 xmlSchemaFacetLinkPtr next
, link
;
4065 link
= type
->facetSet
;
4070 } while (link
!= NULL
);
4072 if (type
->contModel
!= NULL
)
4073 xmlRegFreeRegexp(type
->contModel
);
4078 * xmlSchemaFreeModelGroupDef:
4079 * @item: a schema model group definition
4081 * Deallocates a schema model group definition.
4084 xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item
)
4086 if (item
->annot
!= NULL
)
4087 xmlSchemaFreeAnnot(item
->annot
);
4092 * xmlSchemaFreeModelGroup:
4093 * @item: a schema model group
4095 * Deallocates a schema model group structure.
4098 xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item
)
4100 if (item
->annot
!= NULL
)
4101 xmlSchemaFreeAnnot(item
->annot
);
4106 xmlSchemaComponentListFree(xmlSchemaItemListPtr list
)
4108 if ((list
== NULL
) || (list
->nbItems
== 0))
4111 xmlSchemaTreeItemPtr item
;
4112 xmlSchemaTreeItemPtr
*items
= (xmlSchemaTreeItemPtr
*) list
->items
;
4115 for (i
= 0; i
< list
->nbItems
; i
++) {
4119 switch (item
->type
) {
4120 case XML_SCHEMA_TYPE_SIMPLE
:
4121 case XML_SCHEMA_TYPE_COMPLEX
:
4122 xmlSchemaFreeType((xmlSchemaTypePtr
) item
);
4124 case XML_SCHEMA_TYPE_ATTRIBUTE
:
4125 xmlSchemaFreeAttribute((xmlSchemaAttributePtr
) item
);
4127 case XML_SCHEMA_TYPE_ATTRIBUTE_USE
:
4128 xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr
) item
);
4130 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB
:
4131 xmlSchemaFreeAttributeUseProhib(
4132 (xmlSchemaAttributeUseProhibPtr
) item
);
4134 case XML_SCHEMA_TYPE_ELEMENT
:
4135 xmlSchemaFreeElement((xmlSchemaElementPtr
) item
);
4137 case XML_SCHEMA_TYPE_PARTICLE
:
4138 if (item
->annot
!= NULL
)
4139 xmlSchemaFreeAnnot(item
->annot
);
4142 case XML_SCHEMA_TYPE_SEQUENCE
:
4143 case XML_SCHEMA_TYPE_CHOICE
:
4144 case XML_SCHEMA_TYPE_ALL
:
4145 xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr
) item
);
4147 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
4148 xmlSchemaFreeAttributeGroup(
4149 (xmlSchemaAttributeGroupPtr
) item
);
4151 case XML_SCHEMA_TYPE_GROUP
:
4152 xmlSchemaFreeModelGroupDef(
4153 (xmlSchemaModelGroupDefPtr
) item
);
4155 case XML_SCHEMA_TYPE_ANY
:
4156 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE
:
4157 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr
) item
);
4159 case XML_SCHEMA_TYPE_IDC_KEY
:
4160 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
4161 case XML_SCHEMA_TYPE_IDC_KEYREF
:
4162 xmlSchemaFreeIDC((xmlSchemaIDCPtr
) item
);
4164 case XML_SCHEMA_TYPE_NOTATION
:
4165 xmlSchemaFreeNotation((xmlSchemaNotationPtr
) item
);
4167 case XML_SCHEMA_EXTRA_QNAMEREF
:
4168 xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr
) item
);
4171 /* TODO: This should never be hit. */
4172 xmlSchemaPSimpleInternalErr(NULL
,
4173 "Internal error: xmlSchemaComponentListFree, "
4174 "unexpected component type '%s'\n",
4175 (const xmlChar
*) WXS_ITEM_TYPE_NAME(item
));
4186 * @schema: a schema structure
4188 * Deallocate a Schema structure.
4191 xmlSchemaFree(xmlSchemaPtr schema
)
4195 /* @volatiles is not used anymore :-/ */
4196 if (schema
->volatiles
!= NULL
)
4199 * Note that those slots are not responsible for freeing
4200 * schema components anymore; this will now be done by
4201 * the schema buckets.
4203 if (schema
->notaDecl
!= NULL
)
4204 xmlHashFree(schema
->notaDecl
, NULL
);
4205 if (schema
->attrDecl
!= NULL
)
4206 xmlHashFree(schema
->attrDecl
, NULL
);
4207 if (schema
->attrgrpDecl
!= NULL
)
4208 xmlHashFree(schema
->attrgrpDecl
, NULL
);
4209 if (schema
->elemDecl
!= NULL
)
4210 xmlHashFree(schema
->elemDecl
, NULL
);
4211 if (schema
->typeDecl
!= NULL
)
4212 xmlHashFree(schema
->typeDecl
, NULL
);
4213 if (schema
->groupDecl
!= NULL
)
4214 xmlHashFree(schema
->groupDecl
, NULL
);
4215 if (schema
->idcDef
!= NULL
)
4216 xmlHashFree(schema
->idcDef
, NULL
);
4218 if (schema
->schemasImports
!= NULL
)
4219 xmlHashFree(schema
->schemasImports
, xmlSchemaBucketFreeEntry
);
4220 if (schema
->includes
!= NULL
) {
4221 xmlSchemaItemListPtr list
= (xmlSchemaItemListPtr
) schema
->includes
;
4223 for (i
= 0; i
< list
->nbItems
; i
++) {
4224 xmlSchemaBucketFree((xmlSchemaBucketPtr
) list
->items
[i
]);
4226 xmlSchemaItemListFree(list
);
4228 if (schema
->annot
!= NULL
)
4229 xmlSchemaFreeAnnot(schema
->annot
);
4230 /* Never free the doc here, since this will be done by the buckets. */
4232 xmlDictFree(schema
->dict
);
4236 /************************************************************************
4240 ************************************************************************/
4242 #ifdef LIBXML_OUTPUT_ENABLED
4245 xmlSchemaTypeDump(xmlSchemaTypePtr type
, FILE * output
); /* forward */
4248 * xmlSchemaElementDump:
4250 * @output: the file output
4255 xmlSchemaElementDump(void *payload
, void *data
,
4256 const xmlChar
* name ATTRIBUTE_UNUSED
,
4257 const xmlChar
* namespace ATTRIBUTE_UNUSED
,
4258 const xmlChar
* context ATTRIBUTE_UNUSED
)
4260 xmlSchemaElementPtr elem
= (xmlSchemaElementPtr
) payload
;
4261 FILE *output
= (FILE *) data
;
4266 fprintf(output
, "Element");
4267 if (elem
->flags
& XML_SCHEMAS_ELEM_GLOBAL
)
4268 fprintf(output
, " (global)");
4269 fprintf(output
, ": '%s' ", elem
->name
);
4270 if (namespace != NULL
)
4271 fprintf(output
, "ns '%s'", namespace);
4272 fprintf(output
, "\n");
4274 if ((elem
->minOccurs
!= 1) || (elem
->maxOccurs
!= 1)) {
4275 fprintf(output
, " min %d ", elem
->minOccurs
);
4276 if (elem
->maxOccurs
>= UNBOUNDED
)
4277 fprintf(output
, "max: unbounded\n");
4278 else if (elem
->maxOccurs
!= 1)
4279 fprintf(output
, "max: %d\n", elem
->maxOccurs
);
4281 fprintf(output
, "\n");
4285 * Misc other properties.
4287 if ((elem
->flags
& XML_SCHEMAS_ELEM_NILLABLE
) ||
4288 (elem
->flags
& XML_SCHEMAS_ELEM_ABSTRACT
) ||
4289 (elem
->flags
& XML_SCHEMAS_ELEM_FIXED
) ||
4290 (elem
->flags
& XML_SCHEMAS_ELEM_DEFAULT
)) {
4291 fprintf(output
, " props: ");
4292 if (elem
->flags
& XML_SCHEMAS_ELEM_FIXED
)
4293 fprintf(output
, "[fixed] ");
4294 if (elem
->flags
& XML_SCHEMAS_ELEM_DEFAULT
)
4295 fprintf(output
, "[default] ");
4296 if (elem
->flags
& XML_SCHEMAS_ELEM_ABSTRACT
)
4297 fprintf(output
, "[abstract] ");
4298 if (elem
->flags
& XML_SCHEMAS_ELEM_NILLABLE
)
4299 fprintf(output
, "[nillable] ");
4300 fprintf(output
, "\n");
4303 * Default/fixed value.
4305 if (elem
->value
!= NULL
)
4306 fprintf(output
, " value: '%s'\n", elem
->value
);
4310 if (elem
->namedType
!= NULL
) {
4311 fprintf(output
, " type: '%s' ", elem
->namedType
);
4312 if (elem
->namedTypeNs
!= NULL
)
4313 fprintf(output
, "ns '%s'\n", elem
->namedTypeNs
);
4315 fprintf(output
, "\n");
4316 } else if (elem
->subtypes
!= NULL
) {
4320 xmlSchemaTypeDump(elem
->subtypes
, output
);
4323 * Substitution group.
4325 if (elem
->substGroup
!= NULL
) {
4326 fprintf(output
, " substitutionGroup: '%s' ", elem
->substGroup
);
4327 if (elem
->substGroupNs
!= NULL
)
4328 fprintf(output
, "ns '%s'\n", elem
->substGroupNs
);
4330 fprintf(output
, "\n");
4335 * xmlSchemaAnnotDump:
4336 * @output: the file output
4337 * @annot: a annotation
4339 * Dump the annotation
4342 xmlSchemaAnnotDump(FILE * output
, xmlSchemaAnnotPtr annot
)
4349 content
= xmlNodeGetContent(annot
->content
);
4350 if (content
!= NULL
) {
4351 fprintf(output
, " Annot: %s\n", content
);
4354 fprintf(output
, " Annot: empty\n");
4358 * xmlSchemaContentModelDump:
4359 * @particle: the schema particle
4360 * @output: the file output
4361 * @depth: the depth used for indentation
4363 * Dump a SchemaType structure
4366 xmlSchemaContentModelDump(xmlSchemaParticlePtr particle
, FILE * output
, int depth
)
4368 xmlChar
*str
= NULL
;
4369 xmlSchemaTreeItemPtr term
;
4373 if (particle
== NULL
)
4375 for (i
= 0;((i
< depth
) && (i
< 25));i
++)
4376 shift
[2 * i
] = shift
[2 * i
+ 1] = ' ';
4377 shift
[2 * i
] = shift
[2 * i
+ 1] = 0;
4378 fprintf(output
, "%s", shift
);
4379 if (particle
->children
== NULL
) {
4380 fprintf(output
, "MISSING particle term\n");
4383 term
= particle
->children
;
4385 fprintf(output
, "(NULL)");
4387 switch (term
->type
) {
4388 case XML_SCHEMA_TYPE_ELEMENT
:
4389 fprintf(output
, "ELEM '%s'", xmlSchemaFormatQName(&str
,
4390 ((xmlSchemaElementPtr
)term
)->targetNamespace
,
4391 ((xmlSchemaElementPtr
)term
)->name
));
4394 case XML_SCHEMA_TYPE_SEQUENCE
:
4395 fprintf(output
, "SEQUENCE");
4397 case XML_SCHEMA_TYPE_CHOICE
:
4398 fprintf(output
, "CHOICE");
4400 case XML_SCHEMA_TYPE_ALL
:
4401 fprintf(output
, "ALL");
4403 case XML_SCHEMA_TYPE_ANY
:
4404 fprintf(output
, "ANY");
4407 fprintf(output
, "UNKNOWN\n");
4411 if (particle
->minOccurs
!= 1)
4412 fprintf(output
, " min: %d", particle
->minOccurs
);
4413 if (particle
->maxOccurs
>= UNBOUNDED
)
4414 fprintf(output
, " max: unbounded");
4415 else if (particle
->maxOccurs
!= 1)
4416 fprintf(output
, " max: %d", particle
->maxOccurs
);
4417 fprintf(output
, "\n");
4419 ((term
->type
== XML_SCHEMA_TYPE_SEQUENCE
) ||
4420 (term
->type
== XML_SCHEMA_TYPE_CHOICE
) ||
4421 (term
->type
== XML_SCHEMA_TYPE_ALL
)) &&
4422 (term
->children
!= NULL
)) {
4423 xmlSchemaContentModelDump((xmlSchemaParticlePtr
) term
->children
,
4426 if (particle
->next
!= NULL
)
4427 xmlSchemaContentModelDump((xmlSchemaParticlePtr
) particle
->next
,
4432 * xmlSchemaAttrUsesDump:
4433 * @uses: attribute uses list
4434 * @output: the file output
4436 * Dumps a list of attribute use components.
4439 xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses
, FILE * output
)
4441 xmlSchemaAttributeUsePtr use
;
4442 xmlSchemaAttributeUseProhibPtr prohib
;
4443 xmlSchemaQNameRefPtr ref
;
4444 const xmlChar
*name
, *tns
;
4445 xmlChar
*str
= NULL
;
4448 if ((uses
== NULL
) || (uses
->nbItems
== 0))
4451 fprintf(output
, " attributes:\n");
4452 for (i
= 0; i
< uses
->nbItems
; i
++) {
4453 use
= uses
->items
[i
];
4454 if (use
->type
== XML_SCHEMA_EXTRA_ATTR_USE_PROHIB
) {
4455 fprintf(output
, " [prohibition] ");
4456 prohib
= (xmlSchemaAttributeUseProhibPtr
) use
;
4457 name
= prohib
->name
;
4458 tns
= prohib
->targetNamespace
;
4459 } else if (use
->type
== XML_SCHEMA_EXTRA_QNAMEREF
) {
4460 fprintf(output
, " [reference] ");
4461 ref
= (xmlSchemaQNameRefPtr
) use
;
4463 tns
= ref
->targetNamespace
;
4465 fprintf(output
, " [use] ");
4466 name
= WXS_ATTRUSE_DECL_NAME(use
);
4467 tns
= WXS_ATTRUSE_DECL_TNS(use
);
4469 fprintf(output
, "'%s'\n",
4470 (const char *) xmlSchemaFormatQName(&str
, tns
, name
));
4476 * xmlSchemaTypeDump:
4477 * @output: the file output
4478 * @type: a type structure
4480 * Dump a SchemaType structure
4483 xmlSchemaTypeDump(xmlSchemaTypePtr type
, FILE * output
)
4486 fprintf(output
, "Type: NULL\n");
4489 fprintf(output
, "Type: ");
4490 if (type
->name
!= NULL
)
4491 fprintf(output
, "'%s' ", type
->name
);
4493 fprintf(output
, "(no name) ");
4494 if (type
->targetNamespace
!= NULL
)
4495 fprintf(output
, "ns '%s' ", type
->targetNamespace
);
4496 switch (type
->type
) {
4497 case XML_SCHEMA_TYPE_BASIC
:
4498 fprintf(output
, "[basic] ");
4500 case XML_SCHEMA_TYPE_SIMPLE
:
4501 fprintf(output
, "[simple] ");
4503 case XML_SCHEMA_TYPE_COMPLEX
:
4504 fprintf(output
, "[complex] ");
4506 case XML_SCHEMA_TYPE_SEQUENCE
:
4507 fprintf(output
, "[sequence] ");
4509 case XML_SCHEMA_TYPE_CHOICE
:
4510 fprintf(output
, "[choice] ");
4512 case XML_SCHEMA_TYPE_ALL
:
4513 fprintf(output
, "[all] ");
4515 case XML_SCHEMA_TYPE_UR
:
4516 fprintf(output
, "[ur] ");
4518 case XML_SCHEMA_TYPE_RESTRICTION
:
4519 fprintf(output
, "[restriction] ");
4521 case XML_SCHEMA_TYPE_EXTENSION
:
4522 fprintf(output
, "[extension] ");
4525 fprintf(output
, "[unknown type %d] ", type
->type
);
4528 fprintf(output
, "content: ");
4529 switch (type
->contentType
) {
4530 case XML_SCHEMA_CONTENT_UNKNOWN
:
4531 fprintf(output
, "[unknown] ");
4533 case XML_SCHEMA_CONTENT_EMPTY
:
4534 fprintf(output
, "[empty] ");
4536 case XML_SCHEMA_CONTENT_ELEMENTS
:
4537 fprintf(output
, "[element] ");
4539 case XML_SCHEMA_CONTENT_MIXED
:
4540 fprintf(output
, "[mixed] ");
4542 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS
:
4545 case XML_SCHEMA_CONTENT_BASIC
:
4546 fprintf(output
, "[basic] ");
4548 case XML_SCHEMA_CONTENT_SIMPLE
:
4549 fprintf(output
, "[simple] ");
4551 case XML_SCHEMA_CONTENT_ANY
:
4552 fprintf(output
, "[any] ");
4555 fprintf(output
, "\n");
4556 if (type
->base
!= NULL
) {
4557 fprintf(output
, " base type: '%s'", type
->base
);
4558 if (type
->baseNs
!= NULL
)
4559 fprintf(output
, " ns '%s'\n", type
->baseNs
);
4561 fprintf(output
, "\n");
4563 if (type
->attrUses
!= NULL
)
4564 xmlSchemaAttrUsesDump(type
->attrUses
, output
);
4565 if (type
->annot
!= NULL
)
4566 xmlSchemaAnnotDump(output
, type
->annot
);
4567 #ifdef DUMP_CONTENT_MODEL
4568 if ((type
->type
== XML_SCHEMA_TYPE_COMPLEX
) &&
4569 (type
->subtypes
!= NULL
)) {
4570 xmlSchemaContentModelDump((xmlSchemaParticlePtr
) type
->subtypes
,
4577 xmlSchemaTypeDumpEntry(void *type
, void *output
,
4578 const xmlChar
*name ATTRIBUTE_UNUSED
)
4580 xmlSchemaTypeDump((xmlSchemaTypePtr
) type
, (FILE *) output
);
4585 * @output: the file output
4586 * @schema: a schema structure
4588 * Dump a Schema structure.
4591 xmlSchemaDump(FILE * output
, xmlSchemaPtr schema
)
4595 if (schema
== NULL
) {
4596 fprintf(output
, "Schemas: NULL\n");
4599 fprintf(output
, "Schemas: ");
4600 if (schema
->name
!= NULL
)
4601 fprintf(output
, "%s, ", schema
->name
);
4603 fprintf(output
, "no name, ");
4604 if (schema
->targetNamespace
!= NULL
)
4605 fprintf(output
, "%s", (const char *) schema
->targetNamespace
);
4607 fprintf(output
, "no target namespace");
4608 fprintf(output
, "\n");
4609 if (schema
->annot
!= NULL
)
4610 xmlSchemaAnnotDump(output
, schema
->annot
);
4611 xmlHashScan(schema
->typeDecl
, xmlSchemaTypeDumpEntry
, output
);
4612 xmlHashScanFull(schema
->elemDecl
, xmlSchemaElementDump
, output
);
4615 #ifdef DEBUG_IDC_NODE_TABLE
4617 * xmlSchemaDebugDumpIDCTable:
4618 * @vctxt: the WXS validation context
4620 * Displays the current IDC table for debug purposes.
4623 xmlSchemaDebugDumpIDCTable(FILE * output
,
4624 const xmlChar
*namespaceName
,
4625 const xmlChar
*localName
,
4626 xmlSchemaPSVIIDCBindingPtr bind
)
4628 xmlChar
*str
= NULL
;
4629 const xmlChar
*value
;
4630 xmlSchemaPSVIIDCNodePtr tab
;
4631 xmlSchemaPSVIIDCKeyPtr key
;
4634 fprintf(output
, "IDC: TABLES on '%s'\n",
4635 xmlSchemaFormatQName(&str
, namespaceName
, localName
));
4641 fprintf(output
, "IDC: BINDING '%s' (%d)\n",
4642 xmlSchemaGetComponentQName(&str
,
4643 bind
->definition
), bind
->nbNodes
);
4645 for (i
= 0; i
< bind
->nbNodes
; i
++) {
4646 tab
= bind
->nodeTable
[i
];
4647 fprintf(output
, " ( ");
4648 for (j
= 0; j
< bind
->definition
->nbFields
; j
++) {
4650 if ((key
!= NULL
) && (key
->val
!= NULL
)) {
4651 res
= xmlSchemaGetCanonValue(key
->val
, &value
);
4653 fprintf(output
, "'%s' ", value
);
4655 fprintf(output
, "CANON-VALUE-FAILED ");
4657 FREE_AND_NULL(value
)
4658 } else if (key
!= NULL
)
4659 fprintf(output
, "(no val), ");
4661 fprintf(output
, "(key missing), ");
4663 fprintf(output
, ")\n");
4665 if (bind
->dupls
&& bind
->dupls
->nbItems
) {
4666 fprintf(output
, "IDC: dupls (%d):\n", bind
->dupls
->nbItems
);
4667 for (i
= 0; i
< bind
->dupls
->nbItems
; i
++) {
4668 tab
= bind
->dupls
->items
[i
];
4669 fprintf(output
, " ( ");
4670 for (j
= 0; j
< bind
->definition
->nbFields
; j
++) {
4672 if ((key
!= NULL
) && (key
->val
!= NULL
)) {
4673 res
= xmlSchemaGetCanonValue(key
->val
, &value
);
4675 fprintf(output
, "'%s' ", value
);
4677 fprintf(output
, "CANON-VALUE-FAILED ");
4679 FREE_AND_NULL(value
)
4680 } else if (key
!= NULL
)
4681 fprintf(output
, "(no val), ");
4683 fprintf(output
, "(key missing), ");
4685 fprintf(output
, ")\n");
4689 } while (bind
!= NULL
);
4691 #endif /* DEBUG_IDC */
4692 #endif /* LIBXML_OUTPUT_ENABLED */
4694 /************************************************************************
4698 ************************************************************************/
4701 * xmlSchemaGetPropNode:
4702 * @node: the element node
4703 * @name: the name of the attribute
4705 * Seeks an attribute with a name of @name in
4708 * Returns the attribute or NULL if not present.
4711 xmlSchemaGetPropNode(xmlNodePtr node
, const char *name
)
4715 if ((node
== NULL
) || (name
== NULL
))
4717 prop
= node
->properties
;
4718 while (prop
!= NULL
) {
4719 if ((prop
->ns
== NULL
) && xmlStrEqual(prop
->name
, BAD_CAST name
))
4727 * xmlSchemaGetPropNodeNs:
4728 * @node: the element node
4730 * @name: the name of the attribute
4732 * Seeks an attribute with a local name of @name and
4733 * a namespace URI of @uri.
4735 * Returns the attribute or NULL if not present.
4738 xmlSchemaGetPropNodeNs(xmlNodePtr node
, const char *uri
, const char *name
)
4742 if ((node
== NULL
) || (name
== NULL
))
4744 prop
= node
->properties
;
4745 while (prop
!= NULL
) {
4746 if ((prop
->ns
!= NULL
) &&
4747 xmlStrEqual(prop
->name
, BAD_CAST name
) &&
4748 xmlStrEqual(prop
->ns
->href
, BAD_CAST uri
))
4755 static const xmlChar
*
4756 xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
)
4761 val
= xmlNodeGetContent(node
);
4763 val
= xmlStrdup((xmlChar
*)"");
4764 ret
= xmlDictLookup(ctxt
->dict
, val
, -1);
4767 xmlSchemaPErrMemory(ctxt
, "getting node content", node
);
4771 static const xmlChar
*
4772 xmlSchemaGetNodeContentNoDict(xmlNodePtr node
)
4774 return((const xmlChar
*) xmlNodeGetContent(node
));
4779 * @ctxt: the parser context
4781 * @name: the property name
4783 * Read a attribute value and internalize the string
4785 * Returns the string or NULL if not present.
4787 static const xmlChar
*
4788 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
,
4794 val
= xmlGetNoNsProp(node
, BAD_CAST name
);
4797 ret
= xmlDictLookup(ctxt
->dict
, val
, -1);
4802 /************************************************************************
4804 * Parsing functions *
4806 ************************************************************************/
4808 #define WXS_FIND_GLOBAL_ITEM(slot) \
4809 if (xmlStrEqual(nsName, schema->targetNamespace)) { \
4810 ret = xmlHashLookup(schema->slot, name); \
4811 if (ret != NULL) goto exit; \
4813 if (xmlHashSize(schema->schemasImports) > 1) { \
4814 xmlSchemaImportPtr import; \
4815 if (nsName == NULL) \
4816 import = xmlHashLookup(schema->schemasImports, \
4817 XML_SCHEMAS_NO_NAMESPACE); \
4819 import = xmlHashLookup(schema->schemasImports, nsName); \
4820 if (import == NULL) \
4822 ret = xmlHashLookup(import->schema->slot, name); \
4827 * @schema: the schema context
4828 * @name: the element name
4829 * @ns: the element namespace
4831 * Lookup a global element declaration in the schema.
4833 * Returns the element declaration or NULL if not found.
4835 static xmlSchemaElementPtr
4836 xmlSchemaGetElem(xmlSchemaPtr schema
, const xmlChar
* name
,
4837 const xmlChar
* nsName
)
4839 xmlSchemaElementPtr ret
= NULL
;
4841 if ((name
== NULL
) || (schema
== NULL
))
4843 if (schema
!= NULL
) {
4844 WXS_FIND_GLOBAL_ITEM(elemDecl
)
4850 fprintf(stderr
, "Unable to lookup element decl. %s", name
);
4852 fprintf(stderr
, "Unable to lookup element decl. %s:%s", name
,
4861 * @schema: the main schema
4862 * @name: the type's name
4863 * nsName: the type's namespace
4865 * Lookup a type in the schemas or the predefined types
4867 * Returns the group definition or NULL if not found.
4869 static xmlSchemaTypePtr
4870 xmlSchemaGetType(xmlSchemaPtr schema
, const xmlChar
* name
,
4871 const xmlChar
* nsName
)
4873 xmlSchemaTypePtr ret
= NULL
;
4877 /* First try the built-in types. */
4878 if ((nsName
!= NULL
) && xmlStrEqual(nsName
, xmlSchemaNs
)) {
4879 ret
= xmlSchemaGetPredefinedType(name
, nsName
);
4883 * Note that we try the parsed schemas as well here
4884 * since one might have parsed the S4S, which contain more
4885 * than the built-in types.
4886 * TODO: Can we optimize this?
4889 if (schema
!= NULL
) {
4890 WXS_FIND_GLOBAL_ITEM(typeDecl
)
4897 fprintf(stderr
, "Unable to lookup type %s", name
);
4899 fprintf(stderr
, "Unable to lookup type %s:%s", name
,
4907 * xmlSchemaGetAttributeDecl:
4908 * @schema: the context of the schema
4909 * @name: the name of the attribute
4910 * @ns: the target namespace of the attribute
4912 * Lookup a an attribute in the schema or imported schemas
4914 * Returns the attribute declaration or NULL if not found.
4916 static xmlSchemaAttributePtr
4917 xmlSchemaGetAttributeDecl(xmlSchemaPtr schema
, const xmlChar
* name
,
4918 const xmlChar
* nsName
)
4920 xmlSchemaAttributePtr ret
= NULL
;
4922 if ((name
== NULL
) || (schema
== NULL
))
4924 if (schema
!= NULL
) {
4925 WXS_FIND_GLOBAL_ITEM(attrDecl
)
4931 fprintf(stderr
, "Unable to lookup attribute %s", name
);
4933 fprintf(stderr
, "Unable to lookup attribute %s:%s", name
,
4941 * xmlSchemaGetAttributeGroup:
4942 * @schema: the context of the schema
4943 * @name: the name of the attribute group
4944 * @ns: the target namespace of the attribute group
4946 * Lookup a an attribute group in the schema or imported schemas
4948 * Returns the attribute group definition or NULL if not found.
4950 static xmlSchemaAttributeGroupPtr
4951 xmlSchemaGetAttributeGroup(xmlSchemaPtr schema
, const xmlChar
* name
,
4952 const xmlChar
* nsName
)
4954 xmlSchemaAttributeGroupPtr ret
= NULL
;
4956 if ((name
== NULL
) || (schema
== NULL
))
4958 if (schema
!= NULL
) {
4959 WXS_FIND_GLOBAL_ITEM(attrgrpDecl
)
4963 if ((ret != NULL) && (ret->redef != NULL)) {
4964 * Return the last redefinition. *
4971 fprintf(stderr
, "Unable to lookup attribute group %s", name
);
4973 fprintf(stderr
, "Unable to lookup attribute group %s:%s", name
,
4981 * xmlSchemaGetGroup:
4982 * @schema: the context of the schema
4983 * @name: the name of the group
4984 * @ns: the target namespace of the group
4986 * Lookup a group in the schema or imported schemas
4988 * Returns the group definition or NULL if not found.
4990 static xmlSchemaModelGroupDefPtr
4991 xmlSchemaGetGroup(xmlSchemaPtr schema
, const xmlChar
* name
,
4992 const xmlChar
* nsName
)
4994 xmlSchemaModelGroupDefPtr ret
= NULL
;
4996 if ((name
== NULL
) || (schema
== NULL
))
4998 if (schema
!= NULL
) {
4999 WXS_FIND_GLOBAL_ITEM(groupDecl
)
5006 fprintf(stderr
, "Unable to lookup group %s", name
);
5008 fprintf(stderr
, "Unable to lookup group %s:%s", name
,
5015 static xmlSchemaNotationPtr
5016 xmlSchemaGetNotation(xmlSchemaPtr schema
,
5017 const xmlChar
*name
,
5018 const xmlChar
*nsName
)
5020 xmlSchemaNotationPtr ret
= NULL
;
5022 if ((name
== NULL
) || (schema
== NULL
))
5024 if (schema
!= NULL
) {
5025 WXS_FIND_GLOBAL_ITEM(notaDecl
)
5031 static xmlSchemaIDCPtr
5032 xmlSchemaGetIDC(xmlSchemaPtr schema
,
5033 const xmlChar
*name
,
5034 const xmlChar
*nsName
)
5036 xmlSchemaIDCPtr ret
= NULL
;
5038 if ((name
== NULL
) || (schema
== NULL
))
5040 if (schema
!= NULL
) {
5041 WXS_FIND_GLOBAL_ITEM(idcDef
)
5048 * xmlSchemaGetNamedComponent:
5049 * @schema: the schema
5050 * @name: the name of the group
5051 * @ns: the target namespace of the group
5053 * Lookup a group in the schema or imported schemas
5055 * Returns the group definition or NULL if not found.
5057 static xmlSchemaBasicItemPtr
5058 xmlSchemaGetNamedComponent(xmlSchemaPtr schema
,
5059 xmlSchemaTypeType itemType
,
5060 const xmlChar
*name
,
5061 const xmlChar
*targetNs
)
5064 case XML_SCHEMA_TYPE_GROUP
:
5065 return ((xmlSchemaBasicItemPtr
) xmlSchemaGetGroup(schema
,
5067 case XML_SCHEMA_TYPE_ELEMENT
:
5068 return ((xmlSchemaBasicItemPtr
) xmlSchemaGetElem(schema
,
5076 /************************************************************************
5078 * Parsing functions *
5080 ************************************************************************/
5082 #define IS_BLANK_NODE(n) \
5083 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
5088 * @len: the length of the string or -1
5090 * Check if a string is ignorable
5092 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
5095 xmlSchemaIsBlank(xmlChar
* str
, int len
)
5101 if (!(IS_BLANK_CH(*str
)))
5105 } else while ((*str
!= 0) && (len
!= 0)) {
5106 if (!(IS_BLANK_CH(*str
)))
5115 #define WXS_COMP_NAME(c, t) ((t) (c))->name
5116 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
5118 * xmlSchemaFindRedefCompInGraph:
5119 * ATTENTION TODO: This uses pointer comp. for strings.
5121 static xmlSchemaBasicItemPtr
5122 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket
,
5123 xmlSchemaTypeType type
,
5124 const xmlChar
*name
,
5125 const xmlChar
*nsName
)
5127 xmlSchemaBasicItemPtr ret
;
5130 if ((bucket
== NULL
) || (name
== NULL
))
5132 if ((bucket
->globals
== NULL
) ||
5133 (bucket
->globals
->nbItems
== 0))
5136 * Search in global components.
5138 for (i
= 0; i
< bucket
->globals
->nbItems
; i
++) {
5139 ret
= bucket
->globals
->items
[i
];
5140 if (ret
->type
== type
) {
5142 case XML_SCHEMA_TYPE_COMPLEX
:
5143 case XML_SCHEMA_TYPE_SIMPLE
:
5144 if ((WXS_COMP_NAME(ret
, xmlSchemaTypePtr
) == name
) &&
5145 (WXS_COMP_TNS(ret
, xmlSchemaTypePtr
) ==
5151 case XML_SCHEMA_TYPE_GROUP
:
5152 if ((WXS_COMP_NAME(ret
,
5153 xmlSchemaModelGroupDefPtr
) == name
) &&
5155 xmlSchemaModelGroupDefPtr
) == nsName
))
5160 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
5161 if ((WXS_COMP_NAME(ret
,
5162 xmlSchemaAttributeGroupPtr
) == name
) &&
5164 xmlSchemaAttributeGroupPtr
) == nsName
))
5170 /* Should not be hit. */
5177 * Process imported/included schemas.
5179 if (bucket
->relations
!= NULL
) {
5180 xmlSchemaSchemaRelationPtr rel
= bucket
->relations
;
5183 * TODO: Marking the bucket will not avoid multiple searches
5184 * in the same schema, but avoids at least circularity.
5186 bucket
->flags
|= XML_SCHEMA_BUCKET_MARKED
;
5188 if ((rel
->bucket
!= NULL
) &&
5189 ((rel
->bucket
->flags
& XML_SCHEMA_BUCKET_MARKED
) == 0)) {
5190 ret
= xmlSchemaFindRedefCompInGraph(rel
->bucket
,
5191 type
, name
, nsName
);
5196 } while (rel
!= NULL
);
5197 bucket
->flags
^= XML_SCHEMA_BUCKET_MARKED
;
5203 * xmlSchemaAddNotation:
5204 * @ctxt: a schema parser context
5205 * @schema: the schema being built
5206 * @name: the item name
5208 * Add an XML schema annotation declaration
5209 * *WARNING* this interface is highly subject to change
5211 * Returns the new structure or NULL in case of error
5213 static xmlSchemaNotationPtr
5214 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
5215 const xmlChar
*name
, const xmlChar
*nsName
,
5216 xmlNodePtr node ATTRIBUTE_UNUSED
)
5218 xmlSchemaNotationPtr ret
= NULL
;
5220 if ((ctxt
== NULL
) || (schema
== NULL
) || (name
== NULL
))
5223 ret
= (xmlSchemaNotationPtr
) xmlMalloc(sizeof(xmlSchemaNotation
));
5225 xmlSchemaPErrMemory(ctxt
, "add annotation", NULL
);
5228 memset(ret
, 0, sizeof(xmlSchemaNotation
));
5229 ret
->type
= XML_SCHEMA_TYPE_NOTATION
;
5231 ret
->targetNamespace
= nsName
;
5232 /* TODO: do we need the node to be set?
5233 * ret->node = node;*/
5234 WXS_ADD_GLOBAL(ctxt
, ret
);
5239 * xmlSchemaAddAttribute:
5240 * @ctxt: a schema parser context
5241 * @schema: the schema being built
5242 * @name: the item name
5243 * @namespace: the namespace
5245 * Add an XML schema Attribute declaration
5246 * *WARNING* this interface is highly subject to change
5248 * Returns the new structure or NULL in case of error
5250 static xmlSchemaAttributePtr
5251 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
5252 const xmlChar
* name
, const xmlChar
* nsName
,
5253 xmlNodePtr node
, int topLevel
)
5255 xmlSchemaAttributePtr ret
= NULL
;
5257 if ((ctxt
== NULL
) || (schema
== NULL
))
5260 ret
= (xmlSchemaAttributePtr
) xmlMalloc(sizeof(xmlSchemaAttribute
));
5262 xmlSchemaPErrMemory(ctxt
, "allocating attribute", NULL
);
5265 memset(ret
, 0, sizeof(xmlSchemaAttribute
));
5266 ret
->type
= XML_SCHEMA_TYPE_ATTRIBUTE
;
5269 ret
->targetNamespace
= nsName
;
5272 WXS_ADD_GLOBAL(ctxt
, ret
);
5274 WXS_ADD_LOCAL(ctxt
, ret
);
5275 WXS_ADD_PENDING(ctxt
, ret
);
5280 * xmlSchemaAddAttributeUse:
5281 * @ctxt: a schema parser context
5282 * @schema: the schema being built
5283 * @name: the item name
5284 * @namespace: the namespace
5286 * Add an XML schema Attribute declaration
5287 * *WARNING* this interface is highly subject to change
5289 * Returns the new structure or NULL in case of error
5291 static xmlSchemaAttributeUsePtr
5292 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt
,
5295 xmlSchemaAttributeUsePtr ret
= NULL
;
5300 ret
= (xmlSchemaAttributeUsePtr
) xmlMalloc(sizeof(xmlSchemaAttributeUse
));
5302 xmlSchemaPErrMemory(pctxt
, "allocating attribute", NULL
);
5305 memset(ret
, 0, sizeof(xmlSchemaAttributeUse
));
5306 ret
->type
= XML_SCHEMA_TYPE_ATTRIBUTE_USE
;
5309 WXS_ADD_LOCAL(pctxt
, ret
);
5314 * xmlSchemaAddRedef:
5316 * Adds a redefinition information. This is used at a later stage to:
5317 * resolve references to the redefined components and to check constraints.
5319 static xmlSchemaRedefPtr
5320 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt
,
5321 xmlSchemaBucketPtr targetBucket
,
5323 const xmlChar
*refName
,
5324 const xmlChar
*refTargetNs
)
5326 xmlSchemaRedefPtr ret
;
5328 ret
= (xmlSchemaRedefPtr
)
5329 xmlMalloc(sizeof(xmlSchemaRedef
));
5331 xmlSchemaPErrMemory(pctxt
,
5332 "allocating redefinition info", NULL
);
5335 memset(ret
, 0, sizeof(xmlSchemaRedef
));
5337 ret
->targetBucket
= targetBucket
;
5338 ret
->refName
= refName
;
5339 ret
->refTargetNs
= refTargetNs
;
5340 if (WXS_CONSTRUCTOR(pctxt
)->redefs
== NULL
)
5341 WXS_CONSTRUCTOR(pctxt
)->redefs
= ret
;
5343 WXS_CONSTRUCTOR(pctxt
)->lastRedef
->next
= ret
;
5344 WXS_CONSTRUCTOR(pctxt
)->lastRedef
= ret
;
5350 * xmlSchemaAddAttributeGroupDefinition:
5351 * @ctxt: a schema parser context
5352 * @schema: the schema being built
5353 * @name: the item name
5354 * @nsName: the target namespace
5355 * @node: the corresponding node
5357 * Add an XML schema Attribute Group definition.
5359 * Returns the new structure or NULL in case of error
5361 static xmlSchemaAttributeGroupPtr
5362 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt
,
5363 xmlSchemaPtr schema ATTRIBUTE_UNUSED
,
5364 const xmlChar
*name
,
5365 const xmlChar
*nsName
,
5368 xmlSchemaAttributeGroupPtr ret
= NULL
;
5370 if ((pctxt
== NULL
) || (name
== NULL
))
5373 ret
= (xmlSchemaAttributeGroupPtr
)
5374 xmlMalloc(sizeof(xmlSchemaAttributeGroup
));
5376 xmlSchemaPErrMemory(pctxt
, "allocating attribute group", NULL
);
5379 memset(ret
, 0, sizeof(xmlSchemaAttributeGroup
));
5380 ret
->type
= XML_SCHEMA_TYPE_ATTRIBUTEGROUP
;
5382 ret
->targetNamespace
= nsName
;
5385 /* TODO: Remove the flag. */
5386 ret
->flags
|= XML_SCHEMAS_ATTRGROUP_GLOBAL
;
5387 if (pctxt
->isRedefine
) {
5388 pctxt
->redef
= xmlSchemaAddRedef(pctxt
, pctxt
->redefined
,
5390 if (pctxt
->redef
== NULL
) {
5394 pctxt
->redefCounter
= 0;
5396 WXS_ADD_GLOBAL(pctxt
, ret
);
5397 WXS_ADD_PENDING(pctxt
, ret
);
5402 * xmlSchemaAddElement:
5403 * @ctxt: a schema parser context
5404 * @schema: the schema being built
5405 * @name: the type name
5406 * @namespace: the type namespace
5408 * Add an XML schema Element declaration
5409 * *WARNING* this interface is highly subject to change
5411 * Returns the new structure or NULL in case of error
5413 static xmlSchemaElementPtr
5414 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt
,
5415 const xmlChar
* name
, const xmlChar
* nsName
,
5416 xmlNodePtr node
, int topLevel
)
5418 xmlSchemaElementPtr ret
= NULL
;
5420 if ((ctxt
== NULL
) || (name
== NULL
))
5423 ret
= (xmlSchemaElementPtr
) xmlMalloc(sizeof(xmlSchemaElement
));
5425 xmlSchemaPErrMemory(ctxt
, "allocating element", NULL
);
5428 memset(ret
, 0, sizeof(xmlSchemaElement
));
5429 ret
->type
= XML_SCHEMA_TYPE_ELEMENT
;
5431 ret
->targetNamespace
= nsName
;
5435 WXS_ADD_GLOBAL(ctxt
, ret
);
5437 WXS_ADD_LOCAL(ctxt
, ret
);
5438 WXS_ADD_PENDING(ctxt
, ret
);
5444 * @ctxt: a schema parser context
5445 * @schema: the schema being built
5446 * @name: the item name
5447 * @namespace: the namespace
5449 * Add an XML schema item
5450 * *WARNING* this interface is highly subject to change
5452 * Returns the new structure or NULL in case of error
5454 static xmlSchemaTypePtr
5455 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
5456 xmlSchemaTypeType type
,
5457 const xmlChar
* name
, const xmlChar
* nsName
,
5458 xmlNodePtr node
, int topLevel
)
5460 xmlSchemaTypePtr ret
= NULL
;
5462 if ((ctxt
== NULL
) || (schema
== NULL
))
5465 ret
= (xmlSchemaTypePtr
) xmlMalloc(sizeof(xmlSchemaType
));
5467 xmlSchemaPErrMemory(ctxt
, "allocating type", NULL
);
5470 memset(ret
, 0, sizeof(xmlSchemaType
));
5473 ret
->targetNamespace
= nsName
;
5476 if (ctxt
->isRedefine
) {
5477 ctxt
->redef
= xmlSchemaAddRedef(ctxt
, ctxt
->redefined
,
5479 if (ctxt
->redef
== NULL
) {
5483 ctxt
->redefCounter
= 0;
5485 WXS_ADD_GLOBAL(ctxt
, ret
);
5487 WXS_ADD_LOCAL(ctxt
, ret
);
5488 WXS_ADD_PENDING(ctxt
, ret
);
5492 static xmlSchemaQNameRefPtr
5493 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt
,
5494 xmlSchemaTypeType refType
,
5495 const xmlChar
*refName
,
5496 const xmlChar
*refNs
)
5498 xmlSchemaQNameRefPtr ret
;
5500 ret
= (xmlSchemaQNameRefPtr
)
5501 xmlMalloc(sizeof(xmlSchemaQNameRef
));
5503 xmlSchemaPErrMemory(pctxt
,
5504 "allocating QName reference item", NULL
);
5508 ret
->type
= XML_SCHEMA_EXTRA_QNAMEREF
;
5509 ret
->name
= refName
;
5510 ret
->targetNamespace
= refNs
;
5512 ret
->itemType
= refType
;
5514 * Store the reference item in the schema.
5516 WXS_ADD_LOCAL(pctxt
, ret
);
5520 static xmlSchemaAttributeUseProhibPtr
5521 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt
)
5523 xmlSchemaAttributeUseProhibPtr ret
;
5525 ret
= (xmlSchemaAttributeUseProhibPtr
)
5526 xmlMalloc(sizeof(xmlSchemaAttributeUseProhib
));
5528 xmlSchemaPErrMemory(pctxt
,
5529 "allocating attribute use prohibition", NULL
);
5532 memset(ret
, 0, sizeof(xmlSchemaAttributeUseProhib
));
5533 ret
->type
= XML_SCHEMA_EXTRA_ATTR_USE_PROHIB
;
5534 WXS_ADD_LOCAL(pctxt
, ret
);
5540 * xmlSchemaAddModelGroup:
5541 * @ctxt: a schema parser context
5542 * @schema: the schema being built
5543 * @type: the "compositor" type of the model group
5544 * @node: the node in the schema doc
5546 * Adds a schema model group
5547 * *WARNING* this interface is highly subject to change
5549 * Returns the new structure or NULL in case of error
5551 static xmlSchemaModelGroupPtr
5552 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt
,
5553 xmlSchemaPtr schema
,
5554 xmlSchemaTypeType type
,
5557 xmlSchemaModelGroupPtr ret
= NULL
;
5559 if ((ctxt
== NULL
) || (schema
== NULL
))
5562 ret
= (xmlSchemaModelGroupPtr
)
5563 xmlMalloc(sizeof(xmlSchemaModelGroup
));
5565 xmlSchemaPErrMemory(ctxt
, "allocating model group component",
5569 memset(ret
, 0, sizeof(xmlSchemaModelGroup
));
5572 WXS_ADD_LOCAL(ctxt
, ret
);
5573 if ((type
== XML_SCHEMA_TYPE_SEQUENCE
) ||
5574 (type
== XML_SCHEMA_TYPE_CHOICE
))
5575 WXS_ADD_PENDING(ctxt
, ret
);
5581 * xmlSchemaAddParticle:
5582 * @ctxt: a schema parser context
5583 * @schema: the schema being built
5584 * @node: the corresponding node in the schema doc
5585 * @min: the minOccurs
5586 * @max: the maxOccurs
5588 * Adds an XML schema particle component.
5589 * *WARNING* this interface is highly subject to change
5591 * Returns the new structure or NULL in case of error
5593 static xmlSchemaParticlePtr
5594 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt
,
5595 xmlNodePtr node
, int min
, int max
)
5597 xmlSchemaParticlePtr ret
= NULL
;
5602 fprintf(stderr
, "Adding particle component\n");
5604 ret
= (xmlSchemaParticlePtr
)
5605 xmlMalloc(sizeof(xmlSchemaParticle
));
5607 xmlSchemaPErrMemory(ctxt
, "allocating particle component",
5611 ret
->type
= XML_SCHEMA_TYPE_PARTICLE
;
5614 ret
->minOccurs
= min
;
5615 ret
->maxOccurs
= max
;
5617 ret
->children
= NULL
;
5619 WXS_ADD_LOCAL(ctxt
, ret
);
5621 * Note that addition to pending components will be done locally
5622 * to the specific parsing function, since the most particles
5623 * need not to be fixed up (i.e. the reference to be resolved).
5624 * REMOVED: WXS_ADD_PENDING(ctxt, ret);
5630 * xmlSchemaAddModelGroupDefinition:
5631 * @ctxt: a schema validation context
5632 * @schema: the schema being built
5633 * @name: the group name
5635 * Add an XML schema Group definition
5637 * Returns the new structure or NULL in case of error
5639 static xmlSchemaModelGroupDefPtr
5640 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt
,
5641 xmlSchemaPtr schema
,
5642 const xmlChar
*name
,
5643 const xmlChar
*nsName
,
5646 xmlSchemaModelGroupDefPtr ret
= NULL
;
5648 if ((ctxt
== NULL
) || (schema
== NULL
) || (name
== NULL
))
5651 ret
= (xmlSchemaModelGroupDefPtr
)
5652 xmlMalloc(sizeof(xmlSchemaModelGroupDef
));
5654 xmlSchemaPErrMemory(ctxt
, "adding group", NULL
);
5657 memset(ret
, 0, sizeof(xmlSchemaModelGroupDef
));
5659 ret
->type
= XML_SCHEMA_TYPE_GROUP
;
5661 ret
->targetNamespace
= nsName
;
5663 if (ctxt
->isRedefine
) {
5664 ctxt
->redef
= xmlSchemaAddRedef(ctxt
, ctxt
->redefined
,
5666 if (ctxt
->redef
== NULL
) {
5670 ctxt
->redefCounter
= 0;
5672 WXS_ADD_GLOBAL(ctxt
, ret
);
5673 WXS_ADD_PENDING(ctxt
, ret
);
5678 * xmlSchemaNewWildcardNs:
5679 * @ctxt: a schema validation context
5681 * Creates a new wildcard namespace constraint.
5683 * Returns the new structure or NULL in case of error
5685 static xmlSchemaWildcardNsPtr
5686 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt
)
5688 xmlSchemaWildcardNsPtr ret
;
5690 ret
= (xmlSchemaWildcardNsPtr
)
5691 xmlMalloc(sizeof(xmlSchemaWildcardNs
));
5693 xmlSchemaPErrMemory(ctxt
, "creating wildcard namespace constraint", NULL
);
5701 static xmlSchemaIDCPtr
5702 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
5703 const xmlChar
*name
, const xmlChar
*nsName
,
5704 int category
, xmlNodePtr node
)
5706 xmlSchemaIDCPtr ret
= NULL
;
5708 if ((ctxt
== NULL
) || (schema
== NULL
) || (name
== NULL
))
5711 ret
= (xmlSchemaIDCPtr
) xmlMalloc(sizeof(xmlSchemaIDC
));
5713 xmlSchemaPErrMemory(ctxt
,
5714 "allocating an identity-constraint definition", NULL
);
5717 memset(ret
, 0, sizeof(xmlSchemaIDC
));
5718 /* The target namespace of the parent element declaration. */
5719 ret
->targetNamespace
= nsName
;
5721 ret
->type
= category
;
5724 WXS_ADD_GLOBAL(ctxt
, ret
);
5726 * Only keyrefs need to be fixup up.
5728 if (category
== XML_SCHEMA_TYPE_IDC_KEYREF
)
5729 WXS_ADD_PENDING(ctxt
, ret
);
5734 * xmlSchemaAddWildcard:
5735 * @ctxt: a schema validation context
5739 * It corresponds to a xsd:anyAttribute and xsd:any.
5741 * Returns the new structure or NULL in case of error
5743 static xmlSchemaWildcardPtr
5744 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
5745 xmlSchemaTypeType type
, xmlNodePtr node
)
5747 xmlSchemaWildcardPtr ret
= NULL
;
5749 if ((ctxt
== NULL
) || (schema
== NULL
))
5752 ret
= (xmlSchemaWildcardPtr
) xmlMalloc(sizeof(xmlSchemaWildcard
));
5754 xmlSchemaPErrMemory(ctxt
, "adding wildcard", NULL
);
5757 memset(ret
, 0, sizeof(xmlSchemaWildcard
));
5760 WXS_ADD_LOCAL(ctxt
, ret
);
5765 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group
)
5769 if (group
->members
!= NULL
)
5770 xmlSchemaItemListFree(group
->members
);
5775 xmlSchemaSubstGroupFreeEntry(void *group
, const xmlChar
*name ATTRIBUTE_UNUSED
)
5777 xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr
) group
);
5780 static xmlSchemaSubstGroupPtr
5781 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt
,
5782 xmlSchemaElementPtr head
)
5784 xmlSchemaSubstGroupPtr ret
;
5786 /* Init subst group hash. */
5787 if (WXS_SUBST_GROUPS(pctxt
) == NULL
) {
5788 WXS_SUBST_GROUPS(pctxt
) = xmlHashCreateDict(10, pctxt
->dict
);
5789 if (WXS_SUBST_GROUPS(pctxt
) == NULL
)
5792 /* Create a new substitution group. */
5793 ret
= (xmlSchemaSubstGroupPtr
) xmlMalloc(sizeof(xmlSchemaSubstGroup
));
5795 xmlSchemaPErrMemory(NULL
,
5796 "allocating a substitution group container", NULL
);
5799 memset(ret
, 0, sizeof(xmlSchemaSubstGroup
));
5801 /* Create list of members. */
5802 ret
->members
= xmlSchemaItemListCreate();
5803 if (ret
->members
== NULL
) {
5804 xmlSchemaSubstGroupFree(ret
);
5807 /* Add subst group to hash. */
5808 if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt
),
5809 head
->name
, head
->targetNamespace
, ret
) != 0) {
5810 PERROR_INT("xmlSchemaSubstGroupAdd",
5811 "failed to add a new substitution container");
5812 xmlSchemaSubstGroupFree(ret
);
5818 static xmlSchemaSubstGroupPtr
5819 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt
,
5820 xmlSchemaElementPtr head
)
5822 if (WXS_SUBST_GROUPS(pctxt
) == NULL
)
5824 return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt
),
5825 head
->name
, head
->targetNamespace
));
5830 * xmlSchemaAddElementSubstitutionMember:
5831 * @pctxt: a schema parser context
5832 * @head: the head of the substitution group
5833 * @member: the new member of the substitution group
5835 * Allocate a new annotation structure.
5837 * Returns the newly allocated structure or NULL in case or error
5840 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt
,
5841 xmlSchemaElementPtr head
,
5842 xmlSchemaElementPtr member
)
5844 xmlSchemaSubstGroupPtr substGroup
= NULL
;
5846 if ((pctxt
== NULL
) || (head
== NULL
) || (member
== NULL
))
5849 substGroup
= xmlSchemaSubstGroupGet(pctxt
, head
);
5850 if (substGroup
== NULL
)
5851 substGroup
= xmlSchemaSubstGroupAdd(pctxt
, head
);
5852 if (substGroup
== NULL
)
5854 if (xmlSchemaItemListAdd(substGroup
->members
, member
) == -1)
5859 /************************************************************************
5861 * Utilities for parsing *
5863 ************************************************************************/
5866 * xmlSchemaPValAttrNodeQNameValue:
5867 * @ctxt: a schema parser context
5868 * @schema: the schema context
5869 * @ownerItem: the parent as a schema object
5870 * @value: the QName value
5871 * @uri: the resulting namespace URI if found
5872 * @local: the resulting local part if found, the attribute value otherwise
5874 * Extracts the local name and the URI of a QName value and validates it.
5875 * This one is intended to be used on attribute values that
5876 * should resolve to schema components.
5878 * Returns 0, in case the QName is valid, a positive error code
5879 * if not valid and -1 if an internal error occurs.
5882 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt
,
5883 xmlSchemaPtr schema
,
5884 xmlSchemaBasicItemPtr ownerItem
,
5886 const xmlChar
*value
,
5887 const xmlChar
**uri
,
5888 const xmlChar
**local
)
5890 const xmlChar
*pref
;
5896 ret
= xmlValidateQName(value
, 1);
5898 xmlSchemaPSimpleTypeErr(ctxt
,
5899 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
5900 ownerItem
, (xmlNodePtr
) attr
,
5901 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME
),
5902 NULL
, value
, NULL
, NULL
, NULL
);
5908 if (!strchr((char *) value
, ':')) {
5909 ns
= xmlSearchNs(attr
->doc
, attr
->parent
, NULL
);
5910 if (ns
&& ns
->href
&& ns
->href
[0])
5911 *uri
= xmlDictLookup(ctxt
->dict
, ns
->href
, -1);
5912 else if (schema
->flags
& XML_SCHEMAS_INCLUDING_CONVERT_NS
) {
5913 /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
5914 * parser context. */
5916 * This one takes care of included schemas with no
5919 *uri
= ctxt
->targetNamespace
;
5921 *local
= xmlDictLookup(ctxt
->dict
, value
, -1);
5925 * At this point xmlSplitQName3 has to return a local name.
5927 *local
= xmlSplitQName3(value
, &len
);
5928 *local
= xmlDictLookup(ctxt
->dict
, *local
, -1);
5929 pref
= xmlDictLookup(ctxt
->dict
, value
, len
);
5930 ns
= xmlSearchNs(attr
->doc
, attr
->parent
, pref
);
5932 xmlSchemaPSimpleTypeErr(ctxt
,
5933 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
5934 ownerItem
, (xmlNodePtr
) attr
,
5935 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME
), NULL
, value
,
5936 "The value '%s' of simple type 'xs:QName' has no "
5937 "corresponding namespace declaration in scope", value
, NULL
);
5940 *uri
= xmlDictLookup(ctxt
->dict
, ns
->href
, -1);
5946 * xmlSchemaPValAttrNodeQName:
5947 * @ctxt: a schema parser context
5948 * @schema: the schema context
5949 * @ownerItem: the owner as a schema object
5950 * @attr: the attribute node
5951 * @uri: the resulting namespace URI if found
5952 * @local: the resulting local part if found, the attribute value otherwise
5954 * Extracts and validates the QName of an attribute value.
5955 * This one is intended to be used on attribute values that
5956 * should resolve to schema components.
5958 * Returns 0, in case the QName is valid, a positive error code
5959 * if not valid and -1 if an internal error occurs.
5962 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt
,
5963 xmlSchemaPtr schema
,
5964 xmlSchemaBasicItemPtr ownerItem
,
5966 const xmlChar
**uri
,
5967 const xmlChar
**local
)
5969 const xmlChar
*value
;
5971 value
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
5972 return (xmlSchemaPValAttrNodeQNameValue(ctxt
, schema
,
5973 ownerItem
, attr
, value
, uri
, local
));
5977 * xmlSchemaPValAttrQName:
5978 * @ctxt: a schema parser context
5979 * @schema: the schema context
5980 * @ownerItem: the owner as a schema object
5981 * @ownerElem: the parent node of the attribute
5982 * @name: the name of the attribute
5983 * @uri: the resulting namespace URI if found
5984 * @local: the resulting local part if found, the attribute value otherwise
5986 * Extracts and validates the QName of an attribute value.
5988 * Returns 0, in case the QName is valid, a positive error code
5989 * if not valid and -1 if an internal error occurs.
5992 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt
,
5993 xmlSchemaPtr schema
,
5994 xmlSchemaBasicItemPtr ownerItem
,
5995 xmlNodePtr ownerElem
,
5997 const xmlChar
**uri
,
5998 const xmlChar
**local
)
6002 attr
= xmlSchemaGetPropNode(ownerElem
, name
);
6008 return (xmlSchemaPValAttrNodeQName(ctxt
, schema
,
6009 ownerItem
, attr
, uri
, local
));
6013 * xmlSchemaPValAttrID:
6014 * @ctxt: a schema parser context
6016 * Extracts and validates the ID of an attribute value.
6018 * Returns 0, in case the ID is valid, a positive error code
6019 * if not valid and -1 if an internal error occurs.
6022 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt
, xmlAttrPtr attr
)
6025 const xmlChar
*value
;
6029 value
= xmlSchemaGetNodeContentNoDict((xmlNodePtr
) attr
);
6030 ret
= xmlValidateNCName(value
, 1);
6033 * NOTE: the IDness might have already be declared in the DTD
6035 if (attr
->atype
!= XML_ATTRIBUTE_ID
) {
6040 * TODO: Use xmlSchemaStrip here; it's not exported at this
6043 strip
= xmlSchemaCollapseString(value
);
6044 if (strip
!= NULL
) {
6045 xmlFree((xmlChar
*) value
);
6048 res
= xmlAddID(NULL
, attr
->doc
, value
, attr
);
6050 ret
= XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
;
6051 xmlSchemaPSimpleTypeErr(ctxt
,
6052 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
6053 NULL
, (xmlNodePtr
) attr
,
6054 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID
),
6055 NULL
, NULL
, "Duplicate value '%s' of simple "
6056 "type 'xs:ID'", value
, NULL
);
6058 attr
->atype
= XML_ATTRIBUTE_ID
;
6060 } else if (ret
> 0) {
6061 ret
= XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
;
6062 xmlSchemaPSimpleTypeErr(ctxt
,
6063 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
6064 NULL
, (xmlNodePtr
) attr
,
6065 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID
),
6066 NULL
, NULL
, "The value '%s' of simple type 'xs:ID' is "
6067 "not a valid 'xs:NCName'",
6071 xmlFree((xmlChar
*)value
);
6077 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt
,
6078 xmlNodePtr ownerElem
,
6079 const xmlChar
*name
)
6083 attr
= xmlSchemaGetPropNode(ownerElem
, (const char *) name
);
6086 return(xmlSchemaPValAttrNodeID(ctxt
, attr
));
6092 * @ctxt: a schema validation context
6093 * @node: a subtree containing XML Schema information
6095 * Get the maxOccurs property
6097 * Returns the default if not found, or the value
6100 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
,
6101 int min
, int max
, int def
, const char *expected
)
6103 const xmlChar
*val
, *cur
;
6107 attr
= xmlSchemaGetPropNode(node
, "maxOccurs");
6110 val
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
6114 if (xmlStrEqual(val
, (const xmlChar
*) "unbounded")) {
6115 if (max
!= UNBOUNDED
) {
6116 xmlSchemaPSimpleTypeErr(ctxt
,
6117 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
6118 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6119 NULL
, (xmlNodePtr
) attr
, NULL
, expected
,
6120 val
, NULL
, NULL
, NULL
);
6123 return (UNBOUNDED
); /* encoding it with -1 might be another option */
6127 while (IS_BLANK_CH(*cur
))
6130 xmlSchemaPSimpleTypeErr(ctxt
,
6131 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
6132 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6133 NULL
, (xmlNodePtr
) attr
, NULL
, expected
,
6134 val
, NULL
, NULL
, NULL
);
6137 while ((*cur
>= '0') && (*cur
<= '9')) {
6138 if (ret
> INT_MAX
/ 10) {
6141 int digit
= *cur
- '0';
6143 if (ret
> INT_MAX
- digit
)
6150 while (IS_BLANK_CH(*cur
))
6153 * TODO: Restrict the maximal value to Integer.
6155 if ((*cur
!= 0) || (ret
< min
) || ((max
!= -1) && (ret
> max
))) {
6156 xmlSchemaPSimpleTypeErr(ctxt
,
6157 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
6158 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6159 NULL
, (xmlNodePtr
) attr
, NULL
, expected
,
6160 val
, NULL
, NULL
, NULL
);
6168 * @ctxt: a schema validation context
6169 * @node: a subtree containing XML Schema information
6171 * Get the minOccurs property
6173 * Returns the default if not found, or the value
6176 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
,
6177 int min
, int max
, int def
, const char *expected
)
6179 const xmlChar
*val
, *cur
;
6183 attr
= xmlSchemaGetPropNode(node
, "minOccurs");
6186 val
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
6190 while (IS_BLANK_CH(*cur
))
6193 xmlSchemaPSimpleTypeErr(ctxt
,
6194 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
6195 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6196 NULL
, (xmlNodePtr
) attr
, NULL
, expected
,
6197 val
, NULL
, NULL
, NULL
);
6200 while ((*cur
>= '0') && (*cur
<= '9')) {
6201 if (ret
> INT_MAX
/ 10) {
6204 int digit
= *cur
- '0';
6206 if (ret
> INT_MAX
- digit
)
6213 while (IS_BLANK_CH(*cur
))
6216 * TODO: Restrict the maximal value to Integer.
6218 if ((*cur
!= 0) || (ret
< min
) || ((max
!= -1) && (ret
> max
))) {
6219 xmlSchemaPSimpleTypeErr(ctxt
,
6220 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
6221 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6222 NULL
, (xmlNodePtr
) attr
, NULL
, expected
,
6223 val
, NULL
, NULL
, NULL
);
6230 * xmlSchemaPGetBoolNodeValue:
6231 * @ctxt: a schema validation context
6232 * @ownerItem: the owner as a schema item
6233 * @node: the node holding the value
6235 * Converts a boolean string value into 1 or 0.
6240 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt
,
6241 xmlSchemaBasicItemPtr ownerItem
,
6244 xmlChar
*value
= NULL
;
6247 value
= xmlNodeGetContent(node
);
6249 * 3.2.2.1 Lexical representation
6250 * An instance of a datatype that is defined as `boolean`
6251 * can have the following legal literals {true, false, 1, 0}.
6253 if (xmlStrEqual(BAD_CAST value
, BAD_CAST
"true"))
6255 else if (xmlStrEqual(BAD_CAST value
, BAD_CAST
"false"))
6257 else if (xmlStrEqual(BAD_CAST value
, BAD_CAST
"1"))
6259 else if (xmlStrEqual(BAD_CAST value
, BAD_CAST
"0"))
6262 xmlSchemaPSimpleTypeErr(ctxt
,
6263 XML_SCHEMAP_INVALID_BOOLEAN
,
6265 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN
),
6266 NULL
, BAD_CAST value
,
6275 * xmlGetBooleanProp:
6276 * @ctxt: a schema validation context
6277 * @node: a subtree containing XML Schema information
6278 * @name: the attribute name
6279 * @def: the default value
6281 * Evaluate if a boolean property is set
6283 * Returns the default if not found, 0 if found to be false,
6284 * 1 if found to be true
6287 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt
,
6289 const char *name
, int def
)
6293 val
= xmlSchemaGetProp(ctxt
, node
, name
);
6297 * 3.2.2.1 Lexical representation
6298 * An instance of a datatype that is defined as `boolean`
6299 * can have the following legal literals {true, false, 1, 0}.
6301 if (xmlStrEqual(val
, BAD_CAST
"true"))
6303 else if (xmlStrEqual(val
, BAD_CAST
"false"))
6305 else if (xmlStrEqual(val
, BAD_CAST
"1"))
6307 else if (xmlStrEqual(val
, BAD_CAST
"0"))
6310 xmlSchemaPSimpleTypeErr(ctxt
,
6311 XML_SCHEMAP_INVALID_BOOLEAN
,
6313 (xmlNodePtr
) xmlSchemaGetPropNode(node
, name
),
6314 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN
),
6315 NULL
, val
, NULL
, NULL
, NULL
);
6320 /************************************************************************
6322 * Schema extraction from an Infoset *
6324 ************************************************************************/
6325 static xmlSchemaTypePtr
xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
6326 ctxt
, xmlSchemaPtr schema
,
6329 static xmlSchemaTypePtr
xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
6331 xmlSchemaPtr schema
,
6334 static xmlSchemaTypePtr
xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
6336 xmlSchemaPtr schema
,
6338 xmlSchemaTypeType parentType
);
6339 static xmlSchemaBasicItemPtr
6340 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt
,
6341 xmlSchemaPtr schema
,
6343 xmlSchemaItemListPtr uses
,
6345 static xmlSchemaTypePtr
xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt
,
6346 xmlSchemaPtr schema
,
6348 static xmlSchemaWildcardPtr
6349 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt
,
6350 xmlSchemaPtr schema
, xmlNodePtr node
);
6353 * xmlSchemaPValAttrNodeValue:
6355 * @pctxt: a schema parser context
6356 * @ownerItem: the schema object owner if existent
6357 * @attr: the schema attribute node being validated
6359 * @type: the built-in type to be validated against
6361 * Validates a value against the given built-in type.
6362 * This one is intended to be used internally for validation
6363 * of schema attribute values during parsing of the schema.
6365 * Returns 0 if the value is valid, a positive error code
6366 * number otherwise and -1 in case of an internal or API error.
6369 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt
,
6370 xmlSchemaBasicItemPtr ownerItem
,
6372 const xmlChar
*value
,
6373 xmlSchemaTypePtr type
)
6379 * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
6380 * one is really meant to be used internally, so better not.
6382 if ((pctxt
== NULL
) || (type
== NULL
) || (attr
== NULL
))
6384 if (type
->type
!= XML_SCHEMA_TYPE_BASIC
) {
6385 PERROR_INT("xmlSchemaPValAttrNodeValue",
6386 "the given type is not a built-in type");
6389 switch (type
->builtInType
) {
6390 case XML_SCHEMAS_NCNAME
:
6391 case XML_SCHEMAS_QNAME
:
6392 case XML_SCHEMAS_ANYURI
:
6393 case XML_SCHEMAS_TOKEN
:
6394 case XML_SCHEMAS_LANGUAGE
:
6395 ret
= xmlSchemaValPredefTypeNode(type
, value
, NULL
,
6399 PERROR_INT("xmlSchemaPValAttrNodeValue",
6400 "validation using the given type is not supported while "
6401 "parsing a schema");
6406 * TODO: Should we use the S4S error codes instead?
6409 PERROR_INT("xmlSchemaPValAttrNodeValue",
6410 "failed to validate a schema attribute value");
6412 } else if (ret
> 0) {
6413 if (WXS_IS_LIST(type
))
6414 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2
;
6416 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1
;
6417 xmlSchemaPSimpleTypeErr(pctxt
,
6418 ret
, ownerItem
, (xmlNodePtr
) attr
,
6419 type
, NULL
, value
, NULL
, NULL
, NULL
);
6425 * xmlSchemaPValAttrNode:
6427 * @ctxt: a schema parser context
6428 * @ownerItem: the schema object owner if existent
6429 * @attr: the schema attribute node being validated
6430 * @type: the built-in type to be validated against
6431 * @value: the resulting value if any
6433 * Extracts and validates a value against the given built-in type.
6434 * This one is intended to be used internally for validation
6435 * of schema attribute values during parsing of the schema.
6437 * Returns 0 if the value is valid, a positive error code
6438 * number otherwise and -1 in case of an internal or API error.
6441 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt
,
6442 xmlSchemaBasicItemPtr ownerItem
,
6444 xmlSchemaTypePtr type
,
6445 const xmlChar
**value
)
6449 if ((ctxt
== NULL
) || (type
== NULL
) || (attr
== NULL
))
6452 val
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
6456 return (xmlSchemaPValAttrNodeValue(ctxt
, ownerItem
, attr
,
6461 * xmlSchemaPValAttr:
6463 * @ctxt: a schema parser context
6464 * @node: the element node of the attribute
6465 * @ownerItem: the schema object owner if existent
6466 * @ownerElem: the owner element node
6467 * @name: the name of the schema attribute node
6468 * @type: the built-in type to be validated against
6469 * @value: the resulting value if any
6471 * Extracts and validates a value against the given built-in type.
6472 * This one is intended to be used internally for validation
6473 * of schema attribute values during parsing of the schema.
6475 * Returns 0 if the value is valid, a positive error code
6476 * number otherwise and -1 in case of an internal or API error.
6479 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt
,
6480 xmlSchemaBasicItemPtr ownerItem
,
6481 xmlNodePtr ownerElem
,
6483 xmlSchemaTypePtr type
,
6484 const xmlChar
**value
)
6488 if ((ctxt
== NULL
) || (type
== NULL
)) {
6493 if (type
->type
!= XML_SCHEMA_TYPE_BASIC
) {
6496 xmlSchemaPErr(ctxt
, ownerElem
,
6497 XML_SCHEMAP_INTERNAL
,
6498 "Internal error: xmlSchemaPValAttr, the given "
6499 "type '%s' is not a built-in type.\n",
6503 attr
= xmlSchemaGetPropNode(ownerElem
, name
);
6509 return (xmlSchemaPValAttrNode(ctxt
, ownerItem
, attr
,
6514 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt
,
6515 xmlSchemaPtr schema ATTRIBUTE_UNUSED
,
6518 const xmlChar
*namespaceName
)
6520 /* TODO: Pointer comparison instead? */
6521 if (xmlStrEqual(pctxt
->targetNamespace
, namespaceName
))
6523 if (xmlStrEqual(xmlSchemaNs
, namespaceName
))
6526 * Check if the referenced namespace was <import>ed.
6528 if (WXS_BUCKET(pctxt
)->relations
!= NULL
) {
6529 xmlSchemaSchemaRelationPtr rel
;
6531 rel
= WXS_BUCKET(pctxt
)->relations
;
6533 if (WXS_IS_BUCKET_IMPMAIN(rel
->type
) &&
6534 xmlStrEqual(namespaceName
, rel
->importNamespace
))
6537 } while (rel
!= NULL
);
6540 * No matching <import>ed namespace found.
6543 xmlNodePtr n
= (attr
!= NULL
) ? (xmlNodePtr
) attr
: node
;
6545 if (namespaceName
== NULL
)
6546 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
6547 XML_SCHEMAP_SRC_RESOLVE
, n
, NULL
,
6548 "References from this schema to components in no "
6549 "namespace are not allowed, since not indicated by an "
6550 "import statement", NULL
, NULL
);
6552 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
6553 XML_SCHEMAP_SRC_RESOLVE
, n
, NULL
,
6554 "References from this schema to components in the "
6555 "namespace '%s' are not allowed, since not indicated by an "
6556 "import statement", namespaceName
, NULL
);
6558 return (XML_SCHEMAP_SRC_RESOLVE
);
6562 * xmlSchemaParseLocalAttributes:
6563 * @ctxt: a schema validation context
6564 * @schema: the schema being built
6565 * @node: a subtree containing XML Schema information
6566 * @type: the hosting type where the attributes will be anchored
6568 * Parses attribute uses and attribute declarations and
6569 * attribute group references.
6572 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
6573 xmlNodePtr
*child
, xmlSchemaItemListPtr
*list
,
6574 int parentType
, int *hasRefs
)
6578 while ((IS_SCHEMA((*child
), "attribute")) ||
6579 (IS_SCHEMA((*child
), "attributeGroup"))) {
6580 if (IS_SCHEMA((*child
), "attribute")) {
6581 item
= xmlSchemaParseLocalAttribute(ctxt
, schema
, *child
,
6584 item
= xmlSchemaParseAttributeGroupRef(ctxt
, schema
, *child
);
6585 if ((item
!= NULL
) && (hasRefs
!= NULL
))
6589 if (*list
== NULL
) {
6590 /* TODO: Customize grow factor. */
6591 *list
= xmlSchemaItemListCreate();
6595 if (xmlSchemaItemListAddSize(*list
, 2, item
) == -1)
6598 *child
= (*child
)->next
;
6604 * xmlSchemaParseAnnotation:
6605 * @ctxt: a schema validation context
6606 * @schema: the schema being built
6607 * @node: a subtree containing XML Schema information
6609 * parse a XML schema Attribute declaration
6610 * *WARNING* this interface is highly subject to change
6612 * Returns -1 in case of error, 0 if the declaration is improper and
6613 * 1 in case of success.
6615 static xmlSchemaAnnotPtr
6616 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
, int needed
)
6618 xmlSchemaAnnotPtr ret
;
6619 xmlNodePtr child
= NULL
;
6624 * INFO: S4S completed.
6628 * {any attributes with non-schema namespace . . .}>
6629 * Content: (appinfo | documentation)*
6631 if ((ctxt
== NULL
) || (node
== NULL
))
6634 ret
= xmlSchemaNewAnnot(ctxt
, node
);
6637 attr
= node
->properties
;
6638 while (attr
!= NULL
) {
6639 if (((attr
->ns
== NULL
) &&
6640 (!xmlStrEqual(attr
->name
, BAD_CAST
"id"))) ||
6641 ((attr
->ns
!= NULL
) &&
6642 xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
))) {
6644 xmlSchemaPIllegalAttrErr(ctxt
,
6645 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
6649 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
6651 * And now for the children...
6653 child
= node
->children
;
6654 while (child
!= NULL
) {
6655 if (IS_SCHEMA(child
, "appinfo")) {
6656 /* TODO: make available the content of "appinfo". */
6659 * {any attributes with non-schema namespace . . .}>
6662 attr
= child
->properties
;
6663 while (attr
!= NULL
) {
6664 if (((attr
->ns
== NULL
) &&
6665 (!xmlStrEqual(attr
->name
, BAD_CAST
"source"))) ||
6666 ((attr
->ns
!= NULL
) &&
6667 xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
))) {
6669 xmlSchemaPIllegalAttrErr(ctxt
,
6670 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
6674 xmlSchemaPValAttr(ctxt
, NULL
, child
, "source",
6675 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI
), NULL
);
6676 child
= child
->next
;
6677 } else if (IS_SCHEMA(child
, "documentation")) {
6678 /* TODO: make available the content of "documentation". */
6681 * {any attributes with non-schema namespace . . .}>
6684 attr
= child
->properties
;
6685 while (attr
!= NULL
) {
6686 if (attr
->ns
== NULL
) {
6687 if (!xmlStrEqual(attr
->name
, BAD_CAST
"source")) {
6688 xmlSchemaPIllegalAttrErr(ctxt
,
6689 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
6692 if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
) ||
6693 (xmlStrEqual(attr
->name
, BAD_CAST
"lang") &&
6694 (!xmlStrEqual(attr
->ns
->href
, XML_XML_NAMESPACE
)))) {
6696 xmlSchemaPIllegalAttrErr(ctxt
,
6697 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
6703 * Attribute "xml:lang".
6705 attr
= xmlSchemaGetPropNodeNs(child
, (const char *) XML_XML_NAMESPACE
, "lang");
6707 xmlSchemaPValAttrNode(ctxt
, NULL
, attr
,
6708 xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE
), NULL
);
6709 child
= child
->next
;
6712 xmlSchemaPContentErr(ctxt
,
6713 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
6714 NULL
, node
, child
, NULL
, "(appinfo | documentation)*");
6716 child
= child
->next
;
6724 * xmlSchemaParseFacet:
6725 * @ctxt: a schema validation context
6726 * @schema: the schema being built
6727 * @node: a subtree containing XML Schema information
6729 * parse a XML schema Facet declaration
6730 * *WARNING* this interface is highly subject to change
6732 * Returns the new type structure or NULL in case of error
6734 static xmlSchemaFacetPtr
6735 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
6738 xmlSchemaFacetPtr facet
;
6739 xmlNodePtr child
= NULL
;
6740 const xmlChar
*value
;
6742 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
6745 facet
= xmlSchemaNewFacet();
6746 if (facet
== NULL
) {
6747 xmlSchemaPErrMemory(ctxt
, "allocating facet", node
);
6751 value
= xmlSchemaGetProp(ctxt
, node
, "value");
6752 if (value
== NULL
) {
6753 xmlSchemaPErr2(ctxt
, node
, child
, XML_SCHEMAP_FACET_NO_VALUE
,
6754 "Facet %s has no value\n", node
->name
, NULL
);
6755 xmlSchemaFreeFacet(facet
);
6758 if (IS_SCHEMA(node
, "minInclusive")) {
6759 facet
->type
= XML_SCHEMA_FACET_MININCLUSIVE
;
6760 } else if (IS_SCHEMA(node
, "minExclusive")) {
6761 facet
->type
= XML_SCHEMA_FACET_MINEXCLUSIVE
;
6762 } else if (IS_SCHEMA(node
, "maxInclusive")) {
6763 facet
->type
= XML_SCHEMA_FACET_MAXINCLUSIVE
;
6764 } else if (IS_SCHEMA(node
, "maxExclusive")) {
6765 facet
->type
= XML_SCHEMA_FACET_MAXEXCLUSIVE
;
6766 } else if (IS_SCHEMA(node
, "totalDigits")) {
6767 facet
->type
= XML_SCHEMA_FACET_TOTALDIGITS
;
6768 } else if (IS_SCHEMA(node
, "fractionDigits")) {
6769 facet
->type
= XML_SCHEMA_FACET_FRACTIONDIGITS
;
6770 } else if (IS_SCHEMA(node
, "pattern")) {
6771 facet
->type
= XML_SCHEMA_FACET_PATTERN
;
6772 } else if (IS_SCHEMA(node
, "enumeration")) {
6773 facet
->type
= XML_SCHEMA_FACET_ENUMERATION
;
6774 } else if (IS_SCHEMA(node
, "whiteSpace")) {
6775 facet
->type
= XML_SCHEMA_FACET_WHITESPACE
;
6776 } else if (IS_SCHEMA(node
, "length")) {
6777 facet
->type
= XML_SCHEMA_FACET_LENGTH
;
6778 } else if (IS_SCHEMA(node
, "maxLength")) {
6779 facet
->type
= XML_SCHEMA_FACET_MAXLENGTH
;
6780 } else if (IS_SCHEMA(node
, "minLength")) {
6781 facet
->type
= XML_SCHEMA_FACET_MINLENGTH
;
6783 xmlSchemaPErr2(ctxt
, node
, child
, XML_SCHEMAP_UNKNOWN_FACET_TYPE
,
6784 "Unknown facet type %s\n", node
->name
, NULL
);
6785 xmlSchemaFreeFacet(facet
);
6788 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
6789 facet
->value
= value
;
6790 if ((facet
->type
!= XML_SCHEMA_FACET_PATTERN
) &&
6791 (facet
->type
!= XML_SCHEMA_FACET_ENUMERATION
)) {
6792 const xmlChar
*fixed
;
6794 fixed
= xmlSchemaGetProp(ctxt
, node
, "fixed");
6795 if (fixed
!= NULL
) {
6796 if (xmlStrEqual(fixed
, BAD_CAST
"true"))
6800 child
= node
->children
;
6802 if (IS_SCHEMA(child
, "annotation")) {
6803 facet
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
6804 child
= child
->next
;
6806 if (child
!= NULL
) {
6807 xmlSchemaPErr2(ctxt
, node
, child
, XML_SCHEMAP_UNKNOWN_FACET_CHILD
,
6808 "Facet %s has unexpected child content\n",
6815 * xmlSchemaParseWildcardNs:
6816 * @ctxt: a schema parser context
6817 * @wildc: the wildcard, already created
6818 * @node: a subtree containing XML Schema information
6820 * Parses the attribute "processContents" and "namespace"
6821 * of a xsd:anyAttribute and xsd:any.
6822 * *WARNING* this interface is highly subject to change
6824 * Returns 0 if everything goes fine, a positive error code
6825 * if something is not valid and -1 if an internal error occurs.
6828 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt
,
6829 xmlSchemaPtr schema ATTRIBUTE_UNUSED
,
6830 xmlSchemaWildcardPtr wildc
,
6833 const xmlChar
*pc
, *ns
, *dictnsItem
;
6836 xmlSchemaWildcardNsPtr tmp
, lastNs
= NULL
;
6839 pc
= xmlSchemaGetProp(ctxt
, node
, "processContents");
6841 || (xmlStrEqual(pc
, (const xmlChar
*) "strict"))) {
6842 wildc
->processContents
= XML_SCHEMAS_ANY_STRICT
;
6843 } else if (xmlStrEqual(pc
, (const xmlChar
*) "skip")) {
6844 wildc
->processContents
= XML_SCHEMAS_ANY_SKIP
;
6845 } else if (xmlStrEqual(pc
, (const xmlChar
*) "lax")) {
6846 wildc
->processContents
= XML_SCHEMAS_ANY_LAX
;
6848 xmlSchemaPSimpleTypeErr(ctxt
,
6849 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
6851 NULL
, "(strict | skip | lax)", pc
,
6853 wildc
->processContents
= XML_SCHEMAS_ANY_STRICT
;
6854 ret
= XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
;
6857 * Build the namespace constraints.
6859 attr
= xmlSchemaGetPropNode(node
, "namespace");
6860 ns
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
6863 if ((attr
== NULL
) || (xmlStrEqual(ns
, BAD_CAST
"##any")))
6865 else if (xmlStrEqual(ns
, BAD_CAST
"##other")) {
6866 wildc
->negNsSet
= xmlSchemaNewWildcardNsConstraint(ctxt
);
6867 if (wildc
->negNsSet
== NULL
) {
6870 wildc
->negNsSet
->value
= ctxt
->targetNamespace
;
6872 const xmlChar
*end
, *cur
;
6876 while (IS_BLANK_CH(*cur
))
6879 while ((*end
!= 0) && (!(IS_BLANK_CH(*end
))))
6883 nsItem
= xmlStrndup(cur
, end
- cur
);
6884 if ((xmlStrEqual(nsItem
, BAD_CAST
"##other")) ||
6885 (xmlStrEqual(nsItem
, BAD_CAST
"##any"))) {
6886 xmlSchemaPSimpleTypeErr(ctxt
,
6887 XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER
,
6888 NULL
, (xmlNodePtr
) attr
,
6890 "((##any | ##other) | List of (xs:anyURI | "
6891 "(##targetNamespace | ##local)))",
6892 nsItem
, NULL
, NULL
, NULL
);
6893 ret
= XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER
;
6895 if (xmlStrEqual(nsItem
, BAD_CAST
"##targetNamespace")) {
6896 dictnsItem
= ctxt
->targetNamespace
;
6897 } else if (xmlStrEqual(nsItem
, BAD_CAST
"##local")) {
6901 * Validate the item (anyURI).
6903 xmlSchemaPValAttrNodeValue(ctxt
, NULL
, attr
,
6904 nsItem
, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI
));
6905 dictnsItem
= xmlDictLookup(ctxt
->dict
, nsItem
, -1);
6908 * Avoid duplicate namespaces.
6911 while (tmp
!= NULL
) {
6912 if (dictnsItem
== tmp
->value
)
6917 tmp
= xmlSchemaNewWildcardNsConstraint(ctxt
);
6922 tmp
->value
= dictnsItem
;
6924 if (wildc
->nsSet
== NULL
)
6926 else if (lastNs
!= NULL
)
6934 } while (*cur
!= 0);
6940 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt
,
6941 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED
,
6946 if ((maxOccurs
== 0) && ( minOccurs
== 0))
6948 if (maxOccurs
!= UNBOUNDED
) {
6950 * TODO: Maybe we should better not create the particle,
6951 * if min/max is invalid, since it could confuse the build of the
6955 * 3.9.6 Schema Component Constraint: Particle Correct
6958 if (maxOccurs
< 1) {
6960 * 2.2 {max occurs} must be greater than or equal to 1.
6962 xmlSchemaPCustomAttrErr(ctxt
,
6963 XML_SCHEMAP_P_PROPS_CORRECT_2_2
,
6965 xmlSchemaGetPropNode(node
, "maxOccurs"),
6966 "The value must be greater than or equal to 1");
6967 return (XML_SCHEMAP_P_PROPS_CORRECT_2_2
);
6968 } else if (minOccurs
> maxOccurs
) {
6970 * 2.1 {min occurs} must not be greater than {max occurs}.
6972 xmlSchemaPCustomAttrErr(ctxt
,
6973 XML_SCHEMAP_P_PROPS_CORRECT_2_1
,
6975 xmlSchemaGetPropNode(node
, "minOccurs"),
6976 "The value must not be greater than the value of 'maxOccurs'");
6977 return (XML_SCHEMAP_P_PROPS_CORRECT_2_1
);
6984 * xmlSchemaParseAny:
6985 * @ctxt: a schema validation context
6986 * @schema: the schema being built
6987 * @node: a subtree containing XML Schema information
6989 * Parsea a XML schema <any> element. A particle and wildcard
6990 * will be created (except if minOccurs==maxOccurs==0, in this case
6991 * nothing will be created).
6992 * *WARNING* this interface is highly subject to change
6994 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
6996 static xmlSchemaParticlePtr
6997 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
7000 xmlSchemaParticlePtr particle
;
7001 xmlNodePtr child
= NULL
;
7002 xmlSchemaWildcardPtr wild
;
7005 xmlSchemaAnnotPtr annot
= NULL
;
7007 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
7010 * Check for illegal attributes.
7012 attr
= node
->properties
;
7013 while (attr
!= NULL
) {
7014 if (attr
->ns
== NULL
) {
7015 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
7016 (!xmlStrEqual(attr
->name
, BAD_CAST
"minOccurs")) &&
7017 (!xmlStrEqual(attr
->name
, BAD_CAST
"maxOccurs")) &&
7018 (!xmlStrEqual(attr
->name
, BAD_CAST
"namespace")) &&
7019 (!xmlStrEqual(attr
->name
, BAD_CAST
"processContents"))) {
7020 xmlSchemaPIllegalAttrErr(ctxt
,
7021 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7023 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
7024 xmlSchemaPIllegalAttrErr(ctxt
,
7025 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7029 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
7031 * minOccurs/maxOccurs.
7033 max
= xmlGetMaxOccurs(ctxt
, node
, 0, UNBOUNDED
, 1,
7034 "(xs:nonNegativeInteger | unbounded)");
7035 min
= xmlGetMinOccurs(ctxt
, node
, 0, -1, 1,
7036 "xs:nonNegativeInteger");
7037 xmlSchemaPCheckParticleCorrect_2(ctxt
, NULL
, node
, min
, max
);
7039 * Create & parse the wildcard.
7041 wild
= xmlSchemaAddWildcard(ctxt
, schema
, XML_SCHEMA_TYPE_ANY
, node
);
7044 xmlSchemaParseWildcardNs(ctxt
, schema
, wild
, node
);
7046 * And now for the children...
7048 child
= node
->children
;
7049 if (IS_SCHEMA(child
, "annotation")) {
7050 annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
7051 child
= child
->next
;
7053 if (child
!= NULL
) {
7054 xmlSchemaPContentErr(ctxt
,
7055 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7057 NULL
, "(annotation?)");
7060 * No component if minOccurs==maxOccurs==0.
7062 if ((min
== 0) && (max
== 0)) {
7063 /* Don't free the wildcard, since it's already on the list. */
7067 * Create the particle.
7069 particle
= xmlSchemaAddParticle(ctxt
, node
, min
, max
);
7070 if (particle
== NULL
)
7072 particle
->annot
= annot
;
7073 particle
->children
= (xmlSchemaTreeItemPtr
) wild
;
7079 * xmlSchemaParseNotation:
7080 * @ctxt: a schema validation context
7081 * @schema: the schema being built
7082 * @node: a subtree containing XML Schema information
7084 * parse a XML schema Notation declaration
7086 * Returns the new structure or NULL in case of error
7088 static xmlSchemaNotationPtr
7089 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
7092 const xmlChar
*name
;
7093 xmlSchemaNotationPtr ret
;
7094 xmlNodePtr child
= NULL
;
7096 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
7098 name
= xmlSchemaGetProp(ctxt
, node
, "name");
7100 xmlSchemaPErr2(ctxt
, node
, child
, XML_SCHEMAP_NOTATION_NO_NAME
,
7101 "Notation has no name\n", NULL
, NULL
);
7104 ret
= xmlSchemaAddNotation(ctxt
, schema
, name
,
7105 ctxt
->targetNamespace
, node
);
7108 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
7110 child
= node
->children
;
7111 if (IS_SCHEMA(child
, "annotation")) {
7112 ret
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
7113 child
= child
->next
;
7115 if (child
!= NULL
) {
7116 xmlSchemaPContentErr(ctxt
,
7117 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7119 NULL
, "(annotation?)");
7126 * xmlSchemaParseAnyAttribute:
7127 * @ctxt: a schema validation context
7128 * @schema: the schema being built
7129 * @node: a subtree containing XML Schema information
7131 * parse a XML schema AnyAttribute declaration
7132 * *WARNING* this interface is highly subject to change
7134 * Returns a wildcard or NULL.
7136 static xmlSchemaWildcardPtr
7137 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt
,
7138 xmlSchemaPtr schema
, xmlNodePtr node
)
7140 xmlSchemaWildcardPtr ret
;
7141 xmlNodePtr child
= NULL
;
7144 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
7147 ret
= xmlSchemaAddWildcard(ctxt
, schema
, XML_SCHEMA_TYPE_ANY_ATTRIBUTE
,
7153 * Check for illegal attributes.
7155 attr
= node
->properties
;
7156 while (attr
!= NULL
) {
7157 if (attr
->ns
== NULL
) {
7158 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
7159 (!xmlStrEqual(attr
->name
, BAD_CAST
"namespace")) &&
7160 (!xmlStrEqual(attr
->name
, BAD_CAST
"processContents"))) {
7161 xmlSchemaPIllegalAttrErr(ctxt
,
7162 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7164 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
7165 xmlSchemaPIllegalAttrErr(ctxt
,
7166 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7170 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
7172 * Parse the namespace list.
7174 if (xmlSchemaParseWildcardNs(ctxt
, schema
, ret
, node
) != 0)
7177 * And now for the children...
7179 child
= node
->children
;
7180 if (IS_SCHEMA(child
, "annotation")) {
7181 ret
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
7182 child
= child
->next
;
7184 if (child
!= NULL
) {
7185 xmlSchemaPContentErr(ctxt
,
7186 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7188 NULL
, "(annotation?)");
7196 * xmlSchemaParseAttribute:
7197 * @ctxt: a schema validation context
7198 * @schema: the schema being built
7199 * @node: a subtree containing XML Schema information
7201 * parse a XML schema Attribute declaration
7202 * *WARNING* this interface is highly subject to change
7204 * Returns the attribute declaration.
7206 static xmlSchemaBasicItemPtr
7207 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt
,
7208 xmlSchemaPtr schema
,
7210 xmlSchemaItemListPtr uses
,
7213 const xmlChar
*attrValue
, *name
= NULL
, *ns
= NULL
;
7214 xmlSchemaAttributeUsePtr use
= NULL
;
7215 xmlNodePtr child
= NULL
;
7217 const xmlChar
*tmpNs
= NULL
, *tmpName
= NULL
, *defValue
= NULL
;
7218 int isRef
= 0, occurs
= XML_SCHEMAS_ATTR_USE_OPTIONAL
;
7219 int nberrors
, hasForm
= 0, defValueType
= 0;
7221 #define WXS_ATTR_DEF_VAL_DEFAULT 1
7222 #define WXS_ATTR_DEF_VAL_FIXED 2
7225 * 3.2.3 Constraints on XML Representations of Attribute Declarations
7228 if ((pctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
7230 attr
= xmlSchemaGetPropNode(node
, "ref");
7232 if (xmlSchemaPValAttrNodeQName(pctxt
, schema
,
7233 NULL
, attr
, &tmpNs
, &tmpName
) != 0) {
7236 if (xmlSchemaCheckReference(pctxt
, schema
, node
, attr
, tmpNs
) != 0)
7240 nberrors
= pctxt
->nberrors
;
7242 * Check for illegal attributes.
7244 attr
= node
->properties
;
7245 while (attr
!= NULL
) {
7246 if (attr
->ns
== NULL
) {
7248 if (xmlStrEqual(attr
->name
, BAD_CAST
"id")) {
7249 xmlSchemaPValAttrNodeID(pctxt
, attr
);
7251 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"ref")) {
7255 if (xmlStrEqual(attr
->name
, BAD_CAST
"name")) {
7257 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"id")) {
7258 xmlSchemaPValAttrNodeID(pctxt
, attr
);
7260 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"type")) {
7261 xmlSchemaPValAttrNodeQName(pctxt
, schema
, NULL
,
7262 attr
, &tmpNs
, &tmpName
);
7264 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"form")) {
7266 * Evaluate the target namespace
7269 attrValue
= xmlSchemaGetNodeContent(pctxt
,
7271 if (xmlStrEqual(attrValue
, BAD_CAST
"qualified")) {
7272 ns
= pctxt
->targetNamespace
;
7273 } else if (!xmlStrEqual(attrValue
, BAD_CAST
"unqualified"))
7275 xmlSchemaPSimpleTypeErr(pctxt
,
7276 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
7277 NULL
, (xmlNodePtr
) attr
,
7278 NULL
, "(qualified | unqualified)",
7279 attrValue
, NULL
, NULL
, NULL
);
7284 if (xmlStrEqual(attr
->name
, BAD_CAST
"use")) {
7286 attrValue
= xmlSchemaGetNodeContent(pctxt
, (xmlNodePtr
) attr
);
7287 /* TODO: Maybe we need to normalize the value beforehand. */
7288 if (xmlStrEqual(attrValue
, BAD_CAST
"optional"))
7289 occurs
= XML_SCHEMAS_ATTR_USE_OPTIONAL
;
7290 else if (xmlStrEqual(attrValue
, BAD_CAST
"prohibited"))
7291 occurs
= XML_SCHEMAS_ATTR_USE_PROHIBITED
;
7292 else if (xmlStrEqual(attrValue
, BAD_CAST
"required"))
7293 occurs
= XML_SCHEMAS_ATTR_USE_REQUIRED
;
7295 xmlSchemaPSimpleTypeErr(pctxt
,
7296 XML_SCHEMAP_INVALID_ATTR_USE
,
7297 NULL
, (xmlNodePtr
) attr
,
7298 NULL
, "(optional | prohibited | required)",
7299 attrValue
, NULL
, NULL
, NULL
);
7302 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"default")) {
7305 * default and fixed must not both be present.
7308 xmlSchemaPMutualExclAttrErr(pctxt
,
7309 XML_SCHEMAP_SRC_ATTRIBUTE_1
,
7310 NULL
, attr
, "default", "fixed");
7312 defValue
= xmlSchemaGetNodeContent(pctxt
, (xmlNodePtr
) attr
);
7313 defValueType
= WXS_ATTR_DEF_VAL_DEFAULT
;
7316 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"fixed")) {
7319 * default and fixed must not both be present.
7322 xmlSchemaPMutualExclAttrErr(pctxt
,
7323 XML_SCHEMAP_SRC_ATTRIBUTE_1
,
7324 NULL
, attr
, "default", "fixed");
7326 defValue
= xmlSchemaGetNodeContent(pctxt
, (xmlNodePtr
) attr
);
7327 defValueType
= WXS_ATTR_DEF_VAL_FIXED
;
7331 } else if (! xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
))
7334 xmlSchemaPIllegalAttrErr(pctxt
,
7335 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7342 * If default and use are both present, use must have
7343 * the actual value optional.
7345 if ((defValueType
== WXS_ATTR_DEF_VAL_DEFAULT
) &&
7346 (occurs
!= XML_SCHEMAS_ATTR_USE_OPTIONAL
)) {
7347 xmlSchemaPSimpleTypeErr(pctxt
,
7348 XML_SCHEMAP_SRC_ATTRIBUTE_2
,
7350 "(optional | prohibited | required)", NULL
,
7351 "The value of the attribute 'use' must be 'optional' "
7352 "if the attribute 'default' is present",
7356 * We want correct attributes.
7358 if (nberrors
!= pctxt
->nberrors
)
7361 xmlSchemaAttributePtr attrDecl
;
7363 /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
7364 if ((! hasForm
) && (schema
->flags
& XML_SCHEMAS_QUALIF_ATTR
))
7365 ns
= pctxt
->targetNamespace
;
7367 * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7368 * TODO: Move this to the component layer.
7370 if (xmlStrEqual(ns
, xmlSchemaInstanceNs
)) {
7371 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
7374 "The target namespace must not match '%s'",
7375 xmlSchemaInstanceNs
, NULL
);
7377 attr
= xmlSchemaGetPropNode(node
, "name");
7379 xmlSchemaPMissingAttrErr(pctxt
, XML_SCHEMAP_S4S_ATTR_MISSING
,
7380 NULL
, node
, "name", NULL
);
7383 if (xmlSchemaPValAttrNode(pctxt
, NULL
, attr
,
7384 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), &name
) != 0) {
7388 * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7389 * TODO: Move this to the component layer.
7391 if (xmlStrEqual(name
, BAD_CAST
"xmlns")) {
7392 xmlSchemaPSimpleTypeErr(pctxt
,
7393 XML_SCHEMAP_NO_XMLNS
,
7394 NULL
, (xmlNodePtr
) attr
,
7395 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), NULL
, NULL
,
7396 "The value of the attribute must not match 'xmlns'",
7400 if (occurs
== XML_SCHEMAS_ATTR_USE_PROHIBITED
)
7401 goto check_children
;
7403 * Create the attribute use component.
7405 use
= xmlSchemaAddAttributeUse(pctxt
, node
);
7408 use
->occurs
= occurs
;
7410 * Create the attribute declaration.
7412 attrDecl
= xmlSchemaAddAttribute(pctxt
, schema
, name
, ns
, node
, 0);
7413 if (attrDecl
== NULL
)
7415 if (tmpName
!= NULL
) {
7416 attrDecl
->typeName
= tmpName
;
7417 attrDecl
->typeNs
= tmpNs
;
7419 use
->attrDecl
= attrDecl
;
7423 if (defValue
!= NULL
) {
7424 attrDecl
->defValue
= defValue
;
7425 if (defValueType
== WXS_ATTR_DEF_VAL_FIXED
)
7426 attrDecl
->flags
|= XML_SCHEMAS_ATTR_FIXED
;
7428 } else if (occurs
!= XML_SCHEMAS_ATTR_USE_PROHIBITED
) {
7429 xmlSchemaQNameRefPtr ref
;
7432 * Create the attribute use component.
7434 use
= xmlSchemaAddAttributeUse(pctxt
, node
);
7438 * We need to resolve the reference at later stage.
7440 WXS_ADD_PENDING(pctxt
, use
);
7441 use
->occurs
= occurs
;
7443 * Create a QName reference to the attribute declaration.
7445 ref
= xmlSchemaNewQNameRef(pctxt
, XML_SCHEMA_TYPE_ATTRIBUTE
,
7450 * Assign the reference. This will be substituted for the
7451 * referenced attribute declaration when the QName is resolved.
7453 use
->attrDecl
= WXS_ATTR_CAST ref
;
7457 if (defValue
!= NULL
)
7458 use
->defValue
= defValue
;
7459 if (defValueType
== WXS_ATTR_DEF_VAL_FIXED
)
7460 use
->flags
|= XML_SCHEMA_ATTR_USE_FIXED
;
7465 * And now for the children...
7467 child
= node
->children
;
7468 if (occurs
== XML_SCHEMAS_ATTR_USE_PROHIBITED
) {
7469 xmlSchemaAttributeUseProhibPtr prohib
;
7471 if (IS_SCHEMA(child
, "annotation")) {
7472 xmlSchemaParseAnnotation(pctxt
, child
, 0);
7473 child
= child
->next
;
7475 if (child
!= NULL
) {
7476 xmlSchemaPContentErr(pctxt
,
7477 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7478 NULL
, node
, child
, NULL
,
7482 * Check for pointlessness of attribute prohibitions.
7484 if (parentType
== XML_SCHEMA_TYPE_ATTRIBUTEGROUP
) {
7485 xmlSchemaCustomWarning(ACTXT_CAST pctxt
,
7486 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH
,
7488 "Skipping attribute use prohibition, since it is "
7489 "pointless inside an <attributeGroup>",
7492 } else if (parentType
== XML_SCHEMA_TYPE_EXTENSION
) {
7493 xmlSchemaCustomWarning(ACTXT_CAST pctxt
,
7494 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH
,
7496 "Skipping attribute use prohibition, since it is "
7497 "pointless when extending a type",
7506 * Check for duplicate attribute prohibitions.
7511 for (i
= 0; i
< uses
->nbItems
; i
++) {
7512 use
= uses
->items
[i
];
7513 if ((use
->type
== XML_SCHEMA_EXTRA_ATTR_USE_PROHIB
) &&
7514 (tmpName
== (WXS_ATTR_PROHIB_CAST use
)->name
) &&
7515 (tmpNs
== (WXS_ATTR_PROHIB_CAST use
)->targetNamespace
))
7517 xmlChar
*str
= NULL
;
7519 xmlSchemaCustomWarning(ACTXT_CAST pctxt
,
7520 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH
,
7522 "Skipping duplicate attribute use prohibition '%s'",
7523 xmlSchemaFormatQName(&str
, tmpNs
, tmpName
),
7531 * Create the attribute prohibition helper component.
7533 prohib
= xmlSchemaAddAttributeUseProhib(pctxt
);
7536 prohib
->node
= node
;
7537 prohib
->name
= tmpName
;
7538 prohib
->targetNamespace
= tmpNs
;
7541 * We need at least to resolve to the attribute declaration.
7543 WXS_ADD_PENDING(pctxt
, prohib
);
7545 return(WXS_BASIC_CAST prohib
);
7547 if (IS_SCHEMA(child
, "annotation")) {
7549 * TODO: Should this go into the attr decl?
7551 use
->annot
= xmlSchemaParseAnnotation(pctxt
, child
, 1);
7552 child
= child
->next
;
7555 if (child
!= NULL
) {
7556 if (IS_SCHEMA(child
, "simpleType"))
7559 * If ref is present, then all of <simpleType>,
7560 * form and type must be absent.
7562 xmlSchemaPContentErr(pctxt
,
7563 XML_SCHEMAP_SRC_ATTRIBUTE_3_2
,
7564 NULL
, node
, child
, NULL
,
7567 xmlSchemaPContentErr(pctxt
,
7568 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7569 NULL
, node
, child
, NULL
,
7573 if (IS_SCHEMA(child
, "simpleType")) {
7574 if (WXS_ATTRUSE_DECL(use
)->typeName
!= NULL
) {
7577 * type and <simpleType> must not both be present.
7579 xmlSchemaPContentErr(pctxt
, XML_SCHEMAP_SRC_ATTRIBUTE_4
,
7581 "The attribute 'type' and the <simpleType> child "
7582 "are mutually exclusive", NULL
);
7584 WXS_ATTRUSE_TYPEDEF(use
) =
7585 xmlSchemaParseSimpleType(pctxt
, schema
, child
, 0);
7586 child
= child
->next
;
7589 xmlSchemaPContentErr(pctxt
, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7590 NULL
, node
, child
, NULL
,
7591 "(annotation?, simpleType?)");
7594 return (WXS_BASIC_CAST use
);
7598 static xmlSchemaAttributePtr
7599 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt
,
7600 xmlSchemaPtr schema
,
7603 const xmlChar
*attrValue
;
7604 xmlSchemaAttributePtr ret
;
7605 xmlNodePtr child
= NULL
;
7609 * Note that the w3c spec assumes the schema to be validated with schema
7610 * for schemas beforehand.
7612 * 3.2.3 Constraints on XML Representations of Attribute Declarations
7614 if ((pctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
7618 * One of ref or name must be present, but not both
7620 attr
= xmlSchemaGetPropNode(node
, "name");
7622 xmlSchemaPMissingAttrErr(pctxt
, XML_SCHEMAP_S4S_ATTR_MISSING
,
7623 NULL
, node
, "name", NULL
);
7626 if (xmlSchemaPValAttrNode(pctxt
, NULL
, attr
,
7627 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), &attrValue
) != 0) {
7631 * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7632 * TODO: Move this to the component layer.
7634 if (xmlStrEqual(attrValue
, BAD_CAST
"xmlns")) {
7635 xmlSchemaPSimpleTypeErr(pctxt
,
7636 XML_SCHEMAP_NO_XMLNS
,
7637 NULL
, (xmlNodePtr
) attr
,
7638 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), NULL
, NULL
,
7639 "The value of the attribute must not match 'xmlns'",
7644 * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7645 * TODO: Move this to the component layer.
7646 * Or better leave it here and add it to the component layer
7647 * if we have a schema construction API.
7649 if (xmlStrEqual(pctxt
->targetNamespace
, xmlSchemaInstanceNs
)) {
7650 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
7651 XML_SCHEMAP_NO_XSI
, node
, NULL
,
7652 "The target namespace must not match '%s'",
7653 xmlSchemaInstanceNs
, NULL
);
7656 ret
= xmlSchemaAddAttribute(pctxt
, schema
, attrValue
,
7657 pctxt
->targetNamespace
, node
, 1);
7660 ret
->flags
|= XML_SCHEMAS_ATTR_GLOBAL
;
7663 * Check for illegal attributes.
7665 attr
= node
->properties
;
7666 while (attr
!= NULL
) {
7667 if (attr
->ns
== NULL
) {
7668 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
7669 (!xmlStrEqual(attr
->name
, BAD_CAST
"default")) &&
7670 (!xmlStrEqual(attr
->name
, BAD_CAST
"fixed")) &&
7671 (!xmlStrEqual(attr
->name
, BAD_CAST
"name")) &&
7672 (!xmlStrEqual(attr
->name
, BAD_CAST
"type")))
7674 xmlSchemaPIllegalAttrErr(pctxt
,
7675 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7677 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
7678 xmlSchemaPIllegalAttrErr(pctxt
,
7679 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7683 xmlSchemaPValAttrQName(pctxt
, schema
, NULL
,
7684 node
, "type", &ret
->typeNs
, &ret
->typeName
);
7686 xmlSchemaPValAttrID(pctxt
, node
, BAD_CAST
"id");
7688 * Attribute "fixed".
7690 ret
->defValue
= xmlSchemaGetProp(pctxt
, node
, "fixed");
7691 if (ret
->defValue
!= NULL
)
7692 ret
->flags
|= XML_SCHEMAS_ATTR_FIXED
;
7694 * Attribute "default".
7696 attr
= xmlSchemaGetPropNode(node
, "default");
7700 * default and fixed must not both be present.
7702 if (ret
->flags
& XML_SCHEMAS_ATTR_FIXED
) {
7703 xmlSchemaPMutualExclAttrErr(pctxt
, XML_SCHEMAP_SRC_ATTRIBUTE_1
,
7704 WXS_BASIC_CAST ret
, attr
, "default", "fixed");
7706 ret
->defValue
= xmlSchemaGetNodeContent(pctxt
, (xmlNodePtr
) attr
);
7709 * And now for the children...
7711 child
= node
->children
;
7712 if (IS_SCHEMA(child
, "annotation")) {
7713 ret
->annot
= xmlSchemaParseAnnotation(pctxt
, child
, 1);
7714 child
= child
->next
;
7716 if (IS_SCHEMA(child
, "simpleType")) {
7717 if (ret
->typeName
!= NULL
) {
7720 * type and <simpleType> must not both be present.
7722 xmlSchemaPContentErr(pctxt
, XML_SCHEMAP_SRC_ATTRIBUTE_4
,
7724 "The attribute 'type' and the <simpleType> child "
7725 "are mutually exclusive", NULL
);
7727 ret
->subtypes
= xmlSchemaParseSimpleType(pctxt
, schema
, child
, 0);
7728 child
= child
->next
;
7731 xmlSchemaPContentErr(pctxt
, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7732 NULL
, node
, child
, NULL
,
7733 "(annotation?, simpleType?)");
7739 * xmlSchemaParseAttributeGroupRef:
7740 * @ctxt: a schema validation context
7741 * @schema: the schema being built
7742 * @node: a subtree containing XML Schema information
7744 * Parse an attribute group definition reference.
7745 * Note that a reference to an attribute group does not
7746 * correspond to any component at all.
7747 * *WARNING* this interface is highly subject to change
7749 * Returns the attribute group or NULL in case of error.
7751 static xmlSchemaQNameRefPtr
7752 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt
,
7753 xmlSchemaPtr schema
,
7756 xmlSchemaQNameRefPtr ret
;
7757 xmlNodePtr child
= NULL
;
7759 const xmlChar
*refNs
= NULL
, *ref
= NULL
;
7761 if ((pctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
7764 attr
= xmlSchemaGetPropNode(node
, "ref");
7766 xmlSchemaPMissingAttrErr(pctxt
,
7767 XML_SCHEMAP_S4S_ATTR_MISSING
,
7768 NULL
, node
, "ref", NULL
);
7771 xmlSchemaPValAttrNodeQName(pctxt
, schema
,
7772 NULL
, attr
, &refNs
, &ref
);
7773 if (xmlSchemaCheckReference(pctxt
, schema
, node
, attr
, refNs
) != 0)
7777 * Check for illegal attributes.
7779 attr
= node
->properties
;
7780 while (attr
!= NULL
) {
7781 if (attr
->ns
== NULL
) {
7782 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"ref")) &&
7783 (!xmlStrEqual(attr
->name
, BAD_CAST
"id")))
7785 xmlSchemaPIllegalAttrErr(pctxt
,
7786 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7788 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
7789 xmlSchemaPIllegalAttrErr(pctxt
,
7790 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7795 xmlSchemaPValAttrID(pctxt
, node
, BAD_CAST
"id");
7798 * And now for the children...
7800 child
= node
->children
;
7801 if (IS_SCHEMA(child
, "annotation")) {
7803 * TODO: We do not have a place to store the annotation, do we?
7805 xmlSchemaParseAnnotation(pctxt
, child
, 0);
7806 child
= child
->next
;
7808 if (child
!= NULL
) {
7809 xmlSchemaPContentErr(pctxt
,
7810 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7811 NULL
, node
, child
, NULL
,
7816 * Handle attribute group redefinitions.
7818 if (pctxt
->isRedefine
&& pctxt
->redef
&&
7819 (pctxt
->redef
->item
->type
==
7820 XML_SCHEMA_TYPE_ATTRIBUTEGROUP
) &&
7821 (ref
== pctxt
->redef
->refName
) &&
7822 (refNs
== pctxt
->redef
->refTargetNs
))
7825 * SPEC src-redefine:
7826 * (7.1) "If it has an <attributeGroup> among its contents
7827 * the `actual value` of whose ref [attribute] is the same
7828 * as the `actual value` of its own name attribute plus
7829 * target namespace, then it must have exactly one such group."
7831 if (pctxt
->redefCounter
!= 0) {
7832 xmlChar
*str
= NULL
;
7834 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
7835 XML_SCHEMAP_SRC_REDEFINE
, node
, NULL
,
7836 "The redefining attribute group definition "
7837 "'%s' must not contain more than one "
7838 "reference to the redefined definition",
7839 xmlSchemaFormatQName(&str
, refNs
, ref
), NULL
);
7843 pctxt
->redefCounter
++;
7845 * URGENT TODO: How to ensure that the reference will not be
7846 * handled by the normal component resolution mechanism?
7848 ret
= xmlSchemaNewQNameRef(pctxt
,
7849 XML_SCHEMA_TYPE_ATTRIBUTEGROUP
, ref
, refNs
);
7853 pctxt
->redef
->reference
= WXS_BASIC_CAST ret
;
7856 * Create a QName-reference helper component. We will substitute this
7857 * component for the attribute uses of the referenced attribute group
7860 ret
= xmlSchemaNewQNameRef(pctxt
,
7861 XML_SCHEMA_TYPE_ATTRIBUTEGROUP
, ref
, refNs
);
7865 /* Add to pending items, to be able to resolve the reference. */
7866 WXS_ADD_PENDING(pctxt
, ret
);
7872 * xmlSchemaParseAttributeGroupDefinition:
7873 * @pctxt: a schema validation context
7874 * @schema: the schema being built
7875 * @node: a subtree containing XML Schema information
7877 * parse a XML schema Attribute Group declaration
7878 * *WARNING* this interface is highly subject to change
7880 * Returns the attribute group definition or NULL in case of error.
7882 static xmlSchemaAttributeGroupPtr
7883 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt
,
7884 xmlSchemaPtr schema
,
7887 const xmlChar
*name
;
7888 xmlSchemaAttributeGroupPtr ret
;
7889 xmlNodePtr child
= NULL
;
7893 if ((pctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
7896 attr
= xmlSchemaGetPropNode(node
, "name");
7898 xmlSchemaPMissingAttrErr(pctxt
,
7899 XML_SCHEMAP_S4S_ATTR_MISSING
,
7900 NULL
, node
, "name", NULL
);
7904 * The name is crucial, exit if invalid.
7906 if (xmlSchemaPValAttrNode(pctxt
,
7908 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), &name
) != 0) {
7911 ret
= xmlSchemaAddAttributeGroupDefinition(pctxt
, schema
,
7912 name
, pctxt
->targetNamespace
, node
);
7916 * Check for illegal attributes.
7918 attr
= node
->properties
;
7919 while (attr
!= NULL
) {
7920 if (attr
->ns
== NULL
) {
7921 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"name")) &&
7922 (!xmlStrEqual(attr
->name
, BAD_CAST
"id")))
7924 xmlSchemaPIllegalAttrErr(pctxt
,
7925 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7927 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
7928 xmlSchemaPIllegalAttrErr(pctxt
,
7929 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7934 xmlSchemaPValAttrID(pctxt
, node
, BAD_CAST
"id");
7936 * And now for the children...
7938 child
= node
->children
;
7939 if (IS_SCHEMA(child
, "annotation")) {
7940 ret
->annot
= xmlSchemaParseAnnotation(pctxt
, child
, 1);
7941 child
= child
->next
;
7944 * Parse contained attribute decls/refs.
7946 if (xmlSchemaParseLocalAttributes(pctxt
, schema
, &child
,
7947 (xmlSchemaItemListPtr
*) &(ret
->attrUses
),
7948 XML_SCHEMA_TYPE_ATTRIBUTEGROUP
, &hasRefs
) == -1)
7951 ret
->flags
|= XML_SCHEMAS_ATTRGROUP_HAS_REFS
;
7953 * Parse the attribute wildcard.
7955 if (IS_SCHEMA(child
, "anyAttribute")) {
7956 ret
->attributeWildcard
= xmlSchemaParseAnyAttribute(pctxt
,
7958 child
= child
->next
;
7960 if (child
!= NULL
) {
7961 xmlSchemaPContentErr(pctxt
,
7962 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7963 NULL
, node
, child
, NULL
,
7964 "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
7970 * xmlSchemaPValAttrFormDefault:
7972 * @flags: the flags to be modified
7973 * @flagQualified: the specific flag for "qualified"
7975 * Returns 0 if the value is valid, 1 otherwise.
7978 xmlSchemaPValAttrFormDefault(const xmlChar
*value
,
7982 if (xmlStrEqual(value
, BAD_CAST
"qualified")) {
7983 if ((*flags
& flagQualified
) == 0)
7984 *flags
|= flagQualified
;
7985 } else if (!xmlStrEqual(value
, BAD_CAST
"unqualified"))
7992 * xmlSchemaPValAttrBlockFinal:
7994 * @flags: the flags to be modified
7995 * @flagAll: the specific flag for "#all"
7996 * @flagExtension: the specific flag for "extension"
7997 * @flagRestriction: the specific flag for "restriction"
7998 * @flagSubstitution: the specific flag for "substitution"
7999 * @flagList: the specific flag for "list"
8000 * @flagUnion: the specific flag for "union"
8002 * Validates the value of the attribute "final" and "block". The value
8003 * is converted into the specified flag values and returned in @flags.
8005 * Returns 0 if the value is valid, 1 otherwise.
8009 xmlSchemaPValAttrBlockFinal(const xmlChar
*value
,
8013 int flagRestriction
,
8014 int flagSubstitution
,
8021 * TODO: This does not check for duplicate entries.
8023 if ((flags
== NULL
) || (value
== NULL
))
8027 if (xmlStrEqual(value
, BAD_CAST
"#all")) {
8031 if (flagExtension
!= -1)
8032 *flags
|= flagExtension
;
8033 if (flagRestriction
!= -1)
8034 *flags
|= flagRestriction
;
8035 if (flagSubstitution
!= -1)
8036 *flags
|= flagSubstitution
;
8039 if (flagUnion
!= -1)
8040 *flags
|= flagUnion
;
8043 const xmlChar
*end
, *cur
= value
;
8047 while (IS_BLANK_CH(*cur
))
8050 while ((*end
!= 0) && (!(IS_BLANK_CH(*end
))))
8054 item
= xmlStrndup(cur
, end
- cur
);
8055 if (xmlStrEqual(item
, BAD_CAST
"extension")) {
8056 if (flagExtension
!= -1) {
8057 if ((*flags
& flagExtension
) == 0)
8058 *flags
|= flagExtension
;
8061 } else if (xmlStrEqual(item
, BAD_CAST
"restriction")) {
8062 if (flagRestriction
!= -1) {
8063 if ((*flags
& flagRestriction
) == 0)
8064 *flags
|= flagRestriction
;
8067 } else if (xmlStrEqual(item
, BAD_CAST
"substitution")) {
8068 if (flagSubstitution
!= -1) {
8069 if ((*flags
& flagSubstitution
) == 0)
8070 *flags
|= flagSubstitution
;
8073 } else if (xmlStrEqual(item
, BAD_CAST
"list")) {
8074 if (flagList
!= -1) {
8075 if ((*flags
& flagList
) == 0)
8079 } else if (xmlStrEqual(item
, BAD_CAST
"union")) {
8080 if (flagUnion
!= -1) {
8081 if ((*flags
& flagUnion
) == 0)
8082 *flags
|= flagUnion
;
8090 } while ((ret
== 0) && (*cur
!= 0));
8097 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt
,
8098 xmlSchemaIDCPtr idc
,
8099 xmlSchemaIDCSelectPtr selector
,
8107 * Schema Component Constraint: Selector Value OK
8109 * TODO: 1 The {selector} must be a valid XPath expression, as defined
8112 if (selector
== NULL
) {
8113 xmlSchemaPErr(ctxt
, idc
->node
,
8114 XML_SCHEMAP_INTERNAL
,
8115 "Internal error: xmlSchemaCheckCSelectorXPath, "
8116 "the selector is not specified.\n", NULL
, NULL
);
8122 node
= (xmlNodePtr
) attr
;
8123 if (selector
->xpath
== NULL
) {
8124 xmlSchemaPCustomErr(ctxt
,
8125 /* TODO: Adjust error code. */
8126 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
8128 "The XPath expression of the selector is not valid", NULL
);
8129 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
);
8131 const xmlChar
**nsArray
= NULL
;
8132 xmlNsPtr
*nsList
= NULL
;
8134 * Compile the XPath expression.
8137 * TODO: We need the array of in-scope namespaces for compilation.
8138 * TODO: Call xmlPatterncompile with different options for selector/
8144 nsList
= xmlGetNsList(attr
->doc
, attr
->parent
);
8146 * Build an array of prefixes and namespaces.
8148 if (nsList
!= NULL
) {
8151 for (i
= 0; nsList
[i
] != NULL
; i
++)
8154 nsArray
= (const xmlChar
**) xmlMalloc(
8155 (count
* 2 + 1) * sizeof(const xmlChar
*));
8156 if (nsArray
== NULL
) {
8157 xmlSchemaPErrMemory(ctxt
, "allocating a namespace array",
8162 for (i
= 0; i
< count
; i
++) {
8163 nsArray
[2 * i
] = nsList
[i
]->href
;
8164 nsArray
[2 * i
+ 1] = nsList
[i
]->prefix
;
8166 nsArray
[count
* 2] = NULL
;
8170 * TODO: Differentiate between "selector" and "field".
8173 selector
->xpathComp
= (void *) xmlPatterncompile(selector
->xpath
,
8174 NULL
, XML_PATTERN_XSFIELD
, nsArray
);
8176 selector
->xpathComp
= (void *) xmlPatterncompile(selector
->xpath
,
8177 NULL
, XML_PATTERN_XSSEL
, nsArray
);
8178 if (nsArray
!= NULL
)
8179 xmlFree((xmlChar
**) nsArray
);
8181 if (selector
->xpathComp
== NULL
) {
8182 xmlSchemaPCustomErr(ctxt
,
8183 /* TODO: Adjust error code? */
8184 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
8186 "The XPath expression '%s' could not be "
8187 "compiled", selector
->xpath
);
8188 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
);
8194 #define ADD_ANNOTATION(annot) \
8195 xmlSchemaAnnotPtr cur = item->annot; \
8196 if (item->annot == NULL) { \
8197 item->annot = annot; \
8200 cur = item->annot; \
8201 if (cur->next != NULL) { \
8207 * xmlSchemaAssignAnnotation:
8208 * @item: the schema component
8209 * @annot: the annotation
8211 * Adds the annotation to the given schema component.
8213 * Returns the given annotation.
8215 static xmlSchemaAnnotPtr
8216 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem
,
8217 xmlSchemaAnnotPtr annot
)
8219 if ((annItem
== NULL
) || (annot
== NULL
))
8221 switch (annItem
->type
) {
8222 case XML_SCHEMA_TYPE_ELEMENT
: {
8223 xmlSchemaElementPtr item
= (xmlSchemaElementPtr
) annItem
;
8224 ADD_ANNOTATION(annot
)
8227 case XML_SCHEMA_TYPE_ATTRIBUTE
: {
8228 xmlSchemaAttributePtr item
= (xmlSchemaAttributePtr
) annItem
;
8229 ADD_ANNOTATION(annot
)
8232 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE
:
8233 case XML_SCHEMA_TYPE_ANY
: {
8234 xmlSchemaWildcardPtr item
= (xmlSchemaWildcardPtr
) annItem
;
8235 ADD_ANNOTATION(annot
)
8238 case XML_SCHEMA_TYPE_PARTICLE
:
8239 case XML_SCHEMA_TYPE_IDC_KEY
:
8240 case XML_SCHEMA_TYPE_IDC_KEYREF
:
8241 case XML_SCHEMA_TYPE_IDC_UNIQUE
: {
8242 xmlSchemaAnnotItemPtr item
= (xmlSchemaAnnotItemPtr
) annItem
;
8243 ADD_ANNOTATION(annot
)
8246 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
: {
8247 xmlSchemaAttributeGroupPtr item
=
8248 (xmlSchemaAttributeGroupPtr
) annItem
;
8249 ADD_ANNOTATION(annot
)
8252 case XML_SCHEMA_TYPE_NOTATION
: {
8253 xmlSchemaNotationPtr item
= (xmlSchemaNotationPtr
) annItem
;
8254 ADD_ANNOTATION(annot
)
8257 case XML_SCHEMA_FACET_MININCLUSIVE
:
8258 case XML_SCHEMA_FACET_MINEXCLUSIVE
:
8259 case XML_SCHEMA_FACET_MAXINCLUSIVE
:
8260 case XML_SCHEMA_FACET_MAXEXCLUSIVE
:
8261 case XML_SCHEMA_FACET_TOTALDIGITS
:
8262 case XML_SCHEMA_FACET_FRACTIONDIGITS
:
8263 case XML_SCHEMA_FACET_PATTERN
:
8264 case XML_SCHEMA_FACET_ENUMERATION
:
8265 case XML_SCHEMA_FACET_WHITESPACE
:
8266 case XML_SCHEMA_FACET_LENGTH
:
8267 case XML_SCHEMA_FACET_MAXLENGTH
:
8268 case XML_SCHEMA_FACET_MINLENGTH
: {
8269 xmlSchemaFacetPtr item
= (xmlSchemaFacetPtr
) annItem
;
8270 ADD_ANNOTATION(annot
)
8273 case XML_SCHEMA_TYPE_SIMPLE
:
8274 case XML_SCHEMA_TYPE_COMPLEX
: {
8275 xmlSchemaTypePtr item
= (xmlSchemaTypePtr
) annItem
;
8276 ADD_ANNOTATION(annot
)
8279 case XML_SCHEMA_TYPE_GROUP
: {
8280 xmlSchemaModelGroupDefPtr item
= (xmlSchemaModelGroupDefPtr
) annItem
;
8281 ADD_ANNOTATION(annot
)
8284 case XML_SCHEMA_TYPE_SEQUENCE
:
8285 case XML_SCHEMA_TYPE_CHOICE
:
8286 case XML_SCHEMA_TYPE_ALL
: {
8287 xmlSchemaModelGroupPtr item
= (xmlSchemaModelGroupPtr
) annItem
;
8288 ADD_ANNOTATION(annot
)
8292 xmlSchemaPCustomErr(NULL
,
8293 XML_SCHEMAP_INTERNAL
,
8295 "Internal error: xmlSchemaAddAnnotation, "
8296 "The item is not a annotated schema component", NULL
);
8303 * xmlSchemaParseIDCSelectorAndField:
8304 * @ctxt: a schema validation context
8305 * @schema: the schema being built
8306 * @node: a subtree containing XML Schema information
8308 * Parses a XML Schema identity-constraint definition's
8309 * <selector> and <field> elements.
8311 * Returns the parsed identity-constraint definition.
8313 static xmlSchemaIDCSelectPtr
8314 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt
,
8315 xmlSchemaIDCPtr idc
,
8319 xmlSchemaIDCSelectPtr item
;
8320 xmlNodePtr child
= NULL
;
8324 * Check for illegal attributes.
8326 attr
= node
->properties
;
8327 while (attr
!= NULL
) {
8328 if (attr
->ns
== NULL
) {
8329 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
8330 (!xmlStrEqual(attr
->name
, BAD_CAST
"xpath"))) {
8331 xmlSchemaPIllegalAttrErr(ctxt
,
8332 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8334 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
8335 xmlSchemaPIllegalAttrErr(ctxt
,
8336 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8343 item
= (xmlSchemaIDCSelectPtr
) xmlMalloc(sizeof(xmlSchemaIDCSelect
));
8345 xmlSchemaPErrMemory(ctxt
,
8346 "allocating a 'selector' of an identity-constraint definition",
8350 memset(item
, 0, sizeof(xmlSchemaIDCSelect
));
8352 * Attribute "xpath" (mandatory).
8354 attr
= xmlSchemaGetPropNode(node
, "xpath");
8356 xmlSchemaPMissingAttrErr(ctxt
,
8357 XML_SCHEMAP_S4S_ATTR_MISSING
,
8361 item
->xpath
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
8363 * URGENT TODO: "field"s have an other syntax than "selector"s.
8366 if (xmlSchemaCheckCSelectorXPath(ctxt
, idc
, item
, attr
,
8370 XML_SCHEMAP_INTERNAL
,
8371 "Internal error: xmlSchemaParseIDCSelectorAndField, "
8372 "validating the XPath expression of a IDC selector.\n",
8377 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
8379 * And now for the children...
8381 child
= node
->children
;
8382 if (IS_SCHEMA(child
, "annotation")) {
8384 * Add the annotation to the parent IDC.
8386 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr
) idc
,
8387 xmlSchemaParseAnnotation(ctxt
, child
, 1));
8388 child
= child
->next
;
8390 if (child
!= NULL
) {
8391 xmlSchemaPContentErr(ctxt
,
8392 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
8394 NULL
, "(annotation?)");
8401 * xmlSchemaParseIDC:
8402 * @ctxt: a schema validation context
8403 * @schema: the schema being built
8404 * @node: a subtree containing XML Schema information
8406 * Parses a XML Schema identity-constraint definition.
8408 * Returns the parsed identity-constraint definition.
8410 static xmlSchemaIDCPtr
8411 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt
,
8412 xmlSchemaPtr schema
,
8414 xmlSchemaTypeType idcCategory
,
8415 const xmlChar
*targetNamespace
)
8417 xmlSchemaIDCPtr item
= NULL
;
8418 xmlNodePtr child
= NULL
;
8420 const xmlChar
*name
= NULL
;
8421 xmlSchemaIDCSelectPtr field
= NULL
, lastField
= NULL
;
8424 * Check for illegal attributes.
8426 attr
= node
->properties
;
8427 while (attr
!= NULL
) {
8428 if (attr
->ns
== NULL
) {
8429 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
8430 (!xmlStrEqual(attr
->name
, BAD_CAST
"name")) &&
8431 ((idcCategory
!= XML_SCHEMA_TYPE_IDC_KEYREF
) ||
8432 (!xmlStrEqual(attr
->name
, BAD_CAST
"refer")))) {
8433 xmlSchemaPIllegalAttrErr(ctxt
,
8434 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8436 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
8437 xmlSchemaPIllegalAttrErr(ctxt
,
8438 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8443 * Attribute "name" (mandatory).
8445 attr
= xmlSchemaGetPropNode(node
, "name");
8447 xmlSchemaPMissingAttrErr(ctxt
,
8448 XML_SCHEMAP_S4S_ATTR_MISSING
,
8452 } else if (xmlSchemaPValAttrNode(ctxt
,
8454 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), &name
) != 0) {
8457 /* Create the component. */
8458 item
= xmlSchemaAddIDC(ctxt
, schema
, name
, targetNamespace
,
8463 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
8464 if (idcCategory
== XML_SCHEMA_TYPE_IDC_KEYREF
) {
8466 * Attribute "refer" (mandatory).
8468 attr
= xmlSchemaGetPropNode(node
, "refer");
8470 xmlSchemaPMissingAttrErr(ctxt
,
8471 XML_SCHEMAP_S4S_ATTR_MISSING
,
8476 * Create a reference item.
8478 item
->ref
= xmlSchemaNewQNameRef(ctxt
, XML_SCHEMA_TYPE_IDC_KEY
,
8480 if (item
->ref
== NULL
)
8482 xmlSchemaPValAttrNodeQName(ctxt
, schema
,
8484 &(item
->ref
->targetNamespace
),
8485 &(item
->ref
->name
));
8486 xmlSchemaCheckReference(ctxt
, schema
, node
, attr
,
8487 item
->ref
->targetNamespace
);
8491 * And now for the children...
8493 child
= node
->children
;
8494 if (IS_SCHEMA(child
, "annotation")) {
8495 item
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
8496 child
= child
->next
;
8498 if (child
== NULL
) {
8499 xmlSchemaPContentErr(ctxt
,
8500 XML_SCHEMAP_S4S_ELEM_MISSING
,
8502 "A child element is missing",
8503 "(annotation?, (selector, field+))");
8506 * Child element <selector>.
8508 if (IS_SCHEMA(child
, "selector")) {
8509 item
->selector
= xmlSchemaParseIDCSelectorAndField(ctxt
,
8511 child
= child
->next
;
8513 * Child elements <field>.
8515 if (IS_SCHEMA(child
, "field")) {
8517 field
= xmlSchemaParseIDCSelectorAndField(ctxt
,
8519 if (field
!= NULL
) {
8520 field
->index
= item
->nbFields
;
8522 if (lastField
!= NULL
)
8523 lastField
->next
= field
;
8525 item
->fields
= field
;
8528 child
= child
->next
;
8529 } while (IS_SCHEMA(child
, "field"));
8531 xmlSchemaPContentErr(ctxt
,
8532 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
8534 NULL
, "(annotation?, (selector, field+))");
8537 if (child
!= NULL
) {
8538 xmlSchemaPContentErr(ctxt
,
8539 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
8541 NULL
, "(annotation?, (selector, field+))");
8548 * xmlSchemaParseElement:
8549 * @ctxt: a schema validation context
8550 * @schema: the schema being built
8551 * @node: a subtree containing XML Schema information
8552 * @topLevel: indicates if this is global declaration
8554 * Parses a XML schema element declaration.
8555 * *WARNING* this interface is highly subject to change
8557 * Returns the element declaration or a particle; NULL in case
8558 * of an error or if the particle has minOccurs==maxOccurs==0.
8560 static xmlSchemaBasicItemPtr
8561 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
8562 xmlNodePtr node
, int *isElemRef
, int topLevel
)
8564 xmlSchemaElementPtr decl
= NULL
;
8565 xmlSchemaParticlePtr particle
= NULL
;
8566 xmlSchemaAnnotPtr annot
= NULL
;
8567 xmlNodePtr child
= NULL
;
8568 xmlAttrPtr attr
, nameAttr
;
8569 int min
, max
, isRef
= 0;
8570 xmlChar
*des
= NULL
;
8572 /* 3.3.3 Constraints on XML Representations of Element Declarations */
8573 /* TODO: Complete implementation of 3.3.6 */
8575 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
8578 if (isElemRef
!= NULL
)
8581 * If we get a "ref" attribute on a local <element> we will assume it's
8582 * a reference - even if there's a "name" attribute; this seems to be more
8585 nameAttr
= xmlSchemaGetPropNode(node
, "name");
8586 attr
= xmlSchemaGetPropNode(node
, "ref");
8587 if ((topLevel
) || (attr
== NULL
)) {
8588 if (nameAttr
== NULL
) {
8589 xmlSchemaPMissingAttrErr(ctxt
,
8590 XML_SCHEMAP_S4S_ATTR_MISSING
,
8591 NULL
, node
, "name", NULL
);
8597 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
8598 child
= node
->children
;
8599 if (IS_SCHEMA(child
, "annotation")) {
8600 annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
8601 child
= child
->next
;
8604 * Skip particle part if a global declaration.
8607 goto declaration_part
;
8609 * The particle part ==================================================
8611 min
= xmlGetMinOccurs(ctxt
, node
, 0, -1, 1, "xs:nonNegativeInteger");
8612 max
= xmlGetMaxOccurs(ctxt
, node
, 0, UNBOUNDED
, 1, "(xs:nonNegativeInteger | unbounded)");
8613 xmlSchemaPCheckParticleCorrect_2(ctxt
, NULL
, node
, min
, max
);
8614 particle
= xmlSchemaAddParticle(ctxt
, node
, min
, max
);
8615 if (particle
== NULL
)
8618 /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
8621 const xmlChar
*refNs
= NULL
, *ref
= NULL
;
8622 xmlSchemaQNameRefPtr refer
= NULL
;
8624 * The reference part =============================================
8626 if (isElemRef
!= NULL
)
8629 xmlSchemaPValAttrNodeQName(ctxt
, schema
,
8630 NULL
, attr
, &refNs
, &ref
);
8631 xmlSchemaCheckReference(ctxt
, schema
, node
, attr
, refNs
);
8633 * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
8635 if (nameAttr
!= NULL
) {
8636 xmlSchemaPMutualExclAttrErr(ctxt
,
8637 XML_SCHEMAP_SRC_ELEMENT_2_1
, NULL
, nameAttr
, "ref", "name");
8640 * Check for illegal attributes.
8642 attr
= node
->properties
;
8643 while (attr
!= NULL
) {
8644 if (attr
->ns
== NULL
) {
8645 if (xmlStrEqual(attr
->name
, BAD_CAST
"ref") ||
8646 xmlStrEqual(attr
->name
, BAD_CAST
"name") ||
8647 xmlStrEqual(attr
->name
, BAD_CAST
"id") ||
8648 xmlStrEqual(attr
->name
, BAD_CAST
"maxOccurs") ||
8649 xmlStrEqual(attr
->name
, BAD_CAST
"minOccurs"))
8654 /* SPEC (3.3.3 : 2.2) */
8655 xmlSchemaPCustomAttrErr(ctxt
,
8656 XML_SCHEMAP_SRC_ELEMENT_2_2
,
8658 "Only the attributes 'minOccurs', 'maxOccurs' and "
8659 "'id' are allowed in addition to 'ref'");
8662 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
8663 xmlSchemaPIllegalAttrErr(ctxt
,
8664 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8669 * No children except <annotation> expected.
8671 if (child
!= NULL
) {
8672 xmlSchemaPContentErr(ctxt
, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
8673 NULL
, node
, child
, NULL
, "(annotation?)");
8675 if ((min
== 0) && (max
== 0))
8678 * Create the reference item and attach it to the particle.
8680 refer
= xmlSchemaNewQNameRef(ctxt
, XML_SCHEMA_TYPE_ELEMENT
,
8684 particle
->children
= (xmlSchemaTreeItemPtr
) refer
;
8685 particle
->annot
= annot
;
8687 * Add the particle to pending components, since the reference
8688 * need to be resolved.
8690 WXS_ADD_PENDING(ctxt
, particle
);
8691 return ((xmlSchemaBasicItemPtr
) particle
);
8694 * The declaration part ===============================================
8698 const xmlChar
*ns
= NULL
, *fixed
, *name
, *attrValue
;
8699 xmlSchemaIDCPtr curIDC
= NULL
, lastIDC
= NULL
;
8701 if (xmlSchemaPValAttrNode(ctxt
, NULL
, nameAttr
,
8702 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), &name
) != 0)
8705 * Evaluate the target namespace.
8708 ns
= ctxt
->targetNamespace
;
8710 attr
= xmlSchemaGetPropNode(node
, "form");
8712 attrValue
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
8713 if (xmlStrEqual(attrValue
, BAD_CAST
"qualified")) {
8714 ns
= ctxt
->targetNamespace
;
8715 } else if (!xmlStrEqual(attrValue
, BAD_CAST
"unqualified")) {
8716 xmlSchemaPSimpleTypeErr(ctxt
,
8717 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
8718 NULL
, (xmlNodePtr
) attr
,
8719 NULL
, "(qualified | unqualified)",
8720 attrValue
, NULL
, NULL
, NULL
);
8722 } else if (schema
->flags
& XML_SCHEMAS_QUALIF_ELEM
)
8723 ns
= ctxt
->targetNamespace
;
8725 decl
= xmlSchemaAddElement(ctxt
, name
, ns
, node
, topLevel
);
8730 * Check for illegal attributes.
8732 attr
= node
->properties
;
8733 while (attr
!= NULL
) {
8734 if (attr
->ns
== NULL
) {
8735 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"name")) &&
8736 (!xmlStrEqual(attr
->name
, BAD_CAST
"type")) &&
8737 (!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
8738 (!xmlStrEqual(attr
->name
, BAD_CAST
"default")) &&
8739 (!xmlStrEqual(attr
->name
, BAD_CAST
"fixed")) &&
8740 (!xmlStrEqual(attr
->name
, BAD_CAST
"block")) &&
8741 (!xmlStrEqual(attr
->name
, BAD_CAST
"nillable")))
8743 if (topLevel
== 0) {
8744 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"maxOccurs")) &&
8745 (!xmlStrEqual(attr
->name
, BAD_CAST
"minOccurs")) &&
8746 (!xmlStrEqual(attr
->name
, BAD_CAST
"form")))
8748 xmlSchemaPIllegalAttrErr(ctxt
,
8749 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8751 } else if ((!xmlStrEqual(attr
->name
, BAD_CAST
"final")) &&
8752 (!xmlStrEqual(attr
->name
, BAD_CAST
"abstract")) &&
8753 (!xmlStrEqual(attr
->name
, BAD_CAST
"substitutionGroup"))) {
8755 xmlSchemaPIllegalAttrErr(ctxt
,
8756 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8759 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
8761 xmlSchemaPIllegalAttrErr(ctxt
,
8762 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8767 * Extract/validate attributes.
8771 * Process top attributes of global element declarations here.
8773 decl
->flags
|= XML_SCHEMAS_ELEM_GLOBAL
;
8774 decl
->flags
|= XML_SCHEMAS_ELEM_TOPLEVEL
;
8775 xmlSchemaPValAttrQName(ctxt
, schema
,
8776 NULL
, node
, "substitutionGroup",
8777 &(decl
->substGroupNs
), &(decl
->substGroup
));
8778 if (xmlGetBooleanProp(ctxt
, node
, "abstract", 0))
8779 decl
->flags
|= XML_SCHEMAS_ELEM_ABSTRACT
;
8781 * Attribute "final".
8783 attr
= xmlSchemaGetPropNode(node
, "final");
8785 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_EXTENSION
)
8786 decl
->flags
|= XML_SCHEMAS_ELEM_FINAL_EXTENSION
;
8787 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION
)
8788 decl
->flags
|= XML_SCHEMAS_ELEM_FINAL_RESTRICTION
;
8790 attrValue
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
8791 if (xmlSchemaPValAttrBlockFinal(attrValue
, &(decl
->flags
),
8793 XML_SCHEMAS_ELEM_FINAL_EXTENSION
,
8794 XML_SCHEMAS_ELEM_FINAL_RESTRICTION
, -1, -1, -1) != 0) {
8795 xmlSchemaPSimpleTypeErr(ctxt
,
8796 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
8797 NULL
, (xmlNodePtr
) attr
,
8798 NULL
, "(#all | List of (extension | restriction))",
8799 attrValue
, NULL
, NULL
, NULL
);
8804 * Attribute "block".
8806 attr
= xmlSchemaGetPropNode(node
, "block");
8809 * Apply default "block" values.
8811 if (schema
->flags
& XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION
)
8812 decl
->flags
|= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION
;
8813 if (schema
->flags
& XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION
)
8814 decl
->flags
|= XML_SCHEMAS_ELEM_BLOCK_EXTENSION
;
8815 if (schema
->flags
& XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION
)
8816 decl
->flags
|= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION
;
8818 attrValue
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
8819 if (xmlSchemaPValAttrBlockFinal(attrValue
, &(decl
->flags
),
8821 XML_SCHEMAS_ELEM_BLOCK_EXTENSION
,
8822 XML_SCHEMAS_ELEM_BLOCK_RESTRICTION
,
8823 XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION
, -1, -1) != 0) {
8824 xmlSchemaPSimpleTypeErr(ctxt
,
8825 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
8826 NULL
, (xmlNodePtr
) attr
,
8827 NULL
, "(#all | List of (extension | "
8828 "restriction | substitution))", attrValue
,
8832 if (xmlGetBooleanProp(ctxt
, node
, "nillable", 0))
8833 decl
->flags
|= XML_SCHEMAS_ELEM_NILLABLE
;
8835 attr
= xmlSchemaGetPropNode(node
, "type");
8837 xmlSchemaPValAttrNodeQName(ctxt
, schema
,
8839 &(decl
->namedTypeNs
), &(decl
->namedType
));
8840 xmlSchemaCheckReference(ctxt
, schema
, node
,
8841 attr
, decl
->namedTypeNs
);
8843 decl
->value
= xmlSchemaGetProp(ctxt
, node
, "default");
8844 attr
= xmlSchemaGetPropNode(node
, "fixed");
8846 fixed
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
8847 if (decl
->value
!= NULL
) {
8850 * default and fixed must not both be present.
8852 xmlSchemaPMutualExclAttrErr(ctxt
,
8853 XML_SCHEMAP_SRC_ELEMENT_1
,
8854 NULL
, attr
, "default", "fixed");
8856 decl
->flags
|= XML_SCHEMAS_ELEM_FIXED
;
8857 decl
->value
= fixed
;
8861 * And now for the children...
8863 if (IS_SCHEMA(child
, "complexType")) {
8866 * "type" and either <simpleType> or <complexType> are mutually
8869 if (decl
->namedType
!= NULL
) {
8870 xmlSchemaPContentErr(ctxt
,
8871 XML_SCHEMAP_SRC_ELEMENT_3
,
8873 "The attribute 'type' and the <complexType> child are "
8874 "mutually exclusive", NULL
);
8876 WXS_ELEM_TYPEDEF(decl
) = xmlSchemaParseComplexType(ctxt
, schema
, child
, 0);
8877 child
= child
->next
;
8878 } else if (IS_SCHEMA(child
, "simpleType")) {
8881 * "type" and either <simpleType> or <complexType> are
8882 * mutually exclusive
8884 if (decl
->namedType
!= NULL
) {
8885 xmlSchemaPContentErr(ctxt
,
8886 XML_SCHEMAP_SRC_ELEMENT_3
,
8888 "The attribute 'type' and the <simpleType> child are "
8889 "mutually exclusive", NULL
);
8891 WXS_ELEM_TYPEDEF(decl
) = xmlSchemaParseSimpleType(ctxt
, schema
, child
, 0);
8892 child
= child
->next
;
8894 while ((IS_SCHEMA(child
, "unique")) ||
8895 (IS_SCHEMA(child
, "key")) || (IS_SCHEMA(child
, "keyref"))) {
8896 if (IS_SCHEMA(child
, "unique")) {
8897 curIDC
= xmlSchemaParseIDC(ctxt
, schema
, child
,
8898 XML_SCHEMA_TYPE_IDC_UNIQUE
, decl
->targetNamespace
);
8899 } else if (IS_SCHEMA(child
, "key")) {
8900 curIDC
= xmlSchemaParseIDC(ctxt
, schema
, child
,
8901 XML_SCHEMA_TYPE_IDC_KEY
, decl
->targetNamespace
);
8902 } else if (IS_SCHEMA(child
, "keyref")) {
8903 curIDC
= xmlSchemaParseIDC(ctxt
, schema
, child
,
8904 XML_SCHEMA_TYPE_IDC_KEYREF
, decl
->targetNamespace
);
8906 if (lastIDC
!= NULL
)
8907 lastIDC
->next
= curIDC
;
8909 decl
->idcs
= (void *) curIDC
;
8911 child
= child
->next
;
8913 if (child
!= NULL
) {
8914 xmlSchemaPContentErr(ctxt
,
8915 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
8917 NULL
, "(annotation?, ((simpleType | complexType)?, "
8918 "(unique | key | keyref)*))");
8920 decl
->annot
= annot
;
8923 * NOTE: Element Declaration Representation OK 4. will be checked at a
8928 return ((xmlSchemaBasicItemPtr
) decl
);
8930 particle
->children
= (xmlSchemaTreeItemPtr
) decl
;
8931 return ((xmlSchemaBasicItemPtr
) particle
);
8936 if (annot
!= NULL
) {
8937 if (particle
!= NULL
)
8938 particle
->annot
= NULL
;
8941 xmlSchemaFreeAnnot(annot
);
8947 * xmlSchemaParseUnion:
8948 * @ctxt: a schema validation context
8949 * @schema: the schema being built
8950 * @node: a subtree containing XML Schema information
8952 * parse a XML schema Union definition
8953 * *WARNING* this interface is highly subject to change
8955 * Returns -1 in case of internal error, 0 in case of success and a positive
8956 * error code otherwise.
8959 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
8962 xmlSchemaTypePtr type
;
8963 xmlNodePtr child
= NULL
;
8965 const xmlChar
*cur
= NULL
;
8967 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
8969 /* Not a component, don't create it. */
8970 type
= ctxt
->ctxtType
;
8972 * Mark the simple type as being of variety "union".
8974 type
->flags
|= XML_SCHEMAS_TYPE_VARIETY_UNION
;
8976 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
8977 * then the `simple ur-type definition`."
8979 type
->baseType
= xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE
);
8981 * Check for illegal attributes.
8983 attr
= node
->properties
;
8984 while (attr
!= NULL
) {
8985 if (attr
->ns
== NULL
) {
8986 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
8987 (!xmlStrEqual(attr
->name
, BAD_CAST
"memberTypes"))) {
8988 xmlSchemaPIllegalAttrErr(ctxt
,
8989 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8991 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
8992 xmlSchemaPIllegalAttrErr(ctxt
,
8993 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8997 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
8999 * Attribute "memberTypes". This is a list of QNames.
9000 * TODO: Check the value to contain anything.
9002 attr
= xmlSchemaGetPropNode(node
, "memberTypes");
9006 const xmlChar
*localName
, *nsName
;
9007 xmlSchemaTypeLinkPtr link
, lastLink
= NULL
;
9008 xmlSchemaQNameRefPtr ref
;
9010 cur
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
9015 while (IS_BLANK_CH(*cur
))
9018 while ((*end
!= 0) && (!(IS_BLANK_CH(*end
))))
9022 tmp
= xmlStrndup(cur
, end
- cur
);
9024 xmlSchemaPErrMemory(ctxt
, "xmlSchemaParseUnion, "
9025 "duplicating type name", NULL
);
9028 if (xmlSchemaPValAttrNodeQNameValue(ctxt
, schema
,
9029 NULL
, attr
, BAD_CAST tmp
, &nsName
, &localName
) == 0) {
9031 * Create the member type link.
9033 link
= (xmlSchemaTypeLinkPtr
)
9034 xmlMalloc(sizeof(xmlSchemaTypeLink
));
9036 xmlSchemaPErrMemory(ctxt
, "xmlSchemaParseUnion, "
9037 "allocating a type link", NULL
);
9043 if (lastLink
== NULL
)
9044 type
->memberTypes
= link
;
9046 lastLink
->next
= link
;
9049 * Create a reference item.
9051 ref
= xmlSchemaNewQNameRef(ctxt
, XML_SCHEMA_TYPE_SIMPLE
,
9058 * Assign the reference to the link, it will be resolved
9059 * later during fixup of the union simple type.
9061 link
->type
= (xmlSchemaTypePtr
) ref
;
9065 } while (*cur
!= 0);
9069 * And now for the children...
9071 child
= node
->children
;
9072 if (IS_SCHEMA(child
, "annotation")) {
9074 * Add the annotation to the simple type ancestor.
9076 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr
) type
,
9077 xmlSchemaParseAnnotation(ctxt
, child
, 1));
9078 child
= child
->next
;
9080 if (IS_SCHEMA(child
, "simpleType")) {
9081 xmlSchemaTypePtr subtype
, last
= NULL
;
9084 * Anchor the member types in the "subtypes" field of the
9087 while (IS_SCHEMA(child
, "simpleType")) {
9088 subtype
= (xmlSchemaTypePtr
)
9089 xmlSchemaParseSimpleType(ctxt
, schema
, child
, 0);
9090 if (subtype
!= NULL
) {
9092 type
->subtypes
= subtype
;
9095 last
->next
= subtype
;
9100 child
= child
->next
;
9103 if (child
!= NULL
) {
9104 xmlSchemaPContentErr(ctxt
,
9105 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
9106 NULL
, node
, child
, NULL
, "(annotation?, simpleType*)");
9108 if ((attr
== NULL
) && (type
->subtypes
== NULL
)) {
9110 * src-union-memberTypes-or-simpleTypes
9111 * Either the memberTypes [attribute] of the <union> element must
9112 * be non-empty or there must be at least one simpleType [child].
9114 xmlSchemaPCustomErr(ctxt
,
9115 XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES
,
9117 "Either the attribute 'memberTypes' or "
9118 "at least one <simpleType> child must be present", NULL
);
9124 * xmlSchemaParseList:
9125 * @ctxt: a schema validation context
9126 * @schema: the schema being built
9127 * @node: a subtree containing XML Schema information
9129 * parse a XML schema List definition
9130 * *WARNING* this interface is highly subject to change
9132 * Returns -1 in case of error, 0 if the declaration is improper and
9133 * 1 in case of success.
9135 static xmlSchemaTypePtr
9136 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
9139 xmlSchemaTypePtr type
;
9140 xmlNodePtr child
= NULL
;
9143 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
9145 /* Not a component, don't create it. */
9146 type
= ctxt
->ctxtType
;
9148 * Mark the type as being of variety "list".
9150 type
->flags
|= XML_SCHEMAS_TYPE_VARIETY_LIST
;
9152 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
9153 * then the `simple ur-type definition`."
9155 type
->baseType
= xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE
);
9157 * Check for illegal attributes.
9159 attr
= node
->properties
;
9160 while (attr
!= NULL
) {
9161 if (attr
->ns
== NULL
) {
9162 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
9163 (!xmlStrEqual(attr
->name
, BAD_CAST
"itemType"))) {
9164 xmlSchemaPIllegalAttrErr(ctxt
,
9165 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9167 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
9168 xmlSchemaPIllegalAttrErr(ctxt
,
9169 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9174 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
9177 * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
9178 * fields for holding the reference to the itemType.
9180 * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
9183 xmlSchemaPValAttrQName(ctxt
, schema
, NULL
,
9184 node
, "itemType", &(type
->baseNs
), &(type
->base
));
9186 * And now for the children...
9188 child
= node
->children
;
9189 if (IS_SCHEMA(child
, "annotation")) {
9190 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr
) type
,
9191 xmlSchemaParseAnnotation(ctxt
, child
, 1));
9192 child
= child
->next
;
9194 if (IS_SCHEMA(child
, "simpleType")) {
9196 * src-list-itemType-or-simpleType
9197 * Either the itemType [attribute] or the <simpleType> [child] of
9198 * the <list> element must be present, but not both.
9200 if (type
->base
!= NULL
) {
9201 xmlSchemaPCustomErr(ctxt
,
9202 XML_SCHEMAP_SRC_SIMPLE_TYPE_1
,
9204 "The attribute 'itemType' and the <simpleType> child "
9205 "are mutually exclusive", NULL
);
9207 type
->subtypes
= xmlSchemaParseSimpleType(ctxt
, schema
, child
, 0);
9209 child
= child
->next
;
9210 } else if (type
->base
== NULL
) {
9211 xmlSchemaPCustomErr(ctxt
,
9212 XML_SCHEMAP_SRC_SIMPLE_TYPE_1
,
9214 "Either the attribute 'itemType' or the <simpleType> child "
9215 "must be present", NULL
);
9217 if (child
!= NULL
) {
9218 xmlSchemaPContentErr(ctxt
,
9219 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
9220 NULL
, node
, child
, NULL
, "(annotation?, simpleType?)");
9222 if ((type
->base
== NULL
) &&
9223 (type
->subtypes
== NULL
) &&
9224 (xmlSchemaGetPropNode(node
, "itemType") == NULL
)) {
9225 xmlSchemaPCustomErr(ctxt
,
9226 XML_SCHEMAP_SRC_SIMPLE_TYPE_1
,
9228 "Either the attribute 'itemType' or the <simpleType> child "
9229 "must be present", NULL
);
9235 * xmlSchemaParseSimpleType:
9236 * @ctxt: a schema validation context
9237 * @schema: the schema being built
9238 * @node: a subtree containing XML Schema information
9240 * parse a XML schema Simple Type definition
9241 * *WARNING* this interface is highly subject to change
9243 * Returns -1 in case of error, 0 if the declaration is improper and
9244 * 1 in case of success.
9246 static xmlSchemaTypePtr
9247 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
9248 xmlNodePtr node
, int topLevel
)
9250 xmlSchemaTypePtr type
, oldCtxtType
;
9251 xmlNodePtr child
= NULL
;
9252 const xmlChar
*attrValue
= NULL
;
9254 int hasRestriction
= 0;
9256 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
9260 attr
= xmlSchemaGetPropNode(node
, "name");
9262 xmlSchemaPMissingAttrErr(ctxt
,
9263 XML_SCHEMAP_S4S_ATTR_MISSING
,
9268 if (xmlSchemaPValAttrNode(ctxt
,
9270 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), &attrValue
) != 0)
9273 * Skip built-in types.
9276 xmlSchemaTypePtr biType
;
9278 if (ctxt
->isRedefine
) {
9280 * REDEFINE: Disallow redefinition of built-in-types.
9281 * TODO: It seems that the spec does not say anything
9284 xmlSchemaPCustomErr(ctxt
, XML_SCHEMAP_SRC_REDEFINE
,
9286 "Redefinition of built-in simple types is not "
9290 biType
= xmlSchemaGetPredefinedType(attrValue
, xmlSchemaNs
);
9298 * SPEC "The `actual value` of the targetNamespace [attribute]
9299 * of the <schema> ancestor element information item if present,
9300 * otherwise `absent`.
9302 if (topLevel
== 0) {
9303 #ifdef ENABLE_NAMED_LOCALS
9307 * Parse as local simple type definition.
9309 #ifdef ENABLE_NAMED_LOCALS
9310 snprintf(buf
, 39, "#ST%d", ctxt
->counter
++ + 1);
9311 type
= xmlSchemaAddType(ctxt
, schema
,
9312 XML_SCHEMA_TYPE_SIMPLE
,
9313 xmlDictLookup(ctxt
->dict
, (const xmlChar
*)buf
, -1),
9314 ctxt
->targetNamespace
, node
, 0);
9316 type
= xmlSchemaAddType(ctxt
, schema
,
9317 XML_SCHEMA_TYPE_SIMPLE
,
9318 NULL
, ctxt
->targetNamespace
, node
, 0);
9322 type
->type
= XML_SCHEMA_TYPE_SIMPLE
;
9323 type
->contentType
= XML_SCHEMA_CONTENT_SIMPLE
;
9325 * Check for illegal attributes.
9327 attr
= node
->properties
;
9328 while (attr
!= NULL
) {
9329 if (attr
->ns
== NULL
) {
9330 if (!xmlStrEqual(attr
->name
, BAD_CAST
"id")) {
9331 xmlSchemaPIllegalAttrErr(ctxt
,
9332 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9334 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
9335 xmlSchemaPIllegalAttrErr(ctxt
,
9336 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9342 * Parse as global simple type definition.
9344 * Note that attrValue is the value of the attribute "name" here.
9346 type
= xmlSchemaAddType(ctxt
, schema
, XML_SCHEMA_TYPE_SIMPLE
,
9347 attrValue
, ctxt
->targetNamespace
, node
, 1);
9350 type
->type
= XML_SCHEMA_TYPE_SIMPLE
;
9351 type
->contentType
= XML_SCHEMA_CONTENT_SIMPLE
;
9352 type
->flags
|= XML_SCHEMAS_TYPE_GLOBAL
;
9354 * Check for illegal attributes.
9356 attr
= node
->properties
;
9357 while (attr
!= NULL
) {
9358 if (attr
->ns
== NULL
) {
9359 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
9360 (!xmlStrEqual(attr
->name
, BAD_CAST
"name")) &&
9361 (!xmlStrEqual(attr
->name
, BAD_CAST
"final"))) {
9362 xmlSchemaPIllegalAttrErr(ctxt
,
9363 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9365 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
9366 xmlSchemaPIllegalAttrErr(ctxt
,
9367 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9372 * Attribute "final".
9374 attr
= xmlSchemaGetPropNode(node
, "final");
9376 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION
)
9377 type
->flags
|= XML_SCHEMAS_TYPE_FINAL_RESTRICTION
;
9378 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_LIST
)
9379 type
->flags
|= XML_SCHEMAS_TYPE_FINAL_LIST
;
9380 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_UNION
)
9381 type
->flags
|= XML_SCHEMAS_TYPE_FINAL_UNION
;
9383 attrValue
= xmlSchemaGetProp(ctxt
, node
, "final");
9384 if (xmlSchemaPValAttrBlockFinal(attrValue
, &(type
->flags
),
9385 -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION
, -1,
9386 XML_SCHEMAS_TYPE_FINAL_LIST
,
9387 XML_SCHEMAS_TYPE_FINAL_UNION
) != 0) {
9389 xmlSchemaPSimpleTypeErr(ctxt
,
9390 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
9391 WXS_BASIC_CAST type
, (xmlNodePtr
) attr
,
9392 NULL
, "(#all | List of (list | union | restriction)",
9393 attrValue
, NULL
, NULL
, NULL
);
9397 type
->targetNamespace
= ctxt
->targetNamespace
;
9398 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
9400 * And now for the children...
9402 oldCtxtType
= ctxt
->ctxtType
;
9404 ctxt
->ctxtType
= type
;
9406 child
= node
->children
;
9407 if (IS_SCHEMA(child
, "annotation")) {
9408 type
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
9409 child
= child
->next
;
9411 if (child
== NULL
) {
9412 xmlSchemaPContentErr(ctxt
, XML_SCHEMAP_S4S_ELEM_MISSING
,
9413 NULL
, node
, child
, NULL
,
9414 "(annotation?, (restriction | list | union))");
9415 } else if (IS_SCHEMA(child
, "restriction")) {
9416 xmlSchemaParseRestriction(ctxt
, schema
, child
,
9417 XML_SCHEMA_TYPE_SIMPLE
);
9419 child
= child
->next
;
9420 } else if (IS_SCHEMA(child
, "list")) {
9421 xmlSchemaParseList(ctxt
, schema
, child
);
9422 child
= child
->next
;
9423 } else if (IS_SCHEMA(child
, "union")) {
9424 xmlSchemaParseUnion(ctxt
, schema
, child
);
9425 child
= child
->next
;
9427 if (child
!= NULL
) {
9428 xmlSchemaPContentErr(ctxt
, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
9429 NULL
, node
, child
, NULL
,
9430 "(annotation?, (restriction | list | union))");
9433 * REDEFINE: SPEC src-redefine (5)
9434 * "Within the [children], each <simpleType> must have a
9435 * <restriction> among its [children] ... the `actual value` of whose
9436 * base [attribute] must be the same as the `actual value` of its own
9437 * name attribute plus target namespace;"
9439 if (topLevel
&& ctxt
->isRedefine
&& (! hasRestriction
)) {
9440 xmlSchemaPCustomErr(ctxt
, XML_SCHEMAP_SRC_REDEFINE
,
9441 NULL
, node
, "This is a redefinition, thus the "
9442 "<simpleType> must have a <restriction> child", NULL
);
9445 ctxt
->ctxtType
= oldCtxtType
;
9450 * xmlSchemaParseModelGroupDefRef:
9451 * @ctxt: the parser context
9452 * @schema: the schema being built
9455 * Parses a reference to a model group definition.
9457 * We will return a particle component with a qname-component or
9458 * NULL in case of an error.
9460 static xmlSchemaTreeItemPtr
9461 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt
,
9462 xmlSchemaPtr schema
,
9465 xmlSchemaParticlePtr item
;
9466 xmlNodePtr child
= NULL
;
9468 const xmlChar
*ref
= NULL
, *refNs
= NULL
;
9471 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
9474 attr
= xmlSchemaGetPropNode(node
, "ref");
9476 xmlSchemaPMissingAttrErr(ctxt
,
9477 XML_SCHEMAP_S4S_ATTR_MISSING
,
9478 NULL
, node
, "ref", NULL
);
9480 } else if (xmlSchemaPValAttrNodeQName(ctxt
, schema
, NULL
,
9481 attr
, &refNs
, &ref
) != 0) {
9484 xmlSchemaCheckReference(ctxt
, schema
, node
, attr
, refNs
);
9485 min
= xmlGetMinOccurs(ctxt
, node
, 0, -1, 1, "xs:nonNegativeInteger");
9486 max
= xmlGetMaxOccurs(ctxt
, node
, 0, UNBOUNDED
, 1,
9487 "(xs:nonNegativeInteger | unbounded)");
9489 * Check for illegal attributes.
9491 attr
= node
->properties
;
9492 while (attr
!= NULL
) {
9493 if (attr
->ns
== NULL
) {
9494 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"ref")) &&
9495 (!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
9496 (!xmlStrEqual(attr
->name
, BAD_CAST
"minOccurs")) &&
9497 (!xmlStrEqual(attr
->name
, BAD_CAST
"maxOccurs"))) {
9498 xmlSchemaPIllegalAttrErr(ctxt
,
9499 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9501 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
9502 xmlSchemaPIllegalAttrErr(ctxt
,
9503 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9507 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
9508 item
= xmlSchemaAddParticle(ctxt
, node
, min
, max
);
9512 * Create a qname-reference and set as the term; it will be substituted
9513 * for the model group after the reference has been resolved.
9515 item
->children
= (xmlSchemaTreeItemPtr
)
9516 xmlSchemaNewQNameRef(ctxt
, XML_SCHEMA_TYPE_GROUP
, ref
, refNs
);
9517 xmlSchemaPCheckParticleCorrect_2(ctxt
, item
, node
, min
, max
);
9519 * And now for the children...
9521 child
= node
->children
;
9522 /* TODO: Is annotation even allowed for a model group reference? */
9523 if (IS_SCHEMA(child
, "annotation")) {
9525 * TODO: What to do exactly with the annotation?
9527 item
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
9528 child
= child
->next
;
9530 if (child
!= NULL
) {
9531 xmlSchemaPContentErr(ctxt
,
9532 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
9533 NULL
, node
, child
, NULL
,
9537 * Corresponds to no component at all if minOccurs==maxOccurs==0.
9539 if ((min
== 0) && (max
== 0))
9542 return ((xmlSchemaTreeItemPtr
) item
);
9546 * xmlSchemaParseModelGroupDefinition:
9547 * @ctxt: a schema validation context
9548 * @schema: the schema being built
9549 * @node: a subtree containing XML Schema information
9551 * Parses a XML schema model group definition.
9553 * Note that the constraint src-redefine (6.2) can't be applied until
9554 * references have been resolved. So we will do this at the
9555 * component fixup level.
9557 * *WARNING* this interface is highly subject to change
9559 * Returns -1 in case of error, 0 if the declaration is improper and
9560 * 1 in case of success.
9562 static xmlSchemaModelGroupDefPtr
9563 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt
,
9564 xmlSchemaPtr schema
,
9567 xmlSchemaModelGroupDefPtr item
;
9568 xmlNodePtr child
= NULL
;
9570 const xmlChar
*name
;
9572 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
9575 attr
= xmlSchemaGetPropNode(node
, "name");
9577 xmlSchemaPMissingAttrErr(ctxt
,
9578 XML_SCHEMAP_S4S_ATTR_MISSING
,
9582 } else if (xmlSchemaPValAttrNode(ctxt
, NULL
, attr
,
9583 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), &name
) != 0) {
9586 item
= xmlSchemaAddModelGroupDefinition(ctxt
, schema
, name
,
9587 ctxt
->targetNamespace
, node
);
9591 * Check for illegal attributes.
9593 attr
= node
->properties
;
9594 while (attr
!= NULL
) {
9595 if (attr
->ns
== NULL
) {
9596 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"name")) &&
9597 (!xmlStrEqual(attr
->name
, BAD_CAST
"id"))) {
9598 xmlSchemaPIllegalAttrErr(ctxt
,
9599 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9601 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
9602 xmlSchemaPIllegalAttrErr(ctxt
,
9603 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9607 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
9609 * And now for the children...
9611 child
= node
->children
;
9612 if (IS_SCHEMA(child
, "annotation")) {
9613 item
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
9614 child
= child
->next
;
9616 if (IS_SCHEMA(child
, "all")) {
9617 item
->children
= xmlSchemaParseModelGroup(ctxt
, schema
, child
,
9618 XML_SCHEMA_TYPE_ALL
, 0);
9619 child
= child
->next
;
9620 } else if (IS_SCHEMA(child
, "choice")) {
9621 item
->children
= xmlSchemaParseModelGroup(ctxt
, schema
, child
,
9622 XML_SCHEMA_TYPE_CHOICE
, 0);
9623 child
= child
->next
;
9624 } else if (IS_SCHEMA(child
, "sequence")) {
9625 item
->children
= xmlSchemaParseModelGroup(ctxt
, schema
, child
,
9626 XML_SCHEMA_TYPE_SEQUENCE
, 0);
9627 child
= child
->next
;
9632 if (child
!= NULL
) {
9633 xmlSchemaPContentErr(ctxt
,
9634 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
9635 NULL
, node
, child
, NULL
,
9636 "(annotation?, (all | choice | sequence)?)");
9642 * xmlSchemaCleanupDoc:
9643 * @ctxt: a schema validation context
9644 * @node: the root of the document.
9646 * removes unwanted nodes in a schemas document tree
9649 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr root
)
9651 xmlNodePtr
delete, cur
;
9653 if ((ctxt
== NULL
) || (root
== NULL
)) return;
9656 * Remove all the blank text nodes
9660 while (cur
!= NULL
) {
9661 if (delete != NULL
) {
9662 xmlUnlinkNode(delete);
9663 xmlFreeNode(delete);
9666 if (cur
->type
== XML_TEXT_NODE
) {
9667 if (IS_BLANK_NODE(cur
)) {
9668 if (xmlNodeGetSpacePreserve(cur
) != 1) {
9672 } else if ((cur
->type
!= XML_ELEMENT_NODE
) &&
9673 (cur
->type
!= XML_CDATA_SECTION_NODE
)) {
9681 if (cur
->children
!= NULL
) {
9682 if ((cur
->children
->type
!= XML_ENTITY_DECL
) &&
9683 (cur
->children
->type
!= XML_ENTITY_REF_NODE
) &&
9684 (cur
->children
->type
!= XML_ENTITY_NODE
)) {
9685 cur
= cur
->children
;
9690 if (cur
->next
!= NULL
) {
9703 if (cur
->next
!= NULL
) {
9707 } while (cur
!= NULL
);
9709 if (delete != NULL
) {
9710 xmlUnlinkNode(delete);
9711 xmlFreeNode(delete);
9718 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema
)
9720 if (schema
->flags
& XML_SCHEMAS_QUALIF_ELEM
)
9721 schema
->flags
^= XML_SCHEMAS_QUALIF_ELEM
;
9723 if (schema
->flags
& XML_SCHEMAS_QUALIF_ATTR
)
9724 schema
->flags
^= XML_SCHEMAS_QUALIF_ATTR
;
9726 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_EXTENSION
)
9727 schema
->flags
^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION
;
9728 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION
)
9729 schema
->flags
^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION
;
9730 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_LIST
)
9731 schema
->flags
^= XML_SCHEMAS_FINAL_DEFAULT_LIST
;
9732 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_UNION
)
9733 schema
->flags
^= XML_SCHEMAS_FINAL_DEFAULT_UNION
;
9735 if (schema
->flags
& XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION
)
9736 schema
->flags
^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION
;
9737 if (schema
->flags
& XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION
)
9738 schema
->flags
^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION
;
9739 if (schema
->flags
& XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION
)
9740 schema
->flags
^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION
;
9744 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt
,
9745 xmlSchemaPtr schema
,
9750 int res
= 0, oldErrs
= ctxt
->nberrors
;
9753 * Those flags should be moved to the parser context flags,
9754 * since they are not visible at the component level. I.e.
9755 * they are used if processing schema *documents* only.
9757 res
= xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
9761 * Since the version is of type xs:token, we won't bother to
9765 attr = xmlSchemaGetPropNode(node, "version");
9767 res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
9768 xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
9772 attr
= xmlSchemaGetPropNode(node
, "targetNamespace");
9774 res
= xmlSchemaPValAttrNode(ctxt
, NULL
, attr
,
9775 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI
), NULL
);
9778 ctxt
->stop
= XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
;
9782 attr
= xmlSchemaGetPropNode(node
, "elementFormDefault");
9784 val
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
9785 res
= xmlSchemaPValAttrFormDefault(val
, &schema
->flags
,
9786 XML_SCHEMAS_QUALIF_ELEM
);
9789 xmlSchemaPSimpleTypeErr(ctxt
,
9790 XML_SCHEMAP_ELEMFORMDEFAULT_VALUE
,
9791 NULL
, (xmlNodePtr
) attr
, NULL
,
9792 "(qualified | unqualified)", val
, NULL
, NULL
, NULL
);
9795 attr
= xmlSchemaGetPropNode(node
, "attributeFormDefault");
9797 val
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
9798 res
= xmlSchemaPValAttrFormDefault(val
, &schema
->flags
,
9799 XML_SCHEMAS_QUALIF_ATTR
);
9802 xmlSchemaPSimpleTypeErr(ctxt
,
9803 XML_SCHEMAP_ATTRFORMDEFAULT_VALUE
,
9804 NULL
, (xmlNodePtr
) attr
, NULL
,
9805 "(qualified | unqualified)", val
, NULL
, NULL
, NULL
);
9808 attr
= xmlSchemaGetPropNode(node
, "finalDefault");
9810 val
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
9811 res
= xmlSchemaPValAttrBlockFinal(val
, &(schema
->flags
), -1,
9812 XML_SCHEMAS_FINAL_DEFAULT_EXTENSION
,
9813 XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION
,
9815 XML_SCHEMAS_FINAL_DEFAULT_LIST
,
9816 XML_SCHEMAS_FINAL_DEFAULT_UNION
);
9819 xmlSchemaPSimpleTypeErr(ctxt
,
9820 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
9821 NULL
, (xmlNodePtr
) attr
, NULL
,
9822 "(#all | List of (extension | restriction | list | union))",
9823 val
, NULL
, NULL
, NULL
);
9826 attr
= xmlSchemaGetPropNode(node
, "blockDefault");
9828 val
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
9829 res
= xmlSchemaPValAttrBlockFinal(val
, &(schema
->flags
), -1,
9830 XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION
,
9831 XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION
,
9832 XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION
, -1, -1);
9835 xmlSchemaPSimpleTypeErr(ctxt
,
9836 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
9837 NULL
, (xmlNodePtr
) attr
, NULL
,
9838 "(#all | List of (extension | restriction | substitution))",
9839 val
, NULL
, NULL
, NULL
);
9844 if (oldErrs
!= ctxt
->nberrors
)
9852 * xmlSchemaParseSchemaTopLevel:
9853 * @ctxt: a schema validation context
9854 * @schema: the schemas
9855 * @nodes: the list of top level nodes
9857 * Returns the internal XML Schema structure built from the resource or
9858 * NULL in case of error
9861 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt
,
9862 xmlSchemaPtr schema
, xmlNodePtr nodes
)
9865 xmlSchemaAnnotPtr annot
;
9866 int res
= 0, oldErrs
, tmpOldErrs
;
9868 if ((ctxt
== NULL
) || (schema
== NULL
) || (nodes
== NULL
))
9871 oldErrs
= ctxt
->nberrors
;
9873 while ((IS_SCHEMA(child
, "include")) ||
9874 (IS_SCHEMA(child
, "import")) ||
9875 (IS_SCHEMA(child
, "redefine")) ||
9876 (IS_SCHEMA(child
, "annotation"))) {
9877 if (IS_SCHEMA(child
, "annotation")) {
9878 annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
9879 if (schema
->annot
== NULL
)
9880 schema
->annot
= annot
;
9882 xmlSchemaFreeAnnot(annot
);
9883 } else if (IS_SCHEMA(child
, "import")) {
9884 tmpOldErrs
= ctxt
->nberrors
;
9885 res
= xmlSchemaParseImport(ctxt
, schema
, child
);
9888 if (tmpOldErrs
!= ctxt
->nberrors
)
9890 } else if (IS_SCHEMA(child
, "include")) {
9891 tmpOldErrs
= ctxt
->nberrors
;
9892 res
= xmlSchemaParseInclude(ctxt
, schema
, child
);
9895 if (tmpOldErrs
!= ctxt
->nberrors
)
9897 } else if (IS_SCHEMA(child
, "redefine")) {
9898 tmpOldErrs
= ctxt
->nberrors
;
9899 res
= xmlSchemaParseRedefine(ctxt
, schema
, child
);
9902 if (tmpOldErrs
!= ctxt
->nberrors
)
9905 child
= child
->next
;
9908 * URGENT TODO: Change the functions to return int results.
9909 * We need especially to catch internal errors.
9911 while (child
!= NULL
) {
9912 if (IS_SCHEMA(child
, "complexType")) {
9913 xmlSchemaParseComplexType(ctxt
, schema
, child
, 1);
9914 child
= child
->next
;
9915 } else if (IS_SCHEMA(child
, "simpleType")) {
9916 xmlSchemaParseSimpleType(ctxt
, schema
, child
, 1);
9917 child
= child
->next
;
9918 } else if (IS_SCHEMA(child
, "element")) {
9919 xmlSchemaParseElement(ctxt
, schema
, child
, NULL
, 1);
9920 child
= child
->next
;
9921 } else if (IS_SCHEMA(child
, "attribute")) {
9922 xmlSchemaParseGlobalAttribute(ctxt
, schema
, child
);
9923 child
= child
->next
;
9924 } else if (IS_SCHEMA(child
, "attributeGroup")) {
9925 xmlSchemaParseAttributeGroupDefinition(ctxt
, schema
, child
);
9926 child
= child
->next
;
9927 } else if (IS_SCHEMA(child
, "group")) {
9928 xmlSchemaParseModelGroupDefinition(ctxt
, schema
, child
);
9929 child
= child
->next
;
9930 } else if (IS_SCHEMA(child
, "notation")) {
9931 xmlSchemaParseNotation(ctxt
, schema
, child
);
9932 child
= child
->next
;
9934 xmlSchemaPContentErr(ctxt
,
9935 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
9936 NULL
, child
->parent
, child
,
9937 NULL
, "((include | import | redefine | annotation)*, "
9938 "(((simpleType | complexType | group | attributeGroup) "
9939 "| element | attribute | notation), annotation*)*)");
9940 child
= child
->next
;
9942 while (IS_SCHEMA(child
, "annotation")) {
9944 * TODO: We should add all annotations.
9946 annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
9947 if (schema
->annot
== NULL
)
9948 schema
->annot
= annot
;
9950 xmlSchemaFreeAnnot(annot
);
9951 child
= child
->next
;
9955 ctxt
->ctxtType
= NULL
;
9956 if (oldErrs
!= ctxt
->nberrors
)
9963 static xmlSchemaSchemaRelationPtr
9964 xmlSchemaSchemaRelationCreate(void)
9966 xmlSchemaSchemaRelationPtr ret
;
9968 ret
= (xmlSchemaSchemaRelationPtr
)
9969 xmlMalloc(sizeof(xmlSchemaSchemaRelation
));
9971 xmlSchemaPErrMemory(NULL
, "allocating schema relation", NULL
);
9974 memset(ret
, 0, sizeof(xmlSchemaSchemaRelation
));
9980 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel
)
9987 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef
)
9989 xmlSchemaRedefPtr prev
;
9991 while (redef
!= NULL
) {
9993 redef
= redef
->next
;
9999 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con
)
10002 * After the construction context has been freed, there will be
10003 * no schema graph available any more. Only the schema buckets
10004 * will stay alive, which are put into the "schemasImports" and
10005 * "includes" slots of the xmlSchema.
10007 if (con
->buckets
!= NULL
)
10008 xmlSchemaItemListFree(con
->buckets
);
10009 if (con
->pending
!= NULL
)
10010 xmlSchemaItemListFree(con
->pending
);
10011 if (con
->substGroups
!= NULL
)
10012 xmlHashFree(con
->substGroups
, xmlSchemaSubstGroupFreeEntry
);
10013 if (con
->redefs
!= NULL
)
10014 xmlSchemaRedefListFree(con
->redefs
);
10015 if (con
->dict
!= NULL
)
10016 xmlDictFree(con
->dict
);
10020 static xmlSchemaConstructionCtxtPtr
10021 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict
)
10023 xmlSchemaConstructionCtxtPtr ret
;
10025 ret
= (xmlSchemaConstructionCtxtPtr
)
10026 xmlMalloc(sizeof(xmlSchemaConstructionCtxt
));
10028 xmlSchemaPErrMemory(NULL
,
10029 "allocating schema construction context", NULL
);
10032 memset(ret
, 0, sizeof(xmlSchemaConstructionCtxt
));
10034 ret
->buckets
= xmlSchemaItemListCreate();
10035 if (ret
->buckets
== NULL
) {
10036 xmlSchemaPErrMemory(NULL
,
10037 "allocating list of schema buckets", NULL
);
10041 ret
->pending
= xmlSchemaItemListCreate();
10042 if (ret
->pending
== NULL
) {
10043 xmlSchemaPErrMemory(NULL
,
10044 "allocating list of pending global components", NULL
);
10045 xmlSchemaConstructionCtxtFree(ret
);
10049 xmlDictReference(dict
);
10053 static xmlSchemaParserCtxtPtr
10054 xmlSchemaParserCtxtCreate(void)
10056 xmlSchemaParserCtxtPtr ret
;
10058 ret
= (xmlSchemaParserCtxtPtr
) xmlMalloc(sizeof(xmlSchemaParserCtxt
));
10060 xmlSchemaPErrMemory(NULL
, "allocating schema parser context",
10064 memset(ret
, 0, sizeof(xmlSchemaParserCtxt
));
10065 ret
->type
= XML_SCHEMA_CTXT_PARSER
;
10066 ret
->attrProhibs
= xmlSchemaItemListCreate();
10067 if (ret
->attrProhibs
== NULL
) {
10075 * xmlSchemaNewParserCtxtUseDict:
10076 * @URL: the location of the schema
10077 * @dict: the dictionary to be used
10079 * Create an XML Schemas parse context for that file/resource expected
10080 * to contain an XML Schemas file.
10082 * Returns the parser context or NULL in case of error
10084 static xmlSchemaParserCtxtPtr
10085 xmlSchemaNewParserCtxtUseDict(const char *URL
, xmlDictPtr dict
)
10087 xmlSchemaParserCtxtPtr ret
;
10089 ret
= xmlSchemaParserCtxtCreate();
10093 xmlDictReference(dict
);
10095 ret
->URL
= xmlDictLookup(dict
, (const xmlChar
*) URL
, -1);
10100 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt
)
10102 if (vctxt
->pctxt
== NULL
) {
10103 if (vctxt
->schema
!= NULL
)
10105 xmlSchemaNewParserCtxtUseDict("*", vctxt
->schema
->dict
);
10107 vctxt
->pctxt
= xmlSchemaNewParserCtxt("*");
10108 if (vctxt
->pctxt
== NULL
) {
10109 VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
10110 "failed to create a temp. parser context");
10113 /* TODO: Pass user data. */
10114 xmlSchemaSetParserErrors(vctxt
->pctxt
, vctxt
->error
,
10115 vctxt
->warning
, vctxt
->errCtxt
);
10116 xmlSchemaSetParserStructuredErrors(vctxt
->pctxt
, vctxt
->serror
,
10123 * xmlSchemaGetSchemaBucket:
10124 * @pctxt: the schema parser context
10125 * @schemaLocation: the URI of the schema document
10127 * Returns a schema bucket if it was already parsed.
10129 * Returns a schema bucket if it was already parsed from
10130 * @schemaLocation, NULL otherwise.
10132 static xmlSchemaBucketPtr
10133 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt
,
10134 const xmlChar
*schemaLocation
)
10136 xmlSchemaBucketPtr cur
;
10137 xmlSchemaItemListPtr list
;
10139 list
= pctxt
->constructor
->buckets
;
10140 if (list
->nbItems
== 0)
10144 for (i
= 0; i
< list
->nbItems
; i
++) {
10145 cur
= (xmlSchemaBucketPtr
) list
->items
[i
];
10146 /* Pointer comparison! */
10147 if (cur
->schemaLocation
== schemaLocation
)
10154 static xmlSchemaBucketPtr
10155 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt
,
10156 const xmlChar
*schemaLocation
,
10157 const xmlChar
*targetNamespace
)
10159 xmlSchemaBucketPtr cur
;
10160 xmlSchemaItemListPtr list
;
10162 list
= pctxt
->constructor
->buckets
;
10163 if (list
->nbItems
== 0)
10167 for (i
= 0; i
< list
->nbItems
; i
++) {
10168 cur
= (xmlSchemaBucketPtr
) list
->items
[i
];
10169 /* Pointer comparison! */
10170 if ((cur
->origTargetNamespace
== NULL
) &&
10171 (cur
->schemaLocation
== schemaLocation
) &&
10172 (cur
->targetNamespace
== targetNamespace
))
10180 #define IS_BAD_SCHEMA_DOC(b) \
10181 (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
10183 static xmlSchemaBucketPtr
10184 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt
,
10185 const xmlChar
*targetNamespace
,
10188 xmlSchemaBucketPtr cur
;
10189 xmlSchemaItemListPtr list
;
10191 list
= pctxt
->constructor
->buckets
;
10192 if (list
->nbItems
== 0)
10196 for (i
= 0; i
< list
->nbItems
; i
++) {
10197 cur
= (xmlSchemaBucketPtr
) list
->items
[i
];
10198 if ((! IS_BAD_SCHEMA_DOC(cur
)) &&
10199 (cur
->origTargetNamespace
== targetNamespace
) &&
10200 ((imported
&& cur
->imported
) ||
10201 ((!imported
) && (!cur
->imported
))))
10209 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt
,
10210 xmlSchemaPtr schema
,
10211 xmlSchemaBucketPtr bucket
)
10217 xmlSchemaBucketPtr oldbucket
= pctxt
->constructor
->bucket
;
10220 * Save old values; reset the *main* schema.
10221 * URGENT TODO: This is not good; move the per-document information
10222 * to the parser. Get rid of passing the main schema to the
10223 * parsing functions.
10225 oldFlags
= schema
->flags
;
10226 oldDoc
= schema
->doc
;
10227 if (schema
->flags
!= 0)
10228 xmlSchemaClearSchemaDefaults(schema
);
10229 schema
->doc
= bucket
->doc
;
10230 pctxt
->schema
= schema
;
10232 * Keep the current target namespace on the parser *not* on the
10235 pctxt
->targetNamespace
= bucket
->targetNamespace
;
10236 WXS_CONSTRUCTOR(pctxt
)->bucket
= bucket
;
10238 if ((bucket
->targetNamespace
!= NULL
) &&
10239 xmlStrEqual(bucket
->targetNamespace
, xmlSchemaNs
)) {
10241 * We are parsing the schema for schemas!
10245 /* Mark it as parsed, even if parsing fails. */
10247 /* Compile the schema doc. */
10248 node
= xmlDocGetRootElement(bucket
->doc
);
10249 ret
= xmlSchemaParseSchemaElement(pctxt
, schema
, node
);
10252 /* An empty schema; just get out. */
10253 if (node
->children
== NULL
)
10255 oldErrs
= pctxt
->nberrors
;
10256 ret
= xmlSchemaParseSchemaTopLevel(pctxt
, schema
, node
->children
);
10260 * TODO: Not nice, but I'm not 100% sure we will get always an error
10261 * as a result of the above functions; so better rely on pctxt->err
10264 if ((ret
== 0) && (oldErrs
!= pctxt
->nberrors
)) {
10270 WXS_CONSTRUCTOR(pctxt
)->bucket
= oldbucket
;
10271 /* Restore schema values. */
10272 schema
->doc
= oldDoc
;
10273 schema
->flags
= oldFlags
;
10278 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt
,
10279 xmlSchemaPtr schema
,
10280 xmlSchemaBucketPtr bucket
)
10282 xmlSchemaParserCtxtPtr newpctxt
;
10285 if (bucket
== NULL
)
10287 if (bucket
->parsed
) {
10288 PERROR_INT("xmlSchemaParseNewDoc",
10289 "reparsing a schema doc");
10292 if (bucket
->doc
== NULL
) {
10293 PERROR_INT("xmlSchemaParseNewDoc",
10294 "parsing a schema doc, but there's no doc");
10297 if (pctxt
->constructor
== NULL
) {
10298 PERROR_INT("xmlSchemaParseNewDoc",
10302 /* Create and init the temporary parser context. */
10303 newpctxt
= xmlSchemaNewParserCtxtUseDict(
10304 (const char *) bucket
->schemaLocation
, pctxt
->dict
);
10305 if (newpctxt
== NULL
)
10307 newpctxt
->constructor
= pctxt
->constructor
;
10309 * TODO: Can we avoid that the parser knows about the main schema?
10310 * It would be better if he knows about the current schema bucket
10313 newpctxt
->schema
= schema
;
10314 xmlSchemaSetParserErrors(newpctxt
, pctxt
->error
, pctxt
->warning
,
10316 xmlSchemaSetParserStructuredErrors(newpctxt
, pctxt
->serror
,
10318 newpctxt
->counter
= pctxt
->counter
;
10321 res
= xmlSchemaParseNewDocWithContext(newpctxt
, schema
, bucket
);
10323 /* Channel back errors and cleanup the temporary parser context. */
10326 pctxt
->nberrors
+= newpctxt
->nberrors
;
10327 pctxt
->counter
= newpctxt
->counter
;
10328 newpctxt
->constructor
= NULL
;
10329 /* Free the parser context. */
10330 xmlSchemaFreeParserCtxt(newpctxt
);
10335 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket
,
10336 xmlSchemaSchemaRelationPtr rel
)
10338 xmlSchemaSchemaRelationPtr cur
= bucket
->relations
;
10341 bucket
->relations
= rel
;
10344 while (cur
->next
!= NULL
)
10350 static const xmlChar
*
10351 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict
, const xmlChar
* location
,
10352 xmlNodePtr ctxtNode
)
10355 * Build an absolute location URI.
10357 if (location
!= NULL
) {
10358 if (ctxtNode
== NULL
)
10361 xmlChar
*base
, *URI
;
10362 const xmlChar
*ret
= NULL
;
10364 base
= xmlNodeGetBase(ctxtNode
->doc
, ctxtNode
);
10365 if (base
== NULL
) {
10366 URI
= xmlBuildURI(location
, ctxtNode
->doc
->URL
);
10368 URI
= xmlBuildURI(location
, base
);
10372 ret
= xmlDictLookup(dict
, URI
, -1);
10384 * xmlSchemaAddSchemaDoc:
10385 * @pctxt: a schema validation context
10386 * @schema: the schema being built
10387 * @node: a subtree containing XML Schema information
10389 * Parse an included (and to-be-redefined) XML schema document.
10391 * Returns 0 on success, a positive error code on errors and
10392 * -1 in case of an internal or API error.
10396 xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt
,
10397 int type
, /* import or include or redefine */
10398 const xmlChar
*schemaLocation
,
10399 xmlDocPtr schemaDoc
,
10400 const char *schemaBuffer
,
10401 int schemaBufferLen
,
10402 xmlNodePtr invokingNode
,
10403 const xmlChar
*sourceTargetNamespace
,
10404 const xmlChar
*importNamespace
,
10405 xmlSchemaBucketPtr
*bucket
)
10407 const xmlChar
*targetNamespace
= NULL
;
10408 xmlSchemaSchemaRelationPtr relation
= NULL
;
10409 xmlDocPtr doc
= NULL
;
10410 int res
= 0, err
= 0, located
= 0, preserveDoc
= 0;
10411 xmlSchemaBucketPtr bkt
= NULL
;
10413 if (bucket
!= NULL
)
10417 case XML_SCHEMA_SCHEMA_IMPORT
:
10418 case XML_SCHEMA_SCHEMA_MAIN
:
10419 err
= XML_SCHEMAP_SRC_IMPORT
;
10421 case XML_SCHEMA_SCHEMA_INCLUDE
:
10422 err
= XML_SCHEMAP_SRC_INCLUDE
;
10424 case XML_SCHEMA_SCHEMA_REDEFINE
:
10425 err
= XML_SCHEMAP_SRC_REDEFINE
;
10430 /* Special handling for the main schema:
10431 * skip the location and relation logic and just parse the doc.
10432 * We need just a bucket to be returned in this case.
10434 if ((type
== XML_SCHEMA_SCHEMA_MAIN
) || (! WXS_HAS_BUCKETS(pctxt
)))
10437 /* Note that we expect the location to be an absolute URI. */
10438 if (schemaLocation
!= NULL
) {
10439 bkt
= xmlSchemaGetSchemaBucket(pctxt
, schemaLocation
);
10440 if ((bkt
!= NULL
) &&
10441 (pctxt
->constructor
->bucket
== bkt
)) {
10442 /* Report self-imports/inclusions/redefinitions. */
10444 xmlSchemaCustomErr(ACTXT_CAST pctxt
, err
,
10445 invokingNode
, NULL
,
10446 "The schema must not import/include/redefine itself",
10452 * Create a relation for the graph of schemas.
10454 relation
= xmlSchemaSchemaRelationCreate();
10455 if (relation
== NULL
)
10457 xmlSchemaSchemaRelationAddChild(pctxt
->constructor
->bucket
,
10459 relation
->type
= type
;
10462 * Save the namespace import information.
10464 if (WXS_IS_BUCKET_IMPMAIN(type
)) {
10465 relation
->importNamespace
= importNamespace
;
10466 if (schemaLocation
== NULL
) {
10468 * No location; this is just an import of the namespace.
10469 * Note that we don't assign a bucket to the relation
10474 targetNamespace
= importNamespace
;
10477 /* Did we already fetch the doc? */
10479 if ((WXS_IS_BUCKET_IMPMAIN(type
)) && (! bkt
->imported
)) {
10481 * We included/redefined and then try to import a schema,
10482 * but the new location provided for import was different.
10484 if (schemaLocation
== NULL
)
10485 schemaLocation
= BAD_CAST
"in_memory_buffer";
10486 if (!xmlStrEqual(schemaLocation
,
10487 bkt
->schemaLocation
)) {
10488 xmlSchemaCustomErr(ACTXT_CAST pctxt
, err
,
10489 invokingNode
, NULL
,
10490 "The schema document '%s' cannot be imported, since "
10491 "it was already included or redefined",
10492 schemaLocation
, NULL
);
10495 } else if ((! WXS_IS_BUCKET_IMPMAIN(type
)) && (bkt
->imported
)) {
10497 * We imported and then try to include/redefine a schema,
10498 * but the new location provided for the include/redefine
10501 if (schemaLocation
== NULL
)
10502 schemaLocation
= BAD_CAST
"in_memory_buffer";
10503 if (!xmlStrEqual(schemaLocation
,
10504 bkt
->schemaLocation
)) {
10505 xmlSchemaCustomErr(ACTXT_CAST pctxt
, err
,
10506 invokingNode
, NULL
,
10507 "The schema document '%s' cannot be included or "
10508 "redefined, since it was already imported",
10509 schemaLocation
, NULL
);
10515 if (WXS_IS_BUCKET_IMPMAIN(type
)) {
10517 * Given that the schemaLocation [attribute] is only a hint, it is open
10518 * to applications to ignore all but the first <import> for a given
10519 * namespace, regardless of the `actual value` of schemaLocation, but
10520 * such a strategy risks missing useful information when new
10521 * schemaLocations are offered.
10523 * We will use the first <import> that comes with a location.
10524 * Further <import>s *with* a location, will result in an error.
10525 * TODO: Better would be to just report a warning here, but
10526 * we'll try it this way until someone complains.
10528 * Schema Document Location Strategy:
10529 * 3 Based on the namespace name, identify an existing schema document,
10530 * either as a resource which is an XML document or a <schema> element
10531 * information item, in some local schema repository;
10532 * 5 Attempt to resolve the namespace name to locate such a resource.
10534 * NOTE: (3) and (5) are not supported.
10537 relation
->bucket
= bkt
;
10540 bkt
= xmlSchemaGetSchemaBucketByTNS(pctxt
,
10541 importNamespace
, 1);
10544 relation
->bucket
= bkt
;
10545 if (bkt
->schemaLocation
== NULL
) {
10546 /* First given location of the schema; load the doc. */
10547 bkt
->schemaLocation
= schemaLocation
;
10549 if (!xmlStrEqual(schemaLocation
,
10550 bkt
->schemaLocation
)) {
10552 * Additional location given; just skip it.
10553 * URGENT TODO: We should report a warning here.
10554 * res = XML_SCHEMAP_SRC_IMPORT;
10556 if (schemaLocation
== NULL
)
10557 schemaLocation
= BAD_CAST
"in_memory_buffer";
10559 xmlSchemaCustomWarning(ACTXT_CAST pctxt
,
10560 XML_SCHEMAP_WARN_SKIP_SCHEMA
,
10561 invokingNode
, NULL
,
10562 "Skipping import of schema located at '%s' for the "
10563 "namespace '%s', since this namespace was already "
10564 "imported with the schema located at '%s'",
10565 schemaLocation
, importNamespace
, bkt
->schemaLocation
);
10571 * No bucket + first location: load the doc and create a
10575 /* <include> and <redefine> */
10578 if ((bkt
->origTargetNamespace
== NULL
) &&
10579 (bkt
->targetNamespace
!= sourceTargetNamespace
)) {
10580 xmlSchemaBucketPtr chamel
;
10583 * Chameleon include/redefine: skip loading only if it was
10584 * already build for the targetNamespace of the including
10588 * URGENT TODO: If the schema is a chameleon-include then copy
10589 * the components into the including schema and modify the
10590 * targetNamespace of those components, do nothing otherwise.
10591 * NOTE: This is currently worked-around by compiling the
10592 * chameleon for every distinct including targetNamespace; thus
10593 * not performant at the moment.
10594 * TODO: Check when the namespace in wildcards for chameleons
10595 * needs to be converted: before we built wildcard intersections
10599 chamel
= xmlSchemaGetChameleonSchemaBucket(pctxt
,
10600 schemaLocation
, sourceTargetNamespace
);
10601 if (chamel
!= NULL
) {
10602 /* A fitting chameleon was already parsed; NOP. */
10603 relation
->bucket
= chamel
;
10607 * We need to parse the chameleon again for a different
10609 * CHAMELEON TODO: Optimize this by only parsing the
10610 * chameleon once, and then copying the components to
10611 * the new targetNamespace.
10615 relation
->bucket
= bkt
;
10620 if ((bkt
!= NULL
) && (bkt
->doc
!= NULL
)) {
10621 PERROR_INT("xmlSchemaAddSchemaDoc",
10622 "trying to load a schema doc, but a doc is already "
10623 "assigned to the schema bucket");
10629 * Load the document.
10631 if (schemaDoc
!= NULL
) {
10633 /* Don' free this one, since it was provided by the caller. */
10635 /* TODO: Does the context or the doc hold the location? */
10636 if (schemaDoc
->URL
!= NULL
)
10637 schemaLocation
= xmlDictLookup(pctxt
->dict
,
10638 schemaDoc
->URL
, -1);
10640 schemaLocation
= BAD_CAST
"in_memory_buffer";
10641 } else if ((schemaLocation
!= NULL
) || (schemaBuffer
!= NULL
)) {
10642 xmlParserCtxtPtr parserCtxt
;
10644 parserCtxt
= xmlNewParserCtxt();
10645 if (parserCtxt
== NULL
) {
10646 xmlSchemaPErrMemory(NULL
, "xmlSchemaGetDoc, "
10647 "allocating a parser context", NULL
);
10650 if ((pctxt
->dict
!= NULL
) && (parserCtxt
->dict
!= NULL
)) {
10652 * TODO: Do we have to burden the schema parser dict with all
10653 * the content of the schema doc?
10655 xmlDictFree(parserCtxt
->dict
);
10656 parserCtxt
->dict
= pctxt
->dict
;
10657 xmlDictReference(parserCtxt
->dict
);
10659 if (schemaLocation
!= NULL
) {
10660 /* Parse from file. */
10661 doc
= xmlCtxtReadFile(parserCtxt
, (const char *) schemaLocation
,
10662 NULL
, SCHEMAS_PARSE_OPTIONS
);
10663 } else if (schemaBuffer
!= NULL
) {
10664 /* Parse from memory buffer. */
10665 doc
= xmlCtxtReadMemory(parserCtxt
, schemaBuffer
, schemaBufferLen
,
10666 NULL
, NULL
, SCHEMAS_PARSE_OPTIONS
);
10667 schemaLocation
= BAD_CAST
"in_memory_buffer";
10669 doc
->URL
= xmlStrdup(schemaLocation
);
10673 * 2.1 The referent is (a fragment of) a resource which is an
10674 * XML document (see clause 1.1), which in turn corresponds to
10675 * a <schema> element information item in a well-formed information
10676 * set, which in turn corresponds to a valid schema.
10677 * TODO: (2.1) fragments of XML documents are not supported.
10679 * 2.2 The referent is a <schema> element information item in
10680 * a well-formed information set, which in turn corresponds
10681 * to a valid schema.
10682 * TODO: (2.2) is not supported.
10686 lerr
= xmlGetLastError();
10688 * Check if this a parser error, or if the document could
10689 * just not be located.
10690 * TODO: Try to find specific error codes to react only on
10691 * localisation failures.
10693 if ((lerr
== NULL
) || (lerr
->domain
!= XML_FROM_IO
)) {
10695 * We assume a parser error here.
10698 /* TODO: Error code ?? */
10699 res
= XML_SCHEMAP_SRC_IMPORT_2_1
;
10700 xmlSchemaCustomErr(ACTXT_CAST pctxt
, res
,
10701 invokingNode
, NULL
,
10702 "Failed to parse the XML resource '%s'",
10703 schemaLocation
, NULL
);
10706 xmlFreeParserCtxt(parserCtxt
);
10707 if ((doc
== NULL
) && located
)
10710 xmlSchemaPErr(pctxt
, NULL
,
10711 XML_SCHEMAP_NOTHING_TO_PARSE
,
10712 "No information for parsing was provided with the "
10713 "given schema parser context.\n",
10718 * Preprocess the document.
10721 xmlNodePtr docElem
= NULL
;
10724 docElem
= xmlDocGetRootElement(doc
);
10725 if (docElem
== NULL
) {
10726 xmlSchemaCustomErr(ACTXT_CAST pctxt
, XML_SCHEMAP_NOROOT
,
10727 invokingNode
, NULL
,
10728 "The document '%s' has no document element",
10729 schemaLocation
, NULL
);
10733 * Remove all the blank text nodes.
10735 xmlSchemaCleanupDoc(pctxt
, docElem
);
10737 * Check the schema's top level element.
10739 if (!IS_SCHEMA(docElem
, "schema")) {
10740 xmlSchemaCustomErr(ACTXT_CAST pctxt
, XML_SCHEMAP_NOT_SCHEMA
,
10741 invokingNode
, NULL
,
10742 "The XML document '%s' is not a schema document",
10743 schemaLocation
, NULL
);
10747 * Note that we don't apply a type check for the
10748 * targetNamespace value here.
10750 targetNamespace
= xmlSchemaGetProp(pctxt
, docElem
,
10751 "targetNamespace");
10754 /* after_doc_loading: */
10755 if ((bkt
== NULL
) && located
) {
10756 /* Only create a bucket if the schema was located. */
10757 bkt
= xmlSchemaBucketCreate(pctxt
, type
,
10763 bkt
->schemaLocation
= schemaLocation
;
10764 bkt
->located
= located
;
10767 bkt
->targetNamespace
= targetNamespace
;
10768 bkt
->origTargetNamespace
= targetNamespace
;
10770 bkt
->preserveDoc
= 1;
10772 if (WXS_IS_BUCKET_IMPMAIN(type
))
10775 * Add it to the graph of schemas.
10777 if (relation
!= NULL
)
10778 relation
->bucket
= bkt
;
10783 * Return the bucket explicitly; this is needed for the
10786 if (bucket
!= NULL
)
10791 if ((doc
!= NULL
) && (! preserveDoc
)) {
10796 return(pctxt
->err
);
10799 if ((doc
!= NULL
) && (! preserveDoc
)) {
10808 * xmlSchemaParseImport:
10809 * @ctxt: a schema validation context
10810 * @schema: the schema being built
10811 * @node: a subtree containing XML Schema information
10813 * parse a XML schema Import definition
10814 * *WARNING* this interface is highly subject to change
10816 * Returns 0 in case of success, a positive error code if
10817 * not valid and -1 in case of an internal error.
10820 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt
, xmlSchemaPtr schema
,
10824 const xmlChar
*namespaceName
= NULL
, *schemaLocation
= NULL
;
10825 const xmlChar
*thisTargetNamespace
;
10828 xmlSchemaBucketPtr bucket
= NULL
;
10830 if ((pctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
10834 * Check for illegal attributes.
10836 attr
= node
->properties
;
10837 while (attr
!= NULL
) {
10838 if (attr
->ns
== NULL
) {
10839 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
10840 (!xmlStrEqual(attr
->name
, BAD_CAST
"namespace")) &&
10841 (!xmlStrEqual(attr
->name
, BAD_CAST
"schemaLocation"))) {
10842 xmlSchemaPIllegalAttrErr(pctxt
,
10843 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
10845 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
10846 xmlSchemaPIllegalAttrErr(pctxt
,
10847 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
10852 * Extract and validate attributes.
10854 if (xmlSchemaPValAttr(pctxt
, NULL
, node
,
10855 "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI
),
10856 &namespaceName
) != 0) {
10857 xmlSchemaPSimpleTypeErr(pctxt
,
10858 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
10860 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI
),
10861 NULL
, namespaceName
, NULL
, NULL
, NULL
);
10862 return (pctxt
->err
);
10865 if (xmlSchemaPValAttr(pctxt
, NULL
, node
,
10866 "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI
),
10867 &schemaLocation
) != 0) {
10868 xmlSchemaPSimpleTypeErr(pctxt
,
10869 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
10871 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI
),
10872 NULL
, schemaLocation
, NULL
, NULL
, NULL
);
10873 return (pctxt
->err
);
10876 * And now for the children...
10878 child
= node
->children
;
10879 if (IS_SCHEMA(child
, "annotation")) {
10881 * the annotation here is simply discarded ...
10884 child
= child
->next
;
10886 if (child
!= NULL
) {
10887 xmlSchemaPContentErr(pctxt
,
10888 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
10889 NULL
, node
, child
, NULL
,
10893 * Apply additional constraints.
10895 * Note that it is important to use the original @targetNamespace
10896 * (or none at all), to rule out imports of schemas _with_ a
10897 * @targetNamespace if the importing schema is a chameleon schema
10898 * (with no @targetNamespace).
10900 thisTargetNamespace
= WXS_BUCKET(pctxt
)->origTargetNamespace
;
10901 if (namespaceName
!= NULL
) {
10903 * 1.1 If the namespace [attribute] is present, then its `actual value`
10904 * must not match the `actual value` of the enclosing <schema>'s
10905 * targetNamespace [attribute].
10907 if (xmlStrEqual(thisTargetNamespace
, namespaceName
)) {
10908 xmlSchemaPCustomErr(pctxt
,
10909 XML_SCHEMAP_SRC_IMPORT_1_1
,
10911 "The value of the attribute 'namespace' must not match "
10912 "the target namespace '%s' of the importing schema",
10913 thisTargetNamespace
);
10914 return (pctxt
->err
);
10918 * 1.2 If the namespace [attribute] is not present, then the enclosing
10919 * <schema> must have a targetNamespace [attribute].
10921 if (thisTargetNamespace
== NULL
) {
10922 xmlSchemaPCustomErr(pctxt
,
10923 XML_SCHEMAP_SRC_IMPORT_1_2
,
10925 "The attribute 'namespace' must be existent if "
10926 "the importing schema has no target namespace",
10928 return (pctxt
->err
);
10932 * Locate and acquire the schema document.
10934 if (schemaLocation
!= NULL
)
10935 schemaLocation
= xmlSchemaBuildAbsoluteURI(pctxt
->dict
,
10936 schemaLocation
, node
);
10937 ret
= xmlSchemaAddSchemaDoc(pctxt
, XML_SCHEMA_SCHEMA_IMPORT
,
10938 schemaLocation
, NULL
, NULL
, 0, node
, thisTargetNamespace
,
10939 namespaceName
, &bucket
);
10945 * For <import>: "It is *not* an error for the application
10946 * schema reference strategy to fail."
10947 * So just don't parse if no schema document was found.
10948 * Note that we will get no bucket if the schema could not be
10949 * located or if there was no schemaLocation.
10951 if ((bucket
== NULL
) && (schemaLocation
!= NULL
)) {
10952 xmlSchemaCustomWarning(ACTXT_CAST pctxt
,
10953 XML_SCHEMAP_WARN_UNLOCATED_SCHEMA
,
10955 "Failed to locate a schema at location '%s'. "
10956 "Skipping the import", schemaLocation
, NULL
, NULL
);
10959 if ((bucket
!= NULL
) && CAN_PARSE_SCHEMA(bucket
)) {
10960 ret
= xmlSchemaParseNewDoc(pctxt
, schema
, bucket
);
10967 xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt
,
10968 xmlSchemaPtr schema
,
10970 xmlChar
**schemaLocation
,
10975 if ((pctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
) ||
10976 (schemaLocation
== NULL
))
10979 *schemaLocation
= NULL
;
10981 * Check for illegal attributes.
10982 * Applies for both <include> and <redefine>.
10984 attr
= node
->properties
;
10985 while (attr
!= NULL
) {
10986 if (attr
->ns
== NULL
) {
10987 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
10988 (!xmlStrEqual(attr
->name
, BAD_CAST
"schemaLocation"))) {
10989 xmlSchemaPIllegalAttrErr(pctxt
,
10990 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
10992 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
10993 xmlSchemaPIllegalAttrErr(pctxt
,
10994 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
10998 xmlSchemaPValAttrID(pctxt
, node
, BAD_CAST
"id");
11000 * Preliminary step, extract the URI-Reference and make an URI
11004 * Attribute "schemaLocation" is mandatory.
11006 attr
= xmlSchemaGetPropNode(node
, "schemaLocation");
11007 if (attr
!= NULL
) {
11008 xmlChar
*base
= NULL
;
11009 xmlChar
*uri
= NULL
;
11011 if (xmlSchemaPValAttrNode(pctxt
, NULL
, attr
,
11012 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI
),
11013 (const xmlChar
**) schemaLocation
) != 0)
11015 base
= xmlNodeGetBase(node
->doc
, node
);
11016 if (base
== NULL
) {
11017 uri
= xmlBuildURI(*schemaLocation
, node
->doc
->URL
);
11019 uri
= xmlBuildURI(*schemaLocation
, base
);
11023 PERROR_INT("xmlSchemaParseIncludeOrRedefine",
11024 "could not build an URI from the schemaLocation")
11027 (*schemaLocation
) = (xmlChar
*) xmlDictLookup(pctxt
->dict
, uri
, -1);
11030 xmlSchemaPMissingAttrErr(pctxt
,
11031 XML_SCHEMAP_S4S_ATTR_MISSING
,
11032 NULL
, node
, "schemaLocation", NULL
);
11036 * Report self-inclusion and self-redefinition.
11038 if (xmlStrEqual(*schemaLocation
, pctxt
->URL
)) {
11039 if (type
== XML_SCHEMA_SCHEMA_REDEFINE
) {
11040 xmlSchemaPCustomErr(pctxt
,
11041 XML_SCHEMAP_SRC_REDEFINE
,
11043 "The schema document '%s' cannot redefine itself.",
11046 xmlSchemaPCustomErr(pctxt
,
11047 XML_SCHEMAP_SRC_INCLUDE
,
11049 "The schema document '%s' cannot include itself.",
11057 return(pctxt
->err
);
11063 xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt
,
11064 xmlSchemaPtr schema
,
11068 xmlNodePtr child
= NULL
;
11069 const xmlChar
*schemaLocation
= NULL
;
11070 int res
= 0; /* hasRedefinitions = 0 */
11071 int isChameleon
= 0, wasChameleon
= 0;
11072 xmlSchemaBucketPtr bucket
= NULL
;
11074 if ((pctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
11078 * Parse attributes. Note that the returned schemaLocation will
11079 * be already converted to an absolute URI.
11081 res
= xmlSchemaParseIncludeOrRedefineAttrs(pctxt
, schema
,
11082 node
, (xmlChar
**) (&schemaLocation
), type
);
11086 * Load and add the schema document.
11088 res
= xmlSchemaAddSchemaDoc(pctxt
, type
, schemaLocation
, NULL
,
11089 NULL
, 0, node
, pctxt
->targetNamespace
, NULL
, &bucket
);
11093 * If we get no schema bucket back, then this means that the schema
11094 * document could not be located or was broken XML or was not
11095 * a schema document.
11097 if ((bucket
== NULL
) || (bucket
->doc
== NULL
)) {
11098 if (type
== XML_SCHEMA_SCHEMA_INCLUDE
) {
11100 * WARNING for <include>:
11101 * We will raise an error if the schema cannot be located
11102 * for inclusions, since the that was the feedback from the
11103 * schema people. I.e. the following spec piece will *not* be
11105 * SPEC src-include: "It is not an error for the `actual value` of the
11106 * schemaLocation [attribute] to fail to resolve it all, in which
11107 * case no corresponding inclusion is performed.
11108 * So do we need a warning report here?"
11110 res
= XML_SCHEMAP_SRC_INCLUDE
;
11111 xmlSchemaCustomErr(ACTXT_CAST pctxt
, res
,
11113 "Failed to load the document '%s' for inclusion",
11114 schemaLocation
, NULL
);
11117 * NOTE: This was changed to raise an error even if no redefinitions
11120 * SPEC src-redefine (1)
11121 * "If there are any element information items among the [children]
11122 * other than <annotation> then the `actual value` of the
11123 * schemaLocation [attribute] must successfully resolve."
11124 * TODO: Ask the WG if a the location has always to resolve
11127 res
= XML_SCHEMAP_SRC_REDEFINE
;
11128 xmlSchemaCustomErr(ACTXT_CAST pctxt
, res
,
11130 "Failed to load the document '%s' for redefinition",
11131 schemaLocation
, NULL
);
11135 * Check targetNamespace sanity before parsing the new schema.
11136 * TODO: Note that we won't check further content if the
11137 * targetNamespace was bad.
11139 if (bucket
->origTargetNamespace
!= NULL
) {
11141 * SPEC src-include (2.1)
11142 * "SII has a targetNamespace [attribute], and its `actual
11143 * value` is identical to the `actual value` of the targetNamespace
11144 * [attribute] of SII' (which must have such an [attribute])."
11146 if (pctxt
->targetNamespace
== NULL
) {
11147 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
11148 XML_SCHEMAP_SRC_INCLUDE
,
11150 "The target namespace of the included/redefined schema "
11151 "'%s' has to be absent, since the including/redefining "
11152 "schema has no target namespace",
11153 schemaLocation
, NULL
);
11155 } else if (!xmlStrEqual(bucket
->origTargetNamespace
,
11156 pctxt
->targetNamespace
)) {
11157 /* TODO: Change error function. */
11158 xmlSchemaPCustomErrExt(pctxt
,
11159 XML_SCHEMAP_SRC_INCLUDE
,
11161 "The target namespace '%s' of the included/redefined "
11162 "schema '%s' differs from '%s' of the "
11163 "including/redefining schema",
11164 bucket
->origTargetNamespace
, schemaLocation
,
11165 pctxt
->targetNamespace
);
11168 } else if (pctxt
->targetNamespace
!= NULL
) {
11170 * Chameleons: the original target namespace will
11171 * differ from the resulting namespace.
11174 bucket
->targetNamespace
= pctxt
->targetNamespace
;
11178 * Parse the schema.
11180 if (bucket
&& (!bucket
->parsed
) && (bucket
->doc
!= NULL
)) {
11182 /* TODO: Get rid of this flag on the schema itself. */
11183 if ((schema
->flags
& XML_SCHEMAS_INCLUDING_CONVERT_NS
) == 0) {
11184 schema
->flags
|= XML_SCHEMAS_INCLUDING_CONVERT_NS
;
11188 xmlSchemaParseNewDoc(pctxt
, schema
, bucket
);
11189 /* Restore chameleon flag. */
11190 if (isChameleon
&& (!wasChameleon
))
11191 schema
->flags
^= XML_SCHEMAS_INCLUDING_CONVERT_NS
;
11194 * And now for the children...
11196 child
= node
->children
;
11197 if (type
== XML_SCHEMA_SCHEMA_REDEFINE
) {
11199 * Parse (simpleType | complexType | group | attributeGroup))*
11201 pctxt
->redefined
= bucket
;
11203 * How to proceed if the redefined schema was not located?
11205 pctxt
->isRedefine
= 1;
11206 while (IS_SCHEMA(child
, "annotation") ||
11207 IS_SCHEMA(child
, "simpleType") ||
11208 IS_SCHEMA(child
, "complexType") ||
11209 IS_SCHEMA(child
, "group") ||
11210 IS_SCHEMA(child
, "attributeGroup")) {
11211 if (IS_SCHEMA(child
, "annotation")) {
11213 * TODO: discard or not?
11215 } else if (IS_SCHEMA(child
, "simpleType")) {
11216 xmlSchemaParseSimpleType(pctxt
, schema
, child
, 1);
11217 } else if (IS_SCHEMA(child
, "complexType")) {
11218 xmlSchemaParseComplexType(pctxt
, schema
, child
, 1);
11219 /* hasRedefinitions = 1; */
11220 } else if (IS_SCHEMA(child
, "group")) {
11221 /* hasRedefinitions = 1; */
11222 xmlSchemaParseModelGroupDefinition(pctxt
,
11224 } else if (IS_SCHEMA(child
, "attributeGroup")) {
11225 /* hasRedefinitions = 1; */
11226 xmlSchemaParseAttributeGroupDefinition(pctxt
, schema
,
11229 child
= child
->next
;
11231 pctxt
->redefined
= NULL
;
11232 pctxt
->isRedefine
= 0;
11234 if (IS_SCHEMA(child
, "annotation")) {
11236 * TODO: discard or not?
11238 child
= child
->next
;
11241 if (child
!= NULL
) {
11242 res
= XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
;
11243 if (type
== XML_SCHEMA_SCHEMA_REDEFINE
) {
11244 xmlSchemaPContentErr(pctxt
, res
,
11245 NULL
, node
, child
, NULL
,
11246 "(annotation | (simpleType | complexType | group | attributeGroup))*");
11248 xmlSchemaPContentErr(pctxt
, res
,
11249 NULL
, node
, child
, NULL
,
11256 return(pctxt
->err
);
11260 xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt
, xmlSchemaPtr schema
,
11264 #ifndef ENABLE_REDEFINE
11268 res
= xmlSchemaParseIncludeOrRedefine(pctxt
, schema
, node
,
11269 XML_SCHEMA_SCHEMA_REDEFINE
);
11276 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt
, xmlSchemaPtr schema
,
11281 res
= xmlSchemaParseIncludeOrRedefine(pctxt
, schema
, node
,
11282 XML_SCHEMA_SCHEMA_INCLUDE
);
11289 * xmlSchemaParseModelGroup:
11290 * @ctxt: a schema validation context
11291 * @schema: the schema being built
11292 * @node: a subtree containing XML Schema information
11293 * @type: the "compositor" type
11294 * @particleNeeded: if a a model group with a particle
11296 * parse a XML schema Sequence definition.
11297 * Applies parts of:
11298 * Schema Representation Constraint:
11299 * Redefinition Constraints and Semantics (src-redefine)
11300 * (6.1), (6.1.1), (6.1.2)
11302 * Schema Component Constraint:
11303 * All Group Limited (cos-all-limited) (2)
11304 * TODO: Actually this should go to component-level checks,
11305 * but is done here due to performance. Move it to an other layer
11306 * is schema construction via an API is implemented.
11308 * *WARNING* this interface is highly subject to change
11310 * Returns -1 in case of error, 0 if the declaration is improper and
11311 * 1 in case of success.
11313 static xmlSchemaTreeItemPtr
11314 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
11315 xmlNodePtr node
, xmlSchemaTypeType type
,
11318 xmlSchemaModelGroupPtr item
;
11319 xmlSchemaParticlePtr particle
= NULL
;
11320 xmlNodePtr child
= NULL
;
11322 int min
= 1, max
= 1, isElemRef
, hasRefs
= 0;
11324 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
11327 * Create a model group with the given compositor.
11329 item
= xmlSchemaAddModelGroup(ctxt
, schema
, type
, node
);
11333 if (withParticle
) {
11334 if (type
== XML_SCHEMA_TYPE_ALL
) {
11335 min
= xmlGetMinOccurs(ctxt
, node
, 0, 1, 1, "(0 | 1)");
11336 max
= xmlGetMaxOccurs(ctxt
, node
, 1, 1, 1, "1");
11338 /* choice + sequence */
11339 min
= xmlGetMinOccurs(ctxt
, node
, 0, -1, 1, "xs:nonNegativeInteger");
11340 max
= xmlGetMaxOccurs(ctxt
, node
, 0, UNBOUNDED
, 1,
11341 "(xs:nonNegativeInteger | unbounded)");
11343 xmlSchemaPCheckParticleCorrect_2(ctxt
, NULL
, node
, min
, max
);
11345 * Create a particle
11347 particle
= xmlSchemaAddParticle(ctxt
, node
, min
, max
);
11348 if (particle
== NULL
)
11350 particle
->children
= (xmlSchemaTreeItemPtr
) item
;
11352 * Check for illegal attributes.
11354 attr
= node
->properties
;
11355 while (attr
!= NULL
) {
11356 if (attr
->ns
== NULL
) {
11357 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
11358 (!xmlStrEqual(attr
->name
, BAD_CAST
"maxOccurs")) &&
11359 (!xmlStrEqual(attr
->name
, BAD_CAST
"minOccurs"))) {
11360 xmlSchemaPIllegalAttrErr(ctxt
,
11361 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
11363 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
11364 xmlSchemaPIllegalAttrErr(ctxt
,
11365 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
11371 * Check for illegal attributes.
11373 attr
= node
->properties
;
11374 while (attr
!= NULL
) {
11375 if (attr
->ns
== NULL
) {
11376 if (!xmlStrEqual(attr
->name
, BAD_CAST
"id")) {
11377 xmlSchemaPIllegalAttrErr(ctxt
,
11378 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
11380 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
11381 xmlSchemaPIllegalAttrErr(ctxt
,
11382 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
11389 * Extract and validate attributes.
11391 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
11393 * And now for the children...
11395 child
= node
->children
;
11396 if (IS_SCHEMA(child
, "annotation")) {
11397 item
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
11398 child
= child
->next
;
11400 if (type
== XML_SCHEMA_TYPE_ALL
) {
11401 xmlSchemaParticlePtr part
, last
= NULL
;
11403 while (IS_SCHEMA(child
, "element")) {
11404 part
= (xmlSchemaParticlePtr
) xmlSchemaParseElement(ctxt
,
11405 schema
, child
, &isElemRef
, 0);
11407 * SPEC cos-all-limited (2)
11408 * "The {max occurs} of all the particles in the {particles}
11409 * of the ('all') group must be 0 or 1.
11411 if (part
!= NULL
) {
11414 if (part
->minOccurs
> 1) {
11415 xmlSchemaPCustomErr(ctxt
,
11416 XML_SCHEMAP_COS_ALL_LIMITED
,
11418 "Invalid value for minOccurs (must be 0 or 1)",
11421 part
->minOccurs
= 1;
11423 if (part
->maxOccurs
> 1) {
11424 xmlSchemaPCustomErr(ctxt
,
11425 XML_SCHEMAP_COS_ALL_LIMITED
,
11427 "Invalid value for maxOccurs (must be 0 or 1)",
11430 part
->maxOccurs
= 1;
11433 item
->children
= (xmlSchemaTreeItemPtr
) part
;
11435 last
->next
= (xmlSchemaTreeItemPtr
) part
;
11438 child
= child
->next
;
11440 if (child
!= NULL
) {
11441 xmlSchemaPContentErr(ctxt
,
11442 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
11443 NULL
, node
, child
, NULL
,
11444 "(annotation?, (annotation?, element*)");
11447 /* choice + sequence */
11448 xmlSchemaTreeItemPtr part
= NULL
, last
= NULL
;
11450 while ((IS_SCHEMA(child
, "element")) ||
11451 (IS_SCHEMA(child
, "group")) ||
11452 (IS_SCHEMA(child
, "any")) ||
11453 (IS_SCHEMA(child
, "choice")) ||
11454 (IS_SCHEMA(child
, "sequence"))) {
11456 if (IS_SCHEMA(child
, "element")) {
11457 part
= (xmlSchemaTreeItemPtr
)
11458 xmlSchemaParseElement(ctxt
, schema
, child
, &isElemRef
, 0);
11459 if (part
&& isElemRef
)
11461 } else if (IS_SCHEMA(child
, "group")) {
11463 xmlSchemaParseModelGroupDefRef(ctxt
, schema
, child
);
11467 * Handle redefinitions.
11469 if (ctxt
->isRedefine
&& ctxt
->redef
&&
11470 (ctxt
->redef
->item
->type
== XML_SCHEMA_TYPE_GROUP
) &&
11471 part
&& part
->children
)
11473 if ((xmlSchemaGetQNameRefName(part
->children
) ==
11474 ctxt
->redef
->refName
) &&
11475 (xmlSchemaGetQNameRefTargetNs(part
->children
) ==
11476 ctxt
->redef
->refTargetNs
))
11479 * SPEC src-redefine:
11480 * (6.1) "If it has a <group> among its contents at
11481 * some level the `actual value` of whose ref
11482 * [attribute] is the same as the `actual value` of
11483 * its own name attribute plus target namespace, then
11484 * all of the following must be true:"
11485 * (6.1.1) "It must have exactly one such group."
11487 if (ctxt
->redefCounter
!= 0) {
11488 xmlChar
*str
= NULL
;
11490 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
11491 XML_SCHEMAP_SRC_REDEFINE
, child
, NULL
,
11492 "The redefining model group definition "
11493 "'%s' must not contain more than one "
11494 "reference to the redefined definition",
11495 xmlSchemaFormatQName(&str
,
11496 ctxt
->redef
->refTargetNs
,
11497 ctxt
->redef
->refName
),
11501 } else if (((WXS_PARTICLE(part
))->minOccurs
!= 1) ||
11502 ((WXS_PARTICLE(part
))->maxOccurs
!= 1))
11504 xmlChar
*str
= NULL
;
11506 * SPEC src-redefine:
11507 * (6.1.2) "The `actual value` of both that
11508 * group's minOccurs and maxOccurs [attribute]
11509 * must be 1 (or `absent`).
11511 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
11512 XML_SCHEMAP_SRC_REDEFINE
, child
, NULL
,
11513 "The redefining model group definition "
11514 "'%s' must not contain a reference to the "
11515 "redefined definition with a "
11516 "maxOccurs/minOccurs other than 1",
11517 xmlSchemaFormatQName(&str
,
11518 ctxt
->redef
->refTargetNs
,
11519 ctxt
->redef
->refName
),
11524 ctxt
->redef
->reference
= WXS_BASIC_CAST part
;
11525 ctxt
->redefCounter
++;
11528 } else if (IS_SCHEMA(child
, "any")) {
11529 part
= (xmlSchemaTreeItemPtr
)
11530 xmlSchemaParseAny(ctxt
, schema
, child
);
11531 } else if (IS_SCHEMA(child
, "choice")) {
11532 part
= xmlSchemaParseModelGroup(ctxt
, schema
, child
,
11533 XML_SCHEMA_TYPE_CHOICE
, 1);
11534 } else if (IS_SCHEMA(child
, "sequence")) {
11535 part
= xmlSchemaParseModelGroup(ctxt
, schema
, child
,
11536 XML_SCHEMA_TYPE_SEQUENCE
, 1);
11538 if (part
!= NULL
) {
11540 item
->children
= part
;
11545 child
= child
->next
;
11547 if (child
!= NULL
) {
11548 xmlSchemaPContentErr(ctxt
,
11549 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
11550 NULL
, node
, child
, NULL
,
11551 "(annotation?, (element | group | choice | sequence | any)*)");
11554 if ((max
== 0) && (min
== 0))
11558 * We need to resolve references.
11560 WXS_ADD_PENDING(ctxt
, item
);
11563 return ((xmlSchemaTreeItemPtr
) particle
);
11565 return ((xmlSchemaTreeItemPtr
) item
);
11569 * xmlSchemaParseRestriction:
11570 * @ctxt: a schema validation context
11571 * @schema: the schema being built
11572 * @node: a subtree containing XML Schema information
11574 * parse a XML schema Restriction definition
11575 * *WARNING* this interface is highly subject to change
11577 * Returns the type definition or NULL in case of error
11579 static xmlSchemaTypePtr
11580 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
11581 xmlNodePtr node
, xmlSchemaTypeType parentType
)
11583 xmlSchemaTypePtr type
;
11584 xmlNodePtr child
= NULL
;
11587 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
11589 /* Not a component, don't create it. */
11590 type
= ctxt
->ctxtType
;
11591 type
->flags
|= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION
;
11594 * Check for illegal attributes.
11596 attr
= node
->properties
;
11597 while (attr
!= NULL
) {
11598 if (attr
->ns
== NULL
) {
11599 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
11600 (!xmlStrEqual(attr
->name
, BAD_CAST
"base"))) {
11601 xmlSchemaPIllegalAttrErr(ctxt
,
11602 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
11604 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
11605 xmlSchemaPIllegalAttrErr(ctxt
,
11606 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
11611 * Extract and validate attributes.
11613 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
11618 * Extract the base type. The "base" attribute is mandatory if inside
11619 * a complex type or if redefining.
11621 * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
11622 * among its [children]), the simple type definition which is
11623 * the {content type} of the type definition `resolved` to by
11624 * the `actual value` of the base [attribute]"
11626 if (xmlSchemaPValAttrQName(ctxt
, schema
, NULL
, node
, "base",
11627 &(type
->baseNs
), &(type
->base
)) == 0)
11629 if ((type
->base
== NULL
) && (type
->type
== XML_SCHEMA_TYPE_COMPLEX
)) {
11630 xmlSchemaPMissingAttrErr(ctxt
,
11631 XML_SCHEMAP_S4S_ATTR_MISSING
,
11632 NULL
, node
, "base", NULL
);
11633 } else if ((ctxt
->isRedefine
) &&
11634 (type
->flags
& XML_SCHEMAS_TYPE_GLOBAL
))
11636 if (type
->base
== NULL
) {
11637 xmlSchemaPMissingAttrErr(ctxt
,
11638 XML_SCHEMAP_S4S_ATTR_MISSING
,
11639 NULL
, node
, "base", NULL
);
11640 } else if ((! xmlStrEqual(type
->base
, type
->name
)) ||
11641 (! xmlStrEqual(type
->baseNs
, type
->targetNamespace
)))
11643 xmlChar
*str1
= NULL
, *str2
= NULL
;
11645 * REDEFINE: SPEC src-redefine (5)
11646 * "Within the [children], each <simpleType> must have a
11647 * <restriction> among its [children] ... the `actual value` of
11648 * whose base [attribute] must be the same as the `actual value`
11649 * of its own name attribute plus target namespace;"
11651 xmlSchemaPCustomErrExt(ctxt
, XML_SCHEMAP_SRC_REDEFINE
,
11652 NULL
, node
, "This is a redefinition, but the QName "
11653 "value '%s' of the 'base' attribute does not match the "
11654 "type's designation '%s'",
11655 xmlSchemaFormatQName(&str1
, type
->baseNs
, type
->base
),
11656 xmlSchemaFormatQName(&str2
, type
->targetNamespace
,
11657 type
->name
), NULL
);
11658 FREE_AND_NULL(str1
);
11659 FREE_AND_NULL(str2
);
11660 /* Avoid confusion and erase the values. */
11662 type
->baseNs
= NULL
;
11667 * And now for the children...
11669 child
= node
->children
;
11670 if (IS_SCHEMA(child
, "annotation")) {
11672 * Add the annotation to the simple type ancestor.
11674 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr
) type
,
11675 xmlSchemaParseAnnotation(ctxt
, child
, 1));
11676 child
= child
->next
;
11678 if (parentType
== XML_SCHEMA_TYPE_SIMPLE
) {
11680 * Corresponds to <simpleType><restriction><simpleType>.
11682 if (IS_SCHEMA(child
, "simpleType")) {
11683 if (type
->base
!= NULL
) {
11685 * src-restriction-base-or-simpleType
11686 * Either the base [attribute] or the simpleType [child] of the
11687 * <restriction> element must be present, but not both.
11689 xmlSchemaPContentErr(ctxt
,
11690 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE
,
11692 "The attribute 'base' and the <simpleType> child are "
11693 "mutually exclusive", NULL
);
11695 type
->baseType
= (xmlSchemaTypePtr
)
11696 xmlSchemaParseSimpleType(ctxt
, schema
, child
, 0);
11698 child
= child
->next
;
11699 } else if (type
->base
== NULL
) {
11700 xmlSchemaPContentErr(ctxt
,
11701 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE
,
11703 "Either the attribute 'base' or a <simpleType> child "
11704 "must be present", NULL
);
11706 } else if (parentType
== XML_SCHEMA_TYPE_COMPLEX_CONTENT
) {
11708 * Corresponds to <complexType><complexContent><restriction>...
11711 * Model groups <all>, <choice> and <sequence>.
11713 if (IS_SCHEMA(child
, "all")) {
11714 type
->subtypes
= (xmlSchemaTypePtr
)
11715 xmlSchemaParseModelGroup(ctxt
, schema
, child
,
11716 XML_SCHEMA_TYPE_ALL
, 1);
11717 child
= child
->next
;
11718 } else if (IS_SCHEMA(child
, "choice")) {
11719 type
->subtypes
= (xmlSchemaTypePtr
)
11720 xmlSchemaParseModelGroup(ctxt
,
11721 schema
, child
, XML_SCHEMA_TYPE_CHOICE
, 1);
11722 child
= child
->next
;
11723 } else if (IS_SCHEMA(child
, "sequence")) {
11724 type
->subtypes
= (xmlSchemaTypePtr
)
11725 xmlSchemaParseModelGroup(ctxt
, schema
, child
,
11726 XML_SCHEMA_TYPE_SEQUENCE
, 1);
11727 child
= child
->next
;
11729 * Model group reference <group>.
11731 } else if (IS_SCHEMA(child
, "group")) {
11732 type
->subtypes
= (xmlSchemaTypePtr
)
11733 xmlSchemaParseModelGroupDefRef(ctxt
, schema
, child
);
11735 * Note that the reference will be resolved in
11736 * xmlSchemaResolveTypeReferences();
11738 child
= child
->next
;
11740 } else if (parentType
== XML_SCHEMA_TYPE_SIMPLE_CONTENT
) {
11742 * Corresponds to <complexType><simpleContent><restriction>...
11744 * "1.1 the simple type definition corresponding to the <simpleType>
11745 * among the [children] of <restriction> if there is one;"
11747 if (IS_SCHEMA(child
, "simpleType")) {
11749 * We will store the to-be-restricted simple type in
11750 * type->contentTypeDef *temporarily*.
11752 type
->contentTypeDef
= (xmlSchemaTypePtr
)
11753 xmlSchemaParseSimpleType(ctxt
, schema
, child
, 0);
11754 if ( type
->contentTypeDef
== NULL
)
11756 child
= child
->next
;
11760 if ((parentType
== XML_SCHEMA_TYPE_SIMPLE
) ||
11761 (parentType
== XML_SCHEMA_TYPE_SIMPLE_CONTENT
)) {
11762 xmlSchemaFacetPtr facet
, lastfacet
= NULL
;
11764 * Corresponds to <complexType><simpleContent><restriction>...
11765 * <simpleType><restriction>...
11769 * Add the facets to the simple type ancestor.
11772 * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
11773 * Simple Type Definition Schema Representation Constraint:
11774 * *Single Facet Value*
11776 while ((IS_SCHEMA(child
, "minInclusive")) ||
11777 (IS_SCHEMA(child
, "minExclusive")) ||
11778 (IS_SCHEMA(child
, "maxInclusive")) ||
11779 (IS_SCHEMA(child
, "maxExclusive")) ||
11780 (IS_SCHEMA(child
, "totalDigits")) ||
11781 (IS_SCHEMA(child
, "fractionDigits")) ||
11782 (IS_SCHEMA(child
, "pattern")) ||
11783 (IS_SCHEMA(child
, "enumeration")) ||
11784 (IS_SCHEMA(child
, "whiteSpace")) ||
11785 (IS_SCHEMA(child
, "length")) ||
11786 (IS_SCHEMA(child
, "maxLength")) ||
11787 (IS_SCHEMA(child
, "minLength"))) {
11788 facet
= xmlSchemaParseFacet(ctxt
, schema
, child
);
11789 if (facet
!= NULL
) {
11790 if (lastfacet
== NULL
)
11791 type
->facets
= facet
;
11793 lastfacet
->next
= facet
;
11795 lastfacet
->next
= NULL
;
11797 child
= child
->next
;
11800 * Create links for derivation and validation.
11802 if (type
->facets
!= NULL
) {
11803 xmlSchemaFacetLinkPtr facetLink
, lastFacetLink
= NULL
;
11805 facet
= type
->facets
;
11807 facetLink
= (xmlSchemaFacetLinkPtr
)
11808 xmlMalloc(sizeof(xmlSchemaFacetLink
));
11809 if (facetLink
== NULL
) {
11810 xmlSchemaPErrMemory(ctxt
, "allocating a facet link", NULL
);
11811 xmlFree(facetLink
);
11814 facetLink
->facet
= facet
;
11815 facetLink
->next
= NULL
;
11816 if (lastFacetLink
== NULL
)
11817 type
->facetSet
= facetLink
;
11819 lastFacetLink
->next
= facetLink
;
11820 lastFacetLink
= facetLink
;
11821 facet
= facet
->next
;
11822 } while (facet
!= NULL
);
11825 if (type
->type
== XML_SCHEMA_TYPE_COMPLEX
) {
11827 * Attribute uses/declarations.
11829 if (xmlSchemaParseLocalAttributes(ctxt
, schema
, &child
,
11830 (xmlSchemaItemListPtr
*) &(type
->attrUses
),
11831 XML_SCHEMA_TYPE_RESTRICTION
, NULL
) == -1)
11834 * Attribute wildcard.
11836 if (IS_SCHEMA(child
, "anyAttribute")) {
11837 type
->attributeWildcard
=
11838 xmlSchemaParseAnyAttribute(ctxt
, schema
, child
);
11839 child
= child
->next
;
11842 if (child
!= NULL
) {
11843 if (parentType
== XML_SCHEMA_TYPE_COMPLEX_CONTENT
) {
11844 xmlSchemaPContentErr(ctxt
,
11845 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
11846 NULL
, node
, child
, NULL
,
11847 "annotation?, (group | all | choice | sequence)?, "
11848 "((attribute | attributeGroup)*, anyAttribute?))");
11849 } else if (parentType
== XML_SCHEMA_TYPE_SIMPLE_CONTENT
) {
11850 xmlSchemaPContentErr(ctxt
,
11851 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
11852 NULL
, node
, child
, NULL
,
11853 "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11854 "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11855 "length | minLength | maxLength | enumeration | whiteSpace | "
11856 "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
11859 xmlSchemaPContentErr(ctxt
,
11860 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
11861 NULL
, node
, child
, NULL
,
11862 "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11863 "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11864 "length | minLength | maxLength | enumeration | whiteSpace | "
11872 * xmlSchemaParseExtension:
11873 * @ctxt: a schema validation context
11874 * @schema: the schema being built
11875 * @node: a subtree containing XML Schema information
11877 * Parses an <extension>, which is found inside a
11878 * <simpleContent> or <complexContent>.
11879 * *WARNING* this interface is highly subject to change.
11881 * TODO: Returns the type definition or NULL in case of error
11883 static xmlSchemaTypePtr
11884 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
11885 xmlNodePtr node
, xmlSchemaTypeType parentType
)
11887 xmlSchemaTypePtr type
;
11888 xmlNodePtr child
= NULL
;
11891 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
11893 /* Not a component, don't create it. */
11894 type
= ctxt
->ctxtType
;
11895 type
->flags
|= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION
;
11898 * Check for illegal attributes.
11900 attr
= node
->properties
;
11901 while (attr
!= NULL
) {
11902 if (attr
->ns
== NULL
) {
11903 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
11904 (!xmlStrEqual(attr
->name
, BAD_CAST
"base"))) {
11905 xmlSchemaPIllegalAttrErr(ctxt
,
11906 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
11908 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
11909 xmlSchemaPIllegalAttrErr(ctxt
,
11910 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
11915 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
11918 * Attribute "base" - mandatory.
11920 if ((xmlSchemaPValAttrQName(ctxt
, schema
, NULL
, node
,
11921 "base", &(type
->baseNs
), &(type
->base
)) == 0) &&
11922 (type
->base
== NULL
)) {
11923 xmlSchemaPMissingAttrErr(ctxt
,
11924 XML_SCHEMAP_S4S_ATTR_MISSING
,
11925 NULL
, node
, "base", NULL
);
11928 * And now for the children...
11930 child
= node
->children
;
11931 if (IS_SCHEMA(child
, "annotation")) {
11933 * Add the annotation to the type ancestor.
11935 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr
) type
,
11936 xmlSchemaParseAnnotation(ctxt
, child
, 1));
11937 child
= child
->next
;
11939 if (parentType
== XML_SCHEMA_TYPE_COMPLEX_CONTENT
) {
11941 * Corresponds to <complexType><complexContent><extension>... and:
11943 * Model groups <all>, <choice>, <sequence> and <group>.
11945 if (IS_SCHEMA(child
, "all")) {
11946 type
->subtypes
= (xmlSchemaTypePtr
)
11947 xmlSchemaParseModelGroup(ctxt
, schema
,
11948 child
, XML_SCHEMA_TYPE_ALL
, 1);
11949 child
= child
->next
;
11950 } else if (IS_SCHEMA(child
, "choice")) {
11951 type
->subtypes
= (xmlSchemaTypePtr
)
11952 xmlSchemaParseModelGroup(ctxt
, schema
,
11953 child
, XML_SCHEMA_TYPE_CHOICE
, 1);
11954 child
= child
->next
;
11955 } else if (IS_SCHEMA(child
, "sequence")) {
11956 type
->subtypes
= (xmlSchemaTypePtr
)
11957 xmlSchemaParseModelGroup(ctxt
, schema
,
11958 child
, XML_SCHEMA_TYPE_SEQUENCE
, 1);
11959 child
= child
->next
;
11960 } else if (IS_SCHEMA(child
, "group")) {
11961 type
->subtypes
= (xmlSchemaTypePtr
)
11962 xmlSchemaParseModelGroupDefRef(ctxt
, schema
, child
);
11964 * Note that the reference will be resolved in
11965 * xmlSchemaResolveTypeReferences();
11967 child
= child
->next
;
11970 if (child
!= NULL
) {
11972 * Attribute uses/declarations.
11974 if (xmlSchemaParseLocalAttributes(ctxt
, schema
, &child
,
11975 (xmlSchemaItemListPtr
*) &(type
->attrUses
),
11976 XML_SCHEMA_TYPE_EXTENSION
, NULL
) == -1)
11979 * Attribute wildcard.
11981 if (IS_SCHEMA(child
, "anyAttribute")) {
11982 ctxt
->ctxtType
->attributeWildcard
=
11983 xmlSchemaParseAnyAttribute(ctxt
, schema
, child
);
11984 child
= child
->next
;
11987 if (child
!= NULL
) {
11988 if (parentType
== XML_SCHEMA_TYPE_COMPLEX_CONTENT
) {
11989 /* Complex content extension. */
11990 xmlSchemaPContentErr(ctxt
,
11991 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
11992 NULL
, node
, child
, NULL
,
11993 "(annotation?, ((group | all | choice | sequence)?, "
11994 "((attribute | attributeGroup)*, anyAttribute?)))");
11996 /* Simple content extension. */
11997 xmlSchemaPContentErr(ctxt
,
11998 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
11999 NULL
, node
, child
, NULL
,
12000 "(annotation?, ((attribute | attributeGroup)*, "
12001 "anyAttribute?))");
12008 * xmlSchemaParseSimpleContent:
12009 * @ctxt: a schema validation context
12010 * @schema: the schema being built
12011 * @node: a subtree containing XML Schema information
12013 * parse a XML schema SimpleContent definition
12014 * *WARNING* this interface is highly subject to change
12016 * Returns the type definition or NULL in case of error
12019 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt
,
12020 xmlSchemaPtr schema
, xmlNodePtr node
,
12021 int *hasRestrictionOrExtension
)
12023 xmlSchemaTypePtr type
;
12024 xmlNodePtr child
= NULL
;
12027 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
) ||
12028 (hasRestrictionOrExtension
== NULL
))
12030 *hasRestrictionOrExtension
= 0;
12031 /* Not a component, don't create it. */
12032 type
= ctxt
->ctxtType
;
12033 type
->contentType
= XML_SCHEMA_CONTENT_SIMPLE
;
12035 * Check for illegal attributes.
12037 attr
= node
->properties
;
12038 while (attr
!= NULL
) {
12039 if (attr
->ns
== NULL
) {
12040 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id"))) {
12041 xmlSchemaPIllegalAttrErr(ctxt
,
12042 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
12044 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
12045 xmlSchemaPIllegalAttrErr(ctxt
,
12046 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
12051 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
12054 * And now for the children...
12056 child
= node
->children
;
12057 if (IS_SCHEMA(child
, "annotation")) {
12059 * Add the annotation to the complex type ancestor.
12061 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr
) type
,
12062 xmlSchemaParseAnnotation(ctxt
, child
, 1));
12063 child
= child
->next
;
12065 if (child
== NULL
) {
12066 xmlSchemaPContentErr(ctxt
,
12067 XML_SCHEMAP_S4S_ELEM_MISSING
,
12068 NULL
, node
, NULL
, NULL
,
12069 "(annotation?, (restriction | extension))");
12071 if (child
== NULL
) {
12072 xmlSchemaPContentErr(ctxt
,
12073 XML_SCHEMAP_S4S_ELEM_MISSING
,
12074 NULL
, node
, NULL
, NULL
,
12075 "(annotation?, (restriction | extension))");
12077 if (IS_SCHEMA(child
, "restriction")) {
12078 xmlSchemaParseRestriction(ctxt
, schema
, child
,
12079 XML_SCHEMA_TYPE_SIMPLE_CONTENT
);
12080 (*hasRestrictionOrExtension
) = 1;
12081 child
= child
->next
;
12082 } else if (IS_SCHEMA(child
, "extension")) {
12083 xmlSchemaParseExtension(ctxt
, schema
, child
,
12084 XML_SCHEMA_TYPE_SIMPLE_CONTENT
);
12085 (*hasRestrictionOrExtension
) = 1;
12086 child
= child
->next
;
12088 if (child
!= NULL
) {
12089 xmlSchemaPContentErr(ctxt
,
12090 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
12091 NULL
, node
, child
, NULL
,
12092 "(annotation?, (restriction | extension))");
12098 * xmlSchemaParseComplexContent:
12099 * @ctxt: a schema validation context
12100 * @schema: the schema being built
12101 * @node: a subtree containing XML Schema information
12103 * parse a XML schema ComplexContent definition
12104 * *WARNING* this interface is highly subject to change
12106 * Returns the type definition or NULL in case of error
12109 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt
,
12110 xmlSchemaPtr schema
, xmlNodePtr node
,
12111 int *hasRestrictionOrExtension
)
12113 xmlSchemaTypePtr type
;
12114 xmlNodePtr child
= NULL
;
12117 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
) ||
12118 (hasRestrictionOrExtension
== NULL
))
12120 *hasRestrictionOrExtension
= 0;
12121 /* Not a component, don't create it. */
12122 type
= ctxt
->ctxtType
;
12124 * Check for illegal attributes.
12126 attr
= node
->properties
;
12127 while (attr
!= NULL
) {
12128 if (attr
->ns
== NULL
) {
12129 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
12130 (!xmlStrEqual(attr
->name
, BAD_CAST
"mixed")))
12132 xmlSchemaPIllegalAttrErr(ctxt
,
12133 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
12135 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
12136 xmlSchemaPIllegalAttrErr(ctxt
,
12137 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
12142 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
12145 * Set the 'mixed' on the complex type ancestor.
12147 if (xmlGetBooleanProp(ctxt
, node
, "mixed", 0)) {
12148 if ((type
->flags
& XML_SCHEMAS_TYPE_MIXED
) == 0)
12149 type
->flags
|= XML_SCHEMAS_TYPE_MIXED
;
12151 child
= node
->children
;
12152 if (IS_SCHEMA(child
, "annotation")) {
12154 * Add the annotation to the complex type ancestor.
12156 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr
) type
,
12157 xmlSchemaParseAnnotation(ctxt
, child
, 1));
12158 child
= child
->next
;
12160 if (child
== NULL
) {
12161 xmlSchemaPContentErr(ctxt
,
12162 XML_SCHEMAP_S4S_ELEM_MISSING
,
12164 NULL
, "(annotation?, (restriction | extension))");
12166 if (child
== NULL
) {
12167 xmlSchemaPContentErr(ctxt
,
12168 XML_SCHEMAP_S4S_ELEM_MISSING
,
12170 NULL
, "(annotation?, (restriction | extension))");
12172 if (IS_SCHEMA(child
, "restriction")) {
12173 xmlSchemaParseRestriction(ctxt
, schema
, child
,
12174 XML_SCHEMA_TYPE_COMPLEX_CONTENT
);
12175 (*hasRestrictionOrExtension
) = 1;
12176 child
= child
->next
;
12177 } else if (IS_SCHEMA(child
, "extension")) {
12178 xmlSchemaParseExtension(ctxt
, schema
, child
,
12179 XML_SCHEMA_TYPE_COMPLEX_CONTENT
);
12180 (*hasRestrictionOrExtension
) = 1;
12181 child
= child
->next
;
12183 if (child
!= NULL
) {
12184 xmlSchemaPContentErr(ctxt
,
12185 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
12187 NULL
, "(annotation?, (restriction | extension))");
12193 * xmlSchemaParseComplexType:
12194 * @ctxt: a schema validation context
12195 * @schema: the schema being built
12196 * @node: a subtree containing XML Schema information
12198 * parse a XML schema Complex Type definition
12199 * *WARNING* this interface is highly subject to change
12201 * Returns the type definition or NULL in case of error
12203 static xmlSchemaTypePtr
12204 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
12205 xmlNodePtr node
, int topLevel
)
12207 xmlSchemaTypePtr type
, ctxtType
;
12208 xmlNodePtr child
= NULL
;
12209 const xmlChar
*name
= NULL
;
12211 const xmlChar
*attrValue
;
12212 #ifdef ENABLE_NAMED_LOCALS
12215 int final
= 0, block
= 0, hasRestrictionOrExtension
= 0;
12218 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
12221 ctxtType
= ctxt
->ctxtType
;
12224 attr
= xmlSchemaGetPropNode(node
, "name");
12225 if (attr
== NULL
) {
12226 xmlSchemaPMissingAttrErr(ctxt
,
12227 XML_SCHEMAP_S4S_ATTR_MISSING
, NULL
, node
, "name", NULL
);
12229 } else if (xmlSchemaPValAttrNode(ctxt
, NULL
, attr
,
12230 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), &name
) != 0) {
12235 if (topLevel
== 0) {
12237 * Parse as local complex type definition.
12239 #ifdef ENABLE_NAMED_LOCALS
12240 snprintf(buf
, 39, "#CT%d", ctxt
->counter
++ + 1);
12241 type
= xmlSchemaAddType(ctxt
, schema
,
12242 XML_SCHEMA_TYPE_COMPLEX
,
12243 xmlDictLookup(ctxt
->dict
, (const xmlChar
*)buf
, -1),
12244 ctxt
->targetNamespace
, node
, 0);
12246 type
= xmlSchemaAddType(ctxt
, schema
,
12247 XML_SCHEMA_TYPE_COMPLEX
,
12248 NULL
, ctxt
->targetNamespace
, node
, 0);
12254 type
->type
= XML_SCHEMA_TYPE_COMPLEX
;
12256 * TODO: We need the target namespace.
12260 * Parse as global complex type definition.
12262 type
= xmlSchemaAddType(ctxt
, schema
,
12263 XML_SCHEMA_TYPE_COMPLEX
,
12264 name
, ctxt
->targetNamespace
, node
, 1);
12268 type
->type
= XML_SCHEMA_TYPE_COMPLEX
;
12269 type
->flags
|= XML_SCHEMAS_TYPE_GLOBAL
;
12271 type
->targetNamespace
= ctxt
->targetNamespace
;
12273 * Handle attributes.
12275 attr
= node
->properties
;
12276 while (attr
!= NULL
) {
12277 if (attr
->ns
== NULL
) {
12278 if (xmlStrEqual(attr
->name
, BAD_CAST
"id")) {
12282 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
12283 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"mixed")) {
12285 * Attribute "mixed".
12287 if (xmlSchemaPGetBoolNodeValue(ctxt
,
12288 NULL
, (xmlNodePtr
) attr
))
12289 type
->flags
|= XML_SCHEMAS_TYPE_MIXED
;
12290 } else if (topLevel
) {
12292 * Attributes of global complex type definitions.
12294 if (xmlStrEqual(attr
->name
, BAD_CAST
"name")) {
12296 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"abstract")) {
12298 * Attribute "abstract".
12300 if (xmlSchemaPGetBoolNodeValue(ctxt
,
12301 NULL
, (xmlNodePtr
) attr
))
12302 type
->flags
|= XML_SCHEMAS_TYPE_ABSTRACT
;
12303 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"final")) {
12305 * Attribute "final".
12307 attrValue
= xmlSchemaGetNodeContent(ctxt
,
12308 (xmlNodePtr
) attr
);
12309 if (xmlSchemaPValAttrBlockFinal(attrValue
,
12312 XML_SCHEMAS_TYPE_FINAL_EXTENSION
,
12313 XML_SCHEMAS_TYPE_FINAL_RESTRICTION
,
12316 xmlSchemaPSimpleTypeErr(ctxt
,
12317 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
12318 NULL
, (xmlNodePtr
) attr
, NULL
,
12319 "(#all | List of (extension | restriction))",
12320 attrValue
, NULL
, NULL
, NULL
);
12323 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"block")) {
12325 * Attribute "block".
12327 attrValue
= xmlSchemaGetNodeContent(ctxt
,
12328 (xmlNodePtr
) attr
);
12329 if (xmlSchemaPValAttrBlockFinal(attrValue
, &(type
->flags
),
12331 XML_SCHEMAS_TYPE_BLOCK_EXTENSION
,
12332 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
,
12333 -1, -1, -1) != 0) {
12334 xmlSchemaPSimpleTypeErr(ctxt
,
12335 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
12336 NULL
, (xmlNodePtr
) attr
, NULL
,
12337 "(#all | List of (extension | restriction)) ",
12338 attrValue
, NULL
, NULL
, NULL
);
12342 xmlSchemaPIllegalAttrErr(ctxt
,
12343 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
12346 xmlSchemaPIllegalAttrErr(ctxt
,
12347 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
12349 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
12350 xmlSchemaPIllegalAttrErr(ctxt
,
12351 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
12357 * Apply default "block" values.
12359 if (schema
->flags
& XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION
)
12360 type
->flags
|= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
;
12361 if (schema
->flags
& XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION
)
12362 type
->flags
|= XML_SCHEMAS_TYPE_BLOCK_EXTENSION
;
12366 * Apply default "block" values.
12368 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION
)
12369 type
->flags
|= XML_SCHEMAS_TYPE_FINAL_RESTRICTION
;
12370 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_EXTENSION
)
12371 type
->flags
|= XML_SCHEMAS_TYPE_FINAL_EXTENSION
;
12374 * And now for the children...
12376 child
= node
->children
;
12377 if (IS_SCHEMA(child
, "annotation")) {
12378 type
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
12379 child
= child
->next
;
12381 ctxt
->ctxtType
= type
;
12382 if (IS_SCHEMA(child
, "simpleContent")) {
12384 * <complexType><simpleContent>...
12386 * Specifying mixed='true' when the <simpleContent>
12387 * alternative is chosen has no effect
12389 if (type
->flags
& XML_SCHEMAS_TYPE_MIXED
)
12390 type
->flags
^= XML_SCHEMAS_TYPE_MIXED
;
12391 xmlSchemaParseSimpleContent(ctxt
, schema
, child
,
12392 &hasRestrictionOrExtension
);
12393 child
= child
->next
;
12394 } else if (IS_SCHEMA(child
, "complexContent")) {
12396 * <complexType><complexContent>...
12398 type
->contentType
= XML_SCHEMA_CONTENT_EMPTY
;
12399 xmlSchemaParseComplexContent(ctxt
, schema
, child
,
12400 &hasRestrictionOrExtension
);
12401 child
= child
->next
;
12404 * E.g <complexType><sequence>... or <complexType><attribute>... etc.
12407 * "...the third alternative (neither <simpleContent> nor
12408 * <complexContent>) is chosen. This case is understood as shorthand
12409 * for complex content restricting the `ur-type definition`, and the
12410 * details of the mappings should be modified as necessary.
12412 type
->baseType
= xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE
);
12413 type
->flags
|= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION
;
12415 * Parse model groups.
12417 if (IS_SCHEMA(child
, "all")) {
12418 type
->subtypes
= (xmlSchemaTypePtr
)
12419 xmlSchemaParseModelGroup(ctxt
, schema
, child
,
12420 XML_SCHEMA_TYPE_ALL
, 1);
12421 child
= child
->next
;
12422 } else if (IS_SCHEMA(child
, "choice")) {
12423 type
->subtypes
= (xmlSchemaTypePtr
)
12424 xmlSchemaParseModelGroup(ctxt
, schema
, child
,
12425 XML_SCHEMA_TYPE_CHOICE
, 1);
12426 child
= child
->next
;
12427 } else if (IS_SCHEMA(child
, "sequence")) {
12428 type
->subtypes
= (xmlSchemaTypePtr
)
12429 xmlSchemaParseModelGroup(ctxt
, schema
, child
,
12430 XML_SCHEMA_TYPE_SEQUENCE
, 1);
12431 child
= child
->next
;
12432 } else if (IS_SCHEMA(child
, "group")) {
12433 type
->subtypes
= (xmlSchemaTypePtr
)
12434 xmlSchemaParseModelGroupDefRef(ctxt
, schema
, child
);
12436 * Note that the reference will be resolved in
12437 * xmlSchemaResolveTypeReferences();
12439 child
= child
->next
;
12442 * Parse attribute decls/refs.
12444 if (xmlSchemaParseLocalAttributes(ctxt
, schema
, &child
,
12445 (xmlSchemaItemListPtr
*) &(type
->attrUses
),
12446 XML_SCHEMA_TYPE_RESTRICTION
, NULL
) == -1)
12449 * Parse attribute wildcard.
12451 if (IS_SCHEMA(child
, "anyAttribute")) {
12452 type
->attributeWildcard
= xmlSchemaParseAnyAttribute(ctxt
, schema
, child
);
12453 child
= child
->next
;
12456 if (child
!= NULL
) {
12457 xmlSchemaPContentErr(ctxt
,
12458 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
12460 NULL
, "(annotation?, (simpleContent | complexContent | "
12461 "((group | all | choice | sequence)?, ((attribute | "
12462 "attributeGroup)*, anyAttribute?))))");
12465 * REDEFINE: SPEC src-redefine (5)
12467 if (topLevel
&& ctxt
->isRedefine
&& (! hasRestrictionOrExtension
)) {
12468 xmlSchemaPCustomErr(ctxt
, XML_SCHEMAP_SRC_REDEFINE
,
12469 NULL
, node
, "This is a redefinition, thus the "
12470 "<complexType> must have a <restriction> or <extension> "
12471 "grand-child", NULL
);
12473 ctxt
->ctxtType
= ctxtType
;
12477 /************************************************************************
12479 * Validating using Schemas *
12481 ************************************************************************/
12483 /************************************************************************
12485 * Reading/Writing Schemas *
12487 ************************************************************************/
12489 #if 0 /* Will be enabled if it is clear what options are needed. */
12491 * xmlSchemaParserCtxtSetOptions:
12492 * @ctxt: a schema parser context
12493 * @options: a combination of xmlSchemaParserOption
12495 * Sets the options to be used during the parse.
12497 * Returns 0 in case of success, -1 in case of an
12501 xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt
,
12510 * WARNING: Change the start value if adding to the
12511 * xmlSchemaParseOption.
12513 for (i
= 1; i
< (int) sizeof(int) * 8; i
++) {
12514 if (options
& 1<<i
) {
12518 ctxt
->options
= options
;
12523 * xmlSchemaValidCtxtGetOptions:
12524 * @ctxt: a schema parser context
12526 * Returns the option combination of the parser context.
12529 xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt
)
12535 return (ctxt
->options
);
12540 * xmlSchemaNewParserCtxt:
12541 * @URL: the location of the schema
12543 * Create an XML Schemas parse context for that file/resource expected
12544 * to contain an XML Schemas file.
12546 * Returns the parser context or NULL in case of error
12548 xmlSchemaParserCtxtPtr
12549 xmlSchemaNewParserCtxt(const char *URL
)
12551 xmlSchemaParserCtxtPtr ret
;
12556 ret
= xmlSchemaParserCtxtCreate();
12559 ret
->dict
= xmlDictCreate();
12560 ret
->URL
= xmlDictLookup(ret
->dict
, (const xmlChar
*) URL
, -1);
12565 * xmlSchemaNewMemParserCtxt:
12566 * @buffer: a pointer to a char array containing the schemas
12567 * @size: the size of the array
12569 * Create an XML Schemas parse context for that memory buffer expected
12570 * to contain an XML Schemas file.
12572 * Returns the parser context or NULL in case of error
12574 xmlSchemaParserCtxtPtr
12575 xmlSchemaNewMemParserCtxt(const char *buffer
, int size
)
12577 xmlSchemaParserCtxtPtr ret
;
12579 if ((buffer
== NULL
) || (size
<= 0))
12581 ret
= xmlSchemaParserCtxtCreate();
12584 ret
->buffer
= buffer
;
12586 ret
->dict
= xmlDictCreate();
12591 * xmlSchemaNewDocParserCtxt:
12592 * @doc: a preparsed document tree
12594 * Create an XML Schemas parse context for that document.
12595 * NB. The document may be modified during the parsing process.
12597 * Returns the parser context or NULL in case of error
12599 xmlSchemaParserCtxtPtr
12600 xmlSchemaNewDocParserCtxt(xmlDocPtr doc
)
12602 xmlSchemaParserCtxtPtr ret
;
12606 ret
= xmlSchemaParserCtxtCreate();
12610 ret
->dict
= xmlDictCreate();
12611 /* The application has responsibility for the document */
12618 * xmlSchemaFreeParserCtxt:
12619 * @ctxt: the schema parser context
12621 * Free the resources associated to the schema parser context
12624 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt
)
12628 if (ctxt
->doc
!= NULL
&& !ctxt
->preserve
)
12629 xmlFreeDoc(ctxt
->doc
);
12630 if (ctxt
->vctxt
!= NULL
) {
12631 xmlSchemaFreeValidCtxt(ctxt
->vctxt
);
12633 if (ctxt
->ownsConstructor
&& (ctxt
->constructor
!= NULL
)) {
12634 xmlSchemaConstructionCtxtFree(ctxt
->constructor
);
12635 ctxt
->constructor
= NULL
;
12636 ctxt
->ownsConstructor
= 0;
12638 if (ctxt
->attrProhibs
!= NULL
)
12639 xmlSchemaItemListFree(ctxt
->attrProhibs
);
12640 xmlDictFree(ctxt
->dict
);
12644 /************************************************************************
12646 * Building the content models *
12648 ************************************************************************/
12651 * xmlSchemaBuildContentModelForSubstGroup:
12653 * Returns 1 if nillable, 0 otherwise
12656 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt
,
12657 xmlSchemaParticlePtr particle
, int counter
, xmlAutomataStatePtr end
)
12659 xmlAutomataStatePtr start
, tmp
;
12660 xmlSchemaElementPtr elemDecl
, member
;
12661 xmlSchemaSubstGroupPtr substGroup
;
12665 elemDecl
= (xmlSchemaElementPtr
) particle
->children
;
12667 * Wrap the substitution group with a CHOICE.
12669 start
= pctxt
->state
;
12671 end
= xmlAutomataNewState(pctxt
->am
);
12672 substGroup
= xmlSchemaSubstGroupGet(pctxt
, elemDecl
);
12673 if (substGroup
== NULL
) {
12674 xmlSchemaPErr(pctxt
, WXS_ITEM_NODE(particle
),
12675 XML_SCHEMAP_INTERNAL
,
12676 "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
12677 "declaration is marked having a subst. group but none "
12678 "available.\n", elemDecl
->name
, NULL
);
12681 if (counter
>= 0) {
12683 * NOTE that we put the declaration in, even if it's abstract.
12684 * However, an error will be raised during *validation* if an element
12685 * information item shall be validated against an abstract element
12688 tmp
= xmlAutomataNewCountedTrans(pctxt
->am
, start
, NULL
, counter
);
12689 xmlAutomataNewTransition2(pctxt
->am
, tmp
, end
,
12690 elemDecl
->name
, elemDecl
->targetNamespace
, elemDecl
);
12692 * Add subst. group members.
12694 for (i
= 0; i
< substGroup
->members
->nbItems
; i
++) {
12695 member
= (xmlSchemaElementPtr
) substGroup
->members
->items
[i
];
12696 xmlAutomataNewTransition2(pctxt
->am
, tmp
, end
,
12697 member
->name
, member
->targetNamespace
, member
);
12699 } else if (particle
->maxOccurs
== 1) {
12701 * NOTE that we put the declaration in, even if it's abstract,
12703 xmlAutomataNewEpsilon(pctxt
->am
,
12704 xmlAutomataNewTransition2(pctxt
->am
,
12706 elemDecl
->name
, elemDecl
->targetNamespace
, elemDecl
), end
);
12708 * Add subst. group members.
12710 for (i
= 0; i
< substGroup
->members
->nbItems
; i
++) {
12711 member
= (xmlSchemaElementPtr
) substGroup
->members
->items
[i
];
12713 * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
12714 * was incorrectly used instead of xmlAutomataNewTransition2()
12715 * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
12716 * section in xmlSchemaBuildAContentModel() ).
12717 * TODO: Check if xmlAutomataNewOnceTrans2() was instead
12718 * intended for the above "counter" section originally. I.e.,
12719 * check xs:all with subst-groups.
12721 * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
12722 * member->name, member->targetNamespace,
12725 tmp
= xmlAutomataNewTransition2(pctxt
->am
, start
, NULL
,
12726 member
->name
, member
->targetNamespace
, member
);
12727 xmlAutomataNewEpsilon(pctxt
->am
, tmp
, end
);
12730 xmlAutomataStatePtr hop
;
12731 int maxOccurs
= particle
->maxOccurs
== UNBOUNDED
?
12732 UNBOUNDED
: particle
->maxOccurs
- 1;
12733 int minOccurs
= particle
->minOccurs
< 1 ? 0 : particle
->minOccurs
- 1;
12736 xmlAutomataNewCounter(pctxt
->am
, minOccurs
,
12738 hop
= xmlAutomataNewState(pctxt
->am
);
12740 xmlAutomataNewEpsilon(pctxt
->am
,
12741 xmlAutomataNewTransition2(pctxt
->am
,
12743 elemDecl
->name
, elemDecl
->targetNamespace
, elemDecl
),
12746 * Add subst. group members.
12748 for (i
= 0; i
< substGroup
->members
->nbItems
; i
++) {
12749 member
= (xmlSchemaElementPtr
) substGroup
->members
->items
[i
];
12750 xmlAutomataNewEpsilon(pctxt
->am
,
12751 xmlAutomataNewTransition2(pctxt
->am
,
12753 member
->name
, member
->targetNamespace
, member
),
12756 xmlAutomataNewCountedTrans(pctxt
->am
, hop
, start
, counter
);
12757 xmlAutomataNewCounterTrans(pctxt
->am
, hop
, end
, counter
);
12759 if (particle
->minOccurs
== 0) {
12760 xmlAutomataNewEpsilon(pctxt
->am
, start
, end
);
12763 pctxt
->state
= end
;
12768 * xmlSchemaBuildContentModelForElement:
12770 * Returns 1 if nillable, 0 otherwise
12773 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt
,
12774 xmlSchemaParticlePtr particle
)
12778 if (((xmlSchemaElementPtr
) particle
->children
)->flags
&
12779 XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD
) {
12781 * Substitution groups.
12783 ret
= xmlSchemaBuildContentModelForSubstGroup(ctxt
, particle
, -1, NULL
);
12785 xmlSchemaElementPtr elemDecl
;
12786 xmlAutomataStatePtr start
;
12788 elemDecl
= (xmlSchemaElementPtr
) particle
->children
;
12790 if (elemDecl
->flags
& XML_SCHEMAS_ELEM_ABSTRACT
)
12792 if (particle
->maxOccurs
== 1) {
12793 start
= ctxt
->state
;
12794 ctxt
->state
= xmlAutomataNewTransition2(ctxt
->am
, start
, NULL
,
12795 elemDecl
->name
, elemDecl
->targetNamespace
, elemDecl
);
12796 } else if ((particle
->maxOccurs
>= UNBOUNDED
) &&
12797 (particle
->minOccurs
< 2)) {
12798 /* Special case. */
12799 start
= ctxt
->state
;
12800 ctxt
->state
= xmlAutomataNewTransition2(ctxt
->am
, start
, NULL
,
12801 elemDecl
->name
, elemDecl
->targetNamespace
, elemDecl
);
12802 ctxt
->state
= xmlAutomataNewTransition2(ctxt
->am
, ctxt
->state
, ctxt
->state
,
12803 elemDecl
->name
, elemDecl
->targetNamespace
, elemDecl
);
12806 int maxOccurs
= particle
->maxOccurs
== UNBOUNDED
?
12807 UNBOUNDED
: particle
->maxOccurs
- 1;
12808 int minOccurs
= particle
->minOccurs
< 1 ?
12809 0 : particle
->minOccurs
- 1;
12811 start
= xmlAutomataNewEpsilon(ctxt
->am
, ctxt
->state
, NULL
);
12812 counter
= xmlAutomataNewCounter(ctxt
->am
, minOccurs
, maxOccurs
);
12813 ctxt
->state
= xmlAutomataNewTransition2(ctxt
->am
, start
, NULL
,
12814 elemDecl
->name
, elemDecl
->targetNamespace
, elemDecl
);
12815 xmlAutomataNewCountedTrans(ctxt
->am
, ctxt
->state
, start
, counter
);
12816 ctxt
->state
= xmlAutomataNewCounterTrans(ctxt
->am
, ctxt
->state
,
12819 if (particle
->minOccurs
== 0) {
12820 xmlAutomataNewEpsilon(ctxt
->am
, start
, ctxt
->state
);
12828 * xmlSchemaBuildAContentModel:
12829 * @ctxt: the schema parser context
12830 * @particle: the particle component
12831 * @name: the complex type's name whose content is being built
12833 * Create the automaton for the {content type} of a complex type.
12835 * Returns 1 if the content is nillable, 0 otherwise
12838 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt
,
12839 xmlSchemaParticlePtr particle
)
12843 if (particle
== NULL
) {
12844 PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
12847 if (particle
->children
== NULL
) {
12849 * Just return in this case. A missing "term" of the particle
12850 * might arise due to an invalid "term" component.
12855 switch (particle
->children
->type
) {
12856 case XML_SCHEMA_TYPE_ANY
: {
12857 xmlAutomataStatePtr start
, end
;
12858 xmlSchemaWildcardPtr wild
;
12859 xmlSchemaWildcardNsPtr ns
;
12861 wild
= (xmlSchemaWildcardPtr
) particle
->children
;
12863 start
= pctxt
->state
;
12864 end
= xmlAutomataNewState(pctxt
->am
);
12866 if (particle
->maxOccurs
== 1) {
12867 if (wild
->any
== 1) {
12869 * We need to add both transitions:
12871 * 1. the {"*", "*"} for elements in a namespace.
12874 xmlAutomataNewTransition2(pctxt
->am
,
12875 start
, NULL
, BAD_CAST
"*", BAD_CAST
"*", wild
);
12876 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, end
);
12878 * 2. the {"*"} for elements in no namespace.
12881 xmlAutomataNewTransition2(pctxt
->am
,
12882 start
, NULL
, BAD_CAST
"*", NULL
, wild
);
12883 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, end
);
12885 } else if (wild
->nsSet
!= NULL
) {
12888 pctxt
->state
= start
;
12889 pctxt
->state
= xmlAutomataNewTransition2(pctxt
->am
,
12890 pctxt
->state
, NULL
, BAD_CAST
"*", ns
->value
, wild
);
12891 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, end
);
12893 } while (ns
!= NULL
);
12895 } else if (wild
->negNsSet
!= NULL
) {
12896 pctxt
->state
= xmlAutomataNewNegTrans(pctxt
->am
,
12897 start
, end
, BAD_CAST
"*", wild
->negNsSet
->value
,
12902 xmlAutomataStatePtr hop
;
12904 particle
->maxOccurs
== UNBOUNDED
? UNBOUNDED
:
12905 particle
->maxOccurs
- 1;
12907 particle
->minOccurs
< 1 ? 0 : particle
->minOccurs
- 1;
12909 counter
= xmlAutomataNewCounter(pctxt
->am
, minOccurs
, maxOccurs
);
12910 hop
= xmlAutomataNewState(pctxt
->am
);
12911 if (wild
->any
== 1) {
12913 xmlAutomataNewTransition2(pctxt
->am
,
12914 start
, NULL
, BAD_CAST
"*", BAD_CAST
"*", wild
);
12915 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, hop
);
12917 xmlAutomataNewTransition2(pctxt
->am
,
12918 start
, NULL
, BAD_CAST
"*", NULL
, wild
);
12919 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, hop
);
12920 } else if (wild
->nsSet
!= NULL
) {
12924 xmlAutomataNewTransition2(pctxt
->am
,
12925 start
, NULL
, BAD_CAST
"*", ns
->value
, wild
);
12926 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, hop
);
12928 } while (ns
!= NULL
);
12930 } else if (wild
->negNsSet
!= NULL
) {
12931 pctxt
->state
= xmlAutomataNewNegTrans(pctxt
->am
,
12932 start
, hop
, BAD_CAST
"*", wild
->negNsSet
->value
,
12935 xmlAutomataNewCountedTrans(pctxt
->am
, hop
, start
, counter
);
12936 xmlAutomataNewCounterTrans(pctxt
->am
, hop
, end
, counter
);
12938 if (particle
->minOccurs
== 0) {
12939 xmlAutomataNewEpsilon(pctxt
->am
, start
, end
);
12942 pctxt
->state
= end
;
12945 case XML_SCHEMA_TYPE_ELEMENT
:
12946 ret
= xmlSchemaBuildContentModelForElement(pctxt
, particle
);
12948 case XML_SCHEMA_TYPE_SEQUENCE
:{
12949 xmlSchemaTreeItemPtr sub
;
12953 * If max and min occurrences are default (1) then
12954 * simply iterate over the particles of the <sequence>.
12956 if ((particle
->minOccurs
== 1) && (particle
->maxOccurs
== 1)) {
12957 sub
= particle
->children
->children
;
12959 while (sub
!= NULL
) {
12960 tmp2
= xmlSchemaBuildAContentModel(pctxt
,
12961 (xmlSchemaParticlePtr
) sub
);
12962 if (tmp2
!= 1) ret
= 0;
12966 xmlAutomataStatePtr oldstate
= pctxt
->state
;
12968 if (particle
->maxOccurs
>= UNBOUNDED
) {
12969 if (particle
->minOccurs
> 1) {
12970 xmlAutomataStatePtr tmp
;
12973 pctxt
->state
= xmlAutomataNewEpsilon(pctxt
->am
,
12975 oldstate
= pctxt
->state
;
12977 counter
= xmlAutomataNewCounter(pctxt
->am
,
12978 particle
->minOccurs
- 1, UNBOUNDED
);
12980 sub
= particle
->children
->children
;
12981 while (sub
!= NULL
) {
12982 tmp2
= xmlSchemaBuildAContentModel(pctxt
,
12983 (xmlSchemaParticlePtr
) sub
);
12984 if (tmp2
!= 1) ret
= 0;
12987 tmp
= pctxt
->state
;
12988 xmlAutomataNewCountedTrans(pctxt
->am
, tmp
,
12989 oldstate
, counter
);
12991 xmlAutomataNewCounterTrans(pctxt
->am
, tmp
,
12994 xmlAutomataNewEpsilon(pctxt
->am
,
12995 oldstate
, pctxt
->state
);
12998 pctxt
->state
= xmlAutomataNewEpsilon(pctxt
->am
,
13000 oldstate
= pctxt
->state
;
13002 sub
= particle
->children
->children
;
13003 while (sub
!= NULL
) {
13004 tmp2
= xmlSchemaBuildAContentModel(pctxt
,
13005 (xmlSchemaParticlePtr
) sub
);
13006 if (tmp2
!= 1) ret
= 0;
13009 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
,
13012 * epsilon needed to block previous trans from
13013 * being allowed to enter back from another
13016 pctxt
->state
= xmlAutomataNewEpsilon(pctxt
->am
,
13017 pctxt
->state
, NULL
);
13018 if (particle
->minOccurs
== 0) {
13019 xmlAutomataNewEpsilon(pctxt
->am
,
13020 oldstate
, pctxt
->state
);
13024 } else if ((particle
->maxOccurs
> 1)
13025 || (particle
->minOccurs
> 1)) {
13026 xmlAutomataStatePtr tmp
;
13029 pctxt
->state
= xmlAutomataNewEpsilon(pctxt
->am
,
13031 oldstate
= pctxt
->state
;
13033 counter
= xmlAutomataNewCounter(pctxt
->am
,
13034 particle
->minOccurs
- 1,
13035 particle
->maxOccurs
- 1);
13037 sub
= particle
->children
->children
;
13038 while (sub
!= NULL
) {
13039 tmp2
= xmlSchemaBuildAContentModel(pctxt
,
13040 (xmlSchemaParticlePtr
) sub
);
13041 if (tmp2
!= 1) ret
= 0;
13044 tmp
= pctxt
->state
;
13045 xmlAutomataNewCountedTrans(pctxt
->am
,
13046 tmp
, oldstate
, counter
);
13048 xmlAutomataNewCounterTrans(pctxt
->am
, tmp
, NULL
,
13050 if ((particle
->minOccurs
== 0) || (ret
== 1)) {
13051 xmlAutomataNewEpsilon(pctxt
->am
,
13052 oldstate
, pctxt
->state
);
13056 sub
= particle
->children
->children
;
13057 while (sub
!= NULL
) {
13058 tmp2
= xmlSchemaBuildAContentModel(pctxt
,
13059 (xmlSchemaParticlePtr
) sub
);
13060 if (tmp2
!= 1) ret
= 0;
13065 * epsilon needed to block previous trans from
13066 * being allowed to enter back from another
13069 pctxt
->state
= xmlAutomataNewEpsilon(pctxt
->am
,
13070 pctxt
->state
, NULL
);
13072 if (particle
->minOccurs
== 0) {
13073 xmlAutomataNewEpsilon(pctxt
->am
, oldstate
,
13081 case XML_SCHEMA_TYPE_CHOICE
:{
13082 xmlSchemaTreeItemPtr sub
;
13083 xmlAutomataStatePtr start
, end
;
13086 start
= pctxt
->state
;
13087 end
= xmlAutomataNewState(pctxt
->am
);
13090 * iterate over the subtypes and remerge the end with an
13091 * epsilon transition
13093 if (particle
->maxOccurs
== 1) {
13094 sub
= particle
->children
->children
;
13095 while (sub
!= NULL
) {
13096 pctxt
->state
= start
;
13097 tmp2
= xmlSchemaBuildAContentModel(pctxt
,
13098 (xmlSchemaParticlePtr
) sub
);
13099 if (tmp2
== 1) ret
= 1;
13100 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, end
);
13105 xmlAutomataStatePtr hop
, base
;
13106 int maxOccurs
= particle
->maxOccurs
== UNBOUNDED
?
13107 UNBOUNDED
: particle
->maxOccurs
- 1;
13109 particle
->minOccurs
< 1 ? 0 : particle
->minOccurs
- 1;
13112 * use a counter to keep track of the number of transitions
13113 * which went through the choice.
13116 xmlAutomataNewCounter(pctxt
->am
, minOccurs
, maxOccurs
);
13117 hop
= xmlAutomataNewState(pctxt
->am
);
13118 base
= xmlAutomataNewState(pctxt
->am
);
13120 sub
= particle
->children
->children
;
13121 while (sub
!= NULL
) {
13122 pctxt
->state
= base
;
13123 tmp2
= xmlSchemaBuildAContentModel(pctxt
,
13124 (xmlSchemaParticlePtr
) sub
);
13125 if (tmp2
== 1) ret
= 1;
13126 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, hop
);
13129 xmlAutomataNewEpsilon(pctxt
->am
, start
, base
);
13130 xmlAutomataNewCountedTrans(pctxt
->am
, hop
, base
, counter
);
13131 xmlAutomataNewCounterTrans(pctxt
->am
, hop
, end
, counter
);
13133 xmlAutomataNewEpsilon(pctxt
->am
, base
, end
);
13135 if (particle
->minOccurs
== 0) {
13136 xmlAutomataNewEpsilon(pctxt
->am
, start
, end
);
13139 pctxt
->state
= end
;
13142 case XML_SCHEMA_TYPE_ALL
:{
13143 xmlAutomataStatePtr start
, tmp
;
13144 xmlSchemaParticlePtr sub
;
13145 xmlSchemaElementPtr elemDecl
;
13149 sub
= (xmlSchemaParticlePtr
) particle
->children
->children
;
13155 start
= pctxt
->state
;
13156 tmp
= xmlAutomataNewState(pctxt
->am
);
13157 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, tmp
);
13158 pctxt
->state
= tmp
;
13159 while (sub
!= NULL
) {
13160 pctxt
->state
= tmp
;
13162 elemDecl
= (xmlSchemaElementPtr
) sub
->children
;
13163 if (elemDecl
== NULL
) {
13164 PERROR_INT("xmlSchemaBuildAContentModel",
13165 "<element> particle has no term");
13169 * NOTE: The {max occurs} of all the particles in the
13170 * {particles} of the group must be 0 or 1; this is
13171 * already ensured during the parse of the content of
13174 if (elemDecl
->flags
& XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD
) {
13178 * This is an abstract group, we need to share
13179 * the same counter for all the element transitions
13180 * derived from the group
13182 counter
= xmlAutomataNewCounter(pctxt
->am
,
13183 sub
->minOccurs
, sub
->maxOccurs
);
13184 xmlSchemaBuildContentModelForSubstGroup(pctxt
,
13185 sub
, counter
, pctxt
->state
);
13187 if ((sub
->minOccurs
== 1) &&
13188 (sub
->maxOccurs
== 1)) {
13189 xmlAutomataNewOnceTrans2(pctxt
->am
, pctxt
->state
,
13192 elemDecl
->targetNamespace
,
13194 } else if ((sub
->minOccurs
== 0) &&
13195 (sub
->maxOccurs
== 1)) {
13197 xmlAutomataNewCountTrans2(pctxt
->am
, pctxt
->state
,
13200 elemDecl
->targetNamespace
,
13206 sub
= (xmlSchemaParticlePtr
) sub
->next
;
13209 xmlAutomataNewAllTrans(pctxt
->am
, pctxt
->state
, NULL
, 0);
13210 if (particle
->minOccurs
== 0) {
13211 xmlAutomataNewEpsilon(pctxt
->am
, start
, pctxt
->state
);
13216 case XML_SCHEMA_TYPE_GROUP
:
13218 * If we hit a model group definition, then this means that
13219 * it was empty, thus was not substituted for the containing
13220 * model group. Just do nothing in this case.
13221 * TODO: But the group should be substituted and not occur at
13222 * all in the content model at this point. Fix this.
13227 xmlSchemaInternalErr2(ACTXT_CAST pctxt
,
13228 "xmlSchemaBuildAContentModel",
13229 "found unexpected term of type '%s' in content model",
13230 WXS_ITEM_TYPE_NAME(particle
->children
), NULL
);
13237 * xmlSchemaBuildContentModel:
13238 * @ctxt: the schema parser context
13239 * @type: the complex type definition
13240 * @name: the element name
13242 * Builds the content model of the complex type.
13245 xmlSchemaBuildContentModel(xmlSchemaTypePtr type
,
13246 xmlSchemaParserCtxtPtr ctxt
)
13248 if ((type
->type
!= XML_SCHEMA_TYPE_COMPLEX
) ||
13249 (type
->contModel
!= NULL
) ||
13250 ((type
->contentType
!= XML_SCHEMA_CONTENT_ELEMENTS
) &&
13251 (type
->contentType
!= XML_SCHEMA_CONTENT_MIXED
)))
13254 #ifdef DEBUG_CONTENT
13255 xmlGenericError(xmlGenericErrorContext
,
13256 "Building content model for %s\n", name
);
13259 ctxt
->am
= xmlNewAutomata();
13260 if (ctxt
->am
== NULL
) {
13261 xmlGenericError(xmlGenericErrorContext
,
13262 "Cannot create automata for complex type %s\n", type
->name
);
13265 ctxt
->state
= xmlAutomataGetInitState(ctxt
->am
);
13267 * Build the automaton.
13269 xmlSchemaBuildAContentModel(ctxt
, WXS_TYPE_PARTICLE(type
));
13270 xmlAutomataSetFinalState(ctxt
->am
, ctxt
->state
);
13271 type
->contModel
= xmlAutomataCompile(ctxt
->am
);
13272 if (type
->contModel
== NULL
) {
13273 xmlSchemaPCustomErr(ctxt
,
13274 XML_SCHEMAP_INTERNAL
,
13275 WXS_BASIC_CAST type
, type
->node
,
13276 "Failed to compile the content model", NULL
);
13277 } else if (xmlRegexpIsDeterminist(type
->contModel
) != 1) {
13278 xmlSchemaPCustomErr(ctxt
,
13279 XML_SCHEMAP_NOT_DETERMINISTIC
,
13280 /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
13281 WXS_BASIC_CAST type
, type
->node
,
13282 "The content model is not determinist", NULL
);
13284 #ifdef DEBUG_CONTENT_REGEXP
13285 xmlGenericError(xmlGenericErrorContext
,
13286 "Content model of %s:\n", type
->name
);
13287 xmlRegexpPrint(stderr
, type
->contModel
);
13290 ctxt
->state
= NULL
;
13291 xmlFreeAutomata(ctxt
->am
);
13296 * xmlSchemaResolveElementReferences:
13297 * @elem: the schema element context
13298 * @ctxt: the schema parser context
13300 * Resolves the references of an element declaration
13301 * or particle, which has an element declaration as it's
13305 xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl
,
13306 xmlSchemaParserCtxtPtr ctxt
)
13308 if ((ctxt
== NULL
) || (elemDecl
== NULL
) ||
13309 ((elemDecl
!= NULL
) &&
13310 (elemDecl
->flags
& XML_SCHEMAS_ELEM_INTERNAL_RESOLVED
)))
13312 elemDecl
->flags
|= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED
;
13314 if ((elemDecl
->subtypes
== NULL
) && (elemDecl
->namedType
!= NULL
)) {
13315 xmlSchemaTypePtr type
;
13317 /* (type definition) ... otherwise the type definition `resolved`
13318 * to by the `actual value` of the type [attribute] ...
13320 type
= xmlSchemaGetType(ctxt
->schema
, elemDecl
->namedType
,
13321 elemDecl
->namedTypeNs
);
13322 if (type
== NULL
) {
13323 xmlSchemaPResCompAttrErr(ctxt
,
13324 XML_SCHEMAP_SRC_RESOLVE
,
13325 WXS_BASIC_CAST elemDecl
, elemDecl
->node
,
13326 "type", elemDecl
->namedType
, elemDecl
->namedTypeNs
,
13327 XML_SCHEMA_TYPE_BASIC
, "type definition");
13329 elemDecl
->subtypes
= type
;
13331 if (elemDecl
->substGroup
!= NULL
) {
13332 xmlSchemaElementPtr substHead
;
13335 * FIXME TODO: Do we need a new field in _xmlSchemaElement for
13336 * substitutionGroup?
13338 substHead
= xmlSchemaGetElem(ctxt
->schema
, elemDecl
->substGroup
,
13339 elemDecl
->substGroupNs
);
13340 if (substHead
== NULL
) {
13341 xmlSchemaPResCompAttrErr(ctxt
,
13342 XML_SCHEMAP_SRC_RESOLVE
,
13343 WXS_BASIC_CAST elemDecl
, NULL
,
13344 "substitutionGroup", elemDecl
->substGroup
,
13345 elemDecl
->substGroupNs
, XML_SCHEMA_TYPE_ELEMENT
, NULL
);
13347 xmlSchemaResolveElementReferences(substHead
, ctxt
);
13349 * Set the "substitution group affiliation".
13350 * NOTE that now we use the "refDecl" field for this.
13352 WXS_SUBST_HEAD(elemDecl
) = substHead
;
13354 * The type definitions is set to:
13355 * SPEC "...the {type definition} of the element
13356 * declaration `resolved` to by the `actual value`
13357 * of the substitutionGroup [attribute], if present"
13359 if (elemDecl
->subtypes
== NULL
) {
13360 if (substHead
->subtypes
== NULL
) {
13362 * This can happen with self-referencing substitution
13363 * groups. The cycle will be detected later, but we have
13364 * to set subtypes to avoid null-pointer dereferences.
13366 elemDecl
->subtypes
= xmlSchemaGetBuiltInType(
13367 XML_SCHEMAS_ANYTYPE
);
13369 elemDecl
->subtypes
= substHead
->subtypes
;
13375 * SPEC "The definition of anyType serves as the default type definition
13376 * for element declarations whose XML representation does not specify one."
13378 if ((elemDecl
->subtypes
== NULL
) &&
13379 (elemDecl
->namedType
== NULL
) &&
13380 (elemDecl
->substGroup
== NULL
))
13381 elemDecl
->subtypes
= xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE
);
13385 * xmlSchemaResolveUnionMemberTypes:
13386 * @ctxt: the schema parser context
13387 * @type: the schema simple type definition
13389 * Checks and builds the "member type definitions" property of the union
13390 * simple type. This handles part (1), part (2) is done in
13391 * xmlSchemaFinishMemberTypeDefinitionsProperty()
13393 * Returns -1 in case of an internal error, 0 otherwise.
13396 xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt
,
13397 xmlSchemaTypePtr type
)
13400 xmlSchemaTypeLinkPtr link
, lastLink
, newLink
;
13401 xmlSchemaTypePtr memberType
;
13404 * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
13405 * define the explicit members as the type definitions `resolved`
13406 * to by the items in the `actual value` of the memberTypes [attribute],
13407 * if any, followed by the type definitions corresponding to the
13408 * <simpleType>s among the [children] of <union>, if any."
13411 * Resolve references.
13413 link
= type
->memberTypes
;
13415 while (link
!= NULL
) {
13416 const xmlChar
*name
, *nsName
;
13418 name
= ((xmlSchemaQNameRefPtr
) link
->type
)->name
;
13419 nsName
= ((xmlSchemaQNameRefPtr
) link
->type
)->targetNamespace
;
13421 memberType
= xmlSchemaGetType(ctxt
->schema
, name
, nsName
);
13422 if ((memberType
== NULL
) || (! WXS_IS_SIMPLE(memberType
))) {
13423 xmlSchemaPResCompAttrErr(ctxt
, XML_SCHEMAP_SRC_RESOLVE
,
13424 WXS_BASIC_CAST type
, type
->node
, "memberTypes",
13425 name
, nsName
, XML_SCHEMA_TYPE_SIMPLE
, NULL
);
13427 * Remove the member type link.
13429 if (lastLink
== NULL
)
13430 type
->memberTypes
= link
->next
;
13432 lastLink
->next
= link
->next
;
13437 link
->type
= memberType
;
13443 * Add local simple types,
13445 memberType
= type
->subtypes
;
13446 while (memberType
!= NULL
) {
13447 link
= (xmlSchemaTypeLinkPtr
) xmlMalloc(sizeof(xmlSchemaTypeLink
));
13448 if (link
== NULL
) {
13449 xmlSchemaPErrMemory(ctxt
, "allocating a type link", NULL
);
13452 link
->type
= memberType
;
13454 if (lastLink
== NULL
)
13455 type
->memberTypes
= link
;
13457 lastLink
->next
= link
;
13459 memberType
= memberType
->next
;
13465 * xmlSchemaIsDerivedFromBuiltInType:
13466 * @ctxt: the schema parser context
13467 * @type: the type definition
13468 * @valType: the value type
13471 * Returns 1 if the type has the given value type, or
13472 * is derived from such a type.
13475 xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type
, int valType
)
13479 if (WXS_IS_COMPLEX(type
))
13481 if (type
->type
== XML_SCHEMA_TYPE_BASIC
) {
13482 if (type
->builtInType
== valType
)
13484 if ((type
->builtInType
== XML_SCHEMAS_ANYSIMPLETYPE
) ||
13485 (type
->builtInType
== XML_SCHEMAS_ANYTYPE
))
13487 return(xmlSchemaIsDerivedFromBuiltInType(type
->subtypes
, valType
));
13489 return(xmlSchemaIsDerivedFromBuiltInType(type
->subtypes
, valType
));
13494 * xmlSchemaIsDerivedFromBuiltInType:
13495 * @ctxt: the schema parser context
13496 * @type: the type definition
13497 * @valType: the value type
13500 * Returns 1 if the type has the given value type, or
13501 * is derived from such a type.
13504 xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type
, int valType
)
13508 if (WXS_IS_COMPLEX(type
))
13510 if (type
->type
== XML_SCHEMA_TYPE_BASIC
) {
13511 if (type
->builtInType
== valType
)
13515 return(xmlSchemaIsDerivedFromBuiltInType(type
->subtypes
, valType
));
13520 static xmlSchemaTypePtr
13521 xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type
)
13525 if (WXS_IS_COMPLEX(type
))
13527 if (type
->type
== XML_SCHEMA_TYPE_BASIC
)
13529 return(xmlSchemaQueryBuiltInType(type
->subtypes
));
13534 * xmlSchemaGetPrimitiveType:
13535 * @type: the simpleType definition
13537 * Returns the primitive type of the given type or
13538 * NULL in case of error.
13540 static xmlSchemaTypePtr
13541 xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type
)
13544 while (type
!= NULL
) {
13546 * Note that anySimpleType is actually not a primitive type
13547 * but we need that here.
13549 if ((type
->builtInType
== XML_SCHEMAS_ANYSIMPLETYPE
) ||
13550 (type
->flags
& XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE
))
13552 type
= type
->baseType
;
13560 * xmlSchemaGetBuiltInTypeAncestor:
13561 * @type: the simpleType definition
13563 * Returns the primitive type of the given type or
13564 * NULL in case of error.
13566 static xmlSchemaTypePtr
13567 xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type
)
13569 if (WXS_IS_LIST(type
) || WXS_IS_UNION(type
))
13571 while (type
!= NULL
) {
13572 if (type
->type
== XML_SCHEMA_TYPE_BASIC
)
13574 type
= type
->baseType
;
13582 * xmlSchemaCloneWildcardNsConstraints:
13583 * @ctxt: the schema parser context
13584 * @dest: the destination wildcard
13585 * @source: the source wildcard
13587 * Clones the namespace constraints of source
13588 * and assigns them to dest.
13589 * Returns -1 on internal error, 0 otherwise.
13592 xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt
,
13593 xmlSchemaWildcardPtr dest
,
13594 xmlSchemaWildcardPtr source
)
13596 xmlSchemaWildcardNsPtr cur
, tmp
, last
;
13598 if ((source
== NULL
) || (dest
== NULL
))
13600 dest
->any
= source
->any
;
13601 cur
= source
->nsSet
;
13603 while (cur
!= NULL
) {
13604 tmp
= xmlSchemaNewWildcardNsConstraint(ctxt
);
13607 tmp
->value
= cur
->value
;
13615 if (dest
->negNsSet
!= NULL
)
13616 xmlSchemaFreeWildcardNsSet(dest
->negNsSet
);
13617 if (source
->negNsSet
!= NULL
) {
13618 dest
->negNsSet
= xmlSchemaNewWildcardNsConstraint(ctxt
);
13619 if (dest
->negNsSet
== NULL
)
13621 dest
->negNsSet
->value
= source
->negNsSet
->value
;
13623 dest
->negNsSet
= NULL
;
13628 * xmlSchemaUnionWildcards:
13629 * @ctxt: the schema parser context
13630 * @completeWild: the first wildcard
13631 * @curWild: the second wildcard
13633 * Unions the namespace constraints of the given wildcards.
13634 * @completeWild will hold the resulting union.
13635 * Returns a positive error code on failure, -1 in case of an
13636 * internal error, 0 otherwise.
13639 xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt
,
13640 xmlSchemaWildcardPtr completeWild
,
13641 xmlSchemaWildcardPtr curWild
)
13643 xmlSchemaWildcardNsPtr cur
, curB
, tmp
;
13646 * 1 If O1 and O2 are the same value, then that value must be the
13649 if ((completeWild
->any
== curWild
->any
) &&
13650 ((completeWild
->nsSet
== NULL
) == (curWild
->nsSet
== NULL
)) &&
13651 ((completeWild
->negNsSet
== NULL
) == (curWild
->negNsSet
== NULL
))) {
13653 if ((completeWild
->negNsSet
== NULL
) ||
13654 (completeWild
->negNsSet
->value
== curWild
->negNsSet
->value
)) {
13656 if (completeWild
->nsSet
!= NULL
) {
13660 * Check equality of sets.
13662 cur
= completeWild
->nsSet
;
13663 while (cur
!= NULL
) {
13665 curB
= curWild
->nsSet
;
13666 while (curB
!= NULL
) {
13667 if (cur
->value
== curB
->value
) {
13684 * 2 If either O1 or O2 is any, then any must be the value
13686 if (completeWild
->any
!= curWild
->any
) {
13687 if (completeWild
->any
== 0) {
13688 completeWild
->any
= 1;
13689 if (completeWild
->nsSet
!= NULL
) {
13690 xmlSchemaFreeWildcardNsSet(completeWild
->nsSet
);
13691 completeWild
->nsSet
= NULL
;
13693 if (completeWild
->negNsSet
!= NULL
) {
13694 xmlFree(completeWild
->negNsSet
);
13695 completeWild
->negNsSet
= NULL
;
13701 * 3 If both O1 and O2 are sets of (namespace names or `absent`),
13702 * then the union of those sets must be the value.
13704 if ((completeWild
->nsSet
!= NULL
) && (curWild
->nsSet
!= NULL
)) {
13706 xmlSchemaWildcardNsPtr start
;
13708 cur
= curWild
->nsSet
;
13709 start
= completeWild
->nsSet
;
13710 while (cur
!= NULL
) {
13713 while (curB
!= NULL
) {
13714 if (cur
->value
== curB
->value
) {
13721 tmp
= xmlSchemaNewWildcardNsConstraint(ctxt
);
13724 tmp
->value
= cur
->value
;
13725 tmp
->next
= completeWild
->nsSet
;
13726 completeWild
->nsSet
= tmp
;
13734 * 4 If the two are negations of different values (namespace names
13735 * or `absent`), then a pair of not and `absent` must be the value.
13737 if ((completeWild
->negNsSet
!= NULL
) &&
13738 (curWild
->negNsSet
!= NULL
) &&
13739 (completeWild
->negNsSet
->value
!= curWild
->negNsSet
->value
)) {
13740 completeWild
->negNsSet
->value
= NULL
;
13747 if (((completeWild
->negNsSet
!= NULL
) &&
13748 (completeWild
->negNsSet
->value
!= NULL
) &&
13749 (curWild
->nsSet
!= NULL
)) ||
13750 ((curWild
->negNsSet
!= NULL
) &&
13751 (curWild
->negNsSet
->value
!= NULL
) &&
13752 (completeWild
->nsSet
!= NULL
))) {
13754 int nsFound
, absentFound
= 0;
13756 if (completeWild
->nsSet
!= NULL
) {
13757 cur
= completeWild
->nsSet
;
13758 curB
= curWild
->negNsSet
;
13760 cur
= curWild
->nsSet
;
13761 curB
= completeWild
->negNsSet
;
13764 while (cur
!= NULL
) {
13765 if (cur
->value
== NULL
)
13767 else if (cur
->value
== curB
->value
)
13769 if (nsFound
&& absentFound
)
13774 if (nsFound
&& absentFound
) {
13776 * 5.1 If the set S includes both the negated namespace
13777 * name and `absent`, then any must be the value.
13779 completeWild
->any
= 1;
13780 if (completeWild
->nsSet
!= NULL
) {
13781 xmlSchemaFreeWildcardNsSet(completeWild
->nsSet
);
13782 completeWild
->nsSet
= NULL
;
13784 if (completeWild
->negNsSet
!= NULL
) {
13785 xmlFree(completeWild
->negNsSet
);
13786 completeWild
->negNsSet
= NULL
;
13788 } else if (nsFound
&& (!absentFound
)) {
13790 * 5.2 If the set S includes the negated namespace name
13791 * but not `absent`, then a pair of not and `absent` must
13794 if (completeWild
->nsSet
!= NULL
) {
13795 xmlSchemaFreeWildcardNsSet(completeWild
->nsSet
);
13796 completeWild
->nsSet
= NULL
;
13798 if (completeWild
->negNsSet
== NULL
) {
13799 completeWild
->negNsSet
= xmlSchemaNewWildcardNsConstraint(ctxt
);
13800 if (completeWild
->negNsSet
== NULL
)
13803 completeWild
->negNsSet
->value
= NULL
;
13804 } else if ((!nsFound
) && absentFound
) {
13806 * 5.3 If the set S includes `absent` but not the negated
13807 * namespace name, then the union is not expressible.
13809 xmlSchemaPErr(ctxt
, completeWild
->node
,
13810 XML_SCHEMAP_UNION_NOT_EXPRESSIBLE
,
13811 "The union of the wildcard is not expressible.\n",
13813 return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE
);
13814 } else if ((!nsFound
) && (!absentFound
)) {
13816 * 5.4 If the set S does not include either the negated namespace
13817 * name or `absent`, then whichever of O1 or O2 is a pair of not
13818 * and a namespace name must be the value.
13820 if (completeWild
->negNsSet
== NULL
) {
13821 if (completeWild
->nsSet
!= NULL
) {
13822 xmlSchemaFreeWildcardNsSet(completeWild
->nsSet
);
13823 completeWild
->nsSet
= NULL
;
13825 completeWild
->negNsSet
= xmlSchemaNewWildcardNsConstraint(ctxt
);
13826 if (completeWild
->negNsSet
== NULL
)
13828 completeWild
->negNsSet
->value
= curWild
->negNsSet
->value
;
13836 if (((completeWild
->negNsSet
!= NULL
) &&
13837 (completeWild
->negNsSet
->value
== NULL
) &&
13838 (curWild
->nsSet
!= NULL
)) ||
13839 ((curWild
->negNsSet
!= NULL
) &&
13840 (curWild
->negNsSet
->value
== NULL
) &&
13841 (completeWild
->nsSet
!= NULL
))) {
13843 if (completeWild
->nsSet
!= NULL
) {
13844 cur
= completeWild
->nsSet
;
13846 cur
= curWild
->nsSet
;
13848 while (cur
!= NULL
) {
13849 if (cur
->value
== NULL
) {
13851 * 6.1 If the set S includes `absent`, then any must be the
13854 completeWild
->any
= 1;
13855 if (completeWild
->nsSet
!= NULL
) {
13856 xmlSchemaFreeWildcardNsSet(completeWild
->nsSet
);
13857 completeWild
->nsSet
= NULL
;
13859 if (completeWild
->negNsSet
!= NULL
) {
13860 xmlFree(completeWild
->negNsSet
);
13861 completeWild
->negNsSet
= NULL
;
13867 if (completeWild
->negNsSet
== NULL
) {
13869 * 6.2 If the set S does not include `absent`, then a pair of not
13870 * and `absent` must be the value.
13872 if (completeWild
->nsSet
!= NULL
) {
13873 xmlSchemaFreeWildcardNsSet(completeWild
->nsSet
);
13874 completeWild
->nsSet
= NULL
;
13876 completeWild
->negNsSet
= xmlSchemaNewWildcardNsConstraint(ctxt
);
13877 if (completeWild
->negNsSet
== NULL
)
13879 completeWild
->negNsSet
->value
= NULL
;
13888 * xmlSchemaIntersectWildcards:
13889 * @ctxt: the schema parser context
13890 * @completeWild: the first wildcard
13891 * @curWild: the second wildcard
13893 * Intersects the namespace constraints of the given wildcards.
13894 * @completeWild will hold the resulting intersection.
13895 * Returns a positive error code on failure, -1 in case of an
13896 * internal error, 0 otherwise.
13899 xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt
,
13900 xmlSchemaWildcardPtr completeWild
,
13901 xmlSchemaWildcardPtr curWild
)
13903 xmlSchemaWildcardNsPtr cur
, curB
, prev
, tmp
;
13906 * 1 If O1 and O2 are the same value, then that value must be the
13909 if ((completeWild
->any
== curWild
->any
) &&
13910 ((completeWild
->nsSet
== NULL
) == (curWild
->nsSet
== NULL
)) &&
13911 ((completeWild
->negNsSet
== NULL
) == (curWild
->negNsSet
== NULL
))) {
13913 if ((completeWild
->negNsSet
== NULL
) ||
13914 (completeWild
->negNsSet
->value
== curWild
->negNsSet
->value
)) {
13916 if (completeWild
->nsSet
!= NULL
) {
13920 * Check equality of sets.
13922 cur
= completeWild
->nsSet
;
13923 while (cur
!= NULL
) {
13925 curB
= curWild
->nsSet
;
13926 while (curB
!= NULL
) {
13927 if (cur
->value
== curB
->value
) {
13944 * 2 If either O1 or O2 is any, then the other must be the value.
13946 if ((completeWild
->any
!= curWild
->any
) && (completeWild
->any
)) {
13947 if (xmlSchemaCloneWildcardNsConstraints(ctxt
, completeWild
, curWild
) == -1)
13952 * 3 If either O1 or O2 is a pair of not and a value (a namespace
13953 * name or `absent`) and the other is a set of (namespace names or
13954 * `absent`), then that set, minus the negated value if it was in
13955 * the set, minus `absent` if it was in the set, must be the value.
13957 if (((completeWild
->negNsSet
!= NULL
) && (curWild
->nsSet
!= NULL
)) ||
13958 ((curWild
->negNsSet
!= NULL
) && (completeWild
->nsSet
!= NULL
))) {
13959 const xmlChar
*neg
;
13961 if (completeWild
->nsSet
== NULL
) {
13962 neg
= completeWild
->negNsSet
->value
;
13963 if (xmlSchemaCloneWildcardNsConstraints(ctxt
, completeWild
, curWild
) == -1)
13966 neg
= curWild
->negNsSet
->value
;
13968 * Remove absent and negated.
13971 cur
= completeWild
->nsSet
;
13972 while (cur
!= NULL
) {
13973 if (cur
->value
== NULL
) {
13975 completeWild
->nsSet
= cur
->next
;
13977 prev
->next
= cur
->next
;
13986 cur
= completeWild
->nsSet
;
13987 while (cur
!= NULL
) {
13988 if (cur
->value
== neg
) {
13990 completeWild
->nsSet
= cur
->next
;
13992 prev
->next
= cur
->next
;
14004 * 4 If both O1 and O2 are sets of (namespace names or `absent`),
14005 * then the intersection of those sets must be the value.
14007 if ((completeWild
->nsSet
!= NULL
) && (curWild
->nsSet
!= NULL
)) {
14010 cur
= completeWild
->nsSet
;
14012 while (cur
!= NULL
) {
14014 curB
= curWild
->nsSet
;
14015 while (curB
!= NULL
) {
14016 if (cur
->value
== curB
->value
) {
14024 completeWild
->nsSet
= cur
->next
;
14026 prev
->next
= cur
->next
;
14038 /* 5 If the two are negations of different namespace names,
14039 * then the intersection is not expressible
14041 if ((completeWild
->negNsSet
!= NULL
) &&
14042 (curWild
->negNsSet
!= NULL
) &&
14043 (completeWild
->negNsSet
->value
!= curWild
->negNsSet
->value
) &&
14044 (completeWild
->negNsSet
->value
!= NULL
) &&
14045 (curWild
->negNsSet
->value
!= NULL
)) {
14047 xmlSchemaPErr(ctxt
, completeWild
->node
, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE
,
14048 "The intersection of the wildcard is not expressible.\n",
14050 return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE
);
14053 * 6 If the one is a negation of a namespace name and the other
14054 * is a negation of `absent`, then the one which is the negation
14055 * of a namespace name must be the value.
14057 if ((completeWild
->negNsSet
!= NULL
) && (curWild
->negNsSet
!= NULL
) &&
14058 (completeWild
->negNsSet
->value
!= curWild
->negNsSet
->value
) &&
14059 (completeWild
->negNsSet
->value
== NULL
)) {
14060 completeWild
->negNsSet
->value
= curWild
->negNsSet
->value
;
14066 * xmlSchemaIsWildcardNsConstraintSubset:
14067 * @ctxt: the schema parser context
14068 * @sub: the first wildcard
14069 * @super: the second wildcard
14071 * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
14073 * Returns 0 if the namespace constraint of @sub is an intensional
14074 * subset of @super, 1 otherwise.
14077 xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub
,
14078 xmlSchemaWildcardPtr super
)
14081 * 1 super must be any.
14086 * 2.1 sub must be a pair of not and a namespace name or `absent`.
14087 * 2.2 super must be a pair of not and the same value.
14089 if ((sub
->negNsSet
!= NULL
) &&
14090 (super
->negNsSet
!= NULL
) &&
14091 (sub
->negNsSet
->value
== super
->negNsSet
->value
))
14094 * 3.1 sub must be a set whose members are either namespace names or `absent`.
14096 if (sub
->nsSet
!= NULL
) {
14098 * 3.2.1 super must be the same set or a superset thereof.
14100 if (super
->nsSet
!= NULL
) {
14101 xmlSchemaWildcardNsPtr cur
, curB
;
14105 while (cur
!= NULL
) {
14107 curB
= super
->nsSet
;
14108 while (curB
!= NULL
) {
14109 if (cur
->value
== curB
->value
) {
14121 } else if (super
->negNsSet
!= NULL
) {
14122 xmlSchemaWildcardNsPtr cur
;
14124 * 3.2.2 super must be a pair of not and a namespace name or
14125 * `absent` and that value must not be in sub's set.
14128 while (cur
!= NULL
) {
14129 if (cur
->value
== super
->negNsSet
->value
)
14140 xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse
,
14142 const xmlChar
**value
,
14143 xmlSchemaValPtr
*val
)
14150 if (attruse
->defValue
!= NULL
) {
14151 *value
= attruse
->defValue
;
14153 *val
= attruse
->defVal
;
14154 if (attruse
->flags
& XML_SCHEMA_ATTR_USE_FIXED
)
14157 } else if ((attruse
->attrDecl
!= NULL
) &&
14158 (attruse
->attrDecl
->defValue
!= NULL
)) {
14159 *value
= attruse
->attrDecl
->defValue
;
14161 *val
= attruse
->attrDecl
->defVal
;
14162 if (attruse
->attrDecl
->flags
& XML_SCHEMAS_ATTR_FIXED
)
14169 * xmlSchemaCheckCVCWildcardNamespace:
14170 * @wild: the wildcard
14171 * @ns: the namespace
14173 * Validation Rule: Wildcard allows Namespace Name
14174 * (cvc-wildcard-namespace)
14176 * Returns 0 if the given namespace matches the wildcard,
14177 * 1 otherwise and -1 on API errors.
14180 xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild
,
14188 else if (wild
->nsSet
!= NULL
) {
14189 xmlSchemaWildcardNsPtr cur
;
14192 while (cur
!= NULL
) {
14193 if (xmlStrEqual(cur
->value
, ns
))
14197 } else if ((wild
->negNsSet
!= NULL
) && (ns
!= NULL
) &&
14198 (!xmlStrEqual(wild
->negNsSet
->value
, ns
)))
14204 #define XML_SCHEMA_ACTION_DERIVE 0
14205 #define XML_SCHEMA_ACTION_REDEFINE 1
14207 #define WXS_ACTION_STR(a) \
14208 ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
14211 * Schema Component Constraint:
14212 * Derivation Valid (Restriction, Complex)
14213 * derivation-ok-restriction (2) - (4)
14216 * In XML Schema 1.1 this will be:
14218 * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
14222 xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt
,
14224 xmlSchemaBasicItemPtr item
,
14225 xmlSchemaBasicItemPtr baseItem
,
14226 xmlSchemaItemListPtr uses
,
14227 xmlSchemaItemListPtr baseUses
,
14228 xmlSchemaWildcardPtr wild
,
14229 xmlSchemaWildcardPtr baseWild
)
14231 xmlSchemaAttributeUsePtr cur
= NULL
, bcur
;
14232 int i
, j
, found
; /* err = 0; */
14233 const xmlChar
*bEffValue
;
14236 if (uses
!= NULL
) {
14237 for (i
= 0; i
< uses
->nbItems
; i
++) {
14238 cur
= uses
->items
[i
];
14240 if (baseUses
== NULL
)
14242 for (j
= 0; j
< baseUses
->nbItems
; j
++) {
14243 bcur
= baseUses
->items
[j
];
14244 if ((WXS_ATTRUSE_DECL_NAME(cur
) ==
14245 WXS_ATTRUSE_DECL_NAME(bcur
)) &&
14246 (WXS_ATTRUSE_DECL_TNS(cur
) ==
14247 WXS_ATTRUSE_DECL_TNS(bcur
)))
14250 * (2.1) "If there is an attribute use in the {attribute
14251 * uses} of the {base type definition} (call this B) whose
14252 * {attribute declaration} has the same {name} and {target
14253 * namespace}, then all of the following must be true:"
14257 if ((cur
->occurs
== XML_SCHEMAS_ATTR_USE_OPTIONAL
) &&
14258 (bcur
->occurs
== XML_SCHEMAS_ATTR_USE_REQUIRED
))
14260 xmlChar
*str
= NULL
;
14262 * (2.1.1) "one of the following must be true:"
14263 * (2.1.1.1) "B's {required} is false."
14264 * (2.1.1.2) "R's {required} is true."
14266 xmlSchemaPAttrUseErr4(pctxt
,
14267 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1
,
14268 WXS_ITEM_NODE(item
), item
, cur
,
14269 "The 'optional' attribute use is inconsistent "
14270 "with the corresponding 'required' attribute use of "
14272 WXS_ACTION_STR(action
),
14273 xmlSchemaGetComponentDesignation(&str
, baseItem
),
14275 FREE_AND_NULL(str
);
14276 /* err = pctxt->err; */
14277 } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt
,
14278 WXS_ATTRUSE_TYPEDEF(cur
),
14279 WXS_ATTRUSE_TYPEDEF(bcur
), 0) != 0)
14281 xmlChar
*strA
= NULL
, *strB
= NULL
, *strC
= NULL
;
14284 * SPEC (2.1.2) "R's {attribute declaration}'s
14285 * {type definition} must be validly derived from
14286 * B's {type definition} given the empty set as
14287 * defined in Type Derivation OK (Simple) ($3.14.6)."
14289 xmlSchemaPAttrUseErr4(pctxt
,
14290 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2
,
14291 WXS_ITEM_NODE(item
), item
, cur
,
14292 "The attribute declaration's %s "
14293 "is not validly derived from "
14294 "the corresponding %s of the "
14295 "attribute declaration in the %s %s",
14296 xmlSchemaGetComponentDesignation(&strA
,
14297 WXS_ATTRUSE_TYPEDEF(cur
)),
14298 xmlSchemaGetComponentDesignation(&strB
,
14299 WXS_ATTRUSE_TYPEDEF(bcur
)),
14300 WXS_ACTION_STR(action
),
14301 xmlSchemaGetComponentDesignation(&strC
, baseItem
));
14302 /* xmlSchemaGetComponentDesignation(&str, baseItem), */
14303 FREE_AND_NULL(strA
);
14304 FREE_AND_NULL(strB
);
14305 FREE_AND_NULL(strC
);
14306 /* err = pctxt->err; */
14309 * 2.1.3 [Definition:] Let the effective value
14310 * constraint of an attribute use be its {value
14311 * constraint}, if present, otherwise its {attribute
14312 * declaration}'s {value constraint} .
14314 xmlSchemaGetEffectiveValueConstraint(bcur
,
14315 &effFixed
, &bEffValue
, NULL
);
14317 * 2.1.3 ... one of the following must be true
14319 * 2.1.3.1 B's `effective value constraint` is
14320 * `absent` or default.
14322 if ((bEffValue
!= NULL
) &&
14324 const xmlChar
*rEffValue
= NULL
;
14326 xmlSchemaGetEffectiveValueConstraint(bcur
,
14327 &effFixed
, &rEffValue
, NULL
);
14329 * 2.1.3.2 R's `effective value constraint` is
14330 * fixed with the same string as B's.
14331 * MAYBE TODO: Compare the computed values.
14332 * Hmm, it says "same string" so
14333 * string-equality might really be sufficient.
14335 if ((effFixed
== 0) ||
14336 (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue
, bEffValue
)))
14338 xmlChar
*str
= NULL
;
14340 xmlSchemaPAttrUseErr4(pctxt
,
14341 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3
,
14342 WXS_ITEM_NODE(item
), item
, cur
,
14343 "The effective value constraint of the "
14344 "attribute use is inconsistent with "
14345 "its correspondent in the %s %s",
14346 WXS_ACTION_STR(action
),
14347 xmlSchemaGetComponentDesignation(&str
,
14350 FREE_AND_NULL(str
);
14351 /* err = pctxt->err; */
14361 * (2.2) "otherwise the {base type definition} must have an
14362 * {attribute wildcard} and the {target namespace} of the
14363 * R's {attribute declaration} must be `valid` with respect
14364 * to that wildcard, as defined in Wildcard allows Namespace
14367 if ((baseWild
== NULL
) ||
14368 (xmlSchemaCheckCVCWildcardNamespace(baseWild
,
14369 (WXS_ATTRUSE_DECL(cur
))->targetNamespace
) != 0))
14371 xmlChar
*str
= NULL
;
14373 xmlSchemaPAttrUseErr4(pctxt
,
14374 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2
,
14375 WXS_ITEM_NODE(item
), item
, cur
,
14376 "Neither a matching attribute use, "
14377 "nor a matching wildcard exists in the %s %s",
14378 WXS_ACTION_STR(action
),
14379 xmlSchemaGetComponentDesignation(&str
, baseItem
),
14381 FREE_AND_NULL(str
);
14382 /* err = pctxt->err; */
14388 * SPEC derivation-ok-restriction (3):
14389 * (3) "For each attribute use in the {attribute uses} of the {base type
14390 * definition} whose {required} is true, there must be an attribute
14391 * use with an {attribute declaration} with the same {name} and
14392 * {target namespace} as its {attribute declaration} in the {attribute
14393 * uses} of the complex type definition itself whose {required} is true.
14395 if (baseUses
!= NULL
) {
14396 for (j
= 0; j
< baseUses
->nbItems
; j
++) {
14397 bcur
= baseUses
->items
[j
];
14398 if (bcur
->occurs
!= XML_SCHEMAS_ATTR_USE_REQUIRED
)
14401 if (uses
!= NULL
) {
14402 for (i
= 0; i
< uses
->nbItems
; i
++) {
14403 cur
= uses
->items
[i
];
14404 if ((WXS_ATTRUSE_DECL_NAME(cur
) ==
14405 WXS_ATTRUSE_DECL_NAME(bcur
)) &&
14406 (WXS_ATTRUSE_DECL_TNS(cur
) ==
14407 WXS_ATTRUSE_DECL_TNS(bcur
))) {
14414 xmlChar
*strA
= NULL
, *strB
= NULL
;
14416 xmlSchemaCustomErr4(ACTXT_CAST pctxt
,
14417 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3
,
14419 "A matching attribute use for the "
14420 "'required' %s of the %s %s is missing",
14421 xmlSchemaGetComponentDesignation(&strA
, bcur
),
14422 WXS_ACTION_STR(action
),
14423 xmlSchemaGetComponentDesignation(&strB
, baseItem
),
14425 FREE_AND_NULL(strA
);
14426 FREE_AND_NULL(strB
);
14431 * derivation-ok-restriction (4)
14433 if (wild
!= NULL
) {
14435 * (4) "If there is an {attribute wildcard}, all of the
14436 * following must be true:"
14438 if (baseWild
== NULL
) {
14439 xmlChar
*str
= NULL
;
14442 * (4.1) "The {base type definition} must also have one."
14444 xmlSchemaCustomErr4(ACTXT_CAST pctxt
,
14445 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1
,
14447 "The %s has an attribute wildcard, "
14448 "but the %s %s '%s' does not have one",
14449 WXS_ITEM_TYPE_NAME(item
),
14450 WXS_ACTION_STR(action
),
14451 WXS_ITEM_TYPE_NAME(baseItem
),
14452 xmlSchemaGetComponentQName(&str
, baseItem
));
14453 FREE_AND_NULL(str
);
14454 return(pctxt
->err
);
14455 } else if ((baseWild
->any
== 0) &&
14456 xmlSchemaCheckCOSNSSubset(wild
, baseWild
))
14458 xmlChar
*str
= NULL
;
14460 * (4.2) "The complex type definition's {attribute wildcard}'s
14461 * {namespace constraint} must be a subset of the {base type
14462 * definition}'s {attribute wildcard}'s {namespace constraint},
14463 * as defined by Wildcard Subset ($3.10.6)."
14465 xmlSchemaCustomErr4(ACTXT_CAST pctxt
,
14466 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2
,
14468 "The attribute wildcard is not a valid "
14469 "subset of the wildcard in the %s %s '%s'",
14470 WXS_ACTION_STR(action
),
14471 WXS_ITEM_TYPE_NAME(baseItem
),
14472 xmlSchemaGetComponentQName(&str
, baseItem
),
14474 FREE_AND_NULL(str
);
14475 return(pctxt
->err
);
14477 /* 4.3 Unless the {base type definition} is the `ur-type
14478 * definition`, the complex type definition's {attribute
14479 * wildcard}'s {process contents} must be identical to or
14480 * stronger than the {base type definition}'s {attribute
14481 * wildcard}'s {process contents}, where strict is stronger
14482 * than lax is stronger than skip.
14484 if ((! WXS_IS_ANYTYPE(baseItem
)) &&
14485 (wild
->processContents
< baseWild
->processContents
)) {
14486 xmlChar
*str
= NULL
;
14487 xmlSchemaCustomErr4(ACTXT_CAST pctxt
,
14488 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3
,
14490 "The {process contents} of the attribute wildcard is "
14491 "weaker than the one in the %s %s '%s'",
14492 WXS_ACTION_STR(action
),
14493 WXS_ITEM_TYPE_NAME(baseItem
),
14494 xmlSchemaGetComponentQName(&str
, baseItem
),
14497 return(pctxt
->err
);
14505 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt
,
14506 xmlSchemaBasicItemPtr item
,
14507 xmlSchemaWildcardPtr
*completeWild
,
14508 xmlSchemaItemListPtr list
,
14509 xmlSchemaItemListPtr prohibs
);
14511 * xmlSchemaFixupTypeAttributeUses:
14512 * @ctxt: the schema parser context
14513 * @type: the complex type definition
14516 * Builds the wildcard and the attribute uses on the given complex type.
14517 * Returns -1 if an internal error occurs, 0 otherwise.
14519 * ATTENTION TODO: Experimentally this uses pointer comparisons for
14520 * strings, so recheck this if we start to hardcode some schemata, since
14521 * they might not be in the same dict.
14522 * NOTE: It is allowed to "extend" the xs:anyType type.
14525 xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt
,
14526 xmlSchemaTypePtr type
)
14528 xmlSchemaTypePtr baseType
= NULL
;
14529 xmlSchemaAttributeUsePtr use
;
14530 xmlSchemaItemListPtr uses
, baseUses
, prohibs
= NULL
;
14532 if (type
->baseType
== NULL
) {
14533 PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14537 baseType
= type
->baseType
;
14538 if (WXS_IS_TYPE_NOT_FIXED(baseType
))
14539 if (xmlSchemaTypeFixup(baseType
, ACTXT_CAST pctxt
) == -1)
14542 uses
= type
->attrUses
;
14543 baseUses
= baseType
->attrUses
;
14545 * Expand attribute group references. And build the 'complete'
14546 * wildcard, i.e. intersect multiple wildcards.
14547 * Move attribute prohibitions into a separate list.
14549 if (uses
!= NULL
) {
14550 if (WXS_IS_RESTRICTION(type
)) {
14552 * This one will transfer all attr. prohibitions
14553 * into pctxt->attrProhibs.
14555 if (xmlSchemaExpandAttributeGroupRefs(pctxt
,
14556 WXS_BASIC_CAST type
, &(type
->attributeWildcard
), uses
,
14557 pctxt
->attrProhibs
) == -1)
14559 PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14560 "failed to expand attributes");
14563 if (pctxt
->attrProhibs
->nbItems
!= 0)
14564 prohibs
= pctxt
->attrProhibs
;
14566 if (xmlSchemaExpandAttributeGroupRefs(pctxt
,
14567 WXS_BASIC_CAST type
, &(type
->attributeWildcard
), uses
,
14570 PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14571 "failed to expand attributes");
14577 * Inherit the attribute uses of the base type.
14579 if (baseUses
!= NULL
) {
14581 xmlSchemaAttributeUseProhibPtr pro
;
14583 if (WXS_IS_RESTRICTION(type
)) {
14585 xmlSchemaAttributeUsePtr tmp
;
14588 usesCount
= uses
->nbItems
;
14593 for (i
= 0; i
< baseUses
->nbItems
; i
++) {
14594 use
= baseUses
->items
[i
];
14597 * Filter out prohibited uses.
14599 for (j
= 0; j
< prohibs
->nbItems
; j
++) {
14600 pro
= prohibs
->items
[j
];
14601 if ((WXS_ATTRUSE_DECL_NAME(use
) == pro
->name
) &&
14602 (WXS_ATTRUSE_DECL_TNS(use
) ==
14603 pro
->targetNamespace
))
14611 * Filter out existing uses.
14613 for (j
= 0; j
< usesCount
; j
++) {
14614 tmp
= uses
->items
[j
];
14615 if ((WXS_ATTRUSE_DECL_NAME(use
) ==
14616 WXS_ATTRUSE_DECL_NAME(tmp
)) &&
14617 (WXS_ATTRUSE_DECL_TNS(use
) ==
14618 WXS_ATTRUSE_DECL_TNS(tmp
)))
14624 if (uses
== NULL
) {
14625 type
->attrUses
= xmlSchemaItemListCreate();
14626 if (type
->attrUses
== NULL
)
14628 uses
= type
->attrUses
;
14630 xmlSchemaItemListAddSize(uses
, 2, use
);
14635 for (i
= 0; i
< baseUses
->nbItems
; i
++) {
14636 use
= baseUses
->items
[i
];
14637 if (uses
== NULL
) {
14638 type
->attrUses
= xmlSchemaItemListCreate();
14639 if (type
->attrUses
== NULL
)
14641 uses
= type
->attrUses
;
14643 xmlSchemaItemListAddSize(uses
, baseUses
->nbItems
, use
);
14648 * Shrink attr. uses.
14651 if (uses
->nbItems
== 0) {
14652 xmlSchemaItemListFree(uses
);
14653 type
->attrUses
= NULL
;
14656 * TODO: We could shrink the size of the array
14657 * to fit the actual number of items.
14661 * Compute the complete wildcard.
14663 if (WXS_IS_EXTENSION(type
)) {
14664 if (baseType
->attributeWildcard
!= NULL
) {
14666 * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
14667 * the appropriate case among the following:"
14669 if (type
->attributeWildcard
!= NULL
) {
14671 * Union the complete wildcard with the base wildcard.
14672 * SPEC {attribute wildcard}
14673 * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
14674 * and {annotation} are those of the `complete wildcard`,
14675 * and whose {namespace constraint} is the intensional union
14676 * of the {namespace constraint} of the `complete wildcard`
14677 * and of the `base wildcard`, as defined in Attribute
14678 * Wildcard Union ($3.10.6)."
14680 if (xmlSchemaUnionWildcards(pctxt
, type
->attributeWildcard
,
14681 baseType
->attributeWildcard
) == -1)
14685 * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
14686 * then the `base wildcard`."
14688 type
->attributeWildcard
= baseType
->attributeWildcard
;
14692 * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
14693 * `complete wildcard`"
14699 * SPEC {attribute wildcard}
14700 * (3.1) "If the <restriction> alternative is chosen, then the
14701 * `complete wildcard`;"
14713 * xmlSchemaTypeFinalContains:
14714 * @schema: the schema
14715 * @type: the type definition
14716 * @final: the final
14718 * Evaluates if a type definition contains the given "final".
14719 * This does take "finalDefault" into account as well.
14721 * Returns 1 if the type does contain the given "final",
14725 xmlSchemaTypeFinalContains(xmlSchemaTypePtr type
, int final
)
14729 if (type
->flags
& final
)
14736 * xmlSchemaGetUnionSimpleTypeMemberTypes:
14737 * @type: the Union Simple Type
14739 * Returns a list of member types of @type if existing,
14740 * returns NULL otherwise.
14742 static xmlSchemaTypeLinkPtr
14743 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type
)
14745 while ((type
!= NULL
) && (type
->type
== XML_SCHEMA_TYPE_SIMPLE
)) {
14746 if (type
->memberTypes
!= NULL
)
14747 return (type
->memberTypes
);
14749 type
= type
->baseType
;
14756 * xmlSchemaGetParticleTotalRangeMin:
14757 * @particle: the particle
14759 * Schema Component Constraint: Effective Total Range
14760 * (all and sequence) + (choice)
14762 * Returns the minimum Effective Total Range.
14765 xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle
)
14767 if ((particle
->children
== NULL
) ||
14768 (particle
->minOccurs
== 0))
14770 if (particle
->children
->type
== XML_SCHEMA_TYPE_CHOICE
) {
14772 xmlSchemaParticlePtr part
=
14773 (xmlSchemaParticlePtr
) particle
->children
->children
;
14777 while (part
!= NULL
) {
14778 if ((part
->children
->type
== XML_SCHEMA_TYPE_ELEMENT
) ||
14779 (part
->children
->type
== XML_SCHEMA_TYPE_ANY
))
14780 cur
= part
->minOccurs
;
14782 cur
= xmlSchemaGetParticleTotalRangeMin(part
);
14785 if ((min
> cur
) || (min
== -1))
14787 part
= (xmlSchemaParticlePtr
) part
->next
;
14789 return (particle
->minOccurs
* min
);
14791 /* <all> and <sequence> */
14793 xmlSchemaParticlePtr part
=
14794 (xmlSchemaParticlePtr
) particle
->children
->children
;
14799 if ((part
->children
->type
== XML_SCHEMA_TYPE_ELEMENT
) ||
14800 (part
->children
->type
== XML_SCHEMA_TYPE_ANY
))
14801 sum
+= part
->minOccurs
;
14803 sum
+= xmlSchemaGetParticleTotalRangeMin(part
);
14804 part
= (xmlSchemaParticlePtr
) part
->next
;
14805 } while (part
!= NULL
);
14806 return (particle
->minOccurs
* sum
);
14811 * xmlSchemaGetParticleTotalRangeMax:
14812 * @particle: the particle
14814 * Schema Component Constraint: Effective Total Range
14815 * (all and sequence) + (choice)
14817 * Returns the maximum Effective Total Range.
14820 xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle
)
14822 if ((particle
->children
== NULL
) ||
14823 (particle
->children
->children
== NULL
))
14825 if (particle
->children
->type
== XML_SCHEMA_TYPE_CHOICE
) {
14827 xmlSchemaParticlePtr part
=
14828 (xmlSchemaParticlePtr
) particle
->children
->children
;
14830 for (; part
!= NULL
; part
= (xmlSchemaParticlePtr
) part
->next
) {
14831 if (part
->children
== NULL
)
14833 if ((part
->children
->type
== XML_SCHEMA_TYPE_ELEMENT
) ||
14834 (part
->children
->type
== XML_SCHEMA_TYPE_ANY
))
14835 cur
= part
->maxOccurs
;
14837 cur
= xmlSchemaGetParticleTotalRangeMax(part
);
14838 if (cur
== UNBOUNDED
)
14839 return (UNBOUNDED
);
14840 if ((max
< cur
) || (max
== -1))
14843 /* TODO: Handle overflows? */
14844 return (particle
->maxOccurs
* max
);
14846 /* <all> and <sequence> */
14848 xmlSchemaParticlePtr part
=
14849 (xmlSchemaParticlePtr
) particle
->children
->children
;
14851 for (; part
!= NULL
; part
= (xmlSchemaParticlePtr
) part
->next
) {
14852 if (part
->children
== NULL
)
14854 if ((part
->children
->type
== XML_SCHEMA_TYPE_ELEMENT
) ||
14855 (part
->children
->type
== XML_SCHEMA_TYPE_ANY
))
14856 cur
= part
->maxOccurs
;
14858 cur
= xmlSchemaGetParticleTotalRangeMax(part
);
14859 if (cur
== UNBOUNDED
)
14860 return (UNBOUNDED
);
14861 if ((cur
> 0) && (particle
->maxOccurs
== UNBOUNDED
))
14862 return (UNBOUNDED
);
14865 /* TODO: Handle overflows? */
14866 return (particle
->maxOccurs
* sum
);
14872 * xmlSchemaGetParticleEmptiable:
14873 * @particle: the particle
14875 * Returns 1 if emptiable, 0 otherwise.
14878 xmlSchemaGetParticleEmptiable(xmlSchemaParticlePtr particle
)
14880 xmlSchemaParticlePtr part
;
14883 if ((particle
->children
== NULL
) || (particle
->minOccurs
== 0))
14886 part
= (xmlSchemaParticlePtr
) particle
->children
->children
;
14890 while (part
!= NULL
) {
14891 if ((part
->children
->type
== XML_SCHEMA_TYPE_ELEMENT
) ||
14892 (part
->children
->type
== XML_SCHEMA_TYPE_ANY
))
14893 emptiable
= (part
->minOccurs
== 0);
14895 emptiable
= xmlSchemaGetParticleEmptiable(part
);
14896 if (particle
->children
->type
== XML_SCHEMA_TYPE_CHOICE
) {
14900 /* <all> and <sequence> */
14904 part
= (xmlSchemaParticlePtr
) part
->next
;
14907 if (particle
->children
->type
== XML_SCHEMA_TYPE_CHOICE
)
14914 * xmlSchemaIsParticleEmptiable:
14915 * @particle: the particle
14917 * Schema Component Constraint: Particle Emptiable
14918 * Checks whether the given particle is emptiable.
14920 * Returns 1 if emptiable, 0 otherwise.
14923 xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle
)
14926 * SPEC (1) "Its {min occurs} is 0."
14928 if ((particle
== NULL
) || (particle
->minOccurs
== 0) ||
14929 (particle
->children
== NULL
))
14932 * SPEC (2) "Its {term} is a group and the minimum part of the
14933 * effective total range of that group, [...] is 0."
14935 if (WXS_IS_MODEL_GROUP(particle
->children
))
14936 return (xmlSchemaGetParticleEmptiable(particle
));
14941 * xmlSchemaCheckCOSSTDerivedOK:
14942 * @actxt: a context
14943 * @type: the derived simple type definition
14944 * @baseType: the base type definition
14945 * @subset: the subset of ('restriction', etc.)
14947 * Schema Component Constraint:
14948 * Type Derivation OK (Simple) (cos-st-derived-OK)
14950 * Checks whether @type can be validly
14951 * derived from @baseType.
14953 * Returns 0 on success, an positive error code otherwise.
14956 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt
,
14957 xmlSchemaTypePtr type
,
14958 xmlSchemaTypePtr baseType
,
14962 * 1 They are the same type definition.
14963 * TODO: The identity check might have to be more complex than this.
14965 if (type
== baseType
)
14968 * 2.1 restriction is not in the subset, or in the {final}
14969 * of its own {base type definition};
14971 * NOTE that this will be used also via "xsi:type".
14973 * TODO: Revise this, it looks strange. How can the "type"
14974 * not be fixed or *in* fixing?
14976 if (WXS_IS_TYPE_NOT_FIXED(type
))
14977 if (xmlSchemaTypeFixup(type
, actxt
) == -1)
14979 if (WXS_IS_TYPE_NOT_FIXED(baseType
))
14980 if (xmlSchemaTypeFixup(baseType
, actxt
) == -1)
14982 if ((subset
& SUBSET_RESTRICTION
) ||
14983 (xmlSchemaTypeFinalContains(type
->baseType
,
14984 XML_SCHEMAS_TYPE_FINAL_RESTRICTION
))) {
14985 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1
);
14988 if (type
->baseType
== baseType
) {
14990 * 2.2.1 D's `base type definition` is B.
14995 * 2.2.2 D's `base type definition` is not the `ur-type definition`
14996 * and is validly derived from B given the subset, as defined by this
14999 if ((! WXS_IS_ANYTYPE(type
->baseType
)) &&
15000 (xmlSchemaCheckCOSSTDerivedOK(actxt
, type
->baseType
,
15001 baseType
, subset
) == 0)) {
15005 * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
15008 if (WXS_IS_ANY_SIMPLE_TYPE(baseType
) &&
15009 (WXS_IS_LIST(type
) || WXS_IS_UNION(type
))) {
15013 * 2.2.4 B's {variety} is union and D is validly derived from a type
15014 * definition in B's {member type definitions} given the subset, as
15015 * defined by this constraint.
15017 * NOTE: This seems not to involve built-in types, since there is no
15018 * built-in Union Simple Type.
15020 if (WXS_IS_UNION(baseType
)) {
15021 xmlSchemaTypeLinkPtr cur
;
15023 cur
= baseType
->memberTypes
;
15024 while (cur
!= NULL
) {
15025 if (WXS_IS_TYPE_NOT_FIXED(cur
->type
))
15026 if (xmlSchemaTypeFixup(cur
->type
, actxt
) == -1)
15028 if (xmlSchemaCheckCOSSTDerivedOK(actxt
,
15029 type
, cur
->type
, subset
) == 0)
15032 * It just has to be validly derived from at least one
15040 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2
);
15044 * xmlSchemaCheckTypeDefCircularInternal:
15045 * @pctxt: the schema parser context
15046 * @ctxtType: the type definition
15047 * @ancestor: an ancestor of @ctxtType
15049 * Checks st-props-correct (2) + ct-props-correct (3).
15050 * Circular type definitions are not allowed.
15052 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
15053 * circular, 0 otherwise.
15056 xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt
,
15057 xmlSchemaTypePtr ctxtType
,
15058 xmlSchemaTypePtr ancestor
)
15062 if ((ancestor
== NULL
) || (ancestor
->type
== XML_SCHEMA_TYPE_BASIC
))
15065 if (ctxtType
== ancestor
) {
15066 xmlSchemaPCustomErr(pctxt
,
15067 XML_SCHEMAP_ST_PROPS_CORRECT_2
,
15068 WXS_BASIC_CAST ctxtType
, WXS_ITEM_NODE(ctxtType
),
15069 "The definition is circular", NULL
);
15070 return (XML_SCHEMAP_ST_PROPS_CORRECT_2
);
15072 if (ancestor
->flags
& XML_SCHEMAS_TYPE_MARKED
) {
15074 * Avoid infinite recursion on circular types not yet checked.
15078 ancestor
->flags
|= XML_SCHEMAS_TYPE_MARKED
;
15079 ret
= xmlSchemaCheckTypeDefCircularInternal(pctxt
, ctxtType
,
15080 ancestor
->baseType
);
15081 ancestor
->flags
^= XML_SCHEMAS_TYPE_MARKED
;
15086 * xmlSchemaCheckTypeDefCircular:
15087 * @item: the complex/simple type definition
15088 * @ctxt: the parser context
15091 * Checks for circular type definitions.
15094 xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item
,
15095 xmlSchemaParserCtxtPtr ctxt
)
15097 if ((item
== NULL
) ||
15098 (item
->type
== XML_SCHEMA_TYPE_BASIC
) ||
15099 (item
->baseType
== NULL
))
15101 xmlSchemaCheckTypeDefCircularInternal(ctxt
, item
,
15106 * Simple Type Definition Representation OK (src-simple-type) 4
15108 * "4 Circular union type definition is disallowed. That is, if the
15109 * <union> alternative is chosen, there must not be any entries in the
15110 * memberTypes [attribute] at any depth which resolve to the component
15111 * corresponding to the <simpleType>."
15113 * Note that this should work on the *representation* of a component,
15114 * thus assumes any union types in the member types not being yet
15115 * substituted. At this stage we need the variety of the types
15116 * to be already computed.
15119 xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt
,
15120 xmlSchemaTypePtr ctxType
,
15121 xmlSchemaTypeLinkPtr members
)
15123 xmlSchemaTypeLinkPtr member
;
15124 xmlSchemaTypePtr memberType
;
15127 while (member
!= NULL
) {
15128 memberType
= member
->type
;
15129 while ((memberType
!= NULL
) &&
15130 (memberType
->type
!= XML_SCHEMA_TYPE_BASIC
)) {
15131 if (memberType
== ctxType
) {
15132 xmlSchemaPCustomErr(pctxt
,
15133 XML_SCHEMAP_SRC_SIMPLE_TYPE_4
,
15134 WXS_BASIC_CAST ctxType
, NULL
,
15135 "The union type definition is circular", NULL
);
15136 return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4
);
15138 if ((WXS_IS_UNION(memberType
)) &&
15139 ((memberType
->flags
& XML_SCHEMAS_TYPE_MARKED
) == 0))
15142 memberType
->flags
|= XML_SCHEMAS_TYPE_MARKED
;
15143 res
= xmlSchemaCheckUnionTypeDefCircularRecur(pctxt
,
15145 xmlSchemaGetUnionSimpleTypeMemberTypes(memberType
));
15146 memberType
->flags
^= XML_SCHEMAS_TYPE_MARKED
;
15150 memberType
= memberType
->baseType
;
15152 member
= member
->next
;
15158 xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt
,
15159 xmlSchemaTypePtr type
)
15161 if (! WXS_IS_UNION(type
))
15163 return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt
, type
,
15164 type
->memberTypes
));
15168 * xmlSchemaResolveTypeReferences:
15169 * @item: the complex/simple type definition
15170 * @ctxt: the parser context
15173 * Resolves type definition references
15176 xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef
,
15177 xmlSchemaParserCtxtPtr ctxt
)
15179 if (typeDef
== NULL
)
15183 * Resolve the base type.
15185 if (typeDef
->baseType
== NULL
) {
15186 typeDef
->baseType
= xmlSchemaGetType(ctxt
->schema
,
15187 typeDef
->base
, typeDef
->baseNs
);
15188 if (typeDef
->baseType
== NULL
) {
15189 xmlSchemaPResCompAttrErr(ctxt
,
15190 XML_SCHEMAP_SRC_RESOLVE
,
15191 WXS_BASIC_CAST typeDef
, typeDef
->node
,
15192 "base", typeDef
->base
, typeDef
->baseNs
,
15193 XML_SCHEMA_TYPE_SIMPLE
, NULL
);
15197 if (WXS_IS_SIMPLE(typeDef
)) {
15198 if (WXS_IS_UNION(typeDef
)) {
15200 * Resolve the memberTypes.
15202 xmlSchemaResolveUnionMemberTypes(ctxt
, typeDef
);
15204 } else if (WXS_IS_LIST(typeDef
)) {
15206 * Resolve the itemType.
15208 if ((typeDef
->subtypes
== NULL
) && (typeDef
->base
!= NULL
)) {
15210 typeDef
->subtypes
= xmlSchemaGetType(ctxt
->schema
,
15211 typeDef
->base
, typeDef
->baseNs
);
15213 if ((typeDef
->subtypes
== NULL
) ||
15214 (! WXS_IS_SIMPLE(typeDef
->subtypes
)))
15216 typeDef
->subtypes
= NULL
;
15217 xmlSchemaPResCompAttrErr(ctxt
,
15218 XML_SCHEMAP_SRC_RESOLVE
,
15219 WXS_BASIC_CAST typeDef
, typeDef
->node
,
15220 "itemType", typeDef
->base
, typeDef
->baseNs
,
15221 XML_SCHEMA_TYPE_SIMPLE
, NULL
);
15228 * The ball of letters below means, that if we have a particle
15229 * which has a QName-helper component as its {term}, we want
15232 else if ((WXS_TYPE_CONTENTTYPE(typeDef
) != NULL
) &&
15233 ((WXS_TYPE_CONTENTTYPE(typeDef
))->type
==
15234 XML_SCHEMA_TYPE_PARTICLE
) &&
15235 (WXS_TYPE_PARTICLE_TERM(typeDef
) != NULL
) &&
15236 ((WXS_TYPE_PARTICLE_TERM(typeDef
))->type
==
15237 XML_SCHEMA_EXTRA_QNAMEREF
))
15239 xmlSchemaQNameRefPtr ref
=
15240 WXS_QNAME_CAST
WXS_TYPE_PARTICLE_TERM(typeDef
);
15241 xmlSchemaModelGroupDefPtr groupDef
;
15244 * URGENT TODO: Test this.
15246 WXS_TYPE_PARTICLE_TERM(typeDef
) = NULL
;
15248 * Resolve the MG definition reference.
15251 WXS_MODEL_GROUPDEF_CAST
xmlSchemaGetNamedComponent(ctxt
->schema
,
15252 ref
->itemType
, ref
->name
, ref
->targetNamespace
);
15253 if (groupDef
== NULL
) {
15254 xmlSchemaPResCompAttrErr(ctxt
, XML_SCHEMAP_SRC_RESOLVE
,
15255 NULL
, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef
)),
15256 "ref", ref
->name
, ref
->targetNamespace
, ref
->itemType
,
15258 /* Remove the particle. */
15259 WXS_TYPE_CONTENTTYPE(typeDef
) = NULL
;
15260 } else if (WXS_MODELGROUPDEF_MODEL(groupDef
) == NULL
)
15261 /* Remove the particle. */
15262 WXS_TYPE_CONTENTTYPE(typeDef
) = NULL
;
15265 * Assign the MG definition's {model group} to the
15266 * particle's {term}.
15268 WXS_TYPE_PARTICLE_TERM(typeDef
) = WXS_MODELGROUPDEF_MODEL(groupDef
);
15270 if (WXS_MODELGROUPDEF_MODEL(groupDef
)->type
== XML_SCHEMA_TYPE_ALL
) {
15272 * SPEC cos-all-limited (1.2)
15273 * "1.2 the {term} property of a particle with
15274 * {max occurs}=1 which is part of a pair which constitutes
15275 * the {content type} of a complex type definition."
15277 if ((WXS_TYPE_PARTICLE(typeDef
))->maxOccurs
!= 1) {
15278 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
15279 /* TODO: error code */
15280 XML_SCHEMAP_COS_ALL_LIMITED
,
15281 WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef
)), NULL
,
15282 "The particle's {max occurs} must be 1, since the "
15283 "reference resolves to an 'all' model group",
15294 * xmlSchemaCheckSTPropsCorrect:
15295 * @ctxt: the schema parser context
15296 * @type: the simple type definition
15298 * Checks st-props-correct.
15300 * Returns 0 if the properties are correct,
15301 * if not, a positive error code and -1 on internal
15305 xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt
,
15306 xmlSchemaTypePtr type
)
15308 xmlSchemaTypePtr baseType
= type
->baseType
;
15309 xmlChar
*str
= NULL
;
15311 /* STATE: error funcs converted. */
15313 * Schema Component Constraint: Simple Type Definition Properties Correct
15315 * NOTE: This is somehow redundant, since we actually built a simple type
15316 * to have all the needed information; this acts as an self test.
15318 /* Base type: If the datatype has been `derived` by `restriction`
15319 * then the Simple Type Definition component from which it is `derived`,
15320 * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
15322 if (baseType
== NULL
) {
15324 * TODO: Think about: "modulo the impact of Missing
15325 * Sub-components ($5.3)."
15327 xmlSchemaPCustomErr(ctxt
,
15328 XML_SCHEMAP_ST_PROPS_CORRECT_1
,
15329 WXS_BASIC_CAST type
, NULL
,
15330 "No base type existent", NULL
);
15331 return (XML_SCHEMAP_ST_PROPS_CORRECT_1
);
15334 if (! WXS_IS_SIMPLE(baseType
)) {
15335 xmlSchemaPCustomErr(ctxt
,
15336 XML_SCHEMAP_ST_PROPS_CORRECT_1
,
15337 WXS_BASIC_CAST type
, NULL
,
15338 "The base type '%s' is not a simple type",
15339 xmlSchemaGetComponentQName(&str
, baseType
));
15341 return (XML_SCHEMAP_ST_PROPS_CORRECT_1
);
15343 if ((WXS_IS_LIST(type
) || WXS_IS_UNION(type
)) &&
15344 (WXS_IS_RESTRICTION(type
) == 0) &&
15345 ((! WXS_IS_ANY_SIMPLE_TYPE(baseType
)) &&
15346 (baseType
->type
!= XML_SCHEMA_TYPE_SIMPLE
))) {
15347 xmlSchemaPCustomErr(ctxt
,
15348 XML_SCHEMAP_ST_PROPS_CORRECT_1
,
15349 WXS_BASIC_CAST type
, NULL
,
15350 "A type, derived by list or union, must have "
15351 "the simple ur-type definition as base type, not '%s'",
15352 xmlSchemaGetComponentQName(&str
, baseType
));
15354 return (XML_SCHEMAP_ST_PROPS_CORRECT_1
);
15357 * Variety: One of {atomic, list, union}.
15359 if ((! WXS_IS_ATOMIC(type
)) && (! WXS_IS_UNION(type
)) &&
15360 (! WXS_IS_LIST(type
))) {
15361 xmlSchemaPCustomErr(ctxt
,
15362 XML_SCHEMAP_ST_PROPS_CORRECT_1
,
15363 WXS_BASIC_CAST type
, NULL
,
15364 "The variety is absent", NULL
);
15365 return (XML_SCHEMAP_ST_PROPS_CORRECT_1
);
15367 /* TODO: Finish this. Hmm, is this finished? */
15370 * 3 The {final} of the {base type definition} must not contain restriction.
15372 if (xmlSchemaTypeFinalContains(baseType
,
15373 XML_SCHEMAS_TYPE_FINAL_RESTRICTION
)) {
15374 xmlSchemaPCustomErr(ctxt
,
15375 XML_SCHEMAP_ST_PROPS_CORRECT_3
,
15376 WXS_BASIC_CAST type
, NULL
,
15377 "The 'final' of its base type '%s' must not contain "
15379 xmlSchemaGetComponentQName(&str
, baseType
));
15381 return (XML_SCHEMAP_ST_PROPS_CORRECT_3
);
15385 * 2 All simple type definitions must be derived ultimately from the `simple
15386 * ur-type definition` (so circular definitions are disallowed). That is, it
15387 * must be possible to reach a built-in primitive datatype or the `simple
15388 * ur-type definition` by repeatedly following the {base type definition}.
15390 * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
15396 * xmlSchemaCheckCOSSTRestricts:
15397 * @ctxt: the schema parser context
15398 * @type: the simple type definition
15400 * Schema Component Constraint:
15401 * Derivation Valid (Restriction, Simple) (cos-st-restricts)
15403 * Checks if the given @type (simpleType) is derived validly by restriction.
15406 * Returns -1 on internal errors, 0 if the type is validly derived,
15407 * a positive error code otherwise.
15410 xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt
,
15411 xmlSchemaTypePtr type
)
15413 xmlChar
*str
= NULL
;
15415 if (type
->type
!= XML_SCHEMA_TYPE_SIMPLE
) {
15416 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15417 "given type is not a user-derived simpleType");
15421 if (WXS_IS_ATOMIC(type
)) {
15422 xmlSchemaTypePtr primitive
;
15424 * 1.1 The {base type definition} must be an atomic simple
15425 * type definition or a built-in primitive datatype.
15427 if (! WXS_IS_ATOMIC(type
->baseType
)) {
15428 xmlSchemaPCustomErr(pctxt
,
15429 XML_SCHEMAP_COS_ST_RESTRICTS_1_1
,
15430 WXS_BASIC_CAST type
, NULL
,
15431 "The base type '%s' is not an atomic simple type",
15432 xmlSchemaGetComponentQName(&str
, type
->baseType
));
15434 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1
);
15436 /* 1.2 The {final} of the {base type definition} must not contain
15439 /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
15440 if (xmlSchemaTypeFinalContains(type
->baseType
,
15441 XML_SCHEMAS_TYPE_FINAL_RESTRICTION
)) {
15442 xmlSchemaPCustomErr(pctxt
,
15443 XML_SCHEMAP_COS_ST_RESTRICTS_1_2
,
15444 WXS_BASIC_CAST type
, NULL
,
15445 "The final of its base type '%s' must not contain 'restriction'",
15446 xmlSchemaGetComponentQName(&str
, type
->baseType
));
15448 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2
);
15452 * 1.3.1 DF must be an allowed constraining facet for the {primitive
15453 * type definition}, as specified in the appropriate subsection of 3.2
15454 * Primitive datatypes.
15456 if (type
->facets
!= NULL
) {
15457 xmlSchemaFacetPtr facet
;
15460 primitive
= xmlSchemaGetPrimitiveType(type
);
15461 if (primitive
== NULL
) {
15462 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15463 "failed to get primitive type");
15466 facet
= type
->facets
;
15468 if (xmlSchemaIsBuiltInTypeFacet(primitive
, facet
->type
) == 0) {
15470 xmlSchemaPIllegalFacetAtomicErr(pctxt
,
15471 XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1
,
15472 type
, primitive
, facet
);
15474 facet
= facet
->next
;
15475 } while (facet
!= NULL
);
15477 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1
);
15480 * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
15481 * of the {base type definition} (call this BF),then the DF's {value}
15482 * must be a valid restriction of BF's {value} as defined in
15483 * [XML Schemas: Datatypes]."
15485 * NOTE (1.3.2) Facet derivation constraints are currently handled in
15486 * xmlSchemaDeriveAndValidateFacets()
15488 } else if (WXS_IS_LIST(type
)) {
15489 xmlSchemaTypePtr itemType
= NULL
;
15491 itemType
= type
->subtypes
;
15492 if ((itemType
== NULL
) || (! WXS_IS_SIMPLE(itemType
))) {
15493 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15494 "failed to evaluate the item type");
15497 if (WXS_IS_TYPE_NOT_FIXED(itemType
))
15498 xmlSchemaTypeFixup(itemType
, ACTXT_CAST pctxt
);
15500 * 2.1 The {item type definition} must have a {variety} of atomic or
15501 * union (in which case all the {member type definitions}
15504 if ((! WXS_IS_ATOMIC(itemType
)) &&
15505 (! WXS_IS_UNION(itemType
))) {
15506 xmlSchemaPCustomErr(pctxt
,
15507 XML_SCHEMAP_COS_ST_RESTRICTS_2_1
,
15508 WXS_BASIC_CAST type
, NULL
,
15509 "The item type '%s' does not have a variety of atomic or union",
15510 xmlSchemaGetComponentQName(&str
, itemType
));
15512 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1
);
15513 } else if (WXS_IS_UNION(itemType
)) {
15514 xmlSchemaTypeLinkPtr member
;
15516 member
= itemType
->memberTypes
;
15517 while (member
!= NULL
) {
15518 if (! WXS_IS_ATOMIC(member
->type
)) {
15519 xmlSchemaPCustomErr(pctxt
,
15520 XML_SCHEMAP_COS_ST_RESTRICTS_2_1
,
15521 WXS_BASIC_CAST type
, NULL
,
15522 "The item type is a union type, but the "
15523 "member type '%s' of this item type is not atomic",
15524 xmlSchemaGetComponentQName(&str
, member
->type
));
15526 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1
);
15528 member
= member
->next
;
15532 if (WXS_IS_ANY_SIMPLE_TYPE(type
->baseType
)) {
15533 xmlSchemaFacetPtr facet
;
15535 * This is the case if we have: <simpleType><list ..
15539 * 2.3.1.1 The {final} of the {item type definition} must not
15542 if (xmlSchemaTypeFinalContains(itemType
,
15543 XML_SCHEMAS_TYPE_FINAL_LIST
)) {
15544 xmlSchemaPCustomErr(pctxt
,
15545 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1
,
15546 WXS_BASIC_CAST type
, NULL
,
15547 "The final of its item type '%s' must not contain 'list'",
15548 xmlSchemaGetComponentQName(&str
, itemType
));
15550 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1
);
15553 * 2.3.1.2 The {facets} must only contain the whiteSpace
15555 * OPTIMIZE TODO: the S4S already disallows any facet
15558 if (type
->facets
!= NULL
) {
15559 facet
= type
->facets
;
15561 if (facet
->type
!= XML_SCHEMA_FACET_WHITESPACE
) {
15562 xmlSchemaPIllegalFacetListUnionErr(pctxt
,
15563 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2
,
15565 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2
);
15567 facet
= facet
->next
;
15568 } while (facet
!= NULL
);
15571 * MAYBE TODO: (Hmm, not really) Datatypes states:
15572 * A `list` datatype can be `derived` from an `atomic` datatype
15573 * whose `lexical space` allows space (such as string or anyURI)or
15574 * a `union` datatype any of whose {member type definitions}'s
15575 * `lexical space` allows space.
15579 * This is the case if we have: <simpleType><restriction ...
15580 * I.e. the variety of "list" is inherited.
15584 * 2.3.2.1 The {base type definition} must have a {variety} of list.
15586 if (! WXS_IS_LIST(type
->baseType
)) {
15587 xmlSchemaPCustomErr(pctxt
,
15588 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1
,
15589 WXS_BASIC_CAST type
, NULL
,
15590 "The base type '%s' must be a list type",
15591 xmlSchemaGetComponentQName(&str
, type
->baseType
));
15593 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1
);
15596 * 2.3.2.2 The {final} of the {base type definition} must not
15597 * contain restriction.
15599 if (xmlSchemaTypeFinalContains(type
->baseType
,
15600 XML_SCHEMAS_TYPE_FINAL_RESTRICTION
)) {
15601 xmlSchemaPCustomErr(pctxt
,
15602 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2
,
15603 WXS_BASIC_CAST type
, NULL
,
15604 "The 'final' of the base type '%s' must not contain 'restriction'",
15605 xmlSchemaGetComponentQName(&str
, type
->baseType
));
15607 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2
);
15610 * 2.3.2.3 The {item type definition} must be validly derived
15611 * from the {base type definition}'s {item type definition} given
15612 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
15615 xmlSchemaTypePtr baseItemType
;
15617 baseItemType
= type
->baseType
->subtypes
;
15618 if ((baseItemType
== NULL
) || (! WXS_IS_SIMPLE(baseItemType
))) {
15619 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15620 "failed to eval the item type of a base type");
15623 if ((itemType
!= baseItemType
) &&
15624 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt
, itemType
,
15625 baseItemType
, 0) != 0)) {
15626 xmlChar
*strBIT
= NULL
, *strBT
= NULL
;
15627 xmlSchemaPCustomErrExt(pctxt
,
15628 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3
,
15629 WXS_BASIC_CAST type
, NULL
,
15630 "The item type '%s' is not validly derived from "
15631 "the item type '%s' of the base type '%s'",
15632 xmlSchemaGetComponentQName(&str
, itemType
),
15633 xmlSchemaGetComponentQName(&strBIT
, baseItemType
),
15634 xmlSchemaGetComponentQName(&strBT
, type
->baseType
));
15637 FREE_AND_NULL(strBIT
)
15638 FREE_AND_NULL(strBT
)
15639 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3
);
15643 if (type
->facets
!= NULL
) {
15644 xmlSchemaFacetPtr facet
;
15647 * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
15648 * and enumeration facet components are allowed among the {facets}.
15650 facet
= type
->facets
;
15652 switch (facet
->type
) {
15653 case XML_SCHEMA_FACET_LENGTH
:
15654 case XML_SCHEMA_FACET_MINLENGTH
:
15655 case XML_SCHEMA_FACET_MAXLENGTH
:
15656 case XML_SCHEMA_FACET_WHITESPACE
:
15658 * TODO: 2.5.1.2 List datatypes
15659 * The value of `whiteSpace` is fixed to the value collapse.
15661 case XML_SCHEMA_FACET_PATTERN
:
15662 case XML_SCHEMA_FACET_ENUMERATION
:
15665 xmlSchemaPIllegalFacetListUnionErr(pctxt
,
15666 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4
,
15669 * We could return, but it's nicer to report all
15675 facet
= facet
->next
;
15676 } while (facet
!= NULL
);
15678 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4
);
15680 * SPEC (2.3.2.5) (same as 1.3.2)
15682 * NOTE (2.3.2.5) This is currently done in
15683 * xmlSchemaDeriveAndValidateFacets()
15687 } else if (WXS_IS_UNION(type
)) {
15689 * 3.1 The {member type definitions} must all have {variety} of
15692 xmlSchemaTypeLinkPtr member
;
15694 member
= type
->memberTypes
;
15695 while (member
!= NULL
) {
15696 if (WXS_IS_TYPE_NOT_FIXED(member
->type
))
15697 xmlSchemaTypeFixup(member
->type
, ACTXT_CAST pctxt
);
15699 if ((! WXS_IS_ATOMIC(member
->type
)) &&
15700 (! WXS_IS_LIST(member
->type
))) {
15701 xmlSchemaPCustomErr(pctxt
,
15702 XML_SCHEMAP_COS_ST_RESTRICTS_3_1
,
15703 WXS_BASIC_CAST type
, NULL
,
15704 "The member type '%s' is neither an atomic, nor a list type",
15705 xmlSchemaGetComponentQName(&str
, member
->type
));
15707 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1
);
15709 member
= member
->next
;
15712 * 3.3.1 If the {base type definition} is the `simple ur-type
15715 if (type
->baseType
->builtInType
== XML_SCHEMAS_ANYSIMPLETYPE
) {
15717 * 3.3.1.1 All of the {member type definitions} must have a
15718 * {final} which does not contain union.
15720 member
= type
->memberTypes
;
15721 while (member
!= NULL
) {
15722 if (xmlSchemaTypeFinalContains(member
->type
,
15723 XML_SCHEMAS_TYPE_FINAL_UNION
)) {
15724 xmlSchemaPCustomErr(pctxt
,
15725 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1
,
15726 WXS_BASIC_CAST type
, NULL
,
15727 "The 'final' of member type '%s' contains 'union'",
15728 xmlSchemaGetComponentQName(&str
, member
->type
));
15730 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1
);
15732 member
= member
->next
;
15735 * 3.3.1.2 The {facets} must be empty.
15737 if (type
->facetSet
!= NULL
) {
15738 xmlSchemaPCustomErr(pctxt
,
15739 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2
,
15740 WXS_BASIC_CAST type
, NULL
,
15741 "No facets allowed", NULL
);
15742 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2
);
15746 * 3.3.2.1 The {base type definition} must have a {variety} of union.
15747 * I.e. the variety of "list" is inherited.
15749 if (! WXS_IS_UNION(type
->baseType
)) {
15750 xmlSchemaPCustomErr(pctxt
,
15751 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1
,
15752 WXS_BASIC_CAST type
, NULL
,
15753 "The base type '%s' is not a union type",
15754 xmlSchemaGetComponentQName(&str
, type
->baseType
));
15756 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1
);
15759 * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
15761 if (xmlSchemaTypeFinalContains(type
->baseType
,
15762 XML_SCHEMAS_TYPE_FINAL_RESTRICTION
)) {
15763 xmlSchemaPCustomErr(pctxt
,
15764 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2
,
15765 WXS_BASIC_CAST type
, NULL
,
15766 "The 'final' of its base type '%s' must not contain 'restriction'",
15767 xmlSchemaGetComponentQName(&str
, type
->baseType
));
15769 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2
);
15772 * 3.3.2.3 The {member type definitions}, in order, must be validly
15773 * derived from the corresponding type definitions in the {base
15774 * type definition}'s {member type definitions} given the empty set,
15775 * as defined in Type Derivation OK (Simple) ($3.14.6).
15778 xmlSchemaTypeLinkPtr baseMember
;
15781 * OPTIMIZE: if the type is restricting, it has no local defined
15782 * member types and inherits the member types of the base type;
15783 * thus a check for equality can be skipped.
15786 * Even worse: I cannot see a scenario where a restricting
15787 * union simple type can have other member types as the member
15788 * types of it's base type. This check seems not necessary with
15789 * respect to the derivation process in libxml2.
15790 * But necessary if constructing types with an API.
15792 if (type
->memberTypes
!= NULL
) {
15793 member
= type
->memberTypes
;
15794 baseMember
= xmlSchemaGetUnionSimpleTypeMemberTypes(type
->baseType
);
15795 if ((member
== NULL
) && (baseMember
!= NULL
)) {
15796 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15797 "different number of member types in base");
15799 while (member
!= NULL
) {
15800 if (baseMember
== NULL
) {
15801 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15802 "different number of member types in base");
15803 } else if ((member
->type
!= baseMember
->type
) &&
15804 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt
,
15805 member
->type
, baseMember
->type
, 0) != 0)) {
15806 xmlChar
*strBMT
= NULL
, *strBT
= NULL
;
15808 xmlSchemaPCustomErrExt(pctxt
,
15809 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3
,
15810 WXS_BASIC_CAST type
, NULL
,
15811 "The member type %s is not validly "
15812 "derived from its corresponding member "
15813 "type %s of the base type %s",
15814 xmlSchemaGetComponentQName(&str
, member
->type
),
15815 xmlSchemaGetComponentQName(&strBMT
, baseMember
->type
),
15816 xmlSchemaGetComponentQName(&strBT
, type
->baseType
));
15818 FREE_AND_NULL(strBMT
)
15819 FREE_AND_NULL(strBT
)
15820 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3
);
15822 member
= member
->next
;
15823 if (baseMember
!= NULL
)
15824 baseMember
= baseMember
->next
;
15829 * 3.3.2.4 Only pattern and enumeration facet components are
15830 * allowed among the {facets}.
15832 if (type
->facets
!= NULL
) {
15833 xmlSchemaFacetPtr facet
;
15836 facet
= type
->facets
;
15838 if ((facet
->type
!= XML_SCHEMA_FACET_PATTERN
) &&
15839 (facet
->type
!= XML_SCHEMA_FACET_ENUMERATION
)) {
15840 xmlSchemaPIllegalFacetListUnionErr(pctxt
,
15841 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4
,
15845 facet
= facet
->next
;
15846 } while (facet
!= NULL
);
15848 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4
);
15852 * SPEC (3.3.2.5) (same as 1.3.2)
15854 * NOTE (3.3.2.5) This is currently done in
15855 * xmlSchemaDeriveAndValidateFacets()
15864 * xmlSchemaCheckSRCSimpleType:
15865 * @ctxt: the schema parser context
15866 * @type: the simple type definition
15868 * Checks crc-simple-type constraints.
15870 * Returns 0 if the constraints are satisfied,
15871 * if not a positive error code and -1 on internal
15876 xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt
,
15877 xmlSchemaTypePtr type
)
15880 * src-simple-type.1 The corresponding simple type definition, if any,
15881 * must satisfy the conditions set out in Constraints on Simple Type
15882 * Definition Schema Components ($3.14.6).
15884 if (WXS_IS_RESTRICTION(type
)) {
15886 * src-simple-type.2 "If the <restriction> alternative is chosen,
15887 * either it must have a base [attribute] or a <simpleType> among its
15888 * [children], but not both."
15889 * NOTE: This is checked in the parse function of <restriction>.
15894 } else if (WXS_IS_LIST(type
)) {
15895 /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
15896 * an itemType [attribute] or a <simpleType> among its [children],
15899 * NOTE: This is checked in the parse function of <list>.
15901 } else if (WXS_IS_UNION(type
)) {
15903 * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
15911 xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt
)
15913 if (ctxt
->vctxt
== NULL
) {
15914 ctxt
->vctxt
= xmlSchemaNewValidCtxt(NULL
);
15915 if (ctxt
->vctxt
== NULL
) {
15916 xmlSchemaPErr(ctxt
, NULL
,
15917 XML_SCHEMAP_INTERNAL
,
15918 "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
15919 "failed to create a temp. validation context.\n",
15923 /* TODO: Pass user data. */
15924 xmlSchemaSetValidErrors(ctxt
->vctxt
,
15925 ctxt
->error
, ctxt
->warning
, ctxt
->errCtxt
);
15926 xmlSchemaSetValidStructuredErrors(ctxt
->vctxt
,
15927 ctxt
->serror
, ctxt
->errCtxt
);
15933 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt
,
15935 xmlSchemaTypePtr type
,
15936 const xmlChar
*value
,
15937 xmlSchemaValPtr
*retVal
,
15943 * xmlSchemaParseCheckCOSValidDefault:
15944 * @pctxt: the schema parser context
15945 * @type: the simple type definition
15946 * @value: the default value
15947 * @node: an optional node (the holder of the value)
15949 * Schema Component Constraint: Element Default Valid (Immediate)
15950 * (cos-valid-default)
15951 * This will be used by the parser only. For the validator there's
15952 * an other version.
15954 * Returns 0 if the constraints are satisfied,
15955 * if not, a positive error code and -1 on internal
15959 xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt
,
15961 xmlSchemaTypePtr type
,
15962 const xmlChar
*value
,
15963 xmlSchemaValPtr
*val
)
15968 * cos-valid-default:
15969 * Schema Component Constraint: Element Default Valid (Immediate)
15970 * For a string to be a valid default with respect to a type
15971 * definition the appropriate case among the following must be true:
15973 if WXS_IS_COMPLEX(type
) {
15977 * SPEC (2.1) "its {content type} must be a simple type definition
15979 * SPEC (2.2.2) "If the {content type} is mixed, then the {content
15980 * type}'s particle must be `emptiable` as defined by
15981 * Particle Emptiable ($3.9.6)."
15983 if ((! WXS_HAS_SIMPLE_CONTENT(type
)) &&
15984 ((! WXS_HAS_MIXED_CONTENT(type
)) || (! WXS_EMPTIABLE(type
)))) {
15985 /* NOTE that this covers (2.2.2) as well. */
15986 xmlSchemaPCustomErr(pctxt
,
15987 XML_SCHEMAP_COS_VALID_DEFAULT_2_1
,
15988 WXS_BASIC_CAST type
, type
->node
,
15989 "For a string to be a valid default, the type definition "
15990 "must be a simple type or a complex type with mixed content "
15991 "and a particle emptiable", NULL
);
15992 return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1
);
15996 * 1 If the type definition is a simple type definition, then the string
15997 * must be `valid` with respect to that definition as defined by String
16002 * 2.2.1 If the {content type} is a simple type definition, then the
16003 * string must be `valid` with respect to that simple type definition
16004 * as defined by String Valid ($3.14.4).
16006 if (WXS_IS_SIMPLE(type
))
16007 ret
= xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt
, node
,
16008 type
, value
, val
, 1, 1, 0);
16009 else if (WXS_HAS_SIMPLE_CONTENT(type
))
16010 ret
= xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt
, node
,
16011 type
->contentTypeDef
, value
, val
, 1, 1, 0);
16016 PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
16017 "calling xmlSchemaVCheckCVCSimpleType()");
16024 * xmlSchemaCheckCTPropsCorrect:
16025 * @ctxt: the schema parser context
16026 * @type: the complex type definition
16028 *.(4.6) Constraints on Complex Type Definition Schema Components
16029 * Schema Component Constraint:
16030 * Complex Type Definition Properties Correct (ct-props-correct)
16031 * STATUS: (seems) complete
16033 * Returns 0 if the constraints are satisfied, a positive
16034 * error code if not and -1 if an internal error occurred.
16037 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt
,
16038 xmlSchemaTypePtr type
)
16041 * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
16043 * SPEC (1) "The values of the properties of a complex type definition must
16044 * be as described in the property tableau in The Complex Type Definition
16045 * Schema Component ($3.4.1), modulo the impact of Missing
16046 * Sub-components ($5.3)."
16048 if ((type
->baseType
!= NULL
) &&
16049 (WXS_IS_SIMPLE(type
->baseType
)) &&
16050 (WXS_IS_EXTENSION(type
) == 0)) {
16052 * SPEC (2) "If the {base type definition} is a simple type definition,
16053 * the {derivation method} must be extension."
16055 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
16056 XML_SCHEMAP_SRC_CT_1
,
16057 NULL
, WXS_BASIC_CAST type
,
16058 "If the base type is a simple type, the derivation method must be "
16059 "'extension'", NULL
, NULL
);
16060 return (XML_SCHEMAP_SRC_CT_1
);
16063 * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
16064 * definition`. That is, it must be possible to reach the `ur-type
16065 * definition` by repeatedly following the {base type definition}."
16067 * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
16070 * NOTE that (4) and (5) need the following:
16071 * - attribute uses need to be already inherited (apply attr. prohibitions)
16072 * - attribute group references need to be expanded already
16073 * - simple types need to be typefixed already
16075 if (type
->attrUses
&&
16076 (((xmlSchemaItemListPtr
) type
->attrUses
)->nbItems
> 1))
16078 xmlSchemaItemListPtr uses
= (xmlSchemaItemListPtr
) type
->attrUses
;
16079 xmlSchemaAttributeUsePtr use
, tmp
;
16080 int i
, j
, hasId
= 0;
16082 for (i
= uses
->nbItems
-1; i
>= 0; i
--) {
16083 use
= uses
->items
[i
];
16086 * SPEC ct-props-correct
16087 * (4) "Two distinct attribute declarations in the
16088 * {attribute uses} must not have identical {name}s and
16089 * {target namespace}s."
16092 for (j
= i
-1; j
>= 0; j
--) {
16093 tmp
= uses
->items
[j
];
16094 if ((WXS_ATTRUSE_DECL_NAME(use
) ==
16095 WXS_ATTRUSE_DECL_NAME(tmp
)) &&
16096 (WXS_ATTRUSE_DECL_TNS(use
) ==
16097 WXS_ATTRUSE_DECL_TNS(tmp
)))
16099 xmlChar
*str
= NULL
;
16101 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
16102 XML_SCHEMAP_AG_PROPS_CORRECT
,
16103 NULL
, WXS_BASIC_CAST type
,
16105 xmlSchemaGetComponentDesignation(&str
, use
),
16107 FREE_AND_NULL(str
);
16109 * Remove the duplicate.
16111 if (xmlSchemaItemListRemove(uses
, i
) == -1)
16118 * SPEC ct-props-correct
16119 * (5) "Two distinct attribute declarations in the
16120 * {attribute uses} must not have {type definition}s which
16121 * are or are derived from ID."
16123 if (WXS_ATTRUSE_TYPEDEF(use
) != NULL
) {
16124 if (xmlSchemaIsDerivedFromBuiltInType(
16125 WXS_ATTRUSE_TYPEDEF(use
), XML_SCHEMAS_ID
))
16128 xmlChar
*str
= NULL
;
16130 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
16131 XML_SCHEMAP_AG_PROPS_CORRECT
,
16132 NULL
, WXS_BASIC_CAST type
,
16133 "There must not exist more than one attribute "
16134 "declaration of type 'xs:ID' "
16135 "(or derived from 'xs:ID'). The %s violates this "
16137 xmlSchemaGetComponentDesignation(&str
, use
),
16139 FREE_AND_NULL(str
);
16140 if (xmlSchemaItemListRemove(uses
, i
) == -1)
16156 xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA
,
16157 xmlSchemaTypePtr typeB
)
16160 * TODO: This should implement component-identity
16163 if ((typeA
== NULL
) || (typeB
== NULL
))
16165 return (typeA
== typeB
);
16169 * xmlSchemaCheckCOSCTDerivedOK:
16170 * @ctxt: the schema parser context
16171 * @type: the to-be derived complex type definition
16172 * @baseType: the base complex type definition
16173 * @set: the given set
16175 * Schema Component Constraint:
16176 * Type Derivation OK (Complex) (cos-ct-derived-ok)
16178 * STATUS: completed
16180 * Returns 0 if the constraints are satisfied, or 1
16184 xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt
,
16185 xmlSchemaTypePtr type
,
16186 xmlSchemaTypePtr baseType
,
16189 int equal
= xmlSchemaAreEqualTypes(type
, baseType
);
16190 /* TODO: Error codes. */
16192 * SPEC "For a complex type definition (call it D, for derived)
16193 * to be validly derived from a type definition (call this
16194 * B, for base) given a subset of {extension, restriction}
16195 * all of the following must be true:"
16199 * SPEC (1) "If B and D are not the same type definition, then the
16200 * {derivation method} of D must not be in the subset."
16202 if (((set
& SUBSET_EXTENSION
) && (WXS_IS_EXTENSION(type
))) ||
16203 ((set
& SUBSET_RESTRICTION
) && (WXS_IS_RESTRICTION(type
))))
16207 * SPEC (2.1) "B and D must be the same type definition."
16212 * SPEC (2.2) "B must be D's {base type definition}."
16214 if (type
->baseType
== baseType
)
16217 * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
16220 if (WXS_IS_ANYTYPE(type
->baseType
))
16223 if (WXS_IS_COMPLEX(type
->baseType
)) {
16225 * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
16226 * must be validly derived from B given the subset as defined by this
16229 return (xmlSchemaCheckCOSCTDerivedOK(actxt
, type
->baseType
,
16233 * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
16234 * must be validly derived from B given the subset as defined in Type
16235 * Derivation OK (Simple) ($3.14.6).
16237 return (xmlSchemaCheckCOSSTDerivedOK(actxt
, type
->baseType
,
16243 * xmlSchemaCheckCOSDerivedOK:
16244 * @type: the derived simple type definition
16245 * @baseType: the base type definition
16248 * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
16250 * Checks whether @type can be validly derived from @baseType.
16252 * Returns 0 on success, an positive error code otherwise.
16255 xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt
,
16256 xmlSchemaTypePtr type
,
16257 xmlSchemaTypePtr baseType
,
16260 if (WXS_IS_SIMPLE(type
))
16261 return (xmlSchemaCheckCOSSTDerivedOK(actxt
, type
, baseType
, set
));
16263 return (xmlSchemaCheckCOSCTDerivedOK(actxt
, type
, baseType
, set
));
16267 * xmlSchemaCheckCOSCTExtends:
16268 * @ctxt: the schema parser context
16269 * @type: the complex type definition
16271 * (3.4.6) Constraints on Complex Type Definition Schema Components
16272 * Schema Component Constraint:
16273 * Derivation Valid (Extension) (cos-ct-extends)
16278 * (1.4.3.2.2.2) "Particle Valid (Extension)"
16280 * Returns 0 if the constraints are satisfied, a positive
16281 * error code if not and -1 if an internal error occurred.
16284 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt
,
16285 xmlSchemaTypePtr type
)
16287 xmlSchemaTypePtr base
= type
->baseType
;
16289 * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
16290 * temporarily only.
16293 * SPEC (1) "If the {base type definition} is a complex type definition,
16294 * then all of the following must be true:"
16296 if (WXS_IS_COMPLEX(base
)) {
16298 * SPEC (1.1) "The {final} of the {base type definition} must not
16299 * contain extension."
16301 if (base
->flags
& XML_SCHEMAS_TYPE_FINAL_EXTENSION
) {
16302 xmlSchemaPCustomErr(ctxt
,
16303 XML_SCHEMAP_COS_CT_EXTENDS_1_1
,
16304 WXS_BASIC_CAST type
, NULL
,
16305 "The 'final' of the base type definition "
16306 "contains 'extension'", NULL
);
16307 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1
);
16311 * ATTENTION: The constrains (1.2) and (1.3) are not applied,
16312 * since they are automatically satisfied through the
16313 * inheriting mechanism.
16314 * Note that even if redefining components, the inheriting mechanism
16319 * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
16321 * of the complex type definition itself, that is, for every attribute
16322 * use in the {attribute uses} of the {base type definition}, there
16323 * must be an attribute use in the {attribute uses} of the complex
16324 * type definition itself whose {attribute declaration} has the same
16325 * {name}, {target namespace} and {type definition} as its attribute
16328 if (base
->attrUses
!= NULL
) {
16330 xmlSchemaAttributeUsePtr use
, buse
;
16332 for (i
= 0; i
< (WXS_LIST_CAST base
->attrUses
)->nbItems
; i
++) {
16333 buse
= (WXS_LIST_CAST base
->attrUses
)->items
[i
];
16335 if (type
->attrUses
!= NULL
) {
16336 use
= (WXS_LIST_CAST type
->attrUses
)->items
[j
];
16337 for (j
= 0; j
< (WXS_LIST_CAST type
->attrUses
)->nbItems
; j
++)
16339 if ((WXS_ATTRUSE_DECL_NAME(use
) ==
16340 WXS_ATTRUSE_DECL_NAME(buse
)) &&
16341 (WXS_ATTRUSE_DECL_TNS(use
) ==
16342 WXS_ATTRUSE_DECL_TNS(buse
)) &&
16343 (WXS_ATTRUSE_TYPEDEF(use
) ==
16344 WXS_ATTRUSE_TYPEDEF(buse
))
16352 xmlChar
*str
= NULL
;
16354 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
16355 XML_SCHEMAP_COS_CT_EXTENDS_1_2
,
16356 NULL
, WXS_BASIC_CAST type
,
16358 * TODO: The report does not indicate that also the
16359 * type needs to be the same.
16361 "This type is missing a matching correspondent "
16362 "for its {base type}'s %s in its {attribute uses}",
16363 xmlSchemaGetComponentDesignation(&str
,
16371 * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
16372 * definition must also have one, and the base type definition's
16373 * {attribute wildcard}'s {namespace constraint} must be a subset
16374 * of the complex type definition's {attribute wildcard}'s {namespace
16375 * constraint}, as defined by Wildcard Subset ($3.10.6)."
16379 * MAYBE TODO: Enable if ever needed. But this will be needed only
16380 * if created the type via a schema construction API.
16382 if (base
->attributeWildcard
!= NULL
) {
16383 if (type
->attributeWildcard
== NULL
) {
16384 xmlChar
*str
= NULL
;
16386 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
16387 XML_SCHEMAP_COS_CT_EXTENDS_1_3
,
16389 "The base %s has an attribute wildcard, "
16390 "but this type is missing an attribute wildcard",
16391 xmlSchemaGetComponentDesignation(&str
, base
));
16394 } else if (xmlSchemaCheckCOSNSSubset(
16395 base
->attributeWildcard
, type
->attributeWildcard
))
16397 xmlChar
*str
= NULL
;
16399 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
16400 XML_SCHEMAP_COS_CT_EXTENDS_1_3
,
16402 "The attribute wildcard is not a valid "
16403 "superset of the one in the base %s",
16404 xmlSchemaGetComponentDesignation(&str
, base
));
16410 * SPEC (1.4) "One of the following must be true:"
16412 if ((type
->contentTypeDef
!= NULL
) &&
16413 (type
->contentTypeDef
== base
->contentTypeDef
)) {
16415 * SPEC (1.4.1) "The {content type} of the {base type definition}
16416 * and the {content type} of the complex type definition itself
16417 * must be the same simple type definition"
16420 } else if ((type
->contentType
== XML_SCHEMA_CONTENT_EMPTY
) &&
16421 (base
->contentType
== XML_SCHEMA_CONTENT_EMPTY
) ) {
16423 * SPEC (1.4.2) "The {content type} of both the {base type
16424 * definition} and the complex type definition itself must
16430 * SPEC (1.4.3) "All of the following must be true:"
16432 if (type
->subtypes
== NULL
) {
16434 * SPEC 1.4.3.1 The {content type} of the complex type
16435 * definition itself must specify a particle.
16437 xmlSchemaPCustomErr(ctxt
,
16438 XML_SCHEMAP_COS_CT_EXTENDS_1_1
,
16439 WXS_BASIC_CAST type
, NULL
,
16440 "The content type must specify a particle", NULL
);
16441 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1
);
16444 * SPEC (1.4.3.2) "One of the following must be true:"
16446 if (base
->contentType
== XML_SCHEMA_CONTENT_EMPTY
) {
16448 * SPEC (1.4.3.2.1) "The {content type} of the {base type
16449 * definition} must be empty.
16454 * SPEC (1.4.3.2.2) "All of the following must be true:"
16456 if ((type
->contentType
!= base
->contentType
) ||
16457 ((type
->contentType
!= XML_SCHEMA_CONTENT_MIXED
) &&
16458 (type
->contentType
!= XML_SCHEMA_CONTENT_ELEMENTS
))) {
16460 * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
16461 * or both must be element-only."
16463 xmlSchemaPCustomErr(ctxt
,
16464 XML_SCHEMAP_COS_CT_EXTENDS_1_1
,
16465 WXS_BASIC_CAST type
, NULL
,
16466 "The content type of both, the type and its base "
16467 "type, must either 'mixed' or 'element-only'", NULL
);
16468 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1
);
16471 * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
16472 * complex type definition must be a `valid extension`
16473 * of the {base type definition}'s particle, as defined
16474 * in Particle Valid (Extension) ($3.9.6)."
16476 * NOTE that we won't check "Particle Valid (Extension)",
16477 * since it is ensured by the derivation process in
16478 * xmlSchemaTypeFixup(). We need to implement this when heading
16479 * for a construction API
16480 * TODO: !! This is needed to be checked if redefining a type !!
16484 * URGENT TODO (1.5)
16489 * SPEC (2) "If the {base type definition} is a simple type definition,
16490 * then all of the following must be true:"
16492 if (type
->contentTypeDef
!= base
) {
16494 * SPEC (2.1) "The {content type} must be the same simple type
16497 xmlSchemaPCustomErr(ctxt
,
16498 XML_SCHEMAP_COS_CT_EXTENDS_1_1
,
16499 WXS_BASIC_CAST type
, NULL
,
16500 "The content type must be the simple base type", NULL
);
16501 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1
);
16503 if (base
->flags
& XML_SCHEMAS_TYPE_FINAL_EXTENSION
) {
16505 * SPEC (2.2) "The {final} of the {base type definition} must not
16506 * contain extension"
16507 * NOTE that this is the same as (1.1).
16509 xmlSchemaPCustomErr(ctxt
,
16510 XML_SCHEMAP_COS_CT_EXTENDS_1_1
,
16511 WXS_BASIC_CAST type
, NULL
,
16512 "The 'final' of the base type definition "
16513 "contains 'extension'", NULL
);
16514 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1
);
16521 * xmlSchemaCheckDerivationOKRestriction:
16522 * @ctxt: the schema parser context
16523 * @type: the complex type definition
16525 * (3.4.6) Constraints on Complex Type Definition Schema Components
16526 * Schema Component Constraint:
16527 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
16534 * In XML Schema 1.1 this will be:
16535 * Validation Rule: Checking complex type subsumption
16537 * Returns 0 if the constraints are satisfied, a positive
16538 * error code if not and -1 if an internal error occurred.
16541 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt
,
16542 xmlSchemaTypePtr type
)
16544 xmlSchemaTypePtr base
;
16547 * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
16548 * temporarily only.
16550 base
= type
->baseType
;
16551 if (! WXS_IS_COMPLEX(base
)) {
16552 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
16553 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1
,
16554 type
->node
, WXS_BASIC_CAST type
,
16555 "The base type must be a complex type", NULL
, NULL
);
16558 if (base
->flags
& XML_SCHEMAS_TYPE_FINAL_RESTRICTION
) {
16560 * SPEC (1) "The {base type definition} must be a complex type
16561 * definition whose {final} does not contain restriction."
16563 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
16564 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1
,
16565 type
->node
, WXS_BASIC_CAST type
,
16566 "The 'final' of the base type definition "
16567 "contains 'restriction'", NULL
, NULL
);
16568 return (ctxt
->err
);
16571 * SPEC (2), (3) and (4)
16572 * Those are handled in a separate function, since the
16573 * same constraints are needed for redefinition of
16574 * attribute groups as well.
16576 if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt
,
16577 XML_SCHEMA_ACTION_DERIVE
,
16578 WXS_BASIC_CAST type
, WXS_BASIC_CAST base
,
16579 type
->attrUses
, base
->attrUses
,
16580 type
->attributeWildcard
,
16581 base
->attributeWildcard
) == -1)
16586 * SPEC (5) "One of the following must be true:"
16588 if (base
->builtInType
== XML_SCHEMAS_ANYTYPE
) {
16590 * SPEC (5.1) "The {base type definition} must be the
16591 * `ur-type definition`."
16594 } else if ((type
->contentType
== XML_SCHEMA_CONTENT_SIMPLE
) ||
16595 (type
->contentType
== XML_SCHEMA_CONTENT_BASIC
)) {
16597 * SPEC (5.2.1) "The {content type} of the complex type definition
16598 * must be a simple type definition"
16600 * SPEC (5.2.2) "One of the following must be true:"
16602 if ((base
->contentType
== XML_SCHEMA_CONTENT_SIMPLE
) ||
16603 (base
->contentType
== XML_SCHEMA_CONTENT_BASIC
))
16607 * SPEC (5.2.2.1) "The {content type} of the {base type
16608 * definition} must be a simple type definition from which
16609 * the {content type} is validly derived given the empty
16610 * set as defined in Type Derivation OK (Simple) ($3.14.6)."
16612 * ATTENTION TODO: This seems not needed if the type implicitly
16613 * derived from the base type.
16616 err
= xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt
,
16617 type
->contentTypeDef
, base
->contentTypeDef
, 0);
16619 xmlChar
*strA
= NULL
, *strB
= NULL
;
16623 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
16624 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1
,
16625 NULL
, WXS_BASIC_CAST type
,
16626 "The {content type} %s is not validly derived from the "
16627 "base type's {content type} %s",
16628 xmlSchemaGetComponentDesignation(&strA
,
16629 type
->contentTypeDef
),
16630 xmlSchemaGetComponentDesignation(&strB
,
16631 base
->contentTypeDef
));
16632 FREE_AND_NULL(strA
);
16633 FREE_AND_NULL(strB
);
16636 } else if ((base
->contentType
== XML_SCHEMA_CONTENT_MIXED
) &&
16637 (xmlSchemaIsParticleEmptiable(
16638 (xmlSchemaParticlePtr
) base
->subtypes
))) {
16640 * SPEC (5.2.2.2) "The {base type definition} must be mixed
16641 * and have a particle which is `emptiable` as defined in
16642 * Particle Emptiable ($3.9.6)."
16646 xmlSchemaPCustomErr(ctxt
,
16647 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1
,
16648 WXS_BASIC_CAST type
, NULL
,
16649 "The content type of the base type must be either "
16650 "a simple type or 'mixed' and an emptiable particle", NULL
);
16651 return (ctxt
->err
);
16653 } else if (type
->contentType
== XML_SCHEMA_CONTENT_EMPTY
) {
16655 * SPEC (5.3.1) "The {content type} of the complex type itself must
16658 if (base
->contentType
== XML_SCHEMA_CONTENT_EMPTY
) {
16660 * SPEC (5.3.2.1) "The {content type} of the {base type
16661 * definition} must also be empty."
16664 } else if (((base
->contentType
== XML_SCHEMA_CONTENT_ELEMENTS
) ||
16665 (base
->contentType
== XML_SCHEMA_CONTENT_MIXED
)) &&
16666 xmlSchemaIsParticleEmptiable(
16667 (xmlSchemaParticlePtr
) base
->subtypes
)) {
16669 * SPEC (5.3.2.2) "The {content type} of the {base type
16670 * definition} must be elementOnly or mixed and have a particle
16671 * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
16675 xmlSchemaPCustomErr(ctxt
,
16676 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1
,
16677 WXS_BASIC_CAST type
, NULL
,
16678 "The content type of the base type must be either "
16679 "empty or 'mixed' (or 'elements-only') and an emptiable "
16681 return (ctxt
->err
);
16683 } else if ((type
->contentType
== XML_SCHEMA_CONTENT_ELEMENTS
) ||
16684 WXS_HAS_MIXED_CONTENT(type
)) {
16686 * SPEC (5.4.1.1) "The {content type} of the complex type definition
16687 * itself must be element-only"
16689 if (WXS_HAS_MIXED_CONTENT(type
) && (! WXS_HAS_MIXED_CONTENT(base
))) {
16691 * SPEC (5.4.1.2) "The {content type} of the complex type
16692 * definition itself and of the {base type definition} must be
16695 xmlSchemaPCustomErr(ctxt
,
16696 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1
,
16697 WXS_BASIC_CAST type
, NULL
,
16698 "If the content type is 'mixed', then the content type of the "
16699 "base type must also be 'mixed'", NULL
);
16700 return (ctxt
->err
);
16703 * SPEC (5.4.2) "The particle of the complex type definition itself
16704 * must be a `valid restriction` of the particle of the {content
16705 * type} of the {base type definition} as defined in Particle Valid
16706 * (Restriction) ($3.9.6).
16708 * URGENT TODO: (5.4.2)
16711 xmlSchemaPCustomErr(ctxt
,
16712 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1
,
16713 WXS_BASIC_CAST type
, NULL
,
16714 "The type is not a valid restriction of its base type", NULL
);
16715 return (ctxt
->err
);
16721 * xmlSchemaCheckCTComponent:
16722 * @ctxt: the schema parser context
16723 * @type: the complex type definition
16725 * (3.4.6) Constraints on Complex Type Definition Schema Components
16727 * Returns 0 if the constraints are satisfied, a positive
16728 * error code if not and -1 if an internal error occurred.
16731 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt
,
16732 xmlSchemaTypePtr type
)
16736 * Complex Type Definition Properties Correct
16738 ret
= xmlSchemaCheckCTPropsCorrect(ctxt
, type
);
16741 if (WXS_IS_EXTENSION(type
))
16742 ret
= xmlSchemaCheckCOSCTExtends(ctxt
, type
);
16744 ret
= xmlSchemaCheckDerivationOKRestriction(ctxt
, type
);
16749 * xmlSchemaCheckSRCCT:
16750 * @ctxt: the schema parser context
16751 * @type: the complex type definition
16753 * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
16754 * Schema Representation Constraint:
16755 * Complex Type Definition Representation OK (src-ct)
16757 * Returns 0 if the constraints are satisfied, a positive
16758 * error code if not and -1 if an internal error occurred.
16761 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt
,
16762 xmlSchemaTypePtr type
)
16764 xmlSchemaTypePtr base
;
16768 * TODO: Adjust the error codes here, as I used
16769 * XML_SCHEMAP_SRC_CT_1 only yet.
16771 base
= type
->baseType
;
16772 if (! WXS_HAS_SIMPLE_CONTENT(type
)) {
16774 * 1 If the <complexContent> alternative is chosen, the type definition
16775 * `resolved` to by the `actual value` of the base [attribute]
16776 * must be a complex type definition;
16778 if (! WXS_IS_COMPLEX(base
)) {
16779 xmlChar
*str
= NULL
;
16780 xmlSchemaPCustomErr(ctxt
,
16781 XML_SCHEMAP_SRC_CT_1
,
16782 WXS_BASIC_CAST type
, type
->node
,
16783 "If using <complexContent>, the base type is expected to be "
16784 "a complex type. The base type '%s' is a simple type",
16785 xmlSchemaFormatQName(&str
, base
->targetNamespace
,
16788 return (XML_SCHEMAP_SRC_CT_1
);
16793 * 2 If the <simpleContent> alternative is chosen, all of the
16794 * following must be true:
16795 * 2.1 The type definition `resolved` to by the `actual value` of the
16796 * base [attribute] must be one of the following:
16798 if (WXS_IS_SIMPLE(base
)) {
16799 if (WXS_IS_EXTENSION(type
) == 0) {
16800 xmlChar
*str
= NULL
;
16802 * 2.1.3 only if the <extension> alternative is also
16803 * chosen, a simple type definition.
16805 /* TODO: Change error code to ..._SRC_CT_2_1_3. */
16806 xmlSchemaPCustomErr(ctxt
,
16807 XML_SCHEMAP_SRC_CT_1
,
16808 WXS_BASIC_CAST type
, NULL
,
16809 "If using <simpleContent> and <restriction>, the base "
16810 "type must be a complex type. The base type '%s' is "
16812 xmlSchemaFormatQName(&str
, base
->targetNamespace
,
16815 return (XML_SCHEMAP_SRC_CT_1
);
16818 /* Base type is a complex type. */
16819 if ((base
->contentType
== XML_SCHEMA_CONTENT_SIMPLE
) ||
16820 (base
->contentType
== XML_SCHEMA_CONTENT_BASIC
)) {
16822 * 2.1.1 a complex type definition whose {content type} is a
16823 * simple type definition;
16826 if (base
->contentTypeDef
== NULL
) {
16827 xmlSchemaPCustomErr(ctxt
, XML_SCHEMAP_INTERNAL
,
16828 WXS_BASIC_CAST type
, NULL
,
16829 "Internal error: xmlSchemaCheckSRCCT, "
16830 "'%s', base type has no content type",
16834 } else if ((base
->contentType
== XML_SCHEMA_CONTENT_MIXED
) &&
16835 (WXS_IS_RESTRICTION(type
))) {
16838 * 2.1.2 only if the <restriction> alternative is also
16839 * chosen, a complex type definition whose {content type}
16840 * is mixed and a particle emptiable.
16842 if (! xmlSchemaIsParticleEmptiable(
16843 (xmlSchemaParticlePtr
) base
->subtypes
)) {
16844 ret
= XML_SCHEMAP_SRC_CT_1
;
16847 * Attention: at this point the <simpleType> child is in
16848 * ->contentTypeDef (put there during parsing).
16850 if (type
->contentTypeDef
== NULL
) {
16851 xmlChar
*str
= NULL
;
16853 * 2.2 If clause 2.1.2 above is satisfied, then there
16854 * must be a <simpleType> among the [children] of
16857 /* TODO: Change error code to ..._SRC_CT_2_2. */
16858 xmlSchemaPCustomErr(ctxt
,
16859 XML_SCHEMAP_SRC_CT_1
,
16860 WXS_BASIC_CAST type
, NULL
,
16861 "A <simpleType> is expected among the children "
16862 "of <restriction>, if <simpleContent> is used and "
16863 "the base type '%s' is a complex type",
16864 xmlSchemaFormatQName(&str
, base
->targetNamespace
,
16867 return (XML_SCHEMAP_SRC_CT_1
);
16870 ret
= XML_SCHEMAP_SRC_CT_1
;
16874 xmlChar
*str
= NULL
;
16875 if (WXS_IS_RESTRICTION(type
)) {
16876 xmlSchemaPCustomErr(ctxt
,
16877 XML_SCHEMAP_SRC_CT_1
,
16878 WXS_BASIC_CAST type
, NULL
,
16879 "If <simpleContent> and <restriction> is used, the "
16880 "base type must be a simple type or a complex type with "
16881 "mixed content and particle emptiable. The base type "
16882 "'%s' is none of those",
16883 xmlSchemaFormatQName(&str
, base
->targetNamespace
,
16886 xmlSchemaPCustomErr(ctxt
,
16887 XML_SCHEMAP_SRC_CT_1
,
16888 WXS_BASIC_CAST type
, NULL
,
16889 "If <simpleContent> and <extension> is used, the "
16890 "base type must be a simple type. The base type '%s' "
16891 "is a complex type",
16892 xmlSchemaFormatQName(&str
, base
->targetNamespace
,
16899 * SPEC (3) "The corresponding complex type definition component must
16900 * satisfy the conditions set out in Constraints on Complex Type
16901 * Definition Schema Components ($3.4.6);"
16902 * NOTE (3) will be done in xmlSchemaTypeFixup().
16905 * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
16906 * above for {attribute wildcard} is satisfied, the intensional
16907 * intersection must be expressible, as defined in Attribute Wildcard
16908 * Intersection ($3.10.6).
16909 * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
16914 #ifdef ENABLE_PARTICLE_RESTRICTION
16916 * xmlSchemaCheckParticleRangeOK:
16917 * @ctxt: the schema parser context
16918 * @type: the complex type definition
16920 * (3.9.6) Constraints on Particle Schema Components
16921 * Schema Component Constraint:
16922 * Occurrence Range OK (range-ok)
16926 * Returns 0 if the constraints are satisfied, a positive
16927 * error code if not and -1 if an internal error occurred.
16930 xmlSchemaCheckParticleRangeOK(int rmin
, int rmax
,
16931 int bmin
, int bmax
)
16935 if ((bmax
!= UNBOUNDED
) &&
16942 * xmlSchemaCheckRCaseNameAndTypeOK:
16943 * @ctxt: the schema parser context
16944 * @r: the restricting element declaration particle
16945 * @b: the base element declaration particle
16947 * (3.9.6) Constraints on Particle Schema Components
16948 * Schema Component Constraint:
16949 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
16950 * (rcase-NameAndTypeOK)
16956 * Returns 0 if the constraints are satisfied, a positive
16957 * error code if not and -1 if an internal error occurred.
16960 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt
,
16961 xmlSchemaParticlePtr r
,
16962 xmlSchemaParticlePtr b
)
16964 xmlSchemaElementPtr elemR
, elemB
;
16966 /* TODO: Error codes (rcase-NameAndTypeOK). */
16967 elemR
= (xmlSchemaElementPtr
) r
->children
;
16968 elemB
= (xmlSchemaElementPtr
) b
->children
;
16970 * SPEC (1) "The declarations' {name}s and {target namespace}s are
16973 if ((elemR
!= elemB
) &&
16974 ((! xmlStrEqual(elemR
->name
, elemB
->name
)) ||
16975 (! xmlStrEqual(elemR
->targetNamespace
, elemB
->targetNamespace
))))
16978 * SPEC (2) "R's occurrence range is a valid restriction of B's
16979 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16981 if (xmlSchemaCheckParticleRangeOK(r
->minOccurs
, r
->maxOccurs
,
16982 b
->minOccurs
, b
->maxOccurs
) != 0)
16985 * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
16986 * {scope} are global."
16988 if (elemR
== elemB
)
16991 * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
16993 if (((elemB
->flags
& XML_SCHEMAS_ELEM_NILLABLE
) == 0) &&
16994 (elemR
->flags
& XML_SCHEMAS_ELEM_NILLABLE
))
16997 * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
16998 * or is not fixed, or R's declaration's {value constraint} is fixed
16999 * with the same value."
17001 if ((elemB
->value
!= NULL
) && (elemB
->flags
& XML_SCHEMAS_ELEM_FIXED
) &&
17002 ((elemR
->value
== NULL
) ||
17003 ((elemR
->flags
& XML_SCHEMAS_ELEM_FIXED
) == 0) ||
17004 /* TODO: Equality of the initial value or normalized or canonical? */
17005 (! xmlStrEqual(elemR
->value
, elemB
->value
))))
17008 * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
17009 * definitions} is a subset of B's declaration's {identity-constraint
17010 * definitions}, if any."
17012 if (elemB
->idcs
!= NULL
) {
17016 * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
17017 * superset of B's declaration's {disallowed substitutions}."
17019 if (((elemB
->flags
& XML_SCHEMAS_ELEM_BLOCK_EXTENSION
) &&
17020 ((elemR
->flags
& XML_SCHEMAS_ELEM_BLOCK_EXTENSION
) == 0)) ||
17021 ((elemB
->flags
& XML_SCHEMAS_ELEM_BLOCK_RESTRICTION
) &&
17022 ((elemR
->flags
& XML_SCHEMAS_ELEM_BLOCK_RESTRICTION
) == 0)) ||
17023 ((elemB
->flags
& XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION
) &&
17024 ((elemR
->flags
& XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION
) == 0)))
17027 * SPEC (3.2.5) "R's {type definition} is validly derived given
17028 * {extension, list, union} from B's {type definition}"
17030 * BADSPEC TODO: What's the point of adding "list" and "union" to the
17031 * set, if the corresponding constraints handle "restriction" and
17032 * "extension" only?
17038 set
|= SUBSET_EXTENSION
;
17039 set
|= SUBSET_LIST
;
17040 set
|= SUBSET_UNION
;
17041 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt
, elemR
->subtypes
,
17042 elemB
->subtypes
, set
) != 0)
17049 * xmlSchemaCheckRCaseNSCompat:
17050 * @ctxt: the schema parser context
17051 * @r: the restricting element declaration particle
17052 * @b: the base wildcard particle
17054 * (3.9.6) Constraints on Particle Schema Components
17055 * Schema Component Constraint:
17056 * Particle Derivation OK (Elt:Any -- NSCompat)
17061 * Returns 0 if the constraints are satisfied, a positive
17062 * error code if not and -1 if an internal error occurred.
17065 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt
,
17066 xmlSchemaParticlePtr r
,
17067 xmlSchemaParticlePtr b
)
17069 /* TODO:Error codes (rcase-NSCompat). */
17071 * SPEC "For an element declaration particle to be a `valid restriction`
17072 * of a wildcard particle all of the following must be true:"
17074 * SPEC (1) "The element declaration's {target namespace} is `valid`
17075 * with respect to the wildcard's {namespace constraint} as defined by
17076 * Wildcard allows Namespace Name ($3.10.4)."
17078 if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr
) b
->children
,
17079 ((xmlSchemaElementPtr
) r
->children
)->targetNamespace
) != 0)
17082 * SPEC (2) "R's occurrence range is a valid restriction of B's
17083 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17085 if (xmlSchemaCheckParticleRangeOK(r
->minOccurs
, r
->maxOccurs
,
17086 b
->minOccurs
, b
->maxOccurs
) != 0)
17093 * xmlSchemaCheckRCaseRecurseAsIfGroup:
17094 * @ctxt: the schema parser context
17095 * @r: the restricting element declaration particle
17096 * @b: the base model group particle
17098 * (3.9.6) Constraints on Particle Schema Components
17099 * Schema Component Constraint:
17100 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
17101 * (rcase-RecurseAsIfGroup)
17105 * Returns 0 if the constraints are satisfied, a positive
17106 * error code if not and -1 if an internal error occurred.
17109 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt
,
17110 xmlSchemaParticlePtr r
,
17111 xmlSchemaParticlePtr b
)
17113 /* TODO: Error codes (rcase-RecurseAsIfGroup). */
17119 * xmlSchemaCheckRCaseNSSubset:
17120 * @ctxt: the schema parser context
17121 * @r: the restricting wildcard particle
17122 * @b: the base wildcard particle
17124 * (3.9.6) Constraints on Particle Schema Components
17125 * Schema Component Constraint:
17126 * Particle Derivation OK (Any:Any -- NSSubset)
17131 * Returns 0 if the constraints are satisfied, a positive
17132 * error code if not and -1 if an internal error occurred.
17135 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt
,
17136 xmlSchemaParticlePtr r
,
17137 xmlSchemaParticlePtr b
,
17140 /* TODO: Error codes (rcase-NSSubset). */
17142 * SPEC (1) "R's occurrence range is a valid restriction of B's
17143 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17145 if (xmlSchemaCheckParticleRangeOK(r
->minOccurs
, r
->maxOccurs
,
17146 b
->minOccurs
, b
->maxOccurs
))
17149 * SPEC (2) "R's {namespace constraint} must be an intensional subset
17150 * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
17152 if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr
) r
->children
,
17153 (xmlSchemaWildcardPtr
) b
->children
))
17156 * SPEC (3) "Unless B is the content model wildcard of the `ur-type
17157 * definition`, R's {process contents} must be identical to or stronger
17158 * than B's {process contents}, where strict is stronger than lax is
17159 * stronger than skip."
17161 if (! isAnyTypeBase
) {
17162 if ( ((xmlSchemaWildcardPtr
) r
->children
)->processContents
<
17163 ((xmlSchemaWildcardPtr
) b
->children
)->processContents
)
17171 * xmlSchemaCheckCOSParticleRestrict:
17172 * @ctxt: the schema parser context
17173 * @type: the complex type definition
17175 * (3.9.6) Constraints on Particle Schema Components
17176 * Schema Component Constraint:
17177 * Particle Valid (Restriction) (cos-particle-restrict)
17181 * Returns 0 if the constraints are satisfied, a positive
17182 * error code if not and -1 if an internal error occurred.
17185 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt
,
17186 xmlSchemaParticlePtr r
,
17187 xmlSchemaParticlePtr b
)
17191 /*part = WXS_TYPE_PARTICLE(type);
17192 basePart = WXS_TYPE_PARTICLE(base);
17198 * SPEC (1) "They are the same particle."
17209 * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
17210 * @ctxt: the schema parser context
17211 * @r: the model group particle
17212 * @b: the base wildcard particle
17214 * (3.9.6) Constraints on Particle Schema Components
17215 * Schema Component Constraint:
17216 * Particle Derivation OK (All/Choice/Sequence:Any --
17217 * NSRecurseCheckCardinality)
17218 * (rcase-NSRecurseCheckCardinality)
17220 * STATUS: TODO: subst-groups
17222 * Returns 0 if the constraints are satisfied, a positive
17223 * error code if not and -1 if an internal error occurred.
17226 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt
,
17227 xmlSchemaParticlePtr r
,
17228 xmlSchemaParticlePtr b
)
17230 xmlSchemaParticlePtr part
;
17231 /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
17232 if ((r
->children
== NULL
) || (r
->children
->children
== NULL
))
17235 * SPEC "For a group particle to be a `valid restriction` of a
17236 * wildcard particle..."
17238 * SPEC (1) "Every member of the {particles} of the group is a `valid
17239 * restriction` of the wildcard as defined by
17240 * Particle Valid (Restriction) ($3.9.6)."
17242 part
= (xmlSchemaParticlePtr
) r
->children
->children
;
17244 if (xmlSchemaCheckCOSParticleRestrict(ctxt
, part
, b
))
17246 part
= (xmlSchemaParticlePtr
) part
->next
;
17247 } while (part
!= NULL
);
17249 * SPEC (2) "The effective total range of the group [...] is a
17250 * valid restriction of B's occurrence range as defined by
17251 * Occurrence Range OK ($3.9.6)."
17253 if (xmlSchemaCheckParticleRangeOK(
17254 xmlSchemaGetParticleTotalRangeMin(r
),
17255 xmlSchemaGetParticleTotalRangeMax(r
),
17256 b
->minOccurs
, b
->maxOccurs
) != 0)
17263 * xmlSchemaCheckRCaseRecurse:
17264 * @ctxt: the schema parser context
17265 * @r: the <all> or <sequence> model group particle
17266 * @b: the base <all> or <sequence> model group particle
17268 * (3.9.6) Constraints on Particle Schema Components
17269 * Schema Component Constraint:
17270 * Particle Derivation OK (All:All,Sequence:Sequence --
17275 * TODO: subst-groups
17277 * Returns 0 if the constraints are satisfied, a positive
17278 * error code if not and -1 if an internal error occurred.
17281 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt
,
17282 xmlSchemaParticlePtr r
,
17283 xmlSchemaParticlePtr b
)
17285 /* xmlSchemaParticlePtr part; */
17286 /* TODO: Error codes (rcase-Recurse). */
17287 if ((r
->children
== NULL
) || (b
->children
== NULL
) ||
17288 (r
->children
->type
!= b
->children
->type
))
17291 * SPEC "For an all or sequence group particle to be a `valid
17292 * restriction` of another group particle with the same {compositor}..."
17294 * SPEC (1) "R's occurrence range is a valid restriction of B's
17295 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17297 if (xmlSchemaCheckParticleRangeOK(r
->minOccurs
, r
->maxOccurs
,
17298 b
->minOccurs
, b
->maxOccurs
))
17307 #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
17308 xmlSchemaPCustomErrExt(pctxt, \
17309 XML_SCHEMAP_INVALID_FACET_VALUE, \
17310 WXS_BASIC_CAST fac1, fac1->node, \
17311 "It is an error for both '%s' and '%s' to be specified on the "\
17312 "same type definition", \
17313 BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
17314 BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
17316 #define FACET_RESTR_ERR(fac1, msg) \
17317 xmlSchemaPCustomErr(pctxt, \
17318 XML_SCHEMAP_INVALID_FACET_VALUE, \
17319 WXS_BASIC_CAST fac1, fac1->node, \
17322 #define FACET_RESTR_FIXED_ERR(fac) \
17323 xmlSchemaPCustomErr(pctxt, \
17324 XML_SCHEMAP_INVALID_FACET_VALUE, \
17325 WXS_BASIC_CAST fac, fac->node, \
17326 "The base type's facet is 'fixed', thus the value must not " \
17330 xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt
,
17331 xmlSchemaFacetPtr facet1
,
17332 xmlSchemaFacetPtr facet2
,
17337 xmlChar
*msg
= NULL
;
17339 msg
= xmlStrdup(BAD_CAST
"'");
17340 msg
= xmlStrcat(msg
, xmlSchemaFacetTypeToString(facet1
->type
));
17341 msg
= xmlStrcat(msg
, BAD_CAST
"' has to be");
17342 if (lessGreater
== 0)
17343 msg
= xmlStrcat(msg
, BAD_CAST
" equal to");
17344 if (lessGreater
== 1)
17345 msg
= xmlStrcat(msg
, BAD_CAST
" greater than");
17347 msg
= xmlStrcat(msg
, BAD_CAST
" less than");
17350 msg
= xmlStrcat(msg
, BAD_CAST
" or equal to");
17351 msg
= xmlStrcat(msg
, BAD_CAST
" '");
17352 msg
= xmlStrcat(msg
, xmlSchemaFacetTypeToString(facet2
->type
));
17354 msg
= xmlStrcat(msg
, BAD_CAST
"' of the base type");
17356 msg
= xmlStrcat(msg
, BAD_CAST
"'");
17358 xmlSchemaPCustomErr(pctxt
,
17359 XML_SCHEMAP_INVALID_FACET_VALUE
,
17360 WXS_BASIC_CAST facet1
, NULL
,
17361 (const char *) msg
, NULL
);
17368 * xmlSchemaDeriveAndValidateFacets:
17370 * Schema Component Constraint: Simple Type Restriction (Facets)
17371 * (st-restrict-facets)
17374 xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt
,
17375 xmlSchemaTypePtr type
)
17377 xmlSchemaTypePtr base
= type
->baseType
;
17378 xmlSchemaFacetLinkPtr link
, cur
, last
= NULL
;
17379 xmlSchemaFacetPtr facet
, bfacet
,
17380 flength
= NULL
, ftotdig
= NULL
, ffracdig
= NULL
,
17381 fmaxlen
= NULL
, fminlen
= NULL
, /* facets of the current type */
17382 fmininc
= NULL
, fmaxinc
= NULL
,
17383 fminexc
= NULL
, fmaxexc
= NULL
,
17384 bflength
= NULL
, bftotdig
= NULL
, bffracdig
= NULL
,
17385 bfmaxlen
= NULL
, bfminlen
= NULL
, /* facets of the base type */
17386 bfmininc
= NULL
, bfmaxinc
= NULL
,
17387 bfminexc
= NULL
, bfmaxexc
= NULL
;
17388 int res
; /* err = 0, fixedErr; */
17391 * SPEC st-restrict-facets 1:
17392 * "The {variety} of R is the same as that of B."
17395 * SPEC st-restrict-facets 2:
17396 * "If {variety} is atomic, the {primitive type definition}
17397 * of R is the same as that of B."
17399 * NOTE: we leave 1 & 2 out for now, since this will be
17400 * satisfied by the derivation process.
17401 * CONSTRUCTION TODO: Maybe needed if using a construction API.
17404 * SPEC st-restrict-facets 3:
17405 * "The {facets} of R are the union of S and the {facets}
17406 * of B, eliminating duplicates. To eliminate duplicates,
17407 * when a facet of the same kind occurs in both S and the
17408 * {facets} of B, the one in the {facets} of B is not
17409 * included, with the exception of enumeration and pattern
17410 * facets, for which multiple occurrences with distinct values
17414 if ((type
->facetSet
== NULL
) && (base
->facetSet
== NULL
))
17417 last
= type
->facetSet
;
17419 while (last
->next
!= NULL
)
17422 for (cur
= type
->facetSet
; cur
!= NULL
; cur
= cur
->next
) {
17423 facet
= cur
->facet
;
17424 switch (facet
->type
) {
17425 case XML_SCHEMA_FACET_LENGTH
:
17426 flength
= facet
; break;
17427 case XML_SCHEMA_FACET_MINLENGTH
:
17428 fminlen
= facet
; break;
17429 case XML_SCHEMA_FACET_MININCLUSIVE
:
17430 fmininc
= facet
; break;
17431 case XML_SCHEMA_FACET_MINEXCLUSIVE
:
17432 fminexc
= facet
; break;
17433 case XML_SCHEMA_FACET_MAXLENGTH
:
17434 fmaxlen
= facet
; break;
17435 case XML_SCHEMA_FACET_MAXINCLUSIVE
:
17436 fmaxinc
= facet
; break;
17437 case XML_SCHEMA_FACET_MAXEXCLUSIVE
:
17438 fmaxexc
= facet
; break;
17439 case XML_SCHEMA_FACET_TOTALDIGITS
:
17440 ftotdig
= facet
; break;
17441 case XML_SCHEMA_FACET_FRACTIONDIGITS
:
17442 ffracdig
= facet
; break;
17447 for (cur
= base
->facetSet
; cur
!= NULL
; cur
= cur
->next
) {
17448 facet
= cur
->facet
;
17449 switch (facet
->type
) {
17450 case XML_SCHEMA_FACET_LENGTH
:
17451 bflength
= facet
; break;
17452 case XML_SCHEMA_FACET_MINLENGTH
:
17453 bfminlen
= facet
; break;
17454 case XML_SCHEMA_FACET_MININCLUSIVE
:
17455 bfmininc
= facet
; break;
17456 case XML_SCHEMA_FACET_MINEXCLUSIVE
:
17457 bfminexc
= facet
; break;
17458 case XML_SCHEMA_FACET_MAXLENGTH
:
17459 bfmaxlen
= facet
; break;
17460 case XML_SCHEMA_FACET_MAXINCLUSIVE
:
17461 bfmaxinc
= facet
; break;
17462 case XML_SCHEMA_FACET_MAXEXCLUSIVE
:
17463 bfmaxexc
= facet
; break;
17464 case XML_SCHEMA_FACET_TOTALDIGITS
:
17465 bftotdig
= facet
; break;
17466 case XML_SCHEMA_FACET_FRACTIONDIGITS
:
17467 bffracdig
= facet
; break;
17473 * length and minLength or maxLength (2.2) + (3.2)
17475 if (flength
&& (fminlen
|| fmaxlen
)) {
17476 FACET_RESTR_ERR(flength
, "It is an error for both 'length' and "
17477 "either of 'minLength' or 'maxLength' to be specified on "
17478 "the same type definition")
17481 * Mutual exclusions in the same derivation step.
17483 if ((fmaxinc
) && (fmaxexc
)) {
17485 * SCC "maxInclusive and maxExclusive"
17487 FACET_RESTR_MUTUAL_ERR(fmaxinc
, fmaxexc
)
17489 if ((fmininc
) && (fminexc
)) {
17491 * SCC "minInclusive and minExclusive"
17493 FACET_RESTR_MUTUAL_ERR(fmininc
, fminexc
)
17496 if (flength
&& bflength
) {
17498 * SCC "length valid restriction"
17499 * The values have to be equal.
17501 res
= xmlSchemaCompareValues(flength
->val
, bflength
->val
);
17503 goto internal_error
;
17505 xmlSchemaDeriveFacetErr(pctxt
, flength
, bflength
, 0, 0, 1);
17506 if ((res
!= 0) && (bflength
->fixed
)) {
17507 FACET_RESTR_FIXED_ERR(flength
)
17511 if (fminlen
&& bfminlen
) {
17513 * SCC "minLength valid restriction"
17514 * minLength >= BASE minLength
17516 res
= xmlSchemaCompareValues(fminlen
->val
, bfminlen
->val
);
17518 goto internal_error
;
17520 xmlSchemaDeriveFacetErr(pctxt
, fminlen
, bfminlen
, 1, 1, 1);
17521 if ((res
!= 0) && (bfminlen
->fixed
)) {
17522 FACET_RESTR_FIXED_ERR(fminlen
)
17525 if (fmaxlen
&& bfmaxlen
) {
17527 * SCC "maxLength valid restriction"
17528 * maxLength <= BASE minLength
17530 res
= xmlSchemaCompareValues(fmaxlen
->val
, bfmaxlen
->val
);
17532 goto internal_error
;
17534 xmlSchemaDeriveFacetErr(pctxt
, fmaxlen
, bfmaxlen
, -1, 1, 1);
17535 if ((res
!= 0) && (bfmaxlen
->fixed
)) {
17536 FACET_RESTR_FIXED_ERR(fmaxlen
)
17540 * SCC "length and minLength or maxLength"
17543 flength
= bflength
;
17546 fminlen
= bfminlen
;
17548 /* (1.1) length >= minLength */
17549 res
= xmlSchemaCompareValues(flength
->val
, fminlen
->val
);
17551 goto internal_error
;
17553 xmlSchemaDeriveFacetErr(pctxt
, flength
, fminlen
, 1, 1, 0);
17556 fmaxlen
= bfmaxlen
;
17558 /* (2.1) length <= maxLength */
17559 res
= xmlSchemaCompareValues(flength
->val
, fmaxlen
->val
);
17561 goto internal_error
;
17563 xmlSchemaDeriveFacetErr(pctxt
, flength
, fmaxlen
, -1, 1, 0);
17571 /* SCC "maxInclusive >= minInclusive" */
17572 res
= xmlSchemaCompareValues(fmaxinc
->val
, fmininc
->val
);
17574 goto internal_error
;
17576 xmlSchemaDeriveFacetErr(pctxt
, fmaxinc
, fmininc
, 1, 1, 0);
17580 * SCC "maxInclusive valid restriction"
17583 /* maxInclusive <= BASE maxInclusive */
17584 res
= xmlSchemaCompareValues(fmaxinc
->val
, bfmaxinc
->val
);
17586 goto internal_error
;
17588 xmlSchemaDeriveFacetErr(pctxt
, fmaxinc
, bfmaxinc
, -1, 1, 1);
17589 if ((res
!= 0) && (bfmaxinc
->fixed
)) {
17590 FACET_RESTR_FIXED_ERR(fmaxinc
)
17594 /* maxInclusive < BASE maxExclusive */
17595 res
= xmlSchemaCompareValues(fmaxinc
->val
, bfmaxexc
->val
);
17597 goto internal_error
;
17599 xmlSchemaDeriveFacetErr(pctxt
, fmaxinc
, bfmaxexc
, -1, 0, 1);
17603 /* maxInclusive >= BASE minInclusive */
17604 res
= xmlSchemaCompareValues(fmaxinc
->val
, bfmininc
->val
);
17606 goto internal_error
;
17608 xmlSchemaDeriveFacetErr(pctxt
, fmaxinc
, bfmininc
, 1, 1, 1);
17612 /* maxInclusive > BASE minExclusive */
17613 res
= xmlSchemaCompareValues(fmaxinc
->val
, bfminexc
->val
);
17615 goto internal_error
;
17617 xmlSchemaDeriveFacetErr(pctxt
, fmaxinc
, bfminexc
, 1, 0, 1);
17623 * "maxExclusive >= minExclusive"
17626 res
= xmlSchemaCompareValues(fmaxexc
->val
, fminexc
->val
);
17628 goto internal_error
;
17630 xmlSchemaDeriveFacetErr(pctxt
, fmaxexc
, fminexc
, 1, 1, 0);
17634 * "maxExclusive valid restriction"
17637 /* maxExclusive <= BASE maxExclusive */
17638 res
= xmlSchemaCompareValues(fmaxexc
->val
, bfmaxexc
->val
);
17640 goto internal_error
;
17642 xmlSchemaDeriveFacetErr(pctxt
, fmaxexc
, bfmaxexc
, -1, 1, 1);
17644 if ((res
!= 0) && (bfmaxexc
->fixed
)) {
17645 FACET_RESTR_FIXED_ERR(fmaxexc
)
17649 /* maxExclusive <= BASE maxInclusive */
17650 res
= xmlSchemaCompareValues(fmaxexc
->val
, bfmaxinc
->val
);
17652 goto internal_error
;
17654 xmlSchemaDeriveFacetErr(pctxt
, fmaxexc
, bfmaxinc
, -1, 1, 1);
17658 /* maxExclusive > BASE minInclusive */
17659 res
= xmlSchemaCompareValues(fmaxexc
->val
, bfmininc
->val
);
17661 goto internal_error
;
17663 xmlSchemaDeriveFacetErr(pctxt
, fmaxexc
, bfmininc
, 1, 0, 1);
17667 /* maxExclusive > BASE minExclusive */
17668 res
= xmlSchemaCompareValues(fmaxexc
->val
, bfminexc
->val
);
17670 goto internal_error
;
17672 xmlSchemaDeriveFacetErr(pctxt
, fmaxexc
, bfminexc
, 1, 0, 1);
17678 * "minExclusive < maxInclusive"
17681 res
= xmlSchemaCompareValues(fminexc
->val
, fmaxinc
->val
);
17683 goto internal_error
;
17685 xmlSchemaDeriveFacetErr(pctxt
, fminexc
, fmaxinc
, -1, 0, 0);
17689 * "minExclusive valid restriction"
17692 /* minExclusive >= BASE minExclusive */
17693 res
= xmlSchemaCompareValues(fminexc
->val
, bfminexc
->val
);
17695 goto internal_error
;
17697 xmlSchemaDeriveFacetErr(pctxt
, fminexc
, bfminexc
, 1, 1, 1);
17699 if ((res
!= 0) && (bfminexc
->fixed
)) {
17700 FACET_RESTR_FIXED_ERR(fminexc
)
17704 /* minExclusive <= BASE maxInclusive */
17705 res
= xmlSchemaCompareValues(fminexc
->val
, bfmaxinc
->val
);
17707 goto internal_error
;
17709 xmlSchemaDeriveFacetErr(pctxt
, fminexc
, bfmaxinc
, -1, 1, 1);
17713 /* minExclusive >= BASE minInclusive */
17714 res
= xmlSchemaCompareValues(fminexc
->val
, bfmininc
->val
);
17716 goto internal_error
;
17718 xmlSchemaDeriveFacetErr(pctxt
, fminexc
, bfmininc
, 1, 1, 1);
17722 /* minExclusive < BASE maxExclusive */
17723 res
= xmlSchemaCompareValues(fminexc
->val
, bfmaxexc
->val
);
17725 goto internal_error
;
17727 xmlSchemaDeriveFacetErr(pctxt
, fminexc
, bfmaxexc
, -1, 0, 1);
17733 * "minInclusive < maxExclusive"
17736 res
= xmlSchemaCompareValues(fmininc
->val
, fmaxexc
->val
);
17738 goto internal_error
;
17740 xmlSchemaDeriveFacetErr(pctxt
, fmininc
, fmaxexc
, -1, 0, 0);
17744 * "minExclusive valid restriction"
17747 /* minInclusive >= BASE minInclusive */
17748 res
= xmlSchemaCompareValues(fmininc
->val
, bfmininc
->val
);
17750 goto internal_error
;
17752 xmlSchemaDeriveFacetErr(pctxt
, fmininc
, bfmininc
, 1, 1, 1);
17754 if ((res
!= 0) && (bfmininc
->fixed
)) {
17755 FACET_RESTR_FIXED_ERR(fmininc
)
17759 /* minInclusive <= BASE maxInclusive */
17760 res
= xmlSchemaCompareValues(fmininc
->val
, bfmaxinc
->val
);
17762 goto internal_error
;
17764 xmlSchemaDeriveFacetErr(pctxt
, fmininc
, bfmaxinc
, -1, 1, 1);
17768 /* minInclusive > BASE minExclusive */
17769 res
= xmlSchemaCompareValues(fmininc
->val
, bfminexc
->val
);
17771 goto internal_error
;
17773 xmlSchemaDeriveFacetErr(pctxt
, fmininc
, bfminexc
, 1, 0, 1);
17776 /* minInclusive < BASE maxExclusive */
17777 res
= xmlSchemaCompareValues(fmininc
->val
, bfmaxexc
->val
);
17779 goto internal_error
;
17781 xmlSchemaDeriveFacetErr(pctxt
, fmininc
, bfmaxexc
, -1, 0, 1);
17784 if (ftotdig
&& bftotdig
) {
17786 * SCC " totalDigits valid restriction"
17787 * totalDigits <= BASE totalDigits
17789 res
= xmlSchemaCompareValues(ftotdig
->val
, bftotdig
->val
);
17791 goto internal_error
;
17793 xmlSchemaDeriveFacetErr(pctxt
, ftotdig
, bftotdig
,
17795 if ((res
!= 0) && (bftotdig
->fixed
)) {
17796 FACET_RESTR_FIXED_ERR(ftotdig
)
17799 if (ffracdig
&& bffracdig
) {
17801 * SCC "fractionDigits valid restriction"
17802 * fractionDigits <= BASE fractionDigits
17804 res
= xmlSchemaCompareValues(ffracdig
->val
, bffracdig
->val
);
17806 goto internal_error
;
17808 xmlSchemaDeriveFacetErr(pctxt
, ffracdig
, bffracdig
,
17810 if ((res
!= 0) && (bffracdig
->fixed
)) {
17811 FACET_RESTR_FIXED_ERR(ffracdig
)
17815 * SCC "fractionDigits less than or equal to totalDigits"
17818 ftotdig
= bftotdig
;
17820 ffracdig
= bffracdig
;
17821 if (ftotdig
&& ffracdig
) {
17822 res
= xmlSchemaCompareValues(ffracdig
->val
, ftotdig
->val
);
17824 goto internal_error
;
17826 xmlSchemaDeriveFacetErr(pctxt
, ffracdig
, ftotdig
,
17830 * *Enumerations* won' be added here, since only the first set
17831 * of enumerations in the ancestor-or-self axis is used
17832 * for validation, plus we need to use the base type of those
17833 * enumerations for whitespace.
17835 * *Patterns*: won't be add here, since they are ORed at
17836 * type level and ANDed at ancestor level. This will
17837 * happen during validation by walking the base axis
17840 for (cur
= base
->facetSet
; cur
!= NULL
; cur
= cur
->next
) {
17841 bfacet
= cur
->facet
;
17843 * Special handling of enumerations and patterns.
17844 * TODO: hmm, they should not appear in the set, so remove this.
17846 if ((bfacet
->type
== XML_SCHEMA_FACET_PATTERN
) ||
17847 (bfacet
->type
== XML_SCHEMA_FACET_ENUMERATION
))
17850 * Search for a duplicate facet in the current type.
17852 link
= type
->facetSet
;
17854 /* fixedErr = 0; */
17855 while (link
!= NULL
) {
17856 facet
= link
->facet
;
17857 if (facet
->type
== bfacet
->type
) {
17858 switch (facet
->type
) {
17859 case XML_SCHEMA_FACET_WHITESPACE
:
17861 * The whitespace must be stronger.
17863 if (facet
->whitespace
< bfacet
->whitespace
) {
17864 FACET_RESTR_ERR(facet
,
17865 "The 'whitespace' value has to be equal to "
17866 "or stronger than the 'whitespace' value of "
17869 if ((bfacet
->fixed
) &&
17870 (facet
->whitespace
!= bfacet
->whitespace
)) {
17871 FACET_RESTR_FIXED_ERR(facet
)
17877 /* Duplicate found. */
17883 * If no duplicate was found: add the base types's facet
17886 if (link
== NULL
) {
17887 link
= (xmlSchemaFacetLinkPtr
)
17888 xmlMalloc(sizeof(xmlSchemaFacetLink
));
17889 if (link
== NULL
) {
17890 xmlSchemaPErrMemory(pctxt
,
17891 "deriving facets, creating a facet link", NULL
);
17894 link
->facet
= cur
->facet
;
17897 type
->facetSet
= link
;
17907 PERROR_INT("xmlSchemaDeriveAndValidateFacets",
17908 "an error occurred");
17913 xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt
,
17914 xmlSchemaTypePtr type
)
17916 xmlSchemaTypeLinkPtr link
, lastLink
, prevLink
, subLink
, newLink
;
17918 * The actual value is then formed by replacing any union type
17919 * definition in the `explicit members` with the members of their
17920 * {member type definitions}, in order.
17922 * TODO: There's a bug entry at
17923 * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
17924 * which indicates that we'll keep the union types the future.
17926 link
= type
->memberTypes
;
17927 while (link
!= NULL
) {
17929 if (WXS_IS_TYPE_NOT_FIXED(link
->type
))
17930 xmlSchemaTypeFixup(link
->type
, ACTXT_CAST pctxt
);
17932 if (WXS_IS_UNION(link
->type
)) {
17933 subLink
= xmlSchemaGetUnionSimpleTypeMemberTypes(link
->type
);
17934 if (subLink
!= NULL
) {
17935 link
->type
= subLink
->type
;
17936 if (subLink
->next
!= NULL
) {
17937 lastLink
= link
->next
;
17938 subLink
= subLink
->next
;
17940 while (subLink
!= NULL
) {
17941 newLink
= (xmlSchemaTypeLinkPtr
)
17942 xmlMalloc(sizeof(xmlSchemaTypeLink
));
17943 if (newLink
== NULL
) {
17944 xmlSchemaPErrMemory(pctxt
, "allocating a type link",
17948 newLink
->type
= subLink
->type
;
17949 prevLink
->next
= newLink
;
17950 prevLink
= newLink
;
17951 newLink
->next
= lastLink
;
17953 subLink
= subLink
->next
;
17964 xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type
)
17966 int has
= 0, needVal
= 0, normVal
= 0;
17968 has
= (type
->baseType
->flags
& XML_SCHEMAS_TYPE_HAS_FACETS
) ? 1 : 0;
17970 needVal
= (type
->baseType
->flags
&
17971 XML_SCHEMAS_TYPE_FACETSNEEDVALUE
) ? 1 : 0;
17972 normVal
= (type
->baseType
->flags
&
17973 XML_SCHEMAS_TYPE_NORMVALUENEEDED
) ? 1 : 0;
17975 if (type
->facets
!= NULL
) {
17976 xmlSchemaFacetPtr fac
;
17978 for (fac
= type
->facets
; fac
!= NULL
; fac
= fac
->next
) {
17979 switch (fac
->type
) {
17980 case XML_SCHEMA_FACET_WHITESPACE
:
17982 case XML_SCHEMA_FACET_PATTERN
:
17986 case XML_SCHEMA_FACET_ENUMERATION
:
17998 type
->flags
|= XML_SCHEMAS_TYPE_NORMVALUENEEDED
;
18000 type
->flags
|= XML_SCHEMAS_TYPE_FACETSNEEDVALUE
;
18002 type
->flags
|= XML_SCHEMAS_TYPE_HAS_FACETS
;
18004 if (has
&& (! needVal
) && WXS_IS_ATOMIC(type
)) {
18005 xmlSchemaTypePtr prim
= xmlSchemaGetPrimitiveType(type
);
18007 * OPTIMIZE VAL TODO: Some facets need a computed value.
18009 if ((prim
->builtInType
!= XML_SCHEMAS_ANYSIMPLETYPE
) &&
18010 (prim
->builtInType
!= XML_SCHEMAS_STRING
)) {
18011 type
->flags
|= XML_SCHEMAS_TYPE_FACETSNEEDVALUE
;
18017 xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type
)
18022 * Evaluate the whitespace-facet value.
18024 if (WXS_IS_LIST(type
)) {
18025 type
->flags
|= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE
;
18027 } else if (WXS_IS_UNION(type
))
18030 if (type
->facetSet
!= NULL
) {
18031 xmlSchemaFacetLinkPtr lin
;
18033 for (lin
= type
->facetSet
; lin
!= NULL
; lin
= lin
->next
) {
18034 if (lin
->facet
->type
== XML_SCHEMA_FACET_WHITESPACE
) {
18035 switch (lin
->facet
->whitespace
) {
18036 case XML_SCHEMAS_FACET_PRESERVE
:
18037 type
->flags
|= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE
;
18039 case XML_SCHEMAS_FACET_REPLACE
:
18040 type
->flags
|= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE
;
18042 case XML_SCHEMAS_FACET_COLLAPSE
:
18043 type
->flags
|= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE
;
18053 * For all `atomic` datatypes other than string (and types `derived`
18054 * by `restriction` from it) the value of whiteSpace is fixed to
18058 xmlSchemaTypePtr anc
;
18060 for (anc
= type
->baseType
; anc
!= NULL
&&
18061 anc
->builtInType
!= XML_SCHEMAS_ANYTYPE
;
18062 anc
= anc
->baseType
) {
18064 if (anc
->type
== XML_SCHEMA_TYPE_BASIC
) {
18065 if (anc
->builtInType
== XML_SCHEMAS_NORMSTRING
) {
18066 type
->flags
|= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE
;
18068 } else if ((anc
->builtInType
== XML_SCHEMAS_STRING
) ||
18069 (anc
->builtInType
== XML_SCHEMAS_ANYSIMPLETYPE
)) {
18070 type
->flags
|= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE
;
18073 type
->flags
|= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE
;
18082 xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt
,
18083 xmlSchemaTypePtr type
)
18085 if (type
->type
!= XML_SCHEMA_TYPE_SIMPLE
)
18087 if (! WXS_IS_TYPE_NOT_FIXED_1(type
))
18089 type
->flags
|= XML_SCHEMAS_TYPE_FIXUP_1
;
18091 if (WXS_IS_LIST(type
)) {
18093 * Corresponds to <simpleType><list>...
18095 if (type
->subtypes
== NULL
) {
18097 * This one is really needed, so get out.
18099 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
18100 "list type has no item-type assigned");
18103 } else if (WXS_IS_UNION(type
)) {
18105 * Corresponds to <simpleType><union>...
18107 if (type
->memberTypes
== NULL
) {
18109 * This one is really needed, so get out.
18111 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
18112 "union type has no member-types assigned");
18117 * Corresponds to <simpleType><restriction>...
18119 if (type
->baseType
== NULL
) {
18120 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
18121 "type has no base-type assigned");
18124 if (WXS_IS_TYPE_NOT_FIXED_1(type
->baseType
))
18125 if (xmlSchemaFixupSimpleTypeStageOne(pctxt
, type
->baseType
) == -1)
18129 * If the <restriction> alternative is chosen, then the
18130 * {variety} of the {base type definition}.
18132 if (WXS_IS_ATOMIC(type
->baseType
))
18133 type
->flags
|= XML_SCHEMAS_TYPE_VARIETY_ATOMIC
;
18134 else if (WXS_IS_LIST(type
->baseType
)) {
18135 type
->flags
|= XML_SCHEMAS_TYPE_VARIETY_LIST
;
18137 * Inherit the itemType.
18139 type
->subtypes
= type
->baseType
->subtypes
;
18140 } else if (WXS_IS_UNION(type
->baseType
)) {
18141 type
->flags
|= XML_SCHEMAS_TYPE_VARIETY_UNION
;
18143 * NOTE that we won't assign the memberTypes of the base,
18144 * since this will make trouble when freeing them; we will
18145 * use a lookup function to access them instead.
18154 xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt
,
18155 xmlSchemaTypePtr type
)
18157 if (type
->node
!= NULL
) {
18158 xmlGenericError(xmlGenericErrorContext
,
18159 "Type of %s : %s:%d :", name
,
18160 type
->node
->doc
->URL
,
18161 xmlGetLineNo(type
->node
));
18163 xmlGenericError(xmlGenericErrorContext
, "Type of %s :", name
);
18165 if ((WXS_IS_SIMPLE(type
)) || (WXS_IS_COMPLEX(type
))) {
18166 switch (type
->contentType
) {
18167 case XML_SCHEMA_CONTENT_SIMPLE
:
18168 xmlGenericError(xmlGenericErrorContext
, "simple\n");
18170 case XML_SCHEMA_CONTENT_ELEMENTS
:
18171 xmlGenericError(xmlGenericErrorContext
, "elements\n");
18173 case XML_SCHEMA_CONTENT_UNKNOWN
:
18174 xmlGenericError(xmlGenericErrorContext
, "unknown !!!\n");
18176 case XML_SCHEMA_CONTENT_EMPTY
:
18177 xmlGenericError(xmlGenericErrorContext
, "empty\n");
18179 case XML_SCHEMA_CONTENT_MIXED
:
18180 if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr
)
18182 xmlGenericError(xmlGenericErrorContext
,
18183 "mixed as emptiable particle\n");
18185 xmlGenericError(xmlGenericErrorContext
, "mixed\n");
18187 /* Removed, since not used. */
18189 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
18190 xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
18193 case XML_SCHEMA_CONTENT_BASIC
:
18194 xmlGenericError(xmlGenericErrorContext
, "basic\n");
18197 xmlGenericError(xmlGenericErrorContext
,
18198 "not registered !!!\n");
18206 * 3.14.6 Constraints on Simple Type Definition Schema Components
18209 xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt
,
18210 xmlSchemaTypePtr type
)
18212 int res
, olderrs
= pctxt
->nberrors
;
18214 if (type
->type
!= XML_SCHEMA_TYPE_SIMPLE
)
18217 if (! WXS_IS_TYPE_NOT_FIXED(type
))
18220 type
->flags
|= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED
;
18221 type
->contentType
= XML_SCHEMA_CONTENT_SIMPLE
;
18223 if (type
->baseType
== NULL
) {
18224 PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
18225 "missing baseType");
18228 if (WXS_IS_TYPE_NOT_FIXED(type
->baseType
))
18229 xmlSchemaTypeFixup(type
->baseType
, ACTXT_CAST pctxt
);
18231 * If a member type of a union is a union itself, we need to substitute
18232 * that member type for its member types.
18233 * NOTE that this might change in WXS 1.1; i.e. we will keep the union
18234 * types in WXS 1.1.
18236 if ((type
->memberTypes
!= NULL
) &&
18237 (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt
, type
) == -1))
18240 * SPEC src-simple-type 1
18241 * "The corresponding simple type definition, if any, must satisfy
18242 * the conditions set out in Constraints on Simple Type Definition
18243 * Schema Components ($3.14.6)."
18246 * Schema Component Constraint: Simple Type Definition Properties Correct
18247 * (st-props-correct)
18249 res
= xmlSchemaCheckSTPropsCorrect(pctxt
, type
);
18252 * Schema Component Constraint: Derivation Valid (Restriction, Simple)
18253 * (cos-st-restricts)
18255 res
= xmlSchemaCheckCOSSTRestricts(pctxt
, type
);
18258 * TODO: Removed the error report, since it got annoying to get an
18259 * extra error report, if anything failed until now.
18260 * Enable this if needed.
18262 * xmlSchemaPErr(ctxt, type->node,
18263 * XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
18264 * "Simple type '%s' does not satisfy the constraints "
18265 * "on simple type definitions.\n",
18266 * type->name, NULL);
18269 * Schema Component Constraint: Simple Type Restriction (Facets)
18270 * (st-restrict-facets)
18272 res
= xmlSchemaCheckFacetValues(type
, pctxt
);
18274 if ((type
->facetSet
!= NULL
) ||
18275 (type
->baseType
->facetSet
!= NULL
)) {
18276 res
= xmlSchemaDeriveAndValidateFacets(pctxt
, type
);
18280 * Whitespace value.
18282 res
= xmlSchemaTypeFixupWhitespace(type
);
18284 xmlSchemaTypeFixupOptimFacets(type
);
18288 xmlSchemaDebugFixedType(pctxt
, type
);
18290 if (olderrs
!= pctxt
->nberrors
)
18291 return(pctxt
->err
);
18296 xmlSchemaDebugFixedType(pctxt
, type
);
18302 xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt
,
18303 xmlSchemaTypePtr type
)
18305 int res
= 0, olderrs
= pctxt
->nberrors
;
18306 xmlSchemaTypePtr baseType
= type
->baseType
;
18308 if (! WXS_IS_TYPE_NOT_FIXED(type
))
18310 type
->flags
|= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED
;
18311 if (baseType
== NULL
) {
18312 PERROR_INT("xmlSchemaFixupComplexType",
18313 "missing baseType");
18317 * Fixup the base type.
18319 if (WXS_IS_TYPE_NOT_FIXED(baseType
))
18320 xmlSchemaTypeFixup(baseType
, ACTXT_CAST pctxt
);
18321 if (baseType
->flags
& XML_SCHEMAS_TYPE_INTERNAL_INVALID
) {
18323 * Skip fixup if the base type is invalid.
18324 * TODO: Generate a warning!
18329 * This basically checks if the base type can be derived.
18331 res
= xmlSchemaCheckSRCCT(pctxt
, type
);
18334 * Fixup the content type.
18336 if (type
->contentType
== XML_SCHEMA_CONTENT_SIMPLE
) {
18338 * Corresponds to <complexType><simpleContent>...
18340 if ((WXS_IS_COMPLEX(baseType
)) &&
18341 (baseType
->contentTypeDef
!= NULL
) &&
18342 (WXS_IS_RESTRICTION(type
))) {
18343 xmlSchemaTypePtr contentBase
, content
;
18344 #ifdef ENABLE_NAMED_LOCALS
18346 const xmlChar
*tmpname
;
18349 * SPEC (1) If <restriction> + base type is <complexType>,
18350 * "whose own {content type} is a simple type..."
18352 if (type
->contentTypeDef
!= NULL
) {
18354 * SPEC (1.1) "the simple type definition corresponding to the
18355 * <simpleType> among the [children] of <restriction> if there
18357 * Note that this "<simpleType> among the [children]" was put
18358 * into ->contentTypeDef during parsing.
18360 contentBase
= type
->contentTypeDef
;
18361 type
->contentTypeDef
= NULL
;
18364 * (1.2) "...otherwise (<restriction> has no <simpleType>
18365 * among its [children]), the simple type definition which
18366 * is the {content type} of the ... base type."
18368 contentBase
= baseType
->contentTypeDef
;
18372 * "... a simple type definition which restricts the simple
18373 * type definition identified in clause 1.1 or clause 1.2
18374 * with a set of facet components"
18376 * Create the anonymous simple type, which will be the content
18377 * type of the complex type.
18379 #ifdef ENABLE_NAMED_LOCALS
18380 snprintf(buf
, 29, "#scST%d", ++(pctxt
->counter
));
18381 tmpname
= xmlDictLookup(pctxt
->dict
, BAD_CAST buf
, -1);
18382 content
= xmlSchemaAddType(pctxt
, pctxt
->schema
,
18383 XML_SCHEMA_TYPE_SIMPLE
, tmpname
, type
->targetNamespace
,
18386 content
= xmlSchemaAddType(pctxt
, pctxt
->schema
,
18387 XML_SCHEMA_TYPE_SIMPLE
, NULL
, type
->targetNamespace
,
18390 if (content
== NULL
)
18393 * We will use the same node as for the <complexType>
18394 * to have it somehow anchored in the schema doc.
18396 content
->type
= XML_SCHEMA_TYPE_SIMPLE
;
18397 content
->baseType
= contentBase
;
18399 * Move the facets, previously anchored on the
18400 * complexType during parsing.
18402 content
->facets
= type
->facets
;
18403 type
->facets
= NULL
;
18404 content
->facetSet
= type
->facetSet
;
18405 type
->facetSet
= NULL
;
18407 type
->contentTypeDef
= content
;
18408 if (WXS_IS_TYPE_NOT_FIXED(contentBase
))
18409 xmlSchemaTypeFixup(contentBase
, ACTXT_CAST pctxt
);
18411 * Fixup the newly created type. We don't need to check
18412 * for circularity here.
18414 res
= xmlSchemaFixupSimpleTypeStageOne(pctxt
, content
);
18416 res
= xmlSchemaFixupSimpleTypeStageTwo(pctxt
, content
);
18419 } else if ((WXS_IS_COMPLEX(baseType
)) &&
18420 (baseType
->contentType
== XML_SCHEMA_CONTENT_MIXED
) &&
18421 (WXS_IS_RESTRICTION(type
))) {
18423 * SPEC (2) If <restriction> + base is a mixed <complexType> with
18424 * an emptiable particle, then a simple type definition which
18425 * restricts the <restriction>'s <simpleType> child.
18427 if ((type
->contentTypeDef
== NULL
) ||
18428 (type
->contentTypeDef
->baseType
== NULL
)) {
18430 * TODO: Check if this ever happens.
18432 xmlSchemaPCustomErr(pctxt
,
18433 XML_SCHEMAP_INTERNAL
,
18434 WXS_BASIC_CAST type
, NULL
,
18435 "Internal error: xmlSchemaTypeFixup, "
18436 "complex type '%s': the <simpleContent><restriction> "
18437 "is missing a <simpleType> child, but was not caught "
18438 "by xmlSchemaCheckSRCCT()", type
->name
);
18441 } else if ((WXS_IS_COMPLEX(baseType
)) && WXS_IS_EXTENSION(type
)) {
18443 * SPEC (3) If <extension> + base is <complexType> with
18444 * <simpleType> content, "...then the {content type} of that
18445 * complex type definition"
18447 if (baseType
->contentTypeDef
== NULL
) {
18449 * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
18450 * should have caught this already.
18452 xmlSchemaPCustomErr(pctxt
,
18453 XML_SCHEMAP_INTERNAL
,
18454 WXS_BASIC_CAST type
, NULL
,
18455 "Internal error: xmlSchemaTypeFixup, "
18456 "complex type '%s': the <extension>ed base type is "
18457 "a complex type with no simple content type",
18461 type
->contentTypeDef
= baseType
->contentTypeDef
;
18462 } else if ((WXS_IS_SIMPLE(baseType
)) && WXS_IS_EXTENSION(type
)) {
18464 * SPEC (4) <extension> + base is <simpleType>
18465 * "... then that simple type definition"
18467 type
->contentTypeDef
= baseType
;
18470 * TODO: Check if this ever happens.
18472 xmlSchemaPCustomErr(pctxt
,
18473 XML_SCHEMAP_INTERNAL
,
18474 WXS_BASIC_CAST type
, NULL
,
18475 "Internal error: xmlSchemaTypeFixup, "
18476 "complex type '%s' with <simpleContent>: unhandled "
18477 "derivation case", type
->name
);
18481 int dummySequence
= 0;
18482 xmlSchemaParticlePtr particle
=
18483 (xmlSchemaParticlePtr
) type
->subtypes
;
18485 * Corresponds to <complexType><complexContent>...
18487 * NOTE that the effective mixed was already set during parsing of
18488 * <complexType> and <complexContent>; its flag value is
18489 * XML_SCHEMAS_TYPE_MIXED.
18491 * Compute the "effective content":
18492 * (2.1.1) + (2.1.2) + (2.1.3)
18494 if ((particle
== NULL
) ||
18495 ((particle
->type
== XML_SCHEMA_TYPE_PARTICLE
) &&
18496 ((particle
->children
->type
== XML_SCHEMA_TYPE_ALL
) ||
18497 (particle
->children
->type
== XML_SCHEMA_TYPE_SEQUENCE
) ||
18498 ((particle
->children
->type
== XML_SCHEMA_TYPE_CHOICE
) &&
18499 (particle
->minOccurs
== 0))) &&
18500 ( ((xmlSchemaTreeItemPtr
) particle
->children
)->children
== NULL
))) {
18501 if (type
->flags
& XML_SCHEMAS_TYPE_MIXED
) {
18503 * SPEC (2.1.4) "If the `effective mixed` is true, then
18504 * a particle whose properties are as follows:..."
18506 * Empty sequence model group with
18507 * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
18508 * NOTE that we sill assign it the <complexType> node to
18509 * somehow anchor it in the doc.
18511 if ((particle
== NULL
) ||
18512 (particle
->children
->type
!= XML_SCHEMA_TYPE_SEQUENCE
)) {
18514 * Create the particle.
18516 particle
= xmlSchemaAddParticle(pctxt
,
18518 if (particle
== NULL
)
18521 * Create the model group.
18522 */ /* URGENT TODO: avoid adding to pending items. */
18523 particle
->children
= (xmlSchemaTreeItemPtr
)
18524 xmlSchemaAddModelGroup(pctxt
, pctxt
->schema
,
18525 XML_SCHEMA_TYPE_SEQUENCE
, type
->node
);
18526 if (particle
->children
== NULL
)
18529 type
->subtypes
= (xmlSchemaTypePtr
) particle
;
18532 type
->contentType
= XML_SCHEMA_CONTENT_ELEMENTS
;
18535 * SPEC (2.1.5) "otherwise empty"
18537 type
->contentType
= XML_SCHEMA_CONTENT_EMPTY
;
18541 * SPEC (2.2) "otherwise the particle corresponding to the
18542 * <all>, <choice>, <group> or <sequence> among the
18545 type
->contentType
= XML_SCHEMA_CONTENT_ELEMENTS
;
18548 * Compute the "content type".
18550 if (WXS_IS_RESTRICTION(type
)) {
18552 * SPEC (3.1) "If <restriction>..."
18553 * (3.1.1) + (3.1.2) */
18554 if (type
->contentType
!= XML_SCHEMA_CONTENT_EMPTY
) {
18555 if (type
->flags
& XML_SCHEMAS_TYPE_MIXED
)
18556 type
->contentType
= XML_SCHEMA_CONTENT_MIXED
;
18560 * SPEC (3.2) "If <extension>..."
18562 if (type
->contentType
== XML_SCHEMA_CONTENT_EMPTY
) {
18565 * "If the `effective content` is empty, then the
18566 * {content type} of the [...] base ..."
18568 type
->contentType
= baseType
->contentType
;
18569 type
->subtypes
= baseType
->subtypes
;
18571 * Fixes bug #347316:
18572 * This is the case when the base type has a simple
18573 * type definition as content.
18575 type
->contentTypeDef
= baseType
->contentTypeDef
;
18577 * NOTE that the effective mixed is ignored here.
18579 } else if (baseType
->contentType
== XML_SCHEMA_CONTENT_EMPTY
) {
18583 if (type
->flags
& XML_SCHEMAS_TYPE_MIXED
)
18584 type
->contentType
= XML_SCHEMA_CONTENT_MIXED
;
18589 if (type
->flags
& XML_SCHEMAS_TYPE_MIXED
)
18590 type
->contentType
= XML_SCHEMA_CONTENT_MIXED
;
18592 * "A model group whose {compositor} is sequence and whose
18593 * {particles} are..."
18595 if ((WXS_TYPE_PARTICLE(type
) != NULL
) &&
18596 (WXS_TYPE_PARTICLE_TERM(type
) != NULL
) &&
18597 ((WXS_TYPE_PARTICLE_TERM(type
))->type
==
18598 XML_SCHEMA_TYPE_ALL
))
18601 * SPEC cos-all-limited (1)
18603 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
18604 /* TODO: error code */
18605 XML_SCHEMAP_COS_ALL_LIMITED
,
18606 WXS_ITEM_NODE(type
), NULL
,
18607 "The type has an 'all' model group in its "
18608 "{content type} and thus cannot be derived from "
18609 "a non-empty type, since this would produce a "
18610 "'sequence' model group containing the 'all' "
18611 "model group; 'all' model groups are not "
18612 "allowed to appear inside other model groups",
18615 } else if ((WXS_TYPE_PARTICLE(baseType
) != NULL
) &&
18616 (WXS_TYPE_PARTICLE_TERM(baseType
) != NULL
) &&
18617 ((WXS_TYPE_PARTICLE_TERM(baseType
))->type
==
18618 XML_SCHEMA_TYPE_ALL
))
18621 * SPEC cos-all-limited (1)
18623 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
18624 /* TODO: error code */
18625 XML_SCHEMAP_COS_ALL_LIMITED
,
18626 WXS_ITEM_NODE(type
), NULL
,
18627 "A type cannot be derived by extension from a type "
18628 "which has an 'all' model group in its "
18629 "{content type}, since this would produce a "
18630 "'sequence' model group containing the 'all' "
18631 "model group; 'all' model groups are not "
18632 "allowed to appear inside other model groups",
18635 } else if ((!dummySequence
) && (baseType
->subtypes
!= NULL
)) {
18636 xmlSchemaTreeItemPtr effectiveContent
=
18637 (xmlSchemaTreeItemPtr
) type
->subtypes
;
18639 * Create the particle.
18641 particle
= xmlSchemaAddParticle(pctxt
,
18643 if (particle
== NULL
)
18646 * Create the "sequence" model group.
18648 particle
->children
= (xmlSchemaTreeItemPtr
)
18649 xmlSchemaAddModelGroup(pctxt
, pctxt
->schema
,
18650 XML_SCHEMA_TYPE_SEQUENCE
, type
->node
);
18651 if (particle
->children
== NULL
)
18653 WXS_TYPE_CONTENTTYPE(type
) = (xmlSchemaTypePtr
) particle
;
18655 * SPEC "the particle of the {content type} of
18656 * the ... base ..."
18657 * Create a duplicate of the base type's particle
18658 * and assign its "term" to it.
18660 particle
->children
->children
=
18661 (xmlSchemaTreeItemPtr
) xmlSchemaAddParticle(pctxt
,
18663 ((xmlSchemaParticlePtr
) baseType
->subtypes
)->minOccurs
,
18664 ((xmlSchemaParticlePtr
) baseType
->subtypes
)->maxOccurs
);
18665 if (particle
->children
->children
== NULL
)
18667 particle
= (xmlSchemaParticlePtr
)
18668 particle
->children
->children
;
18669 particle
->children
=
18670 ((xmlSchemaParticlePtr
) baseType
->subtypes
)->children
;
18672 * SPEC "followed by the `effective content`."
18674 particle
->next
= effectiveContent
;
18676 * This all will result in:
18678 * --> new-sequence(
18687 * This is the case when there is already an empty
18688 * <sequence> with minOccurs==maxOccurs==1.
18689 * Just add the base types's content type.
18690 * NOTE that, although we miss to add an intermediate
18691 * <sequence>, this should produce no difference to
18692 * neither the regex compilation of the content model,
18693 * nor to the complex type constraints.
18695 particle
->children
->children
=
18696 (xmlSchemaTreeItemPtr
) baseType
->subtypes
;
18702 * Now fixup attribute uses:
18703 * - expand attr. group references
18704 * - intersect attribute wildcards
18705 * - inherit attribute uses of the base type
18706 * - inherit or union attr. wildcards if extending
18707 * - apply attr. use prohibitions if restricting
18709 res
= xmlSchemaFixupTypeAttributeUses(pctxt
, type
);
18712 * Apply the complex type component constraints; this will not
18713 * check attributes, since this is done in
18714 * xmlSchemaFixupTypeAttributeUses().
18716 res
= xmlSchemaCheckCTComponent(pctxt
, type
);
18720 xmlSchemaDebugFixedType(pctxt
, type
);
18722 if (olderrs
!= pctxt
->nberrors
)
18723 return(pctxt
->err
);
18728 type
->flags
|= XML_SCHEMAS_TYPE_INTERNAL_INVALID
;
18730 xmlSchemaDebugFixedType(pctxt
, type
);
18732 return(pctxt
->err
);
18735 type
->flags
|= XML_SCHEMAS_TYPE_INTERNAL_INVALID
;
18737 xmlSchemaDebugFixedType(pctxt
, type
);
18744 * xmlSchemaTypeFixup:
18745 * @typeDecl: the schema type definition
18746 * @ctxt: the schema parser context
18748 * Fixes the content model of the type.
18749 * URGENT TODO: We need an int result!
18752 xmlSchemaTypeFixup(xmlSchemaTypePtr type
,
18753 xmlSchemaAbstractCtxtPtr actxt
)
18757 if (actxt
->type
!= XML_SCHEMA_CTXT_PARSER
) {
18758 AERROR_INT("xmlSchemaTypeFixup",
18759 "this function needs a parser context");
18762 if (! WXS_IS_TYPE_NOT_FIXED(type
))
18764 if (type
->type
== XML_SCHEMA_TYPE_COMPLEX
)
18765 return(xmlSchemaFixupComplexType(PCTXT_CAST actxt
, type
));
18766 else if (type
->type
== XML_SCHEMA_TYPE_SIMPLE
)
18767 return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt
, type
));
18772 * xmlSchemaCheckFacet:
18773 * @facet: the facet
18774 * @typeDecl: the schema type definition
18775 * @pctxt: the schema parser context or NULL
18776 * @name: the optional name of the type
18778 * Checks and computes the values of facets.
18780 * Returns 0 if valid, a positive error code if not valid and
18781 * -1 in case of an internal or API error.
18784 xmlSchemaCheckFacet(xmlSchemaFacetPtr facet
,
18785 xmlSchemaTypePtr typeDecl
,
18786 xmlSchemaParserCtxtPtr pctxt
,
18787 const xmlChar
* name ATTRIBUTE_UNUSED
)
18789 int ret
= 0, ctxtGiven
;
18791 if ((facet
== NULL
) || (typeDecl
== NULL
))
18794 * TODO: will the parser context be given if used from
18795 * the relaxNG module?
18802 switch (facet
->type
) {
18803 case XML_SCHEMA_FACET_MININCLUSIVE
:
18804 case XML_SCHEMA_FACET_MINEXCLUSIVE
:
18805 case XML_SCHEMA_FACET_MAXINCLUSIVE
:
18806 case XML_SCHEMA_FACET_MAXEXCLUSIVE
:
18807 case XML_SCHEMA_FACET_ENUMERATION
: {
18809 * Okay we need to validate the value
18812 xmlSchemaTypePtr base
;
18814 /* 4.3.5.5 Constraints on enumeration Schema Components
18815 * Schema Component Constraint: enumeration valid restriction
18816 * It is an `error` if any member of {value} is not in the
18817 * `value space` of {base type definition}.
18819 * minInclusive, maxInclusive, minExclusive, maxExclusive:
18820 * The value `must` be in the
18821 * `value space` of the `base type`.
18824 * This function is intended to deliver a compiled value
18825 * on the facet. In this implementation of XML Schemata the
18826 * type holding a facet, won't be a built-in type.
18827 * Thus to ensure that other API
18828 * calls (relaxng) do work, if the given type is a built-in
18829 * type, we will assume that the given built-in type *is
18830 * already* the base type.
18832 if (typeDecl
->type
!= XML_SCHEMA_TYPE_BASIC
) {
18833 base
= typeDecl
->baseType
;
18834 if (base
== NULL
) {
18835 PERROR_INT("xmlSchemaCheckFacet",
18836 "a type user derived type has no base type");
18844 * A context is needed if called from RelaxNG.
18846 pctxt
= xmlSchemaNewParserCtxt("*");
18851 * NOTE: This call does not check the content nodes,
18852 * since they are not available:
18853 * facet->node is just the node holding the facet
18854 * definition, *not* the attribute holding the *value*
18857 ret
= xmlSchemaVCheckCVCSimpleType(
18858 ACTXT_CAST pctxt
, facet
->node
, base
,
18859 facet
->value
, &(facet
->val
), 1, 1, 0);
18862 /* No error message for RelaxNG. */
18864 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
18865 XML_SCHEMAP_INTERNAL
, facet
->node
, NULL
,
18866 "Internal error: xmlSchemaCheckFacet, "
18867 "failed to validate the value '%s' of the "
18868 "facet '%s' against the base type",
18869 facet
->value
, xmlSchemaFacetTypeToString(facet
->type
));
18871 goto internal_error
;
18873 ret
= XML_SCHEMAP_INVALID_FACET_VALUE
;
18874 /* No error message for RelaxNG. */
18876 xmlChar
*str
= NULL
;
18878 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
18879 ret
, facet
->node
, WXS_BASIC_CAST facet
,
18880 "The value '%s' of the facet does not validate "
18881 "against the base type '%s'",
18883 xmlSchemaFormatQName(&str
,
18884 base
->targetNamespace
, base
->name
));
18885 FREE_AND_NULL(str
);
18888 } else if (facet
->val
== NULL
) {
18890 PERROR_INT("xmlSchemaCheckFacet",
18891 "value was not computed");
18897 case XML_SCHEMA_FACET_PATTERN
:
18898 facet
->regexp
= xmlRegexpCompile(facet
->value
);
18899 if (facet
->regexp
== NULL
) {
18900 ret
= XML_SCHEMAP_REGEXP_INVALID
;
18901 /* No error message for RelaxNG. */
18903 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
18904 ret
, facet
->node
, WXS_BASIC_CAST typeDecl
,
18905 "The value '%s' of the facet 'pattern' is not a "
18906 "valid regular expression",
18907 facet
->value
, NULL
);
18911 case XML_SCHEMA_FACET_TOTALDIGITS
:
18912 case XML_SCHEMA_FACET_FRACTIONDIGITS
:
18913 case XML_SCHEMA_FACET_LENGTH
:
18914 case XML_SCHEMA_FACET_MAXLENGTH
:
18915 case XML_SCHEMA_FACET_MINLENGTH
:
18917 if (facet
->type
== XML_SCHEMA_FACET_TOTALDIGITS
) {
18918 ret
= xmlSchemaValidatePredefinedType(
18919 xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER
),
18920 facet
->value
, &(facet
->val
));
18922 ret
= xmlSchemaValidatePredefinedType(
18923 xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER
),
18924 facet
->value
, &(facet
->val
));
18928 /* No error message for RelaxNG. */
18930 PERROR_INT("xmlSchemaCheckFacet",
18931 "validating facet value");
18933 goto internal_error
;
18935 ret
= XML_SCHEMAP_INVALID_FACET_VALUE
;
18936 /* No error message for RelaxNG. */
18939 xmlSchemaCustomErr4(ACTXT_CAST pctxt
,
18940 ret
, facet
->node
, WXS_BASIC_CAST typeDecl
,
18941 "The value '%s' of the facet '%s' is not a valid '%s'",
18943 xmlSchemaFacetTypeToString(facet
->type
),
18944 (facet
->type
!= XML_SCHEMA_FACET_TOTALDIGITS
) ?
18945 BAD_CAST
"nonNegativeInteger" :
18946 BAD_CAST
"positiveInteger",
18952 case XML_SCHEMA_FACET_WHITESPACE
:{
18953 if (xmlStrEqual(facet
->value
, BAD_CAST
"preserve")) {
18954 facet
->whitespace
= XML_SCHEMAS_FACET_PRESERVE
;
18955 } else if (xmlStrEqual(facet
->value
, BAD_CAST
"replace")) {
18956 facet
->whitespace
= XML_SCHEMAS_FACET_REPLACE
;
18957 } else if (xmlStrEqual(facet
->value
, BAD_CAST
"collapse")) {
18958 facet
->whitespace
= XML_SCHEMAS_FACET_COLLAPSE
;
18960 ret
= XML_SCHEMAP_INVALID_FACET_VALUE
;
18961 /* No error message for RelaxNG. */
18963 /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
18964 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
18965 ret
, facet
->node
, WXS_BASIC_CAST typeDecl
,
18966 "The value '%s' of the facet 'whitespace' is not "
18967 "valid", facet
->value
, NULL
);
18975 if ((! ctxtGiven
) && (pctxt
!= NULL
))
18976 xmlSchemaFreeParserCtxt(pctxt
);
18979 if ((! ctxtGiven
) && (pctxt
!= NULL
))
18980 xmlSchemaFreeParserCtxt(pctxt
);
18985 * xmlSchemaCheckFacetValues:
18986 * @typeDecl: the schema type definition
18987 * @ctxt: the schema parser context
18989 * Checks the default values types, especially for facets
18992 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl
,
18993 xmlSchemaParserCtxtPtr pctxt
)
18995 int res
, olderrs
= pctxt
->nberrors
;
18996 const xmlChar
*name
= typeDecl
->name
;
18998 * NOTE: It is intended to use the facets list, instead
19001 if (typeDecl
->facets
!= NULL
) {
19002 xmlSchemaFacetPtr facet
= typeDecl
->facets
;
19005 * Temporarily assign the "schema" to the validation context
19006 * of the parser context. This is needed for NOTATION validation.
19008 if (pctxt
->vctxt
== NULL
) {
19009 if (xmlSchemaCreateVCtxtOnPCtxt(pctxt
) == -1)
19012 pctxt
->vctxt
->schema
= pctxt
->schema
;
19013 while (facet
!= NULL
) {
19014 res
= xmlSchemaCheckFacet(facet
, typeDecl
, pctxt
, name
);
19016 facet
= facet
->next
;
19018 pctxt
->vctxt
->schema
= NULL
;
19020 if (olderrs
!= pctxt
->nberrors
)
19021 return(pctxt
->err
);
19028 * xmlSchemaGetCircModelGrDefRef:
19029 * @ctxtMGroup: the searched model group
19030 * @selfMGroup: the second searched model group
19031 * @particle: the first particle
19033 * This one is intended to be used by
19034 * xmlSchemaCheckGroupDefCircular only.
19036 * Returns the particle with the circular model group definition reference,
19039 static xmlSchemaTreeItemPtr
19040 xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef
,
19041 xmlSchemaTreeItemPtr particle
)
19043 xmlSchemaTreeItemPtr circ
= NULL
;
19044 xmlSchemaTreeItemPtr term
;
19045 xmlSchemaModelGroupDefPtr gdef
;
19047 for (; particle
!= NULL
; particle
= particle
->next
) {
19048 term
= particle
->children
;
19051 switch (term
->type
) {
19052 case XML_SCHEMA_TYPE_GROUP
:
19053 gdef
= (xmlSchemaModelGroupDefPtr
) term
;
19054 if (gdef
== groupDef
)
19057 * Mark this model group definition to avoid infinite
19058 * recursion on circular references not yet examined.
19060 if (gdef
->flags
& XML_SCHEMA_MODEL_GROUP_DEF_MARKED
)
19062 if (gdef
->children
!= NULL
) {
19063 gdef
->flags
|= XML_SCHEMA_MODEL_GROUP_DEF_MARKED
;
19064 circ
= xmlSchemaGetCircModelGrDefRef(groupDef
,
19065 gdef
->children
->children
);
19066 gdef
->flags
^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED
;
19071 case XML_SCHEMA_TYPE_SEQUENCE
:
19072 case XML_SCHEMA_TYPE_CHOICE
:
19073 case XML_SCHEMA_TYPE_ALL
:
19074 circ
= xmlSchemaGetCircModelGrDefRef(groupDef
, term
->children
);
19086 * xmlSchemaCheckGroupDefCircular:
19087 * @item: the model group definition
19088 * @ctxt: the parser context
19091 * Checks for circular references to model group definitions.
19094 xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item
,
19095 xmlSchemaParserCtxtPtr ctxt
)
19098 * Schema Component Constraint: Model Group Correct
19099 * 2 Circular groups are disallowed. That is, within the {particles}
19100 * of a group there must not be at any depth a particle whose {term}
19101 * is the group itself.
19103 if ((item
== NULL
) ||
19104 (item
->type
!= XML_SCHEMA_TYPE_GROUP
) ||
19105 (item
->children
== NULL
))
19108 xmlSchemaTreeItemPtr circ
;
19110 circ
= xmlSchemaGetCircModelGrDefRef(item
, item
->children
->children
);
19111 if (circ
!= NULL
) {
19112 xmlChar
*str
= NULL
;
19114 * TODO: The error report is not adequate: this constraint
19115 * is defined for model groups but not definitions, but since
19116 * there cannot be any circular model groups without a model group
19117 * definition (if not using a construction API), we check those
19118 * definitions only.
19120 xmlSchemaPCustomErr(ctxt
,
19121 XML_SCHEMAP_MG_PROPS_CORRECT_2
,
19122 NULL
, WXS_ITEM_NODE(circ
),
19123 "Circular reference to the model group definition '%s' "
19124 "defined", xmlSchemaFormatQName(&str
,
19125 item
->targetNamespace
, item
->name
));
19128 * NOTE: We will cut the reference to avoid further
19129 * confusion of the processor. This is a fatal error.
19131 circ
->children
= NULL
;
19137 * xmlSchemaModelGroupToModelGroupDefFixup:
19138 * @ctxt: the parser context
19139 * @mg: the model group
19141 * Assigns the model group of model group definitions to the "term"
19142 * of the referencing particle.
19143 * In xmlSchemaResolveModelGroupParticleReferences the model group
19144 * definitions were assigned to the "term", since needed for the
19145 * circularity check.
19147 * Schema Component Constraint:
19148 * All Group Limited (cos-all-limited) (1.2)
19151 xmlSchemaModelGroupToModelGroupDefFixup(
19152 xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED
,
19153 xmlSchemaModelGroupPtr mg
)
19155 xmlSchemaParticlePtr particle
= WXS_MODELGROUP_PARTICLE(mg
);
19157 while (particle
!= NULL
) {
19158 if ((WXS_PARTICLE_TERM(particle
) == NULL
) ||
19159 ((WXS_PARTICLE_TERM(particle
))->type
!=
19160 XML_SCHEMA_TYPE_GROUP
))
19162 particle
= WXS_PTC_CAST particle
->next
;
19165 if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle
)) == NULL
) {
19167 * TODO: Remove the particle.
19169 WXS_PARTICLE_TERM(particle
) = NULL
;
19170 particle
= WXS_PTC_CAST particle
->next
;
19174 * Assign the model group to the {term} of the particle.
19176 WXS_PARTICLE_TERM(particle
) =
19177 WXS_TREE_CAST
WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle
));
19179 particle
= WXS_PTC_CAST particle
->next
;
19184 * xmlSchemaCheckAttrGroupCircularRecur:
19185 * @ctxtGr: the searched attribute group
19186 * @attr: the current attribute list to be processed
19188 * This one is intended to be used by
19189 * xmlSchemaCheckAttrGroupCircular only.
19191 * Returns the circular attribute group reference, otherwise NULL.
19193 static xmlSchemaQNameRefPtr
19194 xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr
,
19195 xmlSchemaItemListPtr list
)
19197 xmlSchemaAttributeGroupPtr gr
;
19198 xmlSchemaQNameRefPtr ref
, circ
;
19201 * We will search for an attribute group reference which
19202 * references the context attribute group.
19204 for (i
= 0; i
< list
->nbItems
; i
++) {
19205 ref
= list
->items
[i
];
19206 if ((ref
->type
== XML_SCHEMA_EXTRA_QNAMEREF
) &&
19207 (ref
->itemType
== XML_SCHEMA_TYPE_ATTRIBUTEGROUP
) &&
19208 (ref
->item
!= NULL
))
19210 gr
= WXS_ATTR_GROUP_CAST ref
->item
;
19213 if (gr
->flags
& XML_SCHEMAS_ATTRGROUP_MARKED
)
19216 * Mark as visited to avoid infinite recursion on
19217 * circular references not yet examined.
19219 if ((gr
->attrUses
) &&
19220 (gr
->flags
& XML_SCHEMAS_ATTRGROUP_HAS_REFS
))
19222 gr
->flags
|= XML_SCHEMAS_ATTRGROUP_MARKED
;
19223 circ
= xmlSchemaCheckAttrGroupCircularRecur(ctxtGr
,
19224 (xmlSchemaItemListPtr
) gr
->attrUses
);
19225 gr
->flags
^= XML_SCHEMAS_ATTRGROUP_MARKED
;
19236 * xmlSchemaCheckAttrGroupCircular:
19237 * attrGr: the attribute group definition
19238 * @ctxt: the parser context
19241 * Checks for circular references of attribute groups.
19244 xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr
,
19245 xmlSchemaParserCtxtPtr ctxt
)
19248 * Schema Representation Constraint:
19249 * Attribute Group Definition Representation OK
19250 * 3 Circular group reference is disallowed outside <redefine>.
19251 * That is, unless this element information item's parent is
19252 * <redefine>, then among the [children], if any, there must
19253 * not be an <attributeGroup> with ref [attribute] which resolves
19254 * to the component corresponding to this <attributeGroup>. Indirect
19255 * circularity is also ruled out. That is, when QName resolution
19256 * (Schema Document) ($3.15.3) is applied to a `QName` arising from
19257 * any <attributeGroup>s with a ref [attribute] among the [children],
19258 * it must not be the case that a `QName` is encountered at any depth
19259 * which resolves to the component corresponding to this <attributeGroup>.
19261 if (attrGr
->attrUses
== NULL
)
19263 else if ((attrGr
->flags
& XML_SCHEMAS_ATTRGROUP_HAS_REFS
) == 0)
19266 xmlSchemaQNameRefPtr circ
;
19268 circ
= xmlSchemaCheckAttrGroupCircularRecur(attrGr
,
19269 (xmlSchemaItemListPtr
) attrGr
->attrUses
);
19270 if (circ
!= NULL
) {
19271 xmlChar
*str
= NULL
;
19273 * TODO: Report the referenced attr group as QName.
19275 xmlSchemaPCustomErr(ctxt
,
19276 XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3
,
19277 NULL
, WXS_ITEM_NODE(WXS_BASIC_CAST circ
),
19278 "Circular reference to the attribute group '%s' "
19279 "defined", xmlSchemaGetComponentQName(&str
, attrGr
));
19280 FREE_AND_NULL(str
);
19282 * NOTE: We will cut the reference to avoid further
19283 * confusion of the processor.
19284 * BADSPEC TODO: The spec should define how to process in this case.
19294 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt
,
19295 xmlSchemaAttributeGroupPtr attrGr
);
19298 * xmlSchemaExpandAttributeGroupRefs:
19299 * @pctxt: the parser context
19300 * @node: the node of the component holding the attribute uses
19301 * @completeWild: the intersected wildcard to be returned
19302 * @list: the attribute uses
19304 * Substitutes contained attribute group references
19305 * for their attribute uses. Wildcards are intersected.
19306 * Attribute use prohibitions are removed from the list
19307 * and returned via the @prohibs list.
19308 * Pointlessness of attr. prohibs, if a matching attr. decl
19309 * is existent a well, are checked.
19312 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt
,
19313 xmlSchemaBasicItemPtr item
,
19314 xmlSchemaWildcardPtr
*completeWild
,
19315 xmlSchemaItemListPtr list
,
19316 xmlSchemaItemListPtr prohibs
)
19318 xmlSchemaAttributeGroupPtr gr
;
19319 xmlSchemaAttributeUsePtr use
;
19320 xmlSchemaItemListPtr sublist
;
19322 int created
= (*completeWild
== NULL
) ? 0 : 1;
19325 prohibs
->nbItems
= 0;
19327 for (i
= 0; i
< list
->nbItems
; i
++) {
19328 use
= list
->items
[i
];
19330 if (use
->type
== XML_SCHEMA_EXTRA_ATTR_USE_PROHIB
) {
19331 if (prohibs
== NULL
) {
19332 PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
19333 "unexpected attr prohibition found");
19337 * Remove from attribute uses.
19339 if (xmlSchemaItemListRemove(list
, i
) == -1)
19343 * Note that duplicate prohibitions were already
19344 * handled at parsing time.
19347 * Add to list of prohibitions.
19349 xmlSchemaItemListAddSize(prohibs
, 2, use
);
19352 if ((use
->type
== XML_SCHEMA_EXTRA_QNAMEREF
) &&
19353 ((WXS_QNAME_CAST use
)->itemType
== XML_SCHEMA_TYPE_ATTRIBUTEGROUP
))
19355 if ((WXS_QNAME_CAST use
)->item
== NULL
)
19357 gr
= WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use
)->item
;
19359 * Expand the referenced attr. group.
19360 * TODO: remove this, this is done in a previous step, so
19361 * already done here.
19363 if ((gr
->flags
& XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED
) == 0) {
19364 if (xmlSchemaAttributeGroupExpandRefs(pctxt
, gr
) == -1)
19368 * Build the 'complete' wildcard; i.e. intersect multiple
19371 if (gr
->attributeWildcard
!= NULL
) {
19372 if (*completeWild
== NULL
) {
19373 *completeWild
= gr
->attributeWildcard
;
19376 xmlSchemaWildcardPtr tmpWild
;
19379 * Copy the first encountered wildcard as context,
19380 * except for the annotation.
19382 * Although the complete wildcard might not correspond
19383 * to any node in the schema, we will anchor it on
19384 * the node of the owner component.
19386 tmpWild
= xmlSchemaAddWildcard(pctxt
, pctxt
->schema
,
19387 XML_SCHEMA_TYPE_ANY_ATTRIBUTE
,
19388 WXS_ITEM_NODE(item
));
19389 if (tmpWild
== NULL
)
19391 if (xmlSchemaCloneWildcardNsConstraints(pctxt
,
19392 tmpWild
, *completeWild
) == -1)
19394 tmpWild
->processContents
= (*completeWild
)->processContents
;
19395 *completeWild
= tmpWild
;
19399 if (xmlSchemaIntersectWildcards(pctxt
, *completeWild
,
19400 gr
->attributeWildcard
) == -1)
19405 * Just remove the reference if the referenced group does not
19406 * contain any attribute uses.
19408 sublist
= ((xmlSchemaItemListPtr
) gr
->attrUses
);
19409 if ((sublist
== NULL
) || sublist
->nbItems
== 0) {
19410 if (xmlSchemaItemListRemove(list
, i
) == -1)
19416 * Add the attribute uses.
19418 list
->items
[i
] = sublist
->items
[0];
19419 if (sublist
->nbItems
!= 1) {
19420 for (j
= 1; j
< sublist
->nbItems
; j
++) {
19422 if (xmlSchemaItemListInsert(list
,
19423 sublist
->items
[j
], i
) == -1)
19431 * Handle pointless prohibitions of declared attributes.
19433 if (prohibs
&& (prohibs
->nbItems
!= 0) && (list
->nbItems
!= 0)) {
19434 xmlSchemaAttributeUseProhibPtr prohib
;
19436 for (i
= prohibs
->nbItems
-1; i
>= 0; i
--) {
19437 prohib
= prohibs
->items
[i
];
19438 for (j
= 0; j
< list
->nbItems
; j
++) {
19439 use
= list
->items
[j
];
19441 if ((prohib
->name
== WXS_ATTRUSE_DECL_NAME(use
)) &&
19442 (prohib
->targetNamespace
== WXS_ATTRUSE_DECL_TNS(use
)))
19444 xmlChar
*str
= NULL
;
19446 xmlSchemaCustomWarning(ACTXT_CAST pctxt
,
19447 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH
,
19448 prohib
->node
, NULL
,
19449 "Skipping pointless attribute use prohibition "
19450 "'%s', since a corresponding attribute use "
19451 "exists already in the type definition",
19452 xmlSchemaFormatQName(&str
,
19453 prohib
->targetNamespace
, prohib
->name
),
19455 FREE_AND_NULL(str
);
19457 * Remove the prohibition.
19459 if (xmlSchemaItemListRemove(prohibs
, i
) == -1)
19470 * xmlSchemaAttributeGroupExpandRefs:
19471 * @pctxt: the parser context
19472 * @attrGr: the attribute group definition
19475 * {attribute uses} property
19476 * {attribute wildcard} property
19478 * Substitutes contained attribute group references
19479 * for their attribute uses. Wildcards are intersected.
19482 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt
,
19483 xmlSchemaAttributeGroupPtr attrGr
)
19485 if ((attrGr
->attrUses
== NULL
) ||
19486 (attrGr
->flags
& XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED
))
19489 attrGr
->flags
|= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED
;
19490 if (xmlSchemaExpandAttributeGroupRefs(pctxt
, WXS_BASIC_CAST attrGr
,
19491 &(attrGr
->attributeWildcard
), attrGr
->attrUses
, NULL
) == -1)
19497 * xmlSchemaAttributeGroupExpandRefs:
19498 * @pctxt: the parser context
19499 * @attrGr: the attribute group definition
19501 * Substitutes contained attribute group references
19502 * for their attribute uses. Wildcards are intersected.
19504 * Schema Component Constraint:
19505 * Attribute Group Definition Properties Correct (ag-props-correct)
19508 xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt
,
19509 xmlSchemaAttributeGroupPtr attrGr
)
19512 * SPEC ag-props-correct
19513 * (1) "The values of the properties of an attribute group definition
19514 * must be as described in the property tableau in The Attribute
19515 * Group Definition Schema Component ($3.6.1), modulo the impact of
19516 * Missing Sub-components ($5.3);"
19519 if ((attrGr
->attrUses
!= NULL
) &&
19520 (WXS_LIST_CAST attrGr
->attrUses
)->nbItems
> 1)
19522 xmlSchemaItemListPtr uses
= WXS_LIST_CAST attrGr
->attrUses
;
19523 xmlSchemaAttributeUsePtr use
, tmp
;
19524 int i
, j
, hasId
= 0;
19526 for (i
= uses
->nbItems
-1; i
>= 0; i
--) {
19527 use
= uses
->items
[i
];
19529 * SPEC ag-props-correct
19530 * (2) "Two distinct members of the {attribute uses} must not have
19531 * {attribute declaration}s both of whose {name}s match and whose
19532 * {target namespace}s are identical."
19535 for (j
= i
-1; j
>= 0; j
--) {
19536 tmp
= uses
->items
[j
];
19537 if ((WXS_ATTRUSE_DECL_NAME(use
) ==
19538 WXS_ATTRUSE_DECL_NAME(tmp
)) &&
19539 (WXS_ATTRUSE_DECL_TNS(use
) ==
19540 WXS_ATTRUSE_DECL_TNS(tmp
)))
19542 xmlChar
*str
= NULL
;
19544 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
19545 XML_SCHEMAP_AG_PROPS_CORRECT
,
19546 attrGr
->node
, WXS_BASIC_CAST attrGr
,
19548 xmlSchemaGetComponentDesignation(&str
, use
),
19550 FREE_AND_NULL(str
);
19552 * Remove the duplicate.
19554 if (xmlSchemaItemListRemove(uses
, i
) == -1)
19561 * SPEC ag-props-correct
19562 * (3) "Two distinct members of the {attribute uses} must not have
19563 * {attribute declaration}s both of whose {type definition}s are or
19564 * are derived from ID."
19565 * TODO: Does 'derived' include member-types of unions?
19567 if (WXS_ATTRUSE_TYPEDEF(use
) != NULL
) {
19568 if (xmlSchemaIsDerivedFromBuiltInType(
19569 WXS_ATTRUSE_TYPEDEF(use
), XML_SCHEMAS_ID
))
19572 xmlChar
*str
= NULL
;
19574 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
19575 XML_SCHEMAP_AG_PROPS_CORRECT
,
19576 attrGr
->node
, WXS_BASIC_CAST attrGr
,
19577 "There must not exist more than one attribute "
19578 "declaration of type 'xs:ID' "
19579 "(or derived from 'xs:ID'). The %s violates this "
19581 xmlSchemaGetComponentDesignation(&str
, use
),
19583 FREE_AND_NULL(str
);
19584 if (xmlSchemaItemListRemove(uses
, i
) == -1)
19597 * xmlSchemaResolveAttrGroupReferences:
19598 * @attrgrpDecl: the schema attribute definition
19599 * @ctxt: the schema parser context
19600 * @name: the attribute name
19602 * Resolves references to attribute group definitions.
19605 xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref
,
19606 xmlSchemaParserCtxtPtr ctxt
)
19608 xmlSchemaAttributeGroupPtr group
;
19610 if (ref
->item
!= NULL
)
19612 group
= xmlSchemaGetAttributeGroup(ctxt
->schema
,
19614 ref
->targetNamespace
);
19615 if (group
== NULL
) {
19616 xmlSchemaPResCompAttrErr(ctxt
,
19617 XML_SCHEMAP_SRC_RESOLVE
,
19619 "ref", ref
->name
, ref
->targetNamespace
,
19620 ref
->itemType
, NULL
);
19623 ref
->item
= WXS_BASIC_CAST group
;
19628 * xmlSchemaCheckAttrPropsCorrect:
19629 * @item: an schema attribute declaration/use
19630 * @ctxt: a schema parser context
19631 * @name: the name of the attribute
19634 * Schema Component Constraint:
19635 * Attribute Declaration Properties Correct (a-props-correct)
19637 * Validates the value constraints of an attribute declaration/use.
19638 * NOTE that this needs the simple type definitions to be already
19639 * built and checked.
19642 xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt
,
19643 xmlSchemaAttributePtr attr
)
19647 * SPEC a-props-correct (1)
19648 * "The values of the properties of an attribute declaration must
19649 * be as described in the property tableau in The Attribute
19650 * Declaration Schema Component ($3.2.1), modulo the impact of
19651 * Missing Sub-components ($5.3)."
19654 if (WXS_ATTR_TYPEDEF(attr
) == NULL
)
19657 if (attr
->defValue
!= NULL
) {
19661 * SPEC a-props-correct (3)
19662 * "If the {type definition} is or is derived from ID then there
19663 * must not be a {value constraint}."
19665 if (xmlSchemaIsDerivedFromBuiltInType(
19666 WXS_ATTR_TYPEDEF(attr
), XML_SCHEMAS_ID
))
19668 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
19669 XML_SCHEMAP_A_PROPS_CORRECT_3
,
19670 NULL
, WXS_BASIC_CAST attr
,
19671 "Value constraints are not allowed if the type definition "
19672 "is or is derived from xs:ID",
19674 return(pctxt
->err
);
19677 * SPEC a-props-correct (2)
19678 * "if there is a {value constraint}, the canonical lexical
19679 * representation of its value must be `valid` with respect
19680 * to the {type definition} as defined in String Valid ($3.14.4)."
19681 * TODO: Don't care about the *canonical* stuff here, this requirement
19682 * will be removed in WXS 1.1 anyway.
19684 ret
= xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt
,
19685 attr
->node
, WXS_ATTR_TYPEDEF(attr
),
19686 attr
->defValue
, &(attr
->defVal
),
19690 PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
19691 "calling xmlSchemaVCheckCVCSimpleType()");
19694 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
19695 XML_SCHEMAP_A_PROPS_CORRECT_2
,
19696 NULL
, WXS_BASIC_CAST attr
,
19697 "The value of the value constraint is not valid",
19699 return(pctxt
->err
);
19706 static xmlSchemaElementPtr
19707 xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl
,
19708 xmlSchemaElementPtr ancestor
)
19710 xmlSchemaElementPtr ret
;
19712 if (WXS_SUBST_HEAD(ancestor
) == NULL
)
19714 if (WXS_SUBST_HEAD(ancestor
) == elemDecl
)
19717 if (WXS_SUBST_HEAD(ancestor
)->flags
& XML_SCHEMAS_ELEM_CIRCULAR
)
19719 WXS_SUBST_HEAD(ancestor
)->flags
|= XML_SCHEMAS_ELEM_CIRCULAR
;
19720 ret
= xmlSchemaCheckSubstGroupCircular(elemDecl
,
19721 WXS_SUBST_HEAD(ancestor
));
19722 WXS_SUBST_HEAD(ancestor
)->flags
^= XML_SCHEMAS_ELEM_CIRCULAR
;
19728 * xmlSchemaCheckElemPropsCorrect:
19729 * @ctxt: a schema parser context
19730 * @decl: the element declaration
19731 * @name: the name of the attribute
19733 * Schema Component Constraint:
19734 * Element Declaration Properties Correct (e-props-correct)
19740 xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt
,
19741 xmlSchemaElementPtr elemDecl
)
19744 xmlSchemaTypePtr typeDef
= WXS_ELEM_TYPEDEF(elemDecl
);
19746 * SPEC (1) "The values of the properties of an element declaration
19747 * must be as described in the property tableau in The Element
19748 * Declaration Schema Component ($3.3.1), modulo the impact of Missing
19749 * Sub-components ($5.3)."
19751 if (WXS_SUBST_HEAD(elemDecl
) != NULL
) {
19752 xmlSchemaElementPtr head
= WXS_SUBST_HEAD(elemDecl
), circ
;
19754 xmlSchemaCheckElementDeclComponent(head
, pctxt
);
19756 * SPEC (3) "If there is a non-`absent` {substitution group
19757 * affiliation}, then {scope} must be global."
19759 if ((elemDecl
->flags
& XML_SCHEMAS_ELEM_GLOBAL
) == 0) {
19760 xmlSchemaPCustomErr(pctxt
,
19761 XML_SCHEMAP_E_PROPS_CORRECT_3
,
19762 WXS_BASIC_CAST elemDecl
, NULL
,
19763 "Only global element declarations can have a "
19764 "substitution group affiliation", NULL
);
19765 ret
= XML_SCHEMAP_E_PROPS_CORRECT_3
;
19768 * TODO: SPEC (6) "Circular substitution groups are disallowed.
19769 * That is, it must not be possible to return to an element declaration
19770 * by repeatedly following the {substitution group affiliation}
19773 if (head
== elemDecl
)
19775 else if (WXS_SUBST_HEAD(head
) != NULL
)
19776 circ
= xmlSchemaCheckSubstGroupCircular(head
, head
);
19779 if (circ
!= NULL
) {
19780 xmlChar
*strA
= NULL
, *strB
= NULL
;
19782 xmlSchemaPCustomErrExt(pctxt
,
19783 XML_SCHEMAP_E_PROPS_CORRECT_6
,
19784 WXS_BASIC_CAST circ
, NULL
,
19785 "The element declaration '%s' defines a circular "
19786 "substitution group to element declaration '%s'",
19787 xmlSchemaGetComponentQName(&strA
, circ
),
19788 xmlSchemaGetComponentQName(&strB
, head
),
19790 FREE_AND_NULL(strA
)
19791 FREE_AND_NULL(strB
)
19792 ret
= XML_SCHEMAP_E_PROPS_CORRECT_6
;
19795 * SPEC (4) "If there is a {substitution group affiliation},
19796 * the {type definition}
19797 * of the element declaration must be validly derived from the {type
19798 * definition} of the {substitution group affiliation}, given the value
19799 * of the {substitution group exclusions} of the {substitution group
19800 * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
19801 * (if the {type definition} is complex) or as defined in
19802 * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
19805 * NOTE: {substitution group exclusions} means the values of the
19806 * attribute "final".
19809 if (typeDef
!= WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl
))) {
19812 if (head
->flags
& XML_SCHEMAS_ELEM_FINAL_EXTENSION
)
19813 set
|= SUBSET_EXTENSION
;
19814 if (head
->flags
& XML_SCHEMAS_ELEM_FINAL_RESTRICTION
)
19815 set
|= SUBSET_RESTRICTION
;
19817 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt
, typeDef
,
19818 WXS_ELEM_TYPEDEF(head
), set
) != 0) {
19819 xmlChar
*strA
= NULL
, *strB
= NULL
, *strC
= NULL
;
19821 ret
= XML_SCHEMAP_E_PROPS_CORRECT_4
;
19822 xmlSchemaPCustomErrExt(pctxt
,
19823 XML_SCHEMAP_E_PROPS_CORRECT_4
,
19824 WXS_BASIC_CAST elemDecl
, NULL
,
19825 "The type definition '%s' was "
19826 "either rejected by the substitution group "
19827 "affiliation '%s', or not validly derived from its type "
19829 xmlSchemaGetComponentQName(&strA
, typeDef
),
19830 xmlSchemaGetComponentQName(&strB
, head
),
19831 xmlSchemaGetComponentQName(&strC
, WXS_ELEM_TYPEDEF(head
)));
19832 FREE_AND_NULL(strA
)
19833 FREE_AND_NULL(strB
)
19834 FREE_AND_NULL(strC
)
19839 * SPEC (5) "If the {type definition} or {type definition}'s
19841 * is or is derived from ID then there must not be a {value constraint}.
19842 * Note: The use of ID as a type definition for elements goes beyond
19843 * XML 1.0, and should be avoided if backwards compatibility is desired"
19845 if ((elemDecl
->value
!= NULL
) &&
19846 ((WXS_IS_SIMPLE(typeDef
) &&
19847 xmlSchemaIsDerivedFromBuiltInType(typeDef
, XML_SCHEMAS_ID
)) ||
19848 (WXS_IS_COMPLEX(typeDef
) &&
19849 WXS_HAS_SIMPLE_CONTENT(typeDef
) &&
19850 xmlSchemaIsDerivedFromBuiltInType(typeDef
->contentTypeDef
,
19851 XML_SCHEMAS_ID
)))) {
19853 ret
= XML_SCHEMAP_E_PROPS_CORRECT_5
;
19854 xmlSchemaPCustomErr(pctxt
,
19855 XML_SCHEMAP_E_PROPS_CORRECT_5
,
19856 WXS_BASIC_CAST elemDecl
, NULL
,
19857 "The type definition (or type definition's content type) is or "
19858 "is derived from ID; value constraints are not allowed in "
19859 "conjunction with such a type definition", NULL
);
19860 } else if (elemDecl
->value
!= NULL
) {
19862 xmlNodePtr node
= NULL
;
19865 * SPEC (2) "If there is a {value constraint}, the canonical lexical
19866 * representation of its value must be `valid` with respect to the
19867 * {type definition} as defined in Element Default Valid (Immediate)
19870 if (typeDef
== NULL
) {
19871 xmlSchemaPErr(pctxt
, elemDecl
->node
,
19872 XML_SCHEMAP_INTERNAL
,
19873 "Internal error: xmlSchemaCheckElemPropsCorrect, "
19874 "type is missing... skipping validation of "
19875 "the value constraint", NULL
, NULL
);
19878 if (elemDecl
->node
!= NULL
) {
19879 if (elemDecl
->flags
& XML_SCHEMAS_ELEM_FIXED
)
19880 node
= (xmlNodePtr
) xmlHasProp(elemDecl
->node
,
19883 node
= (xmlNodePtr
) xmlHasProp(elemDecl
->node
,
19884 BAD_CAST
"default");
19886 vcret
= xmlSchemaParseCheckCOSValidDefault(pctxt
, node
,
19887 typeDef
, elemDecl
->value
, &(elemDecl
->defVal
));
19890 PERROR_INT("xmlSchemaElemCheckValConstr",
19891 "failed to validate the value constraint of an "
19892 "element declaration");
19903 * xmlSchemaCheckElemSubstGroup:
19904 * @ctxt: a schema parser context
19905 * @decl: the element declaration
19906 * @name: the name of the attribute
19908 * Schema Component Constraint:
19909 * Substitution Group (cos-equiv-class)
19911 * In Libxml2 the subst. groups will be precomputed, in terms of that
19912 * a list will be built for each subst. group head, holding all direct
19913 * referents to this head.
19914 * NOTE that this function needs:
19915 * 1. circular subst. groups to be checked beforehand
19916 * 2. the declaration's type to be derived from the head's type
19922 xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt
,
19923 xmlSchemaElementPtr elemDecl
)
19925 if ((WXS_SUBST_HEAD(elemDecl
) == NULL
) ||
19926 /* SPEC (1) "Its {abstract} is false." */
19927 (elemDecl
->flags
& XML_SCHEMAS_ELEM_ABSTRACT
))
19930 xmlSchemaElementPtr head
;
19931 xmlSchemaTypePtr headType
, type
;
19934 * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
19935 * {disallowed substitutions} as the blocking constraint, as defined in
19936 * Substitution Group OK (Transitive) ($3.3.6)."
19938 for (head
= WXS_SUBST_HEAD(elemDecl
); head
!= NULL
;
19939 head
= WXS_SUBST_HEAD(head
)) {
19943 * The blocking constraints.
19945 if (head
->flags
& XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION
)
19947 headType
= head
->subtypes
;
19948 type
= elemDecl
->subtypes
;
19949 if (headType
== type
)
19951 if (head
->flags
& XML_SCHEMAS_ELEM_BLOCK_RESTRICTION
)
19952 set
|= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
;
19953 if (head
->flags
& XML_SCHEMAS_ELEM_BLOCK_EXTENSION
)
19954 set
|= XML_SCHEMAS_TYPE_BLOCK_EXTENSION
;
19956 * SPEC: Substitution Group OK (Transitive) (2.3)
19957 * "The set of all {derivation method}s involved in the
19958 * derivation of D's {type definition} from C's {type definition}
19959 * does not intersect with the union of the blocking constraint,
19960 * C's {prohibited substitutions} (if C is complex, otherwise the
19961 * empty set) and the {prohibited substitutions} (respectively the
19962 * empty set) of any intermediate {type definition}s in the
19963 * derivation of D's {type definition} from C's {type definition}."
19966 * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
19967 * subst.head axis, the methSet does not need to be computed for
19968 * the full depth over and over.
19971 * The set of all {derivation method}s involved in the derivation
19973 while ((type
!= NULL
) && (type
!= headType
) &&
19974 (type
!= type
->baseType
)) {
19975 if ((WXS_IS_EXTENSION(type
)) &&
19976 ((methSet
& XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
) == 0))
19977 methSet
|= XML_SCHEMAS_TYPE_BLOCK_EXTENSION
;
19979 if (WXS_IS_RESTRICTION(type
) &&
19980 ((methSet
& XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
) == 0))
19981 methSet
|= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
;
19983 type
= type
->baseType
;
19986 * The {prohibited substitutions} of all intermediate types +
19989 type
= elemDecl
->subtypes
->baseType
;
19990 while (type
!= NULL
) {
19991 if (WXS_IS_COMPLEX(type
)) {
19993 XML_SCHEMAS_TYPE_BLOCK_EXTENSION
) &&
19994 ((set
& XML_SCHEMAS_TYPE_BLOCK_EXTENSION
) == 0))
19995 set
|= XML_SCHEMAS_TYPE_BLOCK_EXTENSION
;
19997 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
) &&
19998 ((set
& XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
) == 0))
19999 set
|= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
;
20002 if (type
== headType
)
20004 type
= type
->baseType
;
20007 (((set
& XML_SCHEMAS_TYPE_BLOCK_EXTENSION
) &&
20008 (methSet
& XML_SCHEMAS_TYPE_BLOCK_EXTENSION
)) ||
20009 ((set
& XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
) &&
20010 (methSet
& XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
)))) {
20014 xmlSchemaAddElementSubstitutionMember(ctxt
, head
, elemDecl
);
20015 if ((head
->flags
& XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD
) == 0)
20016 head
->flags
|= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD
;
20021 #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
20023 * xmlSchemaCheckElementDeclComponent
20024 * @pctxt: the schema parser context
20025 * @ctxtComponent: the context component (an element declaration)
20026 * @ctxtParticle: the first particle of the context component
20027 * @searchParticle: the element declaration particle to be analysed
20029 * Schema Component Constraint: Element Declarations Consistent
20032 xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt
,
20033 xmlSchemaBasicItemPtr ctxtComponent
,
20034 xmlSchemaParticlePtr ctxtParticle
,
20035 xmlSchemaParticlePtr searchParticle
,
20036 xmlSchemaParticlePtr curParticle
,
20042 xmlSchemaParticlePtr cur
= curParticle
;
20043 if (curParticle
== NULL
) {
20046 if (WXS_PARTICLE_TERM(curParticle
) == NULL
) {
20048 * Just return in this case. A missing "term" of the particle
20049 * might arise due to an invalid "term" component.
20053 while (cur
!= NULL
) {
20054 switch (WXS_PARTICLE_TERM(cur
)->type
) {
20055 case XML_SCHEMA_TYPE_ANY
:
20057 case XML_SCHEMA_TYPE_ELEMENT
:
20059 ret
= xmlSchemaCheckElementDeclConsistent(pctxt
,
20060 ctxtComponent
, ctxtParticle
, cur
, ctxtParticle
, 1);
20064 xmlSchemaElementPtr elem
=
20065 WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur
));
20067 * SPEC Element Declarations Consistent:
20068 * "If the {particles} contains, either directly,
20069 * indirectly (that is, within the {particles} of a
20070 * contained model group, recursively) or `implicitly`
20071 * two or more element declaration particles with
20072 * the same {name} and {target namespace}, then
20073 * all their type definitions must be the same
20074 * top-level definition [...]"
20076 if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur
)->name
,
20077 WXS_PARTICLE_TERM_AS_ELEM(searchParticle
)->name
) &&
20078 xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur
)->targetNamespace
,
20079 WXS_PARTICLE_TERM_AS_ELEM(searchParticle
)->targetNamespace
))
20081 xmlChar
*strA
= NULL
, *strB
= NULL
;
20083 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
20084 /* TODO: error code */
20085 XML_SCHEMAP_COS_NONAMBIG
,
20086 WXS_ITEM_NODE(cur
), NULL
,
20087 "In the content model of %s, there are multiple "
20088 "element declarations for '%s' with different "
20089 "type definitions",
20090 xmlSchemaGetComponentDesignation(&strA
,
20092 xmlSchemaFormatQName(&strB
,
20093 WXS_PARTICLE_TERM_AS_ELEM(cur
)->targetNamespace
,
20094 WXS_PARTICLE_TERM_AS_ELEM(cur
)->name
));
20095 FREE_AND_NULL(strA
);
20096 FREE_AND_NULL(strB
);
20097 return(XML_SCHEMAP_COS_NONAMBIG
);
20101 case XML_SCHEMA_TYPE_SEQUENCE
: {
20104 case XML_SCHEMA_TYPE_CHOICE
:{
20106 xmlSchemaTreeItemPtr sub;
20108 sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr)
20109 while (sub != NULL) {
20110 ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
20111 ctxtParticle, ctxtElem);
20119 case XML_SCHEMA_TYPE_ALL
:
20121 case XML_SCHEMA_TYPE_GROUP
:
20124 xmlSchemaInternalErr2(ACTXT_CAST pctxt
,
20125 "xmlSchemaCheckElementDeclConsistent",
20126 "found unexpected term of type '%s' in content model",
20127 WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur
)), NULL
);
20130 cur
= (xmlSchemaParticlePtr
) cur
->next
;
20139 * xmlSchemaCheckElementDeclComponent
20140 * @item: an schema element declaration/particle
20141 * @ctxt: a schema parser context
20142 * @name: the name of the attribute
20144 * Validates the value constraints of an element declaration.
20145 * Adds substitution group members.
20148 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl
,
20149 xmlSchemaParserCtxtPtr ctxt
)
20151 if (elemDecl
== NULL
)
20153 if (elemDecl
->flags
& XML_SCHEMAS_ELEM_INTERNAL_CHECKED
)
20155 elemDecl
->flags
|= XML_SCHEMAS_ELEM_INTERNAL_CHECKED
;
20156 if (xmlSchemaCheckElemPropsCorrect(ctxt
, elemDecl
) == 0) {
20158 * Adds substitution group members.
20160 xmlSchemaCheckElemSubstGroup(ctxt
, elemDecl
);
20165 * xmlSchemaResolveModelGroupParticleReferences:
20166 * @particle: a particle component
20167 * @ctxt: a parser context
20169 * Resolves references of a model group's {particles} to
20170 * model group definitions and to element declarations.
20173 xmlSchemaResolveModelGroupParticleReferences(
20174 xmlSchemaParserCtxtPtr ctxt
,
20175 xmlSchemaModelGroupPtr mg
)
20177 xmlSchemaParticlePtr particle
= WXS_MODELGROUP_PARTICLE(mg
);
20178 xmlSchemaQNameRefPtr ref
;
20179 xmlSchemaBasicItemPtr refItem
;
20182 * URGENT TODO: Test this.
20184 while (particle
!= NULL
) {
20185 if ((WXS_PARTICLE_TERM(particle
) == NULL
) ||
20186 ((WXS_PARTICLE_TERM(particle
))->type
!=
20187 XML_SCHEMA_EXTRA_QNAMEREF
))
20189 goto next_particle
;
20191 ref
= WXS_QNAME_CAST
WXS_PARTICLE_TERM(particle
);
20193 * Resolve the reference.
20194 * NULL the {term} by default.
20196 particle
->children
= NULL
;
20198 refItem
= xmlSchemaGetNamedComponent(ctxt
->schema
,
20199 ref
->itemType
, ref
->name
, ref
->targetNamespace
);
20200 if (refItem
== NULL
) {
20201 xmlSchemaPResCompAttrErr(ctxt
, XML_SCHEMAP_SRC_RESOLVE
,
20202 NULL
, WXS_ITEM_NODE(particle
), "ref", ref
->name
,
20203 ref
->targetNamespace
, ref
->itemType
, NULL
);
20204 /* TODO: remove the particle. */
20205 goto next_particle
;
20207 if (refItem
->type
== XML_SCHEMA_TYPE_GROUP
) {
20208 if (WXS_MODELGROUPDEF_MODEL(refItem
) == NULL
)
20209 /* TODO: remove the particle. */
20210 goto next_particle
;
20212 * NOTE that we will assign the model group definition
20213 * itself to the "term" of the particle. This will ease
20214 * the check for circular model group definitions. After
20215 * that the "term" will be assigned the model group of the
20216 * model group definition.
20218 if ((WXS_MODELGROUPDEF_MODEL(refItem
))->type
==
20219 XML_SCHEMA_TYPE_ALL
) {
20221 * SPEC cos-all-limited (1)
20222 * SPEC cos-all-limited (1.2)
20223 * "It appears only as the value of one or both of the
20224 * following properties:"
20225 * (1.1) "the {model group} property of a model group
20227 * (1.2) "the {term} property of a particle [... of] the "
20228 * {content type} of a complex type definition."
20230 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
20231 /* TODO: error code */
20232 XML_SCHEMAP_COS_ALL_LIMITED
,
20233 WXS_ITEM_NODE(particle
), NULL
,
20234 "A model group definition is referenced, but "
20235 "it contains an 'all' model group, which "
20236 "cannot be contained by model groups",
20238 /* TODO: remove the particle. */
20239 goto next_particle
;
20241 particle
->children
= (xmlSchemaTreeItemPtr
) refItem
;
20244 * TODO: Are referenced element declarations the only
20245 * other components we expect here?
20247 particle
->children
= (xmlSchemaTreeItemPtr
) refItem
;
20250 particle
= WXS_PTC_CAST particle
->next
;
20255 xmlSchemaAreValuesEqual(xmlSchemaValPtr x
,
20258 xmlSchemaTypePtr tx
, ty
, ptx
, pty
;
20261 while (x
!= NULL
) {
20263 tx
= xmlSchemaGetBuiltInType(xmlSchemaGetValType(x
));
20264 ty
= xmlSchemaGetBuiltInType(xmlSchemaGetValType(y
));
20265 ptx
= xmlSchemaGetPrimitiveType(tx
);
20266 pty
= xmlSchemaGetPrimitiveType(ty
);
20268 * (1) if a datatype T' is `derived` by `restriction` from an
20269 * atomic datatype T then the `value space` of T' is a subset of
20270 * the `value space` of T. */
20272 * (2) if datatypes T' and T'' are `derived` by `restriction`
20273 * from a common atomic ancestor T then the `value space`s of T'
20274 * and T'' may overlap.
20279 * We assume computed values to be normalized, so do a fast
20280 * string comparison for string based types.
20282 if ((ptx
->builtInType
== XML_SCHEMAS_STRING
) ||
20283 WXS_IS_ANY_SIMPLE_TYPE(ptx
)) {
20285 xmlSchemaValueGetAsString(x
),
20286 xmlSchemaValueGetAsString(y
)))
20289 ret
= xmlSchemaCompareValuesWhtsp(
20290 x
, XML_SCHEMA_WHITESPACE_PRESERVE
,
20291 y
, XML_SCHEMA_WHITESPACE_PRESERVE
);
20300 x
= xmlSchemaValueGetNext(x
);
20302 y
= xmlSchemaValueGetNext(y
);
20305 } else if (xmlSchemaValueGetNext(y
) != NULL
)
20314 * xmlSchemaResolveAttrUseReferences:
20315 * @item: an attribute use
20316 * @ctxt: a parser context
20318 * Resolves the referenced attribute declaration.
20321 xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause
,
20322 xmlSchemaParserCtxtPtr ctxt
)
20324 if ((ctxt
== NULL
) || (ause
== NULL
))
20326 if ((ause
->attrDecl
== NULL
) ||
20327 (ause
->attrDecl
->type
!= XML_SCHEMA_EXTRA_QNAMEREF
))
20331 xmlSchemaQNameRefPtr ref
= WXS_QNAME_CAST ause
->attrDecl
;
20334 * TODO: Evaluate, what errors could occur if the declaration is not
20337 ause
->attrDecl
= xmlSchemaGetAttributeDecl(ctxt
->schema
,
20338 ref
->name
, ref
->targetNamespace
);
20339 if (ause
->attrDecl
== NULL
) {
20340 xmlSchemaPResCompAttrErr(ctxt
,
20341 XML_SCHEMAP_SRC_RESOLVE
,
20342 WXS_BASIC_CAST ause
, ause
->node
,
20343 "ref", ref
->name
, ref
->targetNamespace
,
20344 XML_SCHEMA_TYPE_ATTRIBUTE
, NULL
);
20345 return(ctxt
->err
);;
20352 * xmlSchemaCheckAttrUsePropsCorrect:
20353 * @ctxt: a parser context
20354 * @use: an attribute use
20356 * Schema Component Constraint:
20357 * Attribute Use Correct (au-props-correct)
20361 xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt
,
20362 xmlSchemaAttributeUsePtr use
)
20364 if ((ctxt
== NULL
) || (use
== NULL
))
20366 if ((use
->defValue
== NULL
) || (WXS_ATTRUSE_DECL(use
) == NULL
) ||
20367 ((WXS_ATTRUSE_DECL(use
))->type
!= XML_SCHEMA_TYPE_ATTRIBUTE
))
20371 * SPEC au-props-correct (1)
20372 * "The values of the properties of an attribute use must be as
20373 * described in the property tableau in The Attribute Use Schema
20374 * Component ($3.5.1), modulo the impact of Missing
20375 * Sub-components ($5.3)."
20378 if (((WXS_ATTRUSE_DECL(use
))->defValue
!= NULL
) &&
20379 ((WXS_ATTRUSE_DECL(use
))->flags
& XML_SCHEMAS_ATTR_FIXED
) &&
20380 ((use
->flags
& XML_SCHEMA_ATTR_USE_FIXED
) == 0))
20382 xmlSchemaPCustomErr(ctxt
,
20383 XML_SCHEMAP_AU_PROPS_CORRECT_2
,
20384 WXS_BASIC_CAST use
, NULL
,
20385 "The attribute declaration has a 'fixed' value constraint "
20386 ", thus the attribute use must also have a 'fixed' value "
20392 * Compute and check the value constraint's value.
20394 if ((use
->defVal
!= NULL
) && (WXS_ATTRUSE_TYPEDEF(use
) != NULL
)) {
20397 * TODO: The spec seems to be missing a check of the
20398 * value constraint of the attribute use. We will do it here.
20401 * SPEC a-props-correct (3)
20403 if (xmlSchemaIsDerivedFromBuiltInType(
20404 WXS_ATTRUSE_TYPEDEF(use
), XML_SCHEMAS_ID
))
20406 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
20407 XML_SCHEMAP_AU_PROPS_CORRECT
,
20408 NULL
, WXS_BASIC_CAST use
,
20409 "Value constraints are not allowed if the type definition "
20410 "is or is derived from xs:ID",
20415 ret
= xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt
,
20416 use
->node
, WXS_ATTRUSE_TYPEDEF(use
),
20417 use
->defValue
, &(use
->defVal
),
20421 PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
20422 "calling xmlSchemaVCheckCVCSimpleType()");
20425 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
20426 XML_SCHEMAP_AU_PROPS_CORRECT
,
20427 NULL
, WXS_BASIC_CAST use
,
20428 "The value of the value constraint is not valid",
20434 * SPEC au-props-correct (2)
20435 * "If the {attribute declaration} has a fixed
20436 * {value constraint}, then if the attribute use itself has a
20437 * {value constraint}, it must also be fixed and its value must match
20438 * that of the {attribute declaration}'s {value constraint}."
20440 if (((WXS_ATTRUSE_DECL(use
))->defVal
!= NULL
) &&
20441 (((WXS_ATTRUSE_DECL(use
))->flags
& XML_SCHEMA_ATTR_USE_FIXED
) == 0))
20443 if (! xmlSchemaAreValuesEqual(use
->defVal
,
20444 (WXS_ATTRUSE_DECL(use
))->defVal
))
20446 xmlSchemaPCustomErr(ctxt
,
20447 XML_SCHEMAP_AU_PROPS_CORRECT_2
,
20448 WXS_BASIC_CAST use
, NULL
,
20449 "The 'fixed' value constraint of the attribute use "
20450 "must match the attribute declaration's value "
20452 (WXS_ATTRUSE_DECL(use
))->defValue
);
20463 * xmlSchemaResolveAttrTypeReferences:
20464 * @item: an attribute declaration
20465 * @ctxt: a parser context
20467 * Resolves the referenced type definition component.
20470 xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item
,
20471 xmlSchemaParserCtxtPtr ctxt
)
20474 * The simple type definition corresponding to the <simpleType> element
20475 * information item in the [children], if present, otherwise the simple
20476 * type definition `resolved` to by the `actual value` of the type
20477 * [attribute], if present, otherwise the `simple ur-type definition`.
20479 if (item
->flags
& XML_SCHEMAS_ATTR_INTERNAL_RESOLVED
)
20481 item
->flags
|= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED
;
20482 if (item
->subtypes
!= NULL
)
20484 if (item
->typeName
!= NULL
) {
20485 xmlSchemaTypePtr type
;
20487 type
= xmlSchemaGetType(ctxt
->schema
, item
->typeName
,
20489 if ((type
== NULL
) || (! WXS_IS_SIMPLE(type
))) {
20490 xmlSchemaPResCompAttrErr(ctxt
,
20491 XML_SCHEMAP_SRC_RESOLVE
,
20492 WXS_BASIC_CAST item
, item
->node
,
20493 "type", item
->typeName
, item
->typeNs
,
20494 XML_SCHEMA_TYPE_SIMPLE
, NULL
);
20497 item
->subtypes
= type
;
20501 * The type defaults to the xs:anySimpleType.
20503 item
->subtypes
= xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE
);
20509 * xmlSchemaResolveIDCKeyReferences:
20510 * @idc: the identity-constraint definition
20511 * @ctxt: the schema parser context
20512 * @name: the attribute name
20514 * Resolve keyRef references to key/unique IDCs.
20515 * Schema Component Constraint:
20516 * Identity-constraint Definition Properties Correct (c-props-correct)
20519 xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc
,
20520 xmlSchemaParserCtxtPtr pctxt
)
20522 if (idc
->type
!= XML_SCHEMA_TYPE_IDC_KEYREF
)
20524 if (idc
->ref
->name
!= NULL
) {
20525 idc
->ref
->item
= (xmlSchemaBasicItemPtr
)
20526 xmlSchemaGetIDC(pctxt
->schema
, idc
->ref
->name
,
20527 idc
->ref
->targetNamespace
);
20528 if (idc
->ref
->item
== NULL
) {
20530 * TODO: It is actually not an error to fail to resolve
20531 * at this stage. BUT we need to be that strict!
20533 xmlSchemaPResCompAttrErr(pctxt
,
20534 XML_SCHEMAP_SRC_RESOLVE
,
20535 WXS_BASIC_CAST idc
, idc
->node
,
20536 "refer", idc
->ref
->name
,
20537 idc
->ref
->targetNamespace
,
20538 XML_SCHEMA_TYPE_IDC_KEY
, NULL
);
20539 return(pctxt
->err
);
20540 } else if (idc
->ref
->item
->type
== XML_SCHEMA_TYPE_IDC_KEYREF
) {
20542 * SPEC c-props-correct (1)
20544 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
20545 XML_SCHEMAP_C_PROPS_CORRECT
,
20546 NULL
, WXS_BASIC_CAST idc
,
20547 "The keyref references a keyref",
20549 idc
->ref
->item
= NULL
;
20550 return(pctxt
->err
);
20552 if (idc
->nbFields
!=
20553 ((xmlSchemaIDCPtr
) idc
->ref
->item
)->nbFields
) {
20554 xmlChar
*str
= NULL
;
20555 xmlSchemaIDCPtr refer
;
20557 refer
= (xmlSchemaIDCPtr
) idc
->ref
->item
;
20559 * SPEC c-props-correct(2)
20560 * "If the {identity-constraint category} is keyref,
20561 * the cardinality of the {fields} must equal that of
20562 * the {fields} of the {referenced key}.
20564 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
20565 XML_SCHEMAP_C_PROPS_CORRECT
,
20566 NULL
, WXS_BASIC_CAST idc
,
20567 "The cardinality of the keyref differs from the "
20568 "cardinality of the referenced key/unique '%s'",
20569 xmlSchemaFormatQName(&str
, refer
->targetNamespace
,
20573 return(pctxt
->err
);
20581 xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib
,
20582 xmlSchemaParserCtxtPtr pctxt
)
20584 if (xmlSchemaGetAttributeDecl(pctxt
->schema
, prohib
->name
,
20585 prohib
->targetNamespace
) == NULL
) {
20587 xmlSchemaPResCompAttrErr(pctxt
,
20588 XML_SCHEMAP_SRC_RESOLVE
,
20589 NULL
, prohib
->node
,
20590 "ref", prohib
->name
, prohib
->targetNamespace
,
20591 XML_SCHEMA_TYPE_ATTRIBUTE
, NULL
);
20592 return(XML_SCHEMAP_SRC_RESOLVE
);
20597 #define WXS_REDEFINED_TYPE(c) \
20598 (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
20600 #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
20601 (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20603 #define WXS_REDEFINED_ATTR_GROUP(c) \
20604 (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
20607 xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt
)
20610 xmlSchemaRedefPtr redef
= WXS_CONSTRUCTOR(pctxt
)->redefs
;
20611 xmlSchemaBasicItemPtr prev
, item
;
20618 item
= redef
->item
;
20620 * First try to locate the redefined component in the
20621 * schema graph starting with the redefined schema.
20622 * NOTE: According to this schema bug entry:
20623 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
20624 * it's not clear if the referenced component needs to originate
20625 * from the <redefine>d schema _document_ or the schema; the latter
20626 * would include all imported and included sub-schemas of the
20627 * <redefine>d schema. Currently the latter approach is used.
20628 * SUPPLEMENT: It seems that the WG moves towards the latter
20629 * approach, so we are doing it right.
20632 prev
= xmlSchemaFindRedefCompInGraph(
20633 redef
->targetBucket
, item
->type
,
20634 redef
->refName
, redef
->refTargetNs
);
20635 if (prev
== NULL
) {
20636 xmlChar
*str
= NULL
;
20640 * SPEC src-redefine:
20641 * (6.2.1) "The `actual value` of its own name attribute plus
20642 * target namespace must successfully `resolve` to a model
20643 * group definition in I."
20644 * (7.2.1) "The `actual value` of its own name attribute plus
20645 * target namespace must successfully `resolve` to an attribute
20646 * group definition in I."
20649 * Note that, if we are redefining with the use of references
20650 * to components, the spec assumes the src-resolve to be used;
20651 * but this won't assure that we search only *inside* the
20652 * redefined schema.
20654 if (redef
->reference
)
20655 node
= WXS_ITEM_NODE(redef
->reference
);
20657 node
= WXS_ITEM_NODE(item
);
20658 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
20660 * TODO: error code.
20661 * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
20664 XML_SCHEMAP_SRC_REDEFINE
, node
, NULL
,
20665 "The %s '%s' to be redefined could not be found in "
20666 "the redefined schema",
20667 WXS_ITEM_TYPE_NAME(item
),
20668 xmlSchemaFormatQName(&str
, redef
->refTargetNs
,
20670 FREE_AND_NULL(str
);
20672 redef
= redef
->next
;
20676 * TODO: Obtaining and setting the redefinition state is really
20680 switch (item
->type
) {
20681 case XML_SCHEMA_TYPE_COMPLEX
:
20682 case XML_SCHEMA_TYPE_SIMPLE
:
20683 if ((WXS_TYPE_CAST prev
)->flags
&
20684 XML_SCHEMAS_TYPE_REDEFINED
)
20689 /* Mark it as redefined. */
20690 (WXS_TYPE_CAST prev
)->flags
|= XML_SCHEMAS_TYPE_REDEFINED
;
20692 * Assign the redefined type to the
20693 * base type of the redefining type.
20696 ((xmlSchemaTypePtr
) item
)->baseType
=
20697 (xmlSchemaTypePtr
) prev
;
20699 case XML_SCHEMA_TYPE_GROUP
:
20700 if ((WXS_MODEL_GROUPDEF_CAST prev
)->flags
&
20701 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED
)
20706 /* Mark it as redefined. */
20707 (WXS_MODEL_GROUPDEF_CAST prev
)->flags
|=
20708 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED
;
20709 if (redef
->reference
!= NULL
) {
20711 * Overwrite the QName-reference with the
20712 * referenced model group def.
20714 (WXS_PTC_CAST redef
->reference
)->children
=
20715 WXS_TREE_CAST prev
;
20717 redef
->target
= prev
;
20719 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
20720 if ((WXS_ATTR_GROUP_CAST prev
)->flags
&
20721 XML_SCHEMAS_ATTRGROUP_REDEFINED
)
20726 (WXS_ATTR_GROUP_CAST prev
)->flags
|=
20727 XML_SCHEMAS_ATTRGROUP_REDEFINED
;
20728 if (redef
->reference
!= NULL
) {
20730 * Assign the redefined attribute group to the
20731 * QName-reference component.
20732 * This is the easy case, since we will just
20733 * expand the redefined group.
20735 (WXS_QNAME_CAST redef
->reference
)->item
= prev
;
20736 redef
->target
= NULL
;
20739 * This is the complicated case: we need
20740 * to apply src-redefine (7.2.2) at a later
20741 * stage, i.e. when attribute group references
20742 * have been expanded and simple types have
20745 redef
->target
= prev
;
20749 PERROR_INT("xmlSchemaResolveRedefReferences",
20750 "Unexpected redefined component type");
20753 if (wasRedefined
) {
20754 xmlChar
*str
= NULL
;
20757 if (redef
->reference
)
20758 node
= WXS_ITEM_NODE(redef
->reference
);
20760 node
= WXS_ITEM_NODE(redef
->item
);
20762 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
20763 /* TODO: error code. */
20764 XML_SCHEMAP_SRC_REDEFINE
,
20766 "The referenced %s was already redefined. Multiple "
20767 "redefinition of the same component is not supported",
20768 xmlSchemaGetComponentDesignation(&str
, prev
),
20772 redef
= redef
->next
;
20775 redef
= redef
->next
;
20776 } while (redef
!= NULL
);
20782 xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt
)
20785 xmlSchemaRedefPtr redef
= WXS_CONSTRUCTOR(pctxt
)->redefs
;
20786 xmlSchemaBasicItemPtr item
;
20792 if (redef
->target
== NULL
) {
20793 redef
= redef
->next
;
20796 item
= redef
->item
;
20798 switch (item
->type
) {
20799 case XML_SCHEMA_TYPE_SIMPLE
:
20800 case XML_SCHEMA_TYPE_COMPLEX
:
20802 * Since the spec wants the {name} of the redefined
20803 * type to be 'absent', we'll NULL it.
20805 (WXS_TYPE_CAST redef
->target
)->name
= NULL
;
20808 * TODO: Seems like there's nothing more to do. The normal
20809 * inheritance mechanism is used. But not 100% sure.
20812 case XML_SCHEMA_TYPE_GROUP
:
20815 * SPEC src-redefine:
20816 * (6.2.2) "The {model group} of the model group definition
20817 * which corresponds to it per XML Representation of Model
20818 * Group Definition Schema Components ($3.7.2) must be a
20819 * `valid restriction` of the {model group} of that model
20820 * group definition in I, as defined in Particle Valid
20821 * (Restriction) ($3.9.6)."
20824 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
20826 * SPEC src-redefine:
20827 * (7.2.2) "The {attribute uses} and {attribute wildcard} of
20828 * the attribute group definition which corresponds to it
20829 * per XML Representation of Attribute Group Definition Schema
20830 * Components ($3.6.2) must be `valid restrictions` of the
20831 * {attribute uses} and {attribute wildcard} of that attribute
20832 * group definition in I, as defined in clause 2, clause 3 and
20833 * clause 4 of Derivation Valid (Restriction, Complex)
20834 * ($3.4.6) (where references to the base type definition are
20835 * understood as references to the attribute group definition
20838 err
= xmlSchemaCheckDerivationOKRestriction2to4(pctxt
,
20839 XML_SCHEMA_ACTION_REDEFINE
,
20840 item
, redef
->target
,
20841 (WXS_ATTR_GROUP_CAST item
)->attrUses
,
20842 (WXS_ATTR_GROUP_CAST redef
->target
)->attrUses
,
20843 (WXS_ATTR_GROUP_CAST item
)->attributeWildcard
,
20844 (WXS_ATTR_GROUP_CAST redef
->target
)->attributeWildcard
);
20851 redef
= redef
->next
;
20852 } while (redef
!= NULL
);
20858 xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt
,
20859 xmlSchemaBucketPtr bucket
)
20861 xmlSchemaBasicItemPtr item
;
20863 xmlHashTablePtr
*table
;
20864 const xmlChar
*name
;
20867 #define WXS_GET_GLOBAL_HASH(c, slot) { \
20868 if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
20869 table = &(WXS_IMPBUCKET((c))->schema->slot); \
20871 table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
20874 * Add global components to the schema's hash tables.
20875 * This is the place where duplicate components will be
20877 * TODO: I think normally we should support imports of the
20878 * same namespace from multiple locations. We don't do currently,
20879 * but if we do then according to:
20880 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
20881 * we would need, if imported directly, to import redefined
20882 * components as well to be able to catch clashing components.
20883 * (I hope I'll still know what this means after some months :-()
20885 if (bucket
== NULL
)
20887 if (bucket
->flags
& XML_SCHEMA_BUCKET_COMPS_ADDED
)
20889 bucket
->flags
|= XML_SCHEMA_BUCKET_COMPS_ADDED
;
20891 for (i
= 0; i
< bucket
->globals
->nbItems
; i
++) {
20892 item
= bucket
->globals
->items
[i
];
20894 switch (item
->type
) {
20895 case XML_SCHEMA_TYPE_COMPLEX
:
20896 case XML_SCHEMA_TYPE_SIMPLE
:
20897 if (WXS_REDEFINED_TYPE(item
))
20899 name
= (WXS_TYPE_CAST item
)->name
;
20900 WXS_GET_GLOBAL_HASH(bucket
, typeDecl
)
20902 case XML_SCHEMA_TYPE_ELEMENT
:
20903 name
= (WXS_ELEM_CAST item
)->name
;
20904 WXS_GET_GLOBAL_HASH(bucket
, elemDecl
)
20906 case XML_SCHEMA_TYPE_ATTRIBUTE
:
20907 name
= (WXS_ATTR_CAST item
)->name
;
20908 WXS_GET_GLOBAL_HASH(bucket
, attrDecl
)
20910 case XML_SCHEMA_TYPE_GROUP
:
20911 if (WXS_REDEFINED_MODEL_GROUP_DEF(item
))
20913 name
= (WXS_MODEL_GROUPDEF_CAST item
)->name
;
20914 WXS_GET_GLOBAL_HASH(bucket
, groupDecl
)
20916 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
20917 if (WXS_REDEFINED_ATTR_GROUP(item
))
20919 name
= (WXS_ATTR_GROUP_CAST item
)->name
;
20920 WXS_GET_GLOBAL_HASH(bucket
, attrgrpDecl
)
20922 case XML_SCHEMA_TYPE_IDC_KEY
:
20923 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
20924 case XML_SCHEMA_TYPE_IDC_KEYREF
:
20925 name
= (WXS_IDC_CAST item
)->name
;
20926 WXS_GET_GLOBAL_HASH(bucket
, idcDef
)
20928 case XML_SCHEMA_TYPE_NOTATION
:
20929 name
= ((xmlSchemaNotationPtr
) item
)->name
;
20930 WXS_GET_GLOBAL_HASH(bucket
, notaDecl
)
20933 PERROR_INT("xmlSchemaAddComponents",
20934 "Unexpected global component type");
20937 if (*table
== NULL
) {
20938 *table
= xmlHashCreateDict(10, pctxt
->dict
);
20939 if (*table
== NULL
) {
20940 PERROR_INT("xmlSchemaAddComponents",
20941 "failed to create a component hash table");
20945 err
= xmlHashAddEntry(*table
, name
, item
);
20947 xmlChar
*str
= NULL
;
20949 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
20950 XML_SCHEMAP_REDEFINED_TYPE
,
20951 WXS_ITEM_NODE(item
),
20952 WXS_BASIC_CAST item
,
20953 "A global %s '%s' does already exist",
20954 WXS_ITEM_TYPE_NAME(item
),
20955 xmlSchemaGetComponentQName(&str
, item
));
20956 FREE_AND_NULL(str
);
20960 * Process imported/included schemas.
20962 if (bucket
->relations
!= NULL
) {
20963 xmlSchemaSchemaRelationPtr rel
= bucket
->relations
;
20965 if ((rel
->bucket
!= NULL
) &&
20966 ((rel
->bucket
->flags
& XML_SCHEMA_BUCKET_COMPS_ADDED
) == 0)) {
20967 if (xmlSchemaAddComponents(pctxt
, rel
->bucket
) == -1)
20971 } while (rel
!= NULL
);
20977 xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt
,
20978 xmlSchemaBucketPtr rootBucket
)
20980 xmlSchemaConstructionCtxtPtr con
= pctxt
->constructor
;
20981 xmlSchemaTreeItemPtr item
, *items
;
20982 int nbItems
, i
, ret
= 0;
20983 xmlSchemaBucketPtr oldbucket
= con
->bucket
;
20984 xmlSchemaElementPtr elemDecl
;
20986 #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
20988 if ((con
->pending
== NULL
) ||
20989 (con
->pending
->nbItems
== 0))
20993 * Since xmlSchemaFixupComplexType() will create new particles
20994 * (local components), and those particle components need a bucket
20995 * on the constructor, we'll assure here that the constructor has
20997 * TODO: Think about storing locals _only_ on the main bucket.
20999 if (con
->bucket
== NULL
)
21000 con
->bucket
= rootBucket
;
21003 * SPEC (src-redefine):
21004 * (6.2) "If it has no such self-reference, then all of the
21005 * following must be true:"
21007 * (6.2.2) The {model group} of the model group definition which
21008 * corresponds to it per XML Representation of Model Group
21009 * Definition Schema Components ($3.7.2) must be a `valid
21010 * restriction` of the {model group} of that model group definition
21011 * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
21013 xmlSchemaCheckSRCRedefineFirst(pctxt
);
21016 * Add global components to the schemata's hash tables.
21018 xmlSchemaAddComponents(pctxt
, rootBucket
);
21020 pctxt
->ctxtType
= NULL
;
21021 items
= (xmlSchemaTreeItemPtr
*) con
->pending
->items
;
21022 nbItems
= con
->pending
->nbItems
;
21024 * Now that we have parsed *all* the schema document(s) and converted
21025 * them to schema components, we can resolve references, apply component
21026 * constraints, create the FSA from the content model, etc.
21029 * Resolve references of..
21031 * 1. element declarations:
21032 * - the type definition
21033 * - the substitution group affiliation
21034 * 2. simple/complex types:
21035 * - the base type definition
21036 * - the memberTypes of union types
21037 * - the itemType of list types
21038 * 3. attributes declarations and attribute uses:
21039 * - the type definition
21040 * - if an attribute use, then the attribute declaration
21041 * 4. attribute group references:
21042 * - the attribute group definition
21044 * - the term of the particle (e.g. a model group)
21045 * 6. IDC key-references:
21046 * - the referenced IDC 'key' or 'unique' definition
21047 * 7. Attribute prohibitions which had a "ref" attribute.
21049 for (i
= 0; i
< nbItems
; i
++) {
21051 switch (item
->type
) {
21052 case XML_SCHEMA_TYPE_ELEMENT
:
21053 xmlSchemaResolveElementReferences(
21054 (xmlSchemaElementPtr
) item
, pctxt
);
21057 case XML_SCHEMA_TYPE_COMPLEX
:
21058 case XML_SCHEMA_TYPE_SIMPLE
:
21059 xmlSchemaResolveTypeReferences(
21060 (xmlSchemaTypePtr
) item
, pctxt
);
21063 case XML_SCHEMA_TYPE_ATTRIBUTE
:
21064 xmlSchemaResolveAttrTypeReferences(
21065 (xmlSchemaAttributePtr
) item
, pctxt
);
21068 case XML_SCHEMA_TYPE_ATTRIBUTE_USE
:
21069 xmlSchemaResolveAttrUseReferences(
21070 (xmlSchemaAttributeUsePtr
) item
, pctxt
);
21073 case XML_SCHEMA_EXTRA_QNAMEREF
:
21074 if ((WXS_QNAME_CAST item
)->itemType
==
21075 XML_SCHEMA_TYPE_ATTRIBUTEGROUP
)
21077 xmlSchemaResolveAttrGroupReferences(
21078 WXS_QNAME_CAST item
, pctxt
);
21082 case XML_SCHEMA_TYPE_SEQUENCE
:
21083 case XML_SCHEMA_TYPE_CHOICE
:
21084 case XML_SCHEMA_TYPE_ALL
:
21085 xmlSchemaResolveModelGroupParticleReferences(pctxt
,
21086 WXS_MODEL_GROUP_CAST item
);
21089 case XML_SCHEMA_TYPE_IDC_KEY
:
21090 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
21091 case XML_SCHEMA_TYPE_IDC_KEYREF
:
21092 xmlSchemaResolveIDCKeyReferences(
21093 (xmlSchemaIDCPtr
) item
, pctxt
);
21096 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB
:
21098 * Handle attribute prohibition which had a
21101 xmlSchemaResolveAttrUseProhibReferences(
21102 WXS_ATTR_PROHIB_CAST item
, pctxt
);
21109 if (pctxt
->nberrors
!= 0)
21113 * Now that all references are resolved we
21114 * can check for circularity of...
21115 * 1. the base axis of type definitions
21116 * 2. nested model group definitions
21117 * 3. nested attribute group definitions
21118 * TODO: check for circular substitution groups.
21120 for (i
= 0; i
< nbItems
; i
++) {
21123 * Let's better stop on the first error here.
21125 switch (item
->type
) {
21126 case XML_SCHEMA_TYPE_COMPLEX
:
21127 case XML_SCHEMA_TYPE_SIMPLE
:
21128 xmlSchemaCheckTypeDefCircular(
21129 (xmlSchemaTypePtr
) item
, pctxt
);
21131 if (pctxt
->nberrors
!= 0)
21134 case XML_SCHEMA_TYPE_GROUP
:
21135 xmlSchemaCheckGroupDefCircular(
21136 (xmlSchemaModelGroupDefPtr
) item
, pctxt
);
21138 if (pctxt
->nberrors
!= 0)
21141 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
21142 xmlSchemaCheckAttrGroupCircular(
21143 (xmlSchemaAttributeGroupPtr
) item
, pctxt
);
21145 if (pctxt
->nberrors
!= 0)
21152 if (pctxt
->nberrors
!= 0)
21155 * Model group definition references:
21156 * Such a reference is reflected by a particle at the component
21157 * level. Until now the 'term' of such particles pointed
21158 * to the model group definition; this was done, in order to
21159 * ease circularity checks. Now we need to set the 'term' of
21160 * such particles to the model group of the model group definition.
21162 for (i
= 0; i
< nbItems
; i
++) {
21164 switch (item
->type
) {
21165 case XML_SCHEMA_TYPE_SEQUENCE
:
21166 case XML_SCHEMA_TYPE_CHOICE
:
21167 xmlSchemaModelGroupToModelGroupDefFixup(pctxt
,
21168 WXS_MODEL_GROUP_CAST item
);
21174 if (pctxt
->nberrors
!= 0)
21177 * Expand attribute group references of attribute group definitions.
21179 for (i
= 0; i
< nbItems
; i
++) {
21181 switch (item
->type
) {
21182 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
21183 if ((! WXS_ATTR_GROUP_EXPANDED(item
)) &&
21184 WXS_ATTR_GROUP_HAS_REFS(item
))
21186 xmlSchemaAttributeGroupExpandRefs(pctxt
,
21187 WXS_ATTR_GROUP_CAST item
);
21195 if (pctxt
->nberrors
!= 0)
21198 * First compute the variety of simple types. This is needed as
21199 * a separate step, since otherwise we won't be able to detect
21200 * circular union types in all cases.
21202 for (i
= 0; i
< nbItems
; i
++) {
21204 switch (item
->type
) {
21205 case XML_SCHEMA_TYPE_SIMPLE
:
21206 if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr
) item
)) {
21207 xmlSchemaFixupSimpleTypeStageOne(pctxt
,
21208 (xmlSchemaTypePtr
) item
);
21216 if (pctxt
->nberrors
!= 0)
21219 * Detect circular union types. Note that this needs the variety to
21220 * be already computed.
21222 for (i
= 0; i
< nbItems
; i
++) {
21224 switch (item
->type
) {
21225 case XML_SCHEMA_TYPE_SIMPLE
:
21226 if (((xmlSchemaTypePtr
) item
)->memberTypes
!= NULL
) {
21227 xmlSchemaCheckUnionTypeDefCircular(pctxt
,
21228 (xmlSchemaTypePtr
) item
);
21236 if (pctxt
->nberrors
!= 0)
21240 * Do the complete type fixup for simple types.
21242 for (i
= 0; i
< nbItems
; i
++) {
21244 switch (item
->type
) {
21245 case XML_SCHEMA_TYPE_SIMPLE
:
21246 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item
)) {
21247 xmlSchemaFixupSimpleTypeStageTwo(pctxt
, WXS_TYPE_CAST item
);
21255 if (pctxt
->nberrors
!= 0)
21258 * At this point we need build and check all simple types.
21261 * Apply constraints for attribute declarations.
21263 for (i
= 0; i
< nbItems
; i
++) {
21265 switch (item
->type
) {
21266 case XML_SCHEMA_TYPE_ATTRIBUTE
:
21267 xmlSchemaCheckAttrPropsCorrect(pctxt
, WXS_ATTR_CAST item
);
21274 if (pctxt
->nberrors
!= 0)
21277 * Apply constraints for attribute uses.
21279 for (i
= 0; i
< nbItems
; i
++) {
21281 switch (item
->type
) {
21282 case XML_SCHEMA_TYPE_ATTRIBUTE_USE
:
21283 if (((xmlSchemaAttributeUsePtr
)item
)->defValue
!= NULL
) {
21284 xmlSchemaCheckAttrUsePropsCorrect(pctxt
,
21285 WXS_ATTR_USE_CAST item
);
21293 if (pctxt
->nberrors
!= 0)
21297 * Apply constraints for attribute group definitions.
21299 for (i
= 0; i
< nbItems
; i
++) {
21301 switch (item
->type
) {
21302 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
21303 if (( (WXS_ATTR_GROUP_CAST item
)->attrUses
!= NULL
) &&
21304 ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item
)->attrUses
)->nbItems
> 1))
21306 xmlSchemaCheckAGPropsCorrect(pctxt
, WXS_ATTR_GROUP_CAST item
);
21314 if (pctxt
->nberrors
!= 0)
21318 * Apply constraints for redefinitions.
21320 if (WXS_CONSTRUCTOR(pctxt
)->redefs
!= NULL
)
21321 xmlSchemaCheckSRCRedefineSecond(pctxt
);
21322 if (pctxt
->nberrors
!= 0)
21326 * Complex types are built and checked.
21328 for (i
= 0; i
< nbItems
; i
++) {
21329 item
= con
->pending
->items
[i
];
21330 switch (item
->type
) {
21331 case XML_SCHEMA_TYPE_COMPLEX
:
21332 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item
)) {
21333 xmlSchemaFixupComplexType(pctxt
, WXS_TYPE_CAST item
);
21341 if (pctxt
->nberrors
!= 0)
21345 * The list could have changed, since xmlSchemaFixupComplexType()
21346 * will create particles and model groups in some cases.
21348 items
= (xmlSchemaTreeItemPtr
*) con
->pending
->items
;
21349 nbItems
= con
->pending
->nbItems
;
21352 * Apply some constraints for element declarations.
21354 for (i
= 0; i
< nbItems
; i
++) {
21356 switch (item
->type
) {
21357 case XML_SCHEMA_TYPE_ELEMENT
:
21358 elemDecl
= (xmlSchemaElementPtr
) item
;
21360 if ((elemDecl
->flags
& XML_SCHEMAS_ELEM_INTERNAL_CHECKED
) == 0)
21362 xmlSchemaCheckElementDeclComponent(
21363 (xmlSchemaElementPtr
) elemDecl
, pctxt
);
21367 #ifdef WXS_ELEM_DECL_CONS_ENABLED
21369 * Schema Component Constraint: Element Declarations Consistent
21370 * Apply this constraint to local types of element declarations.
21372 if ((WXS_ELEM_TYPEDEF(elemDecl
) != NULL
) &&
21373 (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl
))) &&
21374 (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl
))))
21376 xmlSchemaCheckElementDeclConsistent(pctxt
,
21377 WXS_BASIC_CAST elemDecl
,
21378 WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl
)),
21387 if (pctxt
->nberrors
!= 0)
21391 * Finally we can build the automaton from the content model of
21395 for (i
= 0; i
< nbItems
; i
++) {
21397 switch (item
->type
) {
21398 case XML_SCHEMA_TYPE_COMPLEX
:
21399 xmlSchemaBuildContentModel((xmlSchemaTypePtr
) item
, pctxt
);
21406 if (pctxt
->nberrors
!= 0)
21409 * URGENT TODO: cos-element-consistent
21422 * Reset the constructor. This is needed for XSI acquisition, since
21423 * those items will be processed over and over again for every XSI
21424 * if not cleared here.
21426 con
->bucket
= oldbucket
;
21427 con
->pending
->nbItems
= 0;
21428 if (con
->substGroups
!= NULL
) {
21429 xmlHashFree(con
->substGroups
, xmlSchemaSubstGroupFreeEntry
);
21430 con
->substGroups
= NULL
;
21432 if (con
->redefs
!= NULL
) {
21433 xmlSchemaRedefListFree(con
->redefs
);
21434 con
->redefs
= NULL
;
21440 * @ctxt: a schema validation context
21442 * parse a schema definition resource and build an internal
21443 * XML Schema structure which can be used to validate instances.
21445 * Returns the internal XML Schema structure built from the resource or
21446 * NULL in case of error
21449 xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt
)
21451 xmlSchemaPtr mainSchema
= NULL
;
21452 xmlSchemaBucketPtr bucket
= NULL
;
21456 * This one is used if the schema to be parsed was specified via
21457 * the API; i.e. not automatically by the validated instance document.
21460 if (xmlSchemaInitTypes() < 0)
21466 /* TODO: Init the context. Is this all we need?*/
21467 ctxt
->nberrors
= 0;
21471 /* Create the *main* schema. */
21472 mainSchema
= xmlSchemaNewSchema(ctxt
);
21473 if (mainSchema
== NULL
)
21476 * Create the schema constructor.
21478 if (ctxt
->constructor
== NULL
) {
21479 ctxt
->constructor
= xmlSchemaConstructionCtxtCreate(ctxt
->dict
);
21480 if (ctxt
->constructor
== NULL
)
21482 /* Take ownership of the constructor to be able to free it. */
21483 ctxt
->ownsConstructor
= 1;
21485 ctxt
->constructor
->mainSchema
= mainSchema
;
21487 * Locate and add the schema document.
21489 res
= xmlSchemaAddSchemaDoc(ctxt
, XML_SCHEMA_SCHEMA_MAIN
,
21490 ctxt
->URL
, ctxt
->doc
, ctxt
->buffer
, ctxt
->size
, NULL
,
21491 NULL
, NULL
, &bucket
);
21497 if (bucket
== NULL
) {
21498 /* TODO: Error code, actually we failed to *locate* the schema. */
21500 xmlSchemaCustomErr(ACTXT_CAST ctxt
, XML_SCHEMAP_FAILED_LOAD
,
21502 "Failed to locate the main schema resource at '%s'",
21505 xmlSchemaCustomErr(ACTXT_CAST ctxt
, XML_SCHEMAP_FAILED_LOAD
,
21507 "Failed to locate the main schema resource",
21511 /* Then do the parsing for good. */
21512 if (xmlSchemaParseNewDocWithContext(ctxt
, mainSchema
, bucket
) == -1)
21514 if (ctxt
->nberrors
!= 0)
21517 mainSchema
->doc
= bucket
->doc
;
21518 mainSchema
->preserve
= ctxt
->preserve
;
21520 ctxt
->schema
= mainSchema
;
21522 if (xmlSchemaFixupComponents(ctxt
, WXS_CONSTRUCTOR(ctxt
)->mainBucket
) == -1)
21526 * TODO: This is not nice, since we cannot distinguish from the
21527 * result if there was an internal error or not.
21530 if (ctxt
->nberrors
!= 0) {
21532 xmlSchemaFree(mainSchema
);
21535 if (ctxt
->constructor
) {
21536 xmlSchemaConstructionCtxtFree(ctxt
->constructor
);
21537 ctxt
->constructor
= NULL
;
21538 ctxt
->ownsConstructor
= 0;
21541 ctxt
->schema
= NULL
;
21542 return(mainSchema
);
21545 * Quite verbose, but should catch internal errors, which were
21546 * not communicated.
21549 xmlSchemaFree(mainSchema
);
21552 if (ctxt
->constructor
) {
21553 xmlSchemaConstructionCtxtFree(ctxt
->constructor
);
21554 ctxt
->constructor
= NULL
;
21555 ctxt
->ownsConstructor
= 0;
21557 PERROR_INT2("xmlSchemaParse",
21558 "An internal error occurred");
21559 ctxt
->schema
= NULL
;
21564 * xmlSchemaSetParserErrors:
21565 * @ctxt: a schema validation context
21566 * @err: the error callback
21567 * @warn: the warning callback
21568 * @ctx: contextual data for the callbacks
21570 * Set the callback functions used to handle errors for a validation context
21573 xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt
,
21574 xmlSchemaValidityErrorFunc err
,
21575 xmlSchemaValidityWarningFunc warn
, void *ctx
)
21580 ctxt
->warning
= warn
;
21581 ctxt
->errCtxt
= ctx
;
21582 if (ctxt
->vctxt
!= NULL
)
21583 xmlSchemaSetValidErrors(ctxt
->vctxt
, err
, warn
, ctx
);
21587 * xmlSchemaSetParserStructuredErrors:
21588 * @ctxt: a schema parser context
21589 * @serror: the structured error function
21590 * @ctx: the functions context
21592 * Set the structured error callback
21595 xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt
,
21596 xmlStructuredErrorFunc serror
,
21601 ctxt
->serror
= serror
;
21602 ctxt
->errCtxt
= ctx
;
21603 if (ctxt
->vctxt
!= NULL
)
21604 xmlSchemaSetValidStructuredErrors(ctxt
->vctxt
, serror
, ctx
);
21608 * xmlSchemaGetParserErrors:
21609 * @ctxt: a XMl-Schema parser context
21610 * @err: the error callback result
21611 * @warn: the warning callback result
21612 * @ctx: contextual data for the callbacks result
21614 * Get the callback information used to handle errors for a parser context
21616 * Returns -1 in case of failure, 0 otherwise
21619 xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt
,
21620 xmlSchemaValidityErrorFunc
* err
,
21621 xmlSchemaValidityWarningFunc
* warn
, void **ctx
)
21626 *err
= ctxt
->error
;
21628 *warn
= ctxt
->warning
;
21630 *ctx
= ctxt
->errCtxt
;
21635 * xmlSchemaFacetTypeToString:
21636 * @type: the facet type
21638 * Convert the xmlSchemaTypeType to a char string.
21640 * Returns the char string representation of the facet type if the
21641 * type is a facet and an "Internal Error" string otherwise.
21643 static const xmlChar
*
21644 xmlSchemaFacetTypeToString(xmlSchemaTypeType type
)
21647 case XML_SCHEMA_FACET_PATTERN
:
21648 return (BAD_CAST
"pattern");
21649 case XML_SCHEMA_FACET_MAXEXCLUSIVE
:
21650 return (BAD_CAST
"maxExclusive");
21651 case XML_SCHEMA_FACET_MAXINCLUSIVE
:
21652 return (BAD_CAST
"maxInclusive");
21653 case XML_SCHEMA_FACET_MINEXCLUSIVE
:
21654 return (BAD_CAST
"minExclusive");
21655 case XML_SCHEMA_FACET_MININCLUSIVE
:
21656 return (BAD_CAST
"minInclusive");
21657 case XML_SCHEMA_FACET_WHITESPACE
:
21658 return (BAD_CAST
"whiteSpace");
21659 case XML_SCHEMA_FACET_ENUMERATION
:
21660 return (BAD_CAST
"enumeration");
21661 case XML_SCHEMA_FACET_LENGTH
:
21662 return (BAD_CAST
"length");
21663 case XML_SCHEMA_FACET_MAXLENGTH
:
21664 return (BAD_CAST
"maxLength");
21665 case XML_SCHEMA_FACET_MINLENGTH
:
21666 return (BAD_CAST
"minLength");
21667 case XML_SCHEMA_FACET_TOTALDIGITS
:
21668 return (BAD_CAST
"totalDigits");
21669 case XML_SCHEMA_FACET_FRACTIONDIGITS
:
21670 return (BAD_CAST
"fractionDigits");
21674 return (BAD_CAST
"Internal Error");
21677 static xmlSchemaWhitespaceValueType
21678 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type
)
21681 * The normalization type can be changed only for types which are derived
21684 if (type
->type
== XML_SCHEMA_TYPE_BASIC
) {
21686 * Note that we assume a whitespace of preserve for anySimpleType.
21688 if ((type
->builtInType
== XML_SCHEMAS_STRING
) ||
21689 (type
->builtInType
== XML_SCHEMAS_ANYSIMPLETYPE
))
21690 return(XML_SCHEMA_WHITESPACE_PRESERVE
);
21691 else if (type
->builtInType
== XML_SCHEMAS_NORMSTRING
)
21692 return(XML_SCHEMA_WHITESPACE_REPLACE
);
21695 * For all `atomic` datatypes other than string (and types `derived`
21696 * by `restriction` from it) the value of whiteSpace is fixed to
21698 * Note that this includes built-in list datatypes.
21700 return(XML_SCHEMA_WHITESPACE_COLLAPSE
);
21702 } else if (WXS_IS_LIST(type
)) {
21704 * For list types the facet "whiteSpace" is fixed to "collapse".
21706 return (XML_SCHEMA_WHITESPACE_COLLAPSE
);
21707 } else if (WXS_IS_UNION(type
)) {
21708 return (XML_SCHEMA_WHITESPACE_UNKNOWN
);
21709 } else if (WXS_IS_ATOMIC(type
)) {
21710 if (type
->flags
& XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE
)
21711 return (XML_SCHEMA_WHITESPACE_PRESERVE
);
21712 else if (type
->flags
& XML_SCHEMAS_TYPE_WHITESPACE_REPLACE
)
21713 return (XML_SCHEMA_WHITESPACE_REPLACE
);
21715 return (XML_SCHEMA_WHITESPACE_COLLAPSE
);
21720 /************************************************************************
21722 * Simple type validation *
21724 ************************************************************************/
21727 /************************************************************************
21729 * DOM Validation code *
21731 ************************************************************************/
21734 * xmlSchemaAssembleByLocation:
21735 * @pctxt: a schema parser context
21736 * @vctxt: a schema validation context
21737 * @schema: the existing schema
21738 * @node: the node that fired the assembling
21739 * @nsName: the namespace name of the new schema
21740 * @location: the location of the schema
21742 * Expands an existing schema by an additional schema.
21744 * Returns 0 if the new schema is correct, a positive error code
21745 * number otherwise and -1 in case of an internal or API error.
21748 xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt
,
21749 xmlSchemaPtr schema
,
21751 const xmlChar
*nsName
,
21752 const xmlChar
*location
)
21755 xmlSchemaParserCtxtPtr pctxt
;
21756 xmlSchemaBucketPtr bucket
= NULL
;
21758 if ((vctxt
== NULL
) || (schema
== NULL
))
21761 if (vctxt
->pctxt
== NULL
) {
21762 VERROR_INT("xmlSchemaAssembleByLocation",
21763 "no parser context available");
21766 pctxt
= vctxt
->pctxt
;
21767 if (pctxt
->constructor
== NULL
) {
21768 PERROR_INT("xmlSchemaAssembleByLocation",
21773 * Acquire the schema document.
21775 location
= xmlSchemaBuildAbsoluteURI(pctxt
->dict
,
21778 * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
21779 * the process will automatically change this to
21780 * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
21782 ret
= xmlSchemaAddSchemaDoc(pctxt
, XML_SCHEMA_SCHEMA_IMPORT
,
21783 location
, NULL
, NULL
, 0, node
, NULL
, nsName
,
21787 if (bucket
== NULL
) {
21789 * Generate a warning that the document could not be located.
21791 xmlSchemaCustomWarning(ACTXT_CAST vctxt
, XML_SCHEMAV_MISC
,
21793 "The document at location '%s' could not be acquired",
21794 location
, NULL
, NULL
);
21798 * The first located schema will be handled as if all other
21799 * schemas imported by XSI were imported by this first schema.
21801 if ((bucket
!= NULL
) &&
21802 (WXS_CONSTRUCTOR(pctxt
)->bucket
== NULL
))
21803 WXS_CONSTRUCTOR(pctxt
)->bucket
= bucket
;
21805 * TODO: Is this handled like an import? I.e. is it not an error
21806 * if the schema cannot be located?
21808 if ((bucket
== NULL
) || (! CAN_PARSE_SCHEMA(bucket
)))
21811 * We will reuse the parser context for every schema imported
21812 * directly via XSI. So reset the context.
21814 pctxt
->nberrors
= 0;
21816 pctxt
->doc
= bucket
->doc
;
21818 ret
= xmlSchemaParseNewDocWithContext(pctxt
, schema
, bucket
);
21823 /* Paranoid error channelling. */
21824 if ((ret
== 0) && (pctxt
->nberrors
!= 0))
21826 if (pctxt
->nberrors
== 0) {
21828 * Only bother to fixup pending components, if there was
21830 * For every XSI acquired schema (and its sub-schemata) we will
21831 * fixup the components.
21833 xmlSchemaFixupComponents(pctxt
, bucket
);
21836 * Not nice, but we need somehow to channel the schema parser
21837 * error to the validation context.
21839 if ((ret
!= 0) && (vctxt
->err
== 0))
21841 vctxt
->nberrors
+= pctxt
->nberrors
;
21843 /* Add to validation error sum. */
21844 vctxt
->nberrors
+= pctxt
->nberrors
;
21853 static xmlSchemaAttrInfoPtr
21854 xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt
,
21857 if (vctxt
->nbAttrInfos
== 0)
21861 xmlSchemaAttrInfoPtr iattr
;
21863 for (i
= 0; i
< vctxt
->nbAttrInfos
; i
++) {
21864 iattr
= vctxt
->attrInfos
[i
];
21865 if (iattr
->metaType
== metaType
)
21874 * xmlSchemaAssembleByXSI:
21875 * @vctxt: a schema validation context
21877 * Expands an existing schema by an additional schema using
21878 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
21879 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
21880 * must be set to 1.
21882 * Returns 0 if the new schema is correct, a positive error code
21883 * number otherwise and -1 in case of an internal or API error.
21886 xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt
)
21888 const xmlChar
*cur
, *end
;
21889 const xmlChar
*nsname
= NULL
, *location
;
21891 xmlSchemaAttrInfoPtr iattr
;
21894 * Parse the value; we will assume an even number of values
21895 * to be given (this is how Xerces and XSV work).
21897 * URGENT TODO: !! This needs to work for both
21898 * @noNamespaceSchemaLocation AND @schemaLocation on the same
21901 iattr
= xmlSchemaGetMetaAttrInfo(vctxt
,
21902 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC
);
21904 iattr
= xmlSchemaGetMetaAttrInfo(vctxt
,
21905 XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC
);
21908 cur
= iattr
->value
;
21911 * TODO: Move the string parsing mechanism away from here.
21913 if (iattr
->metaType
== XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC
) {
21915 * Get the namespace name.
21917 while (IS_BLANK_CH(*cur
))
21920 while ((*end
!= 0) && (!(IS_BLANK_CH(*end
))))
21924 /* TODO: Don't use the schema's dict. */
21925 nsname
= xmlDictLookup(vctxt
->schema
->dict
, cur
, end
- cur
);
21931 while (IS_BLANK_CH(*cur
))
21934 while ((*end
!= 0) && (!(IS_BLANK_CH(*end
))))
21937 if (iattr
->metaType
==
21938 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC
)
21941 * If using @schemaLocation then tuples are expected.
21942 * I.e. the namespace name *and* the document's URI.
21944 xmlSchemaCustomWarning(ACTXT_CAST vctxt
, XML_SCHEMAV_MISC
,
21946 "The value must consist of tuples: the target namespace "
21947 "name and the document's URI", NULL
, NULL
, NULL
);
21951 /* TODO: Don't use the schema's dict. */
21952 location
= xmlDictLookup(vctxt
->schema
->dict
, cur
, end
- cur
);
21954 ret
= xmlSchemaAssembleByLocation(vctxt
, vctxt
->schema
,
21955 iattr
->node
, nsname
, location
);
21957 VERROR_INT("xmlSchemaAssembleByXSI",
21958 "assembling schemata");
21961 } while (*cur
!= 0);
21965 static const xmlChar
*
21966 xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt
,
21967 const xmlChar
*prefix
)
21969 if (vctxt
->sax
!= NULL
) {
21971 xmlSchemaNodeInfoPtr inode
;
21973 for (i
= vctxt
->depth
; i
>= 0; i
--) {
21974 if (vctxt
->elemInfos
[i
]->nbNsBindings
!= 0) {
21975 inode
= vctxt
->elemInfos
[i
];
21976 for (j
= 0; j
< inode
->nbNsBindings
* 2; j
+= 2) {
21977 if (((prefix
== NULL
) &&
21978 (inode
->nsBindings
[j
] == NULL
)) ||
21979 ((prefix
!= NULL
) && xmlStrEqual(prefix
,
21980 inode
->nsBindings
[j
]))) {
21983 * Note that the namespace bindings are already
21984 * in a string dict.
21986 return (inode
->nsBindings
[j
+1]);
21992 #ifdef LIBXML_READER_ENABLED
21993 } else if (vctxt
->reader
!= NULL
) {
21996 nsName
= xmlTextReaderLookupNamespace(vctxt
->reader
, prefix
);
21997 if (nsName
!= NULL
) {
21998 const xmlChar
*ret
;
22000 ret
= xmlDictLookup(vctxt
->dict
, nsName
, -1);
22009 if ((vctxt
->inode
->node
== NULL
) ||
22010 (vctxt
->inode
->node
->doc
== NULL
)) {
22011 VERROR_INT("xmlSchemaLookupNamespace",
22012 "no node or node's doc available");
22015 ns
= xmlSearchNs(vctxt
->inode
->node
->doc
,
22016 vctxt
->inode
->node
, prefix
);
22024 * This one works on the schema of the validation context.
22027 xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt
,
22028 xmlSchemaPtr schema
,
22030 const xmlChar
*value
,
22031 xmlSchemaValPtr
*val
,
22036 if (vctxt
&& (vctxt
->schema
== NULL
)) {
22037 VERROR_INT("xmlSchemaValidateNotation",
22038 "a schema is needed on the validation context");
22041 ret
= xmlValidateQName(value
, 1);
22045 xmlChar
*localName
= NULL
;
22046 xmlChar
*prefix
= NULL
;
22048 localName
= xmlSplitQName2(value
, &prefix
);
22049 if (prefix
!= NULL
) {
22050 const xmlChar
*nsName
= NULL
;
22053 nsName
= xmlSchemaLookupNamespace(vctxt
, BAD_CAST prefix
);
22054 else if (node
!= NULL
) {
22055 xmlNsPtr ns
= xmlSearchNs(node
->doc
, node
, prefix
);
22060 xmlFree(localName
);
22063 if (nsName
== NULL
) {
22065 xmlFree(localName
);
22068 if (xmlSchemaGetNotation(schema
, localName
, nsName
) != NULL
) {
22069 if ((valNeeded
) && (val
!= NULL
)) {
22070 (*val
) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName
),
22071 xmlStrdup(nsName
));
22078 xmlFree(localName
);
22080 if (xmlSchemaGetNotation(schema
, value
, NULL
) != NULL
) {
22081 if (valNeeded
&& (val
!= NULL
)) {
22082 (*val
) = xmlSchemaNewNOTATIONValue(
22083 BAD_CAST
xmlStrdup(value
), NULL
);
22095 xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt
,
22096 const xmlChar
* lname
,
22097 const xmlChar
* nsname
)
22101 lname
= xmlDictLookup(vctxt
->dict
, lname
, -1);
22104 if (nsname
!= NULL
) {
22105 nsname
= xmlDictLookup(vctxt
->dict
, nsname
, -1);
22106 if (nsname
== NULL
)
22109 for (i
= 0; i
< vctxt
->nodeQNames
->nbItems
; i
+= 2) {
22110 if ((vctxt
->nodeQNames
->items
[i
] == lname
) &&
22111 (vctxt
->nodeQNames
->items
[i
+1] == nsname
))
22112 /* Already there */
22115 /* Add new entry. */
22116 i
= vctxt
->nodeQNames
->nbItems
;
22117 xmlSchemaItemListAdd(vctxt
->nodeQNames
, (void *) lname
);
22118 xmlSchemaItemListAdd(vctxt
->nodeQNames
, (void *) nsname
);
22122 /************************************************************************
22124 * Validation of identity-constraints (IDC) *
22126 ************************************************************************/
22129 * xmlSchemaAugmentIDC:
22130 * @idcDef: the IDC definition
22132 * Creates an augmented IDC definition item.
22134 * Returns the item, or NULL on internal errors.
22137 xmlSchemaAugmentIDC(void *payload
, void *data
,
22138 const xmlChar
*name ATTRIBUTE_UNUSED
)
22140 xmlSchemaIDCPtr idcDef
= (xmlSchemaIDCPtr
) payload
;
22141 xmlSchemaValidCtxtPtr vctxt
= (xmlSchemaValidCtxtPtr
) data
;
22142 xmlSchemaIDCAugPtr aidc
;
22144 aidc
= (xmlSchemaIDCAugPtr
) xmlMalloc(sizeof(xmlSchemaIDCAug
));
22145 if (aidc
== NULL
) {
22146 xmlSchemaVErrMemory(vctxt
,
22147 "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
22151 aidc
->keyrefDepth
= -1;
22152 aidc
->def
= idcDef
;
22154 if (vctxt
->aidcs
== NULL
)
22155 vctxt
->aidcs
= aidc
;
22157 aidc
->next
= vctxt
->aidcs
;
22158 vctxt
->aidcs
= aidc
;
22161 * Save if we have keyrefs at all.
22163 if ((vctxt
->hasKeyrefs
== 0) &&
22164 (idcDef
->type
== XML_SCHEMA_TYPE_IDC_KEYREF
))
22165 vctxt
->hasKeyrefs
= 1;
22169 * xmlSchemaAugmentImportedIDC:
22170 * @imported: the imported schema
22172 * Creates an augmented IDC definition for the imported schema.
22175 xmlSchemaAugmentImportedIDC(void *payload
, void *data
,
22176 const xmlChar
*name ATTRIBUTE_UNUSED
) {
22177 xmlSchemaImportPtr imported
= (xmlSchemaImportPtr
) payload
;
22178 xmlSchemaValidCtxtPtr vctxt
= (xmlSchemaValidCtxtPtr
) data
;
22179 if (imported
->schema
->idcDef
!= NULL
) {
22180 xmlHashScan(imported
->schema
->idcDef
, xmlSchemaAugmentIDC
, vctxt
);
22185 * xmlSchemaIDCNewBinding:
22186 * @idcDef: the IDC definition of this binding
22188 * Creates a new IDC binding.
22190 * Returns the new IDC binding, NULL on internal errors.
22192 static xmlSchemaPSVIIDCBindingPtr
22193 xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef
)
22195 xmlSchemaPSVIIDCBindingPtr ret
;
22197 ret
= (xmlSchemaPSVIIDCBindingPtr
) xmlMalloc(
22198 sizeof(xmlSchemaPSVIIDCBinding
));
22200 xmlSchemaVErrMemory(NULL
,
22201 "allocating a PSVI IDC binding item", NULL
);
22204 memset(ret
, 0, sizeof(xmlSchemaPSVIIDCBinding
));
22205 ret
->definition
= idcDef
;
22210 * xmlSchemaIDCStoreNodeTableItem:
22211 * @vctxt: the WXS validation context
22212 * @item: the IDC node table item
22214 * The validation context is used to store IDC node table items.
22215 * They are stored to avoid copying them if IDC node-tables are merged
22216 * with corresponding parent IDC node-tables (bubbling).
22218 * Returns 0 if succeeded, -1 on internal errors.
22221 xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt
,
22222 xmlSchemaPSVIIDCNodePtr item
)
22225 * Add to global list.
22227 if (vctxt
->idcNodes
== NULL
) {
22228 vctxt
->idcNodes
= (xmlSchemaPSVIIDCNodePtr
*)
22229 xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr
));
22230 if (vctxt
->idcNodes
== NULL
) {
22231 xmlSchemaVErrMemory(vctxt
,
22232 "allocating the IDC node table item list", NULL
);
22235 vctxt
->sizeIdcNodes
= 20;
22236 } else if (vctxt
->sizeIdcNodes
<= vctxt
->nbIdcNodes
) {
22237 vctxt
->sizeIdcNodes
*= 2;
22238 vctxt
->idcNodes
= (xmlSchemaPSVIIDCNodePtr
*)
22239 xmlRealloc(vctxt
->idcNodes
, vctxt
->sizeIdcNodes
*
22240 sizeof(xmlSchemaPSVIIDCNodePtr
));
22241 if (vctxt
->idcNodes
== NULL
) {
22242 xmlSchemaVErrMemory(vctxt
,
22243 "re-allocating the IDC node table item list", NULL
);
22247 vctxt
->idcNodes
[vctxt
->nbIdcNodes
++] = item
;
22253 * xmlSchemaIDCStoreKey:
22254 * @vctxt: the WXS validation context
22255 * @item: the IDC key
22257 * The validation context is used to store an IDC key.
22259 * Returns 0 if succeeded, -1 on internal errors.
22262 xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt
,
22263 xmlSchemaPSVIIDCKeyPtr key
)
22266 * Add to global list.
22268 if (vctxt
->idcKeys
== NULL
) {
22269 vctxt
->idcKeys
= (xmlSchemaPSVIIDCKeyPtr
*)
22270 xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr
));
22271 if (vctxt
->idcKeys
== NULL
) {
22272 xmlSchemaVErrMemory(vctxt
,
22273 "allocating the IDC key storage list", NULL
);
22276 vctxt
->sizeIdcKeys
= 40;
22277 } else if (vctxt
->sizeIdcKeys
<= vctxt
->nbIdcKeys
) {
22278 vctxt
->sizeIdcKeys
*= 2;
22279 vctxt
->idcKeys
= (xmlSchemaPSVIIDCKeyPtr
*)
22280 xmlRealloc(vctxt
->idcKeys
, vctxt
->sizeIdcKeys
*
22281 sizeof(xmlSchemaPSVIIDCKeyPtr
));
22282 if (vctxt
->idcKeys
== NULL
) {
22283 xmlSchemaVErrMemory(vctxt
,
22284 "re-allocating the IDC key storage list", NULL
);
22288 vctxt
->idcKeys
[vctxt
->nbIdcKeys
++] = key
;
22294 * xmlSchemaIDCAppendNodeTableItem:
22295 * @bind: the IDC binding
22296 * @ntItem: the node-table item
22298 * Appends the IDC node-table item to the binding.
22300 * Returns 0 on success and -1 on internal errors.
22303 xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind
,
22304 xmlSchemaPSVIIDCNodePtr ntItem
)
22306 if (bind
->nodeTable
== NULL
) {
22307 bind
->sizeNodes
= 10;
22308 bind
->nodeTable
= (xmlSchemaPSVIIDCNodePtr
*)
22309 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr
));
22310 if (bind
->nodeTable
== NULL
) {
22311 xmlSchemaVErrMemory(NULL
,
22312 "allocating an array of IDC node-table items", NULL
);
22315 } else if (bind
->sizeNodes
<= bind
->nbNodes
) {
22316 bind
->sizeNodes
*= 2;
22317 bind
->nodeTable
= (xmlSchemaPSVIIDCNodePtr
*)
22318 xmlRealloc(bind
->nodeTable
, bind
->sizeNodes
*
22319 sizeof(xmlSchemaPSVIIDCNodePtr
));
22320 if (bind
->nodeTable
== NULL
) {
22321 xmlSchemaVErrMemory(NULL
,
22322 "re-allocating an array of IDC node-table items", NULL
);
22326 bind
->nodeTable
[bind
->nbNodes
++] = ntItem
;
22331 * xmlSchemaIDCAcquireBinding:
22332 * @vctxt: the WXS validation context
22333 * @matcher: the IDC matcher
22335 * Looks up an PSVI IDC binding, for the IDC definition and
22336 * of the given matcher. If none found, a new one is created
22337 * and added to the IDC table.
22339 * Returns an IDC binding or NULL on internal errors.
22341 static xmlSchemaPSVIIDCBindingPtr
22342 xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt
,
22343 xmlSchemaIDCMatcherPtr matcher
)
22345 xmlSchemaNodeInfoPtr ielem
;
22347 ielem
= vctxt
->elemInfos
[matcher
->depth
];
22349 if (ielem
->idcTable
== NULL
) {
22350 ielem
->idcTable
= xmlSchemaIDCNewBinding(matcher
->aidc
->def
);
22351 if (ielem
->idcTable
== NULL
)
22353 return(ielem
->idcTable
);
22355 xmlSchemaPSVIIDCBindingPtr bind
= NULL
;
22357 bind
= ielem
->idcTable
;
22359 if (bind
->definition
== matcher
->aidc
->def
)
22361 if (bind
->next
== NULL
) {
22362 bind
->next
= xmlSchemaIDCNewBinding(matcher
->aidc
->def
);
22363 if (bind
->next
== NULL
)
22365 return(bind
->next
);
22368 } while (bind
!= NULL
);
22373 static xmlSchemaItemListPtr
22374 xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED
,
22375 xmlSchemaIDCMatcherPtr matcher
)
22377 if (matcher
->targets
== NULL
)
22378 matcher
->targets
= xmlSchemaItemListCreate();
22379 return(matcher
->targets
);
22383 * xmlSchemaIDCFreeKey:
22384 * @key: the IDC key
22386 * Frees an IDC key together with its compiled value.
22389 xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key
)
22391 if (key
->val
!= NULL
)
22392 xmlSchemaFreeValue(key
->val
);
22397 * xmlSchemaIDCFreeBinding:
22399 * Frees an IDC binding. Note that the node table-items
22403 xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind
)
22405 if (bind
->nodeTable
!= NULL
)
22406 xmlFree(bind
->nodeTable
);
22407 if (bind
->dupls
!= NULL
)
22408 xmlSchemaItemListFree(bind
->dupls
);
22413 * xmlSchemaIDCFreeIDCTable:
22414 * @bind: the first IDC binding in the list
22416 * Frees an IDC table, i.e. all the IDC bindings in the list.
22419 xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind
)
22421 xmlSchemaPSVIIDCBindingPtr prev
;
22423 while (bind
!= NULL
) {
22426 xmlSchemaIDCFreeBinding(prev
);
22431 xmlFreeIDCHashEntry (void *payload
, const xmlChar
*name ATTRIBUTE_UNUSED
)
22433 xmlIDCHashEntryPtr e
= payload
, n
;
22442 * xmlSchemaIDCFreeMatcherList:
22443 * @matcher: the first IDC matcher in the list
22445 * Frees a list of IDC matchers.
22448 xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher
)
22450 xmlSchemaIDCMatcherPtr next
;
22452 while (matcher
!= NULL
) {
22453 next
= matcher
->next
;
22454 if (matcher
->keySeqs
!= NULL
) {
22456 for (i
= 0; i
< matcher
->sizeKeySeqs
; i
++)
22457 if (matcher
->keySeqs
[i
] != NULL
)
22458 xmlFree(matcher
->keySeqs
[i
]);
22459 xmlFree(matcher
->keySeqs
);
22461 if (matcher
->targets
!= NULL
) {
22462 if (matcher
->idcType
== XML_SCHEMA_TYPE_IDC_KEYREF
) {
22464 xmlSchemaPSVIIDCNodePtr idcNode
;
22466 * Node-table items for keyrefs are not stored globally
22467 * to the validation context, since they are not bubbled.
22468 * We need to free them here.
22470 for (i
= 0; i
< matcher
->targets
->nbItems
; i
++) {
22472 (xmlSchemaPSVIIDCNodePtr
) matcher
->targets
->items
[i
];
22473 xmlFree(idcNode
->keys
);
22477 xmlSchemaItemListFree(matcher
->targets
);
22479 if (matcher
->htab
!= NULL
)
22480 xmlHashFree(matcher
->htab
, xmlFreeIDCHashEntry
);
22487 * xmlSchemaIDCReleaseMatcherList:
22488 * @vctxt: the WXS validation context
22489 * @matcher: the first IDC matcher in the list
22491 * Caches a list of IDC matchers for reuse.
22494 xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt
,
22495 xmlSchemaIDCMatcherPtr matcher
)
22497 xmlSchemaIDCMatcherPtr next
;
22499 while (matcher
!= NULL
) {
22500 next
= matcher
->next
;
22501 if (matcher
->keySeqs
!= NULL
) {
22504 * Don't free the array, but only the content.
22506 for (i
= 0; i
< matcher
->sizeKeySeqs
; i
++)
22507 if (matcher
->keySeqs
[i
] != NULL
) {
22508 xmlFree(matcher
->keySeqs
[i
]);
22509 matcher
->keySeqs
[i
] = NULL
;
22512 if (matcher
->targets
) {
22513 if (matcher
->idcType
== XML_SCHEMA_TYPE_IDC_KEYREF
) {
22515 xmlSchemaPSVIIDCNodePtr idcNode
;
22517 * Node-table items for keyrefs are not stored globally
22518 * to the validation context, since they are not bubbled.
22519 * We need to free them here.
22521 for (i
= 0; i
< matcher
->targets
->nbItems
; i
++) {
22523 (xmlSchemaPSVIIDCNodePtr
) matcher
->targets
->items
[i
];
22524 xmlFree(idcNode
->keys
);
22528 xmlSchemaItemListFree(matcher
->targets
);
22529 matcher
->targets
= NULL
;
22531 if (matcher
->htab
!= NULL
) {
22532 xmlHashFree(matcher
->htab
, xmlFreeIDCHashEntry
);
22533 matcher
->htab
= NULL
;
22535 matcher
->next
= NULL
;
22537 * Cache the matcher.
22539 if (vctxt
->idcMatcherCache
!= NULL
)
22540 matcher
->nextCached
= vctxt
->idcMatcherCache
;
22541 vctxt
->idcMatcherCache
= matcher
;
22548 * xmlSchemaIDCAddStateObject:
22549 * @vctxt: the WXS validation context
22550 * @matcher: the IDC matcher
22551 * @sel: the XPath information
22552 * @parent: the parent "selector" state object if any
22553 * @type: "selector" or "field"
22555 * Creates/reuses and activates state objects for the given
22556 * XPath information; if the XPath expression consists of unions,
22557 * multiple state objects are created for every unioned expression.
22559 * Returns 0 on success and -1 on internal errors.
22562 xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt
,
22563 xmlSchemaIDCMatcherPtr matcher
,
22564 xmlSchemaIDCSelectPtr sel
,
22567 xmlSchemaIDCStateObjPtr sto
;
22570 * Reuse the state objects from the pool.
22572 if (vctxt
->xpathStatePool
!= NULL
) {
22573 sto
= vctxt
->xpathStatePool
;
22574 vctxt
->xpathStatePool
= sto
->next
;
22578 * Create a new state object.
22580 sto
= (xmlSchemaIDCStateObjPtr
) xmlMalloc(sizeof(xmlSchemaIDCStateObj
));
22582 xmlSchemaVErrMemory(NULL
,
22583 "allocating an IDC state object", NULL
);
22586 memset(sto
, 0, sizeof(xmlSchemaIDCStateObj
));
22589 * Add to global list.
22591 if (vctxt
->xpathStates
!= NULL
)
22592 sto
->next
= vctxt
->xpathStates
;
22593 vctxt
->xpathStates
= sto
;
22596 * Free the old xpath validation context.
22598 if (sto
->xpathCtxt
!= NULL
)
22599 xmlFreeStreamCtxt((xmlStreamCtxtPtr
) sto
->xpathCtxt
);
22602 * Create a new XPath (pattern) validation context.
22604 sto
->xpathCtxt
= (void *) xmlPatternGetStreamCtxt(
22605 (xmlPatternPtr
) sel
->xpathComp
);
22606 if (sto
->xpathCtxt
== NULL
) {
22607 VERROR_INT("xmlSchemaIDCAddStateObject",
22608 "failed to create an XPath validation context");
22612 sto
->depth
= vctxt
->depth
;
22613 sto
->matcher
= matcher
;
22615 sto
->nbHistory
= 0;
22618 xmlGenericError(xmlGenericErrorContext
, "IDC: STO push '%s'\n",
22625 * xmlSchemaXPathEvaluate:
22626 * @vctxt: the WXS validation context
22627 * @nodeType: the nodeType of the current node
22629 * Evaluates all active XPath state objects.
22631 * Returns the number of IC "field" state objects which resolved to
22632 * this node, 0 if none resolved and -1 on internal errors.
22635 xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt
,
22636 xmlElementType nodeType
)
22638 xmlSchemaIDCStateObjPtr sto
, head
= NULL
, first
;
22639 int res
, resolved
= 0, depth
= vctxt
->depth
;
22641 if (vctxt
->xpathStates
== NULL
)
22644 if (nodeType
== XML_ATTRIBUTE_NODE
)
22648 xmlChar
*str
= NULL
;
22649 xmlGenericError(xmlGenericErrorContext
,
22650 "IDC: EVAL on %s, depth %d, type %d\n",
22651 xmlSchemaFormatQName(&str
, vctxt
->inode
->nsName
,
22652 vctxt
->inode
->localName
), depth
, nodeType
);
22657 * Process all active XPath state objects.
22659 first
= vctxt
->xpathStates
;
22661 while (sto
!= head
) {
22663 if (sto
->type
== XPATH_STATE_OBJ_TYPE_IDC_SELECTOR
)
22664 xmlGenericError(xmlGenericErrorContext
, "IDC: ['%s'] selector '%s'\n",
22665 sto
->matcher
->aidc
->def
->name
, sto
->sel
->xpath
);
22667 xmlGenericError(xmlGenericErrorContext
, "IDC: ['%s'] field '%s'\n",
22668 sto
->matcher
->aidc
->def
->name
, sto
->sel
->xpath
);
22670 if (nodeType
== XML_ELEMENT_NODE
)
22671 res
= xmlStreamPush((xmlStreamCtxtPtr
) sto
->xpathCtxt
,
22672 vctxt
->inode
->localName
, vctxt
->inode
->nsName
);
22674 res
= xmlStreamPushAttr((xmlStreamCtxtPtr
) sto
->xpathCtxt
,
22675 vctxt
->inode
->localName
, vctxt
->inode
->nsName
);
22678 VERROR_INT("xmlSchemaXPathEvaluate",
22679 "calling xmlStreamPush()");
22688 xmlGenericError(xmlGenericErrorContext
, "IDC: "
22692 * Register a match in the state object history.
22694 if (sto
->history
== NULL
) {
22695 sto
->history
= (int *) xmlMalloc(5 * sizeof(int));
22696 if (sto
->history
== NULL
) {
22697 xmlSchemaVErrMemory(NULL
,
22698 "allocating the state object history", NULL
);
22701 sto
->sizeHistory
= 5;
22702 } else if (sto
->sizeHistory
<= sto
->nbHistory
) {
22703 sto
->sizeHistory
*= 2;
22704 sto
->history
= (int *) xmlRealloc(sto
->history
,
22705 sto
->sizeHistory
* sizeof(int));
22706 if (sto
->history
== NULL
) {
22707 xmlSchemaVErrMemory(NULL
,
22708 "re-allocating the state object history", NULL
);
22712 sto
->history
[sto
->nbHistory
++] = depth
;
22715 xmlGenericError(xmlGenericErrorContext
, "IDC: push match '%d'\n",
22719 if (sto
->type
== XPATH_STATE_OBJ_TYPE_IDC_SELECTOR
) {
22720 xmlSchemaIDCSelectPtr sel
;
22722 * Activate state objects for the IDC fields of
22723 * the IDC selector.
22726 xmlGenericError(xmlGenericErrorContext
, "IDC: "
22727 "activating field states\n");
22729 sel
= sto
->matcher
->aidc
->def
->fields
;
22730 while (sel
!= NULL
) {
22731 if (xmlSchemaIDCAddStateObject(vctxt
, sto
->matcher
,
22732 sel
, XPATH_STATE_OBJ_TYPE_IDC_FIELD
) == -1)
22736 } else if (sto
->type
== XPATH_STATE_OBJ_TYPE_IDC_FIELD
) {
22738 * An IDC key node was found by the IDC field.
22741 xmlGenericError(xmlGenericErrorContext
,
22742 "IDC: key found\n");
22745 * Notify that the character value of this node is
22748 if (resolved
== 0) {
22749 if ((vctxt
->inode
->flags
&
22750 XML_SCHEMA_NODE_INFO_VALUE_NEEDED
) == 0)
22751 vctxt
->inode
->flags
|= XML_SCHEMA_NODE_INFO_VALUE_NEEDED
;
22756 if (sto
->next
== NULL
) {
22758 * Evaluate field state objects created on this node as well.
22761 sto
= vctxt
->xpathStates
;
22768 static const xmlChar
*
22769 xmlSchemaFormatIDCKeySequence_1(xmlSchemaValidCtxtPtr vctxt
,
22771 xmlSchemaPSVIIDCKeyPtr
*seq
,
22772 int count
, int for_hash
)
22775 xmlChar
*value
= NULL
;
22777 *buf
= xmlStrdup(BAD_CAST
"[");
22778 for (i
= 0; i
< count
; i
++) {
22779 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
22781 res
= xmlSchemaGetCanonValueWhtspExt(seq
[i
]->val
,
22782 xmlSchemaGetWhiteSpaceFacetValue(seq
[i
]->type
),
22785 res
= xmlSchemaGetCanonValueHash(seq
[i
]->val
, &value
);
22788 *buf
= xmlStrcat(*buf
, BAD_CAST value
);
22790 VERROR_INT("xmlSchemaFormatIDCKeySequence",
22791 "failed to compute a canonical value");
22792 *buf
= xmlStrcat(*buf
, BAD_CAST
"???");
22795 *buf
= xmlStrcat(*buf
, BAD_CAST
"', ");
22797 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
22798 if (value
!= NULL
) {
22803 *buf
= xmlStrcat(*buf
, BAD_CAST
"]");
22805 return (BAD_CAST
*buf
);
22808 static const xmlChar
*
22809 xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt
,
22811 xmlSchemaPSVIIDCKeyPtr
*seq
,
22814 return xmlSchemaFormatIDCKeySequence_1(vctxt
, buf
, seq
, count
, 0);
22817 static const xmlChar
*
22818 xmlSchemaHashKeySequence(xmlSchemaValidCtxtPtr vctxt
,
22820 xmlSchemaPSVIIDCKeyPtr
*seq
,
22823 return xmlSchemaFormatIDCKeySequence_1(vctxt
, buf
, seq
, count
, 1);
22827 * xmlSchemaXPathPop:
22828 * @vctxt: the WXS validation context
22830 * Pops all XPath states.
22832 * Returns 0 on success and -1 on internal errors.
22835 xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt
)
22837 xmlSchemaIDCStateObjPtr sto
;
22840 if (vctxt
->xpathStates
== NULL
)
22842 sto
= vctxt
->xpathStates
;
22844 res
= xmlStreamPop((xmlStreamCtxtPtr
) sto
->xpathCtxt
);
22848 } while (sto
!= NULL
);
22853 * xmlSchemaXPathProcessHistory:
22854 * @vctxt: the WXS validation context
22855 * @type: the simple/complex type of the current node if any at all
22856 * @val: the precompiled value
22858 * Processes and pops the history items of the IDC state objects.
22859 * IDC key-sequences are validated/created on IDC bindings.
22861 * Returns 0 on success and -1 on internal errors.
22864 xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt
,
22867 xmlSchemaIDCStateObjPtr sto
, nextsto
;
22868 int res
, matchDepth
;
22869 xmlSchemaPSVIIDCKeyPtr key
= NULL
;
22870 xmlSchemaTypePtr type
= vctxt
->inode
->typeDef
, simpleType
= NULL
;
22872 if (vctxt
->xpathStates
== NULL
)
22874 sto
= vctxt
->xpathStates
;
22878 xmlChar
*str
= NULL
;
22879 xmlGenericError(xmlGenericErrorContext
,
22880 "IDC: BACK on %s, depth %d\n",
22881 xmlSchemaFormatQName(&str
, vctxt
->inode
->nsName
,
22882 vctxt
->inode
->localName
), vctxt
->depth
);
22887 * Evaluate the state objects.
22889 while (sto
!= NULL
) {
22890 res
= xmlStreamPop((xmlStreamCtxtPtr
) sto
->xpathCtxt
);
22892 VERROR_INT("xmlSchemaXPathProcessHistory",
22893 "calling xmlStreamPop()");
22897 xmlGenericError(xmlGenericErrorContext
, "IDC: stream pop '%s'\n",
22900 if (sto
->nbHistory
== 0)
22901 goto deregister_check
;
22903 matchDepth
= sto
->history
[sto
->nbHistory
-1];
22906 * Only matches at the current depth are of interest.
22908 if (matchDepth
!= depth
) {
22912 if (sto
->type
== XPATH_STATE_OBJ_TYPE_IDC_FIELD
) {
22914 * NOTE: According to
22915 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
22916 * ... the simple-content of complex types is also allowed.
22919 if (WXS_IS_COMPLEX(type
)) {
22920 if (WXS_HAS_SIMPLE_CONTENT(type
)) {
22922 * Sanity check for complex types with simple content.
22924 simpleType
= type
->contentTypeDef
;
22925 if (simpleType
== NULL
) {
22926 VERROR_INT("xmlSchemaXPathProcessHistory",
22927 "field resolves to a CT with simple content "
22928 "but the CT is missing the ST definition");
22935 if (simpleType
== NULL
) {
22936 xmlChar
*str
= NULL
;
22939 * Not qualified if the field resolves to a node of non
22942 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
22943 XML_SCHEMAV_CVC_IDC
, NULL
,
22944 WXS_BASIC_CAST sto
->matcher
->aidc
->def
,
22945 "The XPath '%s' of a field of %s does evaluate to a node of "
22948 xmlSchemaGetIDCDesignation(&str
, sto
->matcher
->aidc
->def
));
22949 FREE_AND_NULL(str
);
22951 goto deregister_check
;
22954 if ((key
== NULL
) && (vctxt
->inode
->val
== NULL
)) {
22956 * Failed to provide the normalized value; maybe
22957 * the value was invalid.
22959 VERROR(XML_SCHEMAV_CVC_IDC
,
22960 WXS_BASIC_CAST sto
->matcher
->aidc
->def
,
22961 "Warning: No precomputed value available, the value "
22962 "was either invalid or something strange happened");
22964 goto deregister_check
;
22966 xmlSchemaIDCMatcherPtr matcher
= sto
->matcher
;
22967 xmlSchemaPSVIIDCKeyPtr
*keySeq
;
22971 * The key will be anchored on the matcher's list of
22972 * key-sequences. The position in this list is determined
22973 * by the target node's depth relative to the matcher's
22974 * depth of creation (i.e. the depth of the scope element).
22976 * Element Depth Pos List-entries
22979 * <target/> 2 2 target
22983 * The size of the list is only dependent on the depth of
22985 * An entry will be NULLed in selector_leave, i.e. when
22986 * we hit the target's
22988 pos
= sto
->depth
- matcher
->depth
;
22989 idx
= sto
->sel
->index
;
22992 * Create/grow the array of key-sequences.
22994 if (matcher
->keySeqs
== NULL
) {
22996 matcher
->sizeKeySeqs
= pos
* 2;
22998 matcher
->sizeKeySeqs
= 10;
22999 matcher
->keySeqs
= (xmlSchemaPSVIIDCKeyPtr
**)
23000 xmlMalloc(matcher
->sizeKeySeqs
*
23001 sizeof(xmlSchemaPSVIIDCKeyPtr
*));
23002 if (matcher
->keySeqs
== NULL
) {
23003 xmlSchemaVErrMemory(NULL
,
23004 "allocating an array of key-sequences",
23008 memset(matcher
->keySeqs
, 0,
23009 matcher
->sizeKeySeqs
*
23010 sizeof(xmlSchemaPSVIIDCKeyPtr
*));
23011 } else if (pos
>= matcher
->sizeKeySeqs
) {
23012 int i
= matcher
->sizeKeySeqs
;
23014 matcher
->sizeKeySeqs
*= 2;
23015 matcher
->keySeqs
= (xmlSchemaPSVIIDCKeyPtr
**)
23016 xmlRealloc(matcher
->keySeqs
,
23017 matcher
->sizeKeySeqs
*
23018 sizeof(xmlSchemaPSVIIDCKeyPtr
*));
23019 if (matcher
->keySeqs
== NULL
) {
23020 xmlSchemaVErrMemory(NULL
,
23021 "reallocating an array of key-sequences",
23026 * The array needs to be NULLed.
23027 * TODO: Use memset?
23029 for (; i
< matcher
->sizeKeySeqs
; i
++)
23030 matcher
->keySeqs
[i
] = NULL
;
23034 * Get/create the key-sequence.
23036 keySeq
= matcher
->keySeqs
[pos
];
23037 if (keySeq
== NULL
) {
23038 goto create_sequence
;
23039 } else if (keySeq
[idx
] != NULL
) {
23040 xmlChar
*str
= NULL
;
23042 * cvc-identity-constraint:
23043 * 3 For each node in the `target node set` all
23044 * of the {fields}, with that node as the context
23045 * node, evaluate to either an empty node-set or
23046 * a node-set with exactly one member, which must
23047 * have a simple type.
23049 * The key was already set; report an error.
23051 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
23052 XML_SCHEMAV_CVC_IDC
, NULL
,
23053 WXS_BASIC_CAST matcher
->aidc
->def
,
23054 "The XPath '%s' of a field of %s evaluates to a "
23055 "node-set with more than one member",
23057 xmlSchemaGetIDCDesignation(&str
, matcher
->aidc
->def
));
23058 FREE_AND_NULL(str
);
23060 goto deregister_check
;
23066 * Create a key-sequence.
23068 keySeq
= (xmlSchemaPSVIIDCKeyPtr
*) xmlMalloc(
23069 matcher
->aidc
->def
->nbFields
*
23070 sizeof(xmlSchemaPSVIIDCKeyPtr
));
23071 if (keySeq
== NULL
) {
23072 xmlSchemaVErrMemory(NULL
,
23073 "allocating an IDC key-sequence", NULL
);
23076 memset(keySeq
, 0, matcher
->aidc
->def
->nbFields
*
23077 sizeof(xmlSchemaPSVIIDCKeyPtr
));
23078 matcher
->keySeqs
[pos
] = keySeq
;
23081 * Create a key once per node only.
23084 key
= (xmlSchemaPSVIIDCKeyPtr
) xmlMalloc(
23085 sizeof(xmlSchemaPSVIIDCKey
));
23087 xmlSchemaVErrMemory(NULL
,
23088 "allocating a IDC key", NULL
);
23090 matcher
->keySeqs
[pos
] = NULL
;
23094 * Consume the compiled value.
23096 key
->type
= simpleType
;
23097 key
->val
= vctxt
->inode
->val
;
23098 vctxt
->inode
->val
= NULL
;
23100 * Store the key in a global list.
23102 if (xmlSchemaIDCStoreKey(vctxt
, key
) == -1) {
23103 xmlSchemaIDCFreeKey(key
);
23109 } else if (sto
->type
== XPATH_STATE_OBJ_TYPE_IDC_SELECTOR
) {
23111 xmlSchemaPSVIIDCKeyPtr
**keySeq
= NULL
;
23112 /* xmlSchemaPSVIIDCBindingPtr bind; */
23113 xmlSchemaPSVIIDCNodePtr ntItem
;
23114 xmlSchemaIDCMatcherPtr matcher
;
23115 xmlSchemaIDCPtr idc
;
23116 xmlSchemaItemListPtr targets
;
23117 int pos
, i
, j
, nbKeys
;
23119 * Here we have the following scenario:
23120 * An IDC 'selector' state object resolved to a target node,
23121 * during the time this target node was in the
23122 * ancestor-or-self axis, the 'field' state object(s) looked
23123 * out for matching nodes to create a key-sequence for this
23124 * target node. Now we are back to this target node and need
23125 * to put the key-sequence, together with the target node
23126 * itself, into the node-table of the corresponding IDC
23129 matcher
= sto
->matcher
;
23130 idc
= matcher
->aidc
->def
;
23131 nbKeys
= idc
->nbFields
;
23132 pos
= depth
- matcher
->depth
;
23134 * Check if the matcher has any key-sequences at all, plus
23135 * if it has a key-sequence for the current target node.
23137 if ((matcher
->keySeqs
== NULL
) ||
23138 (matcher
->sizeKeySeqs
<= pos
)) {
23139 if (idc
->type
== XML_SCHEMA_TYPE_IDC_KEY
)
23140 goto selector_key_error
;
23142 goto selector_leave
;
23145 keySeq
= &(matcher
->keySeqs
[pos
]);
23146 if (*keySeq
== NULL
) {
23147 if (idc
->type
== XML_SCHEMA_TYPE_IDC_KEY
)
23148 goto selector_key_error
;
23150 goto selector_leave
;
23153 for (i
= 0; i
< nbKeys
; i
++) {
23154 if ((*keySeq
)[i
] == NULL
) {
23156 * Not qualified, if not all fields did resolve.
23158 if (idc
->type
== XML_SCHEMA_TYPE_IDC_KEY
) {
23160 * All fields of a "key" IDC must resolve.
23162 goto selector_key_error
;
23164 goto selector_leave
;
23168 * All fields did resolve.
23172 * 4.1 If the {identity-constraint category} is unique(/key),
23173 * then no two members of the `qualified node set` have
23174 * `key-sequences` whose members are pairwise equal, as
23175 * defined by Equal in [XML Schemas: Datatypes].
23177 * Get the IDC binding from the matcher and check for
23178 * duplicate key-sequences.
23181 bind
= xmlSchemaIDCAcquireBinding(vctxt
, matcher
);
23183 targets
= xmlSchemaIDCAcquireTargetList(vctxt
, matcher
);
23184 if ((idc
->type
!= XML_SCHEMA_TYPE_IDC_KEYREF
) &&
23185 (targets
->nbItems
!= 0)) {
23186 xmlSchemaPSVIIDCKeyPtr ckey
, bkey
, *bkeySeq
;
23187 xmlIDCHashEntryPtr e
;
23191 if (!matcher
->htab
)
23194 xmlChar
*value
= NULL
;
23195 xmlSchemaHashKeySequence(vctxt
, &value
, *keySeq
, nbKeys
);
23196 e
= xmlHashLookup(matcher
->htab
, value
);
23197 FREE_AND_NULL(value
);
23201 * Compare the key-sequences, key by key.
23203 for (;e
; e
= e
->next
) {
23205 ((xmlSchemaPSVIIDCNodePtr
) targets
->items
[e
->index
])->keys
;
23206 for (j
= 0; j
< nbKeys
; j
++) {
23207 ckey
= (*keySeq
)[j
];
23209 res
= xmlSchemaAreValuesEqual(ckey
->val
, bkey
->val
);
23212 } else if (res
== 0) {
23214 * One of the keys differs, so the key-sequence
23215 * won't be equal; get out.
23222 * Duplicate key-sequence found.
23228 xmlChar
*str
= NULL
, *strB
= NULL
;
23230 * TODO: Try to report the key-sequence.
23232 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
23233 XML_SCHEMAV_CVC_IDC
, NULL
,
23234 WXS_BASIC_CAST idc
,
23235 "Duplicate key-sequence %s in %s",
23236 xmlSchemaFormatIDCKeySequence(vctxt
, &str
,
23237 (*keySeq
), nbKeys
),
23238 xmlSchemaGetIDCDesignation(&strB
, idc
));
23239 FREE_AND_NULL(str
);
23240 FREE_AND_NULL(strB
);
23241 goto selector_leave
;
23245 * Add a node-table item to the IDC binding.
23247 ntItem
= (xmlSchemaPSVIIDCNodePtr
) xmlMalloc(
23248 sizeof(xmlSchemaPSVIIDCNode
));
23249 if (ntItem
== NULL
) {
23250 xmlSchemaVErrMemory(NULL
,
23251 "allocating an IDC node-table item", NULL
);
23256 memset(ntItem
, 0, sizeof(xmlSchemaPSVIIDCNode
));
23259 * Store the node-table item in a global list.
23261 if (idc
->type
!= XML_SCHEMA_TYPE_IDC_KEYREF
) {
23262 if (xmlSchemaIDCStoreNodeTableItem(vctxt
, ntItem
) == -1) {
23268 ntItem
->nodeQNameID
= -1;
23271 * Save a cached QName for this node on the IDC node, to be
23272 * able to report it, even if the node is not saved.
23274 ntItem
->nodeQNameID
= xmlSchemaVAddNodeQName(vctxt
,
23275 vctxt
->inode
->localName
, vctxt
->inode
->nsName
);
23276 if (ntItem
->nodeQNameID
== -1) {
23284 * Init the node-table item: Save the node, position and
23285 * consume the key-sequence.
23287 ntItem
->node
= vctxt
->node
;
23288 ntItem
->nodeLine
= vctxt
->inode
->nodeLine
;
23289 ntItem
->keys
= *keySeq
;
23292 if (xmlSchemaIDCAppendNodeTableItem(bind
, ntItem
) == -1)
23294 if (xmlSchemaItemListAdd(targets
, ntItem
) == -1) {
23295 if (idc
->type
== XML_SCHEMA_TYPE_IDC_KEYREF
) {
23297 * Free the item, since keyref items won't be
23298 * put on a global list.
23300 xmlFree(ntItem
->keys
);
23305 if (idc
->type
!= XML_SCHEMA_TYPE_IDC_KEYREF
) {
23306 xmlChar
*value
= NULL
;
23307 xmlIDCHashEntryPtr r
, e
;
23308 if (!matcher
->htab
)
23309 matcher
->htab
= xmlHashCreate(4);
23310 xmlSchemaHashKeySequence(vctxt
, &value
, ntItem
->keys
, nbKeys
);
23311 e
= xmlMalloc(sizeof *e
);
23312 e
->index
= targets
->nbItems
- 1;
23313 r
= xmlHashLookup(matcher
->htab
, value
);
23319 xmlHashAddEntry(matcher
->htab
, value
, e
);
23321 FREE_AND_NULL(value
);
23324 goto selector_leave
;
23325 selector_key_error
:
23327 xmlChar
*str
= NULL
;
23329 * 4.2.1 (KEY) The `target node set` and the
23330 * `qualified node set` are equal, that is, every
23331 * member of the `target node set` is also a member
23332 * of the `qualified node set` and vice versa.
23334 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
23335 XML_SCHEMAV_CVC_IDC
, NULL
,
23336 WXS_BASIC_CAST idc
,
23337 "Not all fields of %s evaluate to a node",
23338 xmlSchemaGetIDCDesignation(&str
, idc
), NULL
);
23339 FREE_AND_NULL(str
);
23343 * Free the key-sequence if not added to the IDC table.
23345 if ((keySeq
!= NULL
) && (*keySeq
!= NULL
)) {
23349 } /* if selector */
23355 * Deregister state objects if they reach the depth of creation.
23357 if ((sto
->nbHistory
== 0) && (sto
->depth
== depth
)) {
23359 xmlGenericError(xmlGenericErrorContext
, "IDC: STO pop '%s'\n",
23362 if (vctxt
->xpathStates
!= sto
) {
23363 VERROR_INT("xmlSchemaXPathProcessHistory",
23364 "The state object to be removed is not the first "
23367 nextsto
= sto
->next
;
23369 * Unlink from the list of active XPath state objects.
23371 vctxt
->xpathStates
= sto
->next
;
23372 sto
->next
= vctxt
->xpathStatePool
;
23374 * Link it to the pool of reusable state objects.
23376 vctxt
->xpathStatePool
= sto
;
23380 } /* while (sto != NULL) */
23385 * xmlSchemaIDCRegisterMatchers:
23386 * @vctxt: the WXS validation context
23387 * @elemDecl: the element declaration
23389 * Creates helper objects to evaluate IDC selectors/fields
23392 * Returns 0 if OK and -1 on internal errors.
23395 xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt
,
23396 xmlSchemaElementPtr elemDecl
)
23398 xmlSchemaIDCMatcherPtr matcher
, last
= NULL
;
23399 xmlSchemaIDCPtr idc
, refIdc
;
23400 xmlSchemaIDCAugPtr aidc
;
23402 idc
= (xmlSchemaIDCPtr
) elemDecl
->idcs
;
23408 xmlChar
*str
= NULL
;
23409 xmlGenericError(xmlGenericErrorContext
,
23410 "IDC: REGISTER on %s, depth %d\n",
23411 (char *) xmlSchemaFormatQName(&str
, vctxt
->inode
->nsName
,
23412 vctxt
->inode
->localName
), vctxt
->depth
);
23416 if (vctxt
->inode
->idcMatchers
!= NULL
) {
23417 VERROR_INT("xmlSchemaIDCRegisterMatchers",
23418 "The chain of IDC matchers is expected to be empty");
23422 if (idc
->type
== XML_SCHEMA_TYPE_IDC_KEYREF
) {
23424 * Since IDCs bubbles are expensive we need to know the
23425 * depth at which the bubbles should stop; this will be
23426 * the depth of the top-most keyref IDC. If no keyref
23427 * references a key/unique IDC, the keyrefDepth will
23428 * be -1, indicating that no bubbles are needed.
23430 refIdc
= (xmlSchemaIDCPtr
) idc
->ref
->item
;
23431 if (refIdc
!= NULL
) {
23433 * Remember that we have keyrefs on this node.
23435 vctxt
->inode
->hasKeyrefs
= 1;
23437 * Lookup the referenced augmented IDC info.
23439 aidc
= vctxt
->aidcs
;
23440 while (aidc
!= NULL
) {
23441 if (aidc
->def
== refIdc
)
23445 if (aidc
== NULL
) {
23446 VERROR_INT("xmlSchemaIDCRegisterMatchers",
23447 "Could not find an augmented IDC item for an IDC "
23451 if ((aidc
->keyrefDepth
== -1) ||
23452 (vctxt
->depth
< aidc
->keyrefDepth
))
23453 aidc
->keyrefDepth
= vctxt
->depth
;
23457 * Lookup the augmented IDC item for the IDC definition.
23459 aidc
= vctxt
->aidcs
;
23460 while (aidc
!= NULL
) {
23461 if (aidc
->def
== idc
)
23465 if (aidc
== NULL
) {
23466 VERROR_INT("xmlSchemaIDCRegisterMatchers",
23467 "Could not find an augmented IDC item for an IDC definition");
23471 * Create an IDC matcher for every IDC definition.
23473 if (vctxt
->idcMatcherCache
!= NULL
) {
23475 * Reuse a cached matcher.
23477 matcher
= vctxt
->idcMatcherCache
;
23478 vctxt
->idcMatcherCache
= matcher
->nextCached
;
23479 matcher
->nextCached
= NULL
;
23481 matcher
= (xmlSchemaIDCMatcherPtr
)
23482 xmlMalloc(sizeof(xmlSchemaIDCMatcher
));
23483 if (matcher
== NULL
) {
23484 xmlSchemaVErrMemory(vctxt
,
23485 "allocating an IDC matcher", NULL
);
23488 memset(matcher
, 0, sizeof(xmlSchemaIDCMatcher
));
23491 vctxt
->inode
->idcMatchers
= matcher
;
23493 last
->next
= matcher
;
23496 matcher
->type
= IDC_MATCHER
;
23497 matcher
->depth
= vctxt
->depth
;
23498 matcher
->aidc
= aidc
;
23499 matcher
->idcType
= aidc
->def
->type
;
23501 xmlGenericError(xmlGenericErrorContext
, "IDC: register matcher\n");
23504 * Init the automaton state object.
23506 if (xmlSchemaIDCAddStateObject(vctxt
, matcher
,
23507 idc
->selector
, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR
) == -1)
23511 } while (idc
!= NULL
);
23516 xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt
,
23517 xmlSchemaNodeInfoPtr ielem
)
23519 xmlSchemaPSVIIDCBindingPtr bind
;
23520 int res
, i
, j
, k
, nbTargets
, nbFields
, nbDupls
, nbNodeTable
;
23521 xmlSchemaPSVIIDCKeyPtr
*keys
, *ntkeys
;
23522 xmlSchemaPSVIIDCNodePtr
*targets
, *dupls
;
23524 xmlSchemaIDCMatcherPtr matcher
= ielem
->idcMatchers
;
23525 /* vctxt->createIDCNodeTables */
23526 while (matcher
!= NULL
) {
23528 * Skip keyref IDCs and empty IDC target-lists.
23530 if ((matcher
->aidc
->def
->type
== XML_SCHEMA_TYPE_IDC_KEYREF
) ||
23531 WXS_ILIST_IS_EMPTY(matcher
->targets
))
23533 matcher
= matcher
->next
;
23537 * If we _want_ the IDC node-table to be created in any case
23538 * then do so. Otherwise create them only if keyrefs need them.
23540 if ((! vctxt
->createIDCNodeTables
) &&
23541 ((matcher
->aidc
->keyrefDepth
== -1) ||
23542 (matcher
->aidc
->keyrefDepth
> vctxt
->depth
)))
23544 matcher
= matcher
->next
;
23548 * Get/create the IDC binding on this element for the IDC definition.
23550 bind
= xmlSchemaIDCAcquireBinding(vctxt
, matcher
);
23552 goto internal_error
;
23554 if (! WXS_ILIST_IS_EMPTY(bind
->dupls
)) {
23555 dupls
= (xmlSchemaPSVIIDCNodePtr
*) bind
->dupls
->items
;
23556 nbDupls
= bind
->dupls
->nbItems
;
23561 if (bind
->nodeTable
!= NULL
) {
23562 nbNodeTable
= bind
->nbNodes
;
23567 if ((nbNodeTable
== 0) && (nbDupls
== 0)) {
23569 * Transfer all IDC target-nodes to the IDC node-table.
23572 (xmlSchemaPSVIIDCNodePtr
*) matcher
->targets
->items
;
23573 bind
->sizeNodes
= matcher
->targets
->sizeItems
;
23574 bind
->nbNodes
= matcher
->targets
->nbItems
;
23576 matcher
->targets
->items
= NULL
;
23577 matcher
->targets
->sizeItems
= 0;
23578 matcher
->targets
->nbItems
= 0;
23579 if (matcher
->htab
) {
23580 xmlHashFree(matcher
->htab
, xmlFreeIDCHashEntry
);
23581 matcher
->htab
= NULL
;
23585 * Compare the key-sequences and add to the IDC node-table.
23587 nbTargets
= matcher
->targets
->nbItems
;
23588 targets
= (xmlSchemaPSVIIDCNodePtr
*) matcher
->targets
->items
;
23589 nbFields
= matcher
->aidc
->def
->nbFields
;
23592 keys
= targets
[i
]->keys
;
23595 * Search in already found duplicates first.
23599 if (nbFields
== 1) {
23600 res
= xmlSchemaAreValuesEqual(keys
[0]->val
,
23601 dupls
[j
]->keys
[0]->val
);
23603 goto internal_error
;
23606 * Equal key-sequence.
23612 ntkeys
= dupls
[j
]->keys
;
23613 for (k
= 0; k
< nbFields
; k
++) {
23614 res
= xmlSchemaAreValuesEqual(keys
[k
]->val
,
23617 goto internal_error
;
23620 * One of the keys differs.
23627 * Equal key-sequence found.
23633 } while (j
< nbDupls
);
23638 if (nbFields
== 1) {
23639 res
= xmlSchemaAreValuesEqual(keys
[0]->val
,
23640 bind
->nodeTable
[j
]->keys
[0]->val
);
23642 goto internal_error
;
23645 * The key-sequence differs.
23647 goto next_node_table_entry
;
23651 ntkeys
= bind
->nodeTable
[j
]->keys
;
23652 for (k
= 0; k
< nbFields
; k
++) {
23653 res
= xmlSchemaAreValuesEqual(keys
[k
]->val
,
23656 goto internal_error
;
23659 * One of the keys differs.
23661 goto next_node_table_entry
;
23666 * Add the duplicate to the list of duplicates.
23668 if (bind
->dupls
== NULL
) {
23669 bind
->dupls
= xmlSchemaItemListCreate();
23670 if (bind
->dupls
== NULL
)
23671 goto internal_error
;
23673 if (xmlSchemaItemListAdd(bind
->dupls
, bind
->nodeTable
[j
]) == -1)
23674 goto internal_error
;
23676 * Remove the duplicate entry from the IDC node-table.
23678 bind
->nodeTable
[j
] = bind
->nodeTable
[bind
->nbNodes
-1];
23683 next_node_table_entry
:
23685 } while (j
< nbNodeTable
);
23688 * If everything is fine, then add the IDC target-node to
23689 * the IDC node-table.
23691 if (xmlSchemaIDCAppendNodeTableItem(bind
, targets
[i
]) == -1)
23692 goto internal_error
;
23696 } while (i
< nbTargets
);
23698 matcher
= matcher
->next
;
23707 * xmlSchemaBubbleIDCNodeTables:
23708 * @depth: the current tree depth
23710 * Merges IDC bindings of an element at @depth into the corresponding IDC
23711 * bindings of its parent element. If a duplicate note-table entry is found,
23712 * both, the parent node-table entry and child entry are discarded from the
23713 * node-table of the parent.
23715 * Returns 0 if OK and -1 on internal errors.
23718 xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt
)
23720 xmlSchemaPSVIIDCBindingPtr bind
; /* IDC bindings of the current node. */
23721 xmlSchemaPSVIIDCBindingPtr
*parTable
, parBind
= NULL
; /* parent IDC bindings. */
23722 xmlSchemaPSVIIDCNodePtr node
, parNode
= NULL
, *dupls
, *parNodes
; /* node-table entries. */
23723 xmlSchemaIDCAugPtr aidc
;
23724 int i
, j
, k
, ret
= 0, nbFields
, oldNum
, oldDupls
;
23726 bind
= vctxt
->inode
->idcTable
;
23727 if (bind
== NULL
) {
23728 /* Fine, no table, no bubbles. */
23732 parTable
= &(vctxt
->elemInfos
[vctxt
->depth
-1]->idcTable
);
23734 * Walk all bindings; create new or add to existing bindings.
23735 * Remove duplicate key-sequences.
23737 while (bind
!= NULL
) {
23739 if ((bind
->nbNodes
== 0) && WXS_ILIST_IS_EMPTY(bind
->dupls
))
23742 * Check if the key/unique IDC table needs to be bubbled.
23744 if (! vctxt
->createIDCNodeTables
) {
23745 aidc
= vctxt
->aidcs
;
23747 if (aidc
->def
== bind
->definition
) {
23748 if ((aidc
->keyrefDepth
== -1) ||
23749 (aidc
->keyrefDepth
>= vctxt
->depth
)) {
23755 } while (aidc
!= NULL
);
23758 if (parTable
!= NULL
)
23759 parBind
= *parTable
;
23761 * Search a matching parent binding for the
23764 while (parBind
!= NULL
) {
23765 if (parBind
->definition
== bind
->definition
)
23767 parBind
= parBind
->next
;
23770 if (parBind
!= NULL
) {
23772 * Compare every node-table entry of the child node,
23773 * i.e. the key-sequence within, ...
23775 oldNum
= parBind
->nbNodes
; /* Skip newly added items. */
23777 if (! WXS_ILIST_IS_EMPTY(parBind
->dupls
)) {
23778 oldDupls
= parBind
->dupls
->nbItems
;
23779 dupls
= (xmlSchemaPSVIIDCNodePtr
*) parBind
->dupls
->items
;
23785 parNodes
= parBind
->nodeTable
;
23786 nbFields
= bind
->definition
->nbFields
;
23788 for (i
= 0; i
< bind
->nbNodes
; i
++) {
23789 node
= bind
->nodeTable
[i
];
23793 * ...with every key-sequence of the parent node, already
23794 * evaluated to be a duplicate key-sequence.
23798 while (j
< oldDupls
) {
23799 if (nbFields
== 1) {
23800 ret
= xmlSchemaAreValuesEqual(
23801 node
->keys
[0]->val
,
23802 dupls
[j
]->keys
[0]->val
);
23804 goto internal_error
;
23810 parNode
= dupls
[j
];
23811 for (k
= 0; k
< nbFields
; k
++) {
23812 ret
= xmlSchemaAreValuesEqual(
23813 node
->keys
[k
]->val
,
23814 parNode
->keys
[k
]->val
);
23816 goto internal_error
;
23822 /* Duplicate found. */
23826 if (j
!= oldDupls
) {
23827 /* Duplicate found. Skip this entry. */
23832 * ... and with every key-sequence of the parent node.
23836 while (j
< oldNum
) {
23837 parNode
= parNodes
[j
];
23838 if (nbFields
== 1) {
23839 ret
= xmlSchemaAreValuesEqual(
23840 node
->keys
[0]->val
,
23841 parNode
->keys
[0]->val
);
23843 goto internal_error
;
23849 for (k
= 0; k
< nbFields
; k
++) {
23850 ret
= xmlSchemaAreValuesEqual(
23851 node
->keys
[k
]->val
,
23852 parNode
->keys
[k
]->val
);
23854 goto internal_error
;
23860 /* Duplicate found. */
23866 * Handle duplicates. Move the duplicate in
23867 * the parent's node-table to the list of
23871 parBind
->nbNodes
--;
23873 * Move last old item to pos of duplicate.
23875 parNodes
[j
] = parNodes
[oldNum
];
23877 if (parBind
->nbNodes
!= oldNum
) {
23879 * If new items exist, move last new item to
23880 * last of old items.
23883 parNodes
[parBind
->nbNodes
];
23885 if (parBind
->dupls
== NULL
) {
23886 parBind
->dupls
= xmlSchemaItemListCreate();
23887 if (parBind
->dupls
== NULL
)
23888 goto internal_error
;
23890 xmlSchemaItemListAdd(parBind
->dupls
, parNode
);
23893 * Add the node-table entry (node and key-sequence) of
23894 * the child node to the node table of the parent node.
23896 if (parBind
->nodeTable
== NULL
) {
23897 parBind
->nodeTable
= (xmlSchemaPSVIIDCNodePtr
*)
23898 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr
));
23899 if (parBind
->nodeTable
== NULL
) {
23900 xmlSchemaVErrMemory(NULL
,
23901 "allocating IDC list of node-table items", NULL
);
23902 goto internal_error
;
23904 parBind
->sizeNodes
= 1;
23905 } else if (parBind
->nbNodes
>= parBind
->sizeNodes
) {
23906 parBind
->sizeNodes
*= 2;
23907 parBind
->nodeTable
= (xmlSchemaPSVIIDCNodePtr
*)
23908 xmlRealloc(parBind
->nodeTable
, parBind
->sizeNodes
*
23909 sizeof(xmlSchemaPSVIIDCNodePtr
));
23910 if (parBind
->nodeTable
== NULL
) {
23911 xmlSchemaVErrMemory(NULL
,
23912 "re-allocating IDC list of node-table items", NULL
);
23913 goto internal_error
;
23916 parNodes
= parBind
->nodeTable
;
23918 * Append the new node-table entry to the 'new node-table
23919 * entries' section.
23921 parNodes
[parBind
->nbNodes
++] = node
;
23929 * No binding for the IDC was found: create a new one and
23930 * copy all node-tables.
23932 parBind
= xmlSchemaIDCNewBinding(bind
->definition
);
23933 if (parBind
== NULL
)
23934 goto internal_error
;
23937 * TODO: Hmm, how to optimize the initial number of
23938 * allocated entries?
23940 if (bind
->nbNodes
!= 0) {
23942 * Add all IDC node-table entries.
23944 if (! vctxt
->psviExposeIDCNodeTables
) {
23946 * Just move the entries.
23947 * NOTE: this is quite save here, since
23948 * all the keyref lookups have already been
23951 parBind
->nodeTable
= bind
->nodeTable
;
23952 bind
->nodeTable
= NULL
;
23953 parBind
->sizeNodes
= bind
->sizeNodes
;
23954 bind
->sizeNodes
= 0;
23955 parBind
->nbNodes
= bind
->nbNodes
;
23959 * Copy the entries.
23961 parBind
->nodeTable
= (xmlSchemaPSVIIDCNodePtr
*)
23962 xmlMalloc(bind
->nbNodes
*
23963 sizeof(xmlSchemaPSVIIDCNodePtr
));
23964 if (parBind
->nodeTable
== NULL
) {
23965 xmlSchemaVErrMemory(NULL
,
23966 "allocating an array of IDC node-table "
23968 xmlSchemaIDCFreeBinding(parBind
);
23969 goto internal_error
;
23971 parBind
->sizeNodes
= bind
->nbNodes
;
23972 parBind
->nbNodes
= bind
->nbNodes
;
23973 memcpy(parBind
->nodeTable
, bind
->nodeTable
,
23974 bind
->nbNodes
* sizeof(xmlSchemaPSVIIDCNodePtr
));
23979 * Move the duplicates.
23981 if (parBind
->dupls
!= NULL
)
23982 xmlSchemaItemListFree(parBind
->dupls
);
23983 parBind
->dupls
= bind
->dupls
;
23984 bind
->dupls
= NULL
;
23986 if (parTable
!= NULL
) {
23987 if (*parTable
== NULL
)
23988 *parTable
= parBind
;
23990 parBind
->next
= *parTable
;
23991 *parTable
= parBind
;
24006 * xmlSchemaCheckCVCIDCKeyRef:
24007 * @vctxt: the WXS validation context
24008 * @elemDecl: the element declaration
24010 * Check the cvc-idc-keyref constraints.
24013 xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt
)
24015 xmlSchemaIDCMatcherPtr matcher
;
24016 xmlSchemaPSVIIDCBindingPtr bind
;
24018 matcher
= vctxt
->inode
->idcMatchers
;
24022 while (matcher
!= NULL
) {
24023 if ((matcher
->idcType
== XML_SCHEMA_TYPE_IDC_KEYREF
) &&
24024 matcher
->targets
&&
24025 matcher
->targets
->nbItems
)
24027 int i
, j
, k
, res
, nbFields
, hasDupls
;
24028 xmlSchemaPSVIIDCKeyPtr
*refKeys
, *keys
;
24029 xmlSchemaPSVIIDCNodePtr refNode
= NULL
;
24030 xmlHashTablePtr table
= NULL
;
24032 nbFields
= matcher
->aidc
->def
->nbFields
;
24035 * Find the IDC node-table for the referenced IDC key/unique.
24037 bind
= vctxt
->inode
->idcTable
;
24038 while (bind
!= NULL
) {
24039 if ((xmlSchemaIDCPtr
) matcher
->aidc
->def
->ref
->item
==
24044 hasDupls
= (bind
&& bind
->dupls
&& bind
->dupls
->nbItems
) ? 1 : 0;
24046 * Search for a matching key-sequences.
24049 table
= xmlHashCreate(bind
->nbNodes
* 2);
24050 for (j
= 0; j
< bind
->nbNodes
; j
++) {
24052 xmlIDCHashEntryPtr r
, e
;
24053 keys
= bind
->nodeTable
[j
]->keys
;
24054 xmlSchemaHashKeySequence(vctxt
, &value
, keys
, nbFields
);
24055 e
= xmlMalloc(sizeof *e
);
24057 r
= xmlHashLookup(table
, value
);
24063 xmlHashAddEntry(table
, value
, e
);
24065 FREE_AND_NULL(value
);
24068 for (i
= 0; i
< matcher
->targets
->nbItems
; i
++) {
24070 refNode
= matcher
->targets
->items
[i
];
24071 if (bind
!= NULL
) {
24073 xmlIDCHashEntryPtr e
;
24074 refKeys
= refNode
->keys
;
24075 xmlSchemaHashKeySequence(vctxt
, &value
, refKeys
, nbFields
);
24076 e
= xmlHashLookup(table
, value
);
24077 FREE_AND_NULL(value
);
24079 for (;e
; e
= e
->next
) {
24080 keys
= bind
->nodeTable
[e
->index
]->keys
;
24081 for (k
= 0; k
< nbFields
; k
++) {
24082 res
= xmlSchemaAreValuesEqual(keys
[k
]->val
,
24086 else if (res
== -1) {
24097 if ((res
== 0) && hasDupls
) {
24099 * Search in duplicates
24101 for (j
= 0; j
< bind
->dupls
->nbItems
; j
++) {
24102 keys
= ((xmlSchemaPSVIIDCNodePtr
)
24103 bind
->dupls
->items
[j
])->keys
;
24104 for (k
= 0; k
< nbFields
; k
++) {
24105 res
= xmlSchemaAreValuesEqual(keys
[k
]->val
,
24109 else if (res
== -1) {
24115 * Match in duplicates found.
24117 xmlChar
*str
= NULL
, *strB
= NULL
;
24118 xmlSchemaKeyrefErr(vctxt
,
24119 XML_SCHEMAV_CVC_IDC
, refNode
,
24120 (xmlSchemaTypePtr
) matcher
->aidc
->def
,
24121 "More than one match found for "
24122 "key-sequence %s of keyref '%s'",
24123 xmlSchemaFormatIDCKeySequence(vctxt
, &str
,
24124 refNode
->keys
, nbFields
),
24125 xmlSchemaGetComponentQName(&strB
,
24126 matcher
->aidc
->def
));
24127 FREE_AND_NULL(str
);
24128 FREE_AND_NULL(strB
);
24136 xmlChar
*str
= NULL
, *strB
= NULL
;
24137 xmlSchemaKeyrefErr(vctxt
,
24138 XML_SCHEMAV_CVC_IDC
, refNode
,
24139 (xmlSchemaTypePtr
) matcher
->aidc
->def
,
24140 "No match found for key-sequence %s of keyref '%s'",
24141 xmlSchemaFormatIDCKeySequence(vctxt
, &str
,
24142 refNode
->keys
, nbFields
),
24143 xmlSchemaGetComponentQName(&strB
, matcher
->aidc
->def
));
24144 FREE_AND_NULL(str
);
24145 FREE_AND_NULL(strB
);
24149 xmlHashFree(table
, xmlFreeIDCHashEntry
);
24152 matcher
= matcher
->next
;
24154 /* TODO: Return an error if any error encountered. */
24158 /************************************************************************
24160 * XML Reader validation code *
24162 ************************************************************************/
24164 static xmlSchemaAttrInfoPtr
24165 xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt
)
24167 xmlSchemaAttrInfoPtr iattr
;
24169 * Grow/create list of attribute infos.
24171 if (vctxt
->attrInfos
== NULL
) {
24172 vctxt
->attrInfos
= (xmlSchemaAttrInfoPtr
*)
24173 xmlMalloc(sizeof(xmlSchemaAttrInfoPtr
));
24174 vctxt
->sizeAttrInfos
= 1;
24175 if (vctxt
->attrInfos
== NULL
) {
24176 xmlSchemaVErrMemory(vctxt
,
24177 "allocating attribute info list", NULL
);
24180 } else if (vctxt
->sizeAttrInfos
<= vctxt
->nbAttrInfos
) {
24181 vctxt
->sizeAttrInfos
++;
24182 vctxt
->attrInfos
= (xmlSchemaAttrInfoPtr
*)
24183 xmlRealloc(vctxt
->attrInfos
,
24184 vctxt
->sizeAttrInfos
* sizeof(xmlSchemaAttrInfoPtr
));
24185 if (vctxt
->attrInfos
== NULL
) {
24186 xmlSchemaVErrMemory(vctxt
,
24187 "re-allocating attribute info list", NULL
);
24191 iattr
= vctxt
->attrInfos
[vctxt
->nbAttrInfos
++];
24192 if (iattr
->localName
!= NULL
) {
24193 VERROR_INT("xmlSchemaGetFreshAttrInfo",
24194 "attr info not cleared");
24197 iattr
->nodeType
= XML_ATTRIBUTE_NODE
;
24201 * Create an attribute info.
24203 iattr
= (xmlSchemaAttrInfoPtr
)
24204 xmlMalloc(sizeof(xmlSchemaAttrInfo
));
24205 if (iattr
== NULL
) {
24206 xmlSchemaVErrMemory(vctxt
, "creating new attribute info", NULL
);
24209 memset(iattr
, 0, sizeof(xmlSchemaAttrInfo
));
24210 iattr
->nodeType
= XML_ATTRIBUTE_NODE
;
24211 vctxt
->attrInfos
[vctxt
->nbAttrInfos
++] = iattr
;
24217 xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt
,
24218 xmlNodePtr attrNode
,
24220 const xmlChar
*localName
,
24221 const xmlChar
*nsName
,
24226 xmlSchemaAttrInfoPtr attr
;
24228 attr
= xmlSchemaGetFreshAttrInfo(vctxt
);
24229 if (attr
== NULL
) {
24230 VERROR_INT("xmlSchemaPushAttribute",
24231 "calling xmlSchemaGetFreshAttrInfo()");
24234 attr
->node
= attrNode
;
24235 attr
->nodeLine
= nodeLine
;
24236 attr
->state
= XML_SCHEMAS_ATTR_UNKNOWN
;
24237 attr
->localName
= localName
;
24238 attr
->nsName
= nsName
;
24240 attr
->flags
|= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES
;
24242 * Evaluate if it's an XSI attribute.
24244 if (nsName
!= NULL
) {
24245 if (xmlStrEqual(localName
, BAD_CAST
"nil")) {
24246 if (xmlStrEqual(attr
->nsName
, xmlSchemaInstanceNs
)) {
24247 attr
->metaType
= XML_SCHEMA_ATTR_INFO_META_XSI_NIL
;
24249 } else if (xmlStrEqual(localName
, BAD_CAST
"type")) {
24250 if (xmlStrEqual(attr
->nsName
, xmlSchemaInstanceNs
)) {
24251 attr
->metaType
= XML_SCHEMA_ATTR_INFO_META_XSI_TYPE
;
24253 } else if (xmlStrEqual(localName
, BAD_CAST
"schemaLocation")) {
24254 if (xmlStrEqual(attr
->nsName
, xmlSchemaInstanceNs
)) {
24255 attr
->metaType
= XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC
;
24257 } else if (xmlStrEqual(localName
, BAD_CAST
"noNamespaceSchemaLocation")) {
24258 if (xmlStrEqual(attr
->nsName
, xmlSchemaInstanceNs
)) {
24259 attr
->metaType
= XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC
;
24261 } else if (xmlStrEqual(attr
->nsName
, xmlNamespaceNs
)) {
24262 attr
->metaType
= XML_SCHEMA_ATTR_INFO_META_XMLNS
;
24265 attr
->value
= value
;
24267 attr
->flags
|= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES
;
24268 if (attr
->metaType
!= 0)
24269 attr
->state
= XML_SCHEMAS_ATTR_META
;
24274 * xmlSchemaClearElemInfo:
24275 * @vctxt: the WXS validation context
24276 * @ielem: the element information item
24279 xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt
,
24280 xmlSchemaNodeInfoPtr ielem
)
24282 ielem
->hasKeyrefs
= 0;
24283 ielem
->appliedXPath
= 0;
24284 if (ielem
->flags
& XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES
) {
24285 FREE_AND_NULL(ielem
->localName
);
24286 FREE_AND_NULL(ielem
->nsName
);
24288 ielem
->localName
= NULL
;
24289 ielem
->nsName
= NULL
;
24291 if (ielem
->flags
& XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES
) {
24292 FREE_AND_NULL(ielem
->value
);
24294 ielem
->value
= NULL
;
24296 if (ielem
->val
!= NULL
) {
24298 * PSVI TODO: Be careful not to free it when the value is
24299 * exposed via PSVI.
24301 xmlSchemaFreeValue(ielem
->val
);
24304 if (ielem
->idcMatchers
!= NULL
) {
24306 * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
24309 xmlSchemaIDCReleaseMatcherList(vctxt
, ielem
->idcMatchers
);
24311 xmlSchemaIDCFreeMatcherList(ielem
->idcMatchers
);
24313 ielem
->idcMatchers
= NULL
;
24315 if (ielem
->idcTable
!= NULL
) {
24317 * OPTIMIZE TODO: Use a pool of IDC tables??.
24319 xmlSchemaIDCFreeIDCTable(ielem
->idcTable
);
24320 ielem
->idcTable
= NULL
;
24322 if (ielem
->regexCtxt
!= NULL
) {
24323 xmlRegFreeExecCtxt(ielem
->regexCtxt
);
24324 ielem
->regexCtxt
= NULL
;
24326 if (ielem
->nsBindings
!= NULL
) {
24327 xmlFree((xmlChar
**)ielem
->nsBindings
);
24328 ielem
->nsBindings
= NULL
;
24329 ielem
->nbNsBindings
= 0;
24330 ielem
->sizeNsBindings
= 0;
24335 * xmlSchemaGetFreshElemInfo:
24336 * @vctxt: the schema validation context
24338 * Creates/reuses and initializes the element info item for
24339 * the current tree depth.
24341 * Returns the element info item or NULL on API or internal errors.
24343 static xmlSchemaNodeInfoPtr
24344 xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt
)
24346 xmlSchemaNodeInfoPtr info
= NULL
;
24348 if (vctxt
->depth
> vctxt
->sizeElemInfos
) {
24349 VERROR_INT("xmlSchemaGetFreshElemInfo",
24350 "inconsistent depth encountered");
24353 if (vctxt
->elemInfos
== NULL
) {
24354 vctxt
->elemInfos
= (xmlSchemaNodeInfoPtr
*)
24355 xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr
));
24356 if (vctxt
->elemInfos
== NULL
) {
24357 xmlSchemaVErrMemory(vctxt
,
24358 "allocating the element info array", NULL
);
24361 memset(vctxt
->elemInfos
, 0, 10 * sizeof(xmlSchemaNodeInfoPtr
));
24362 vctxt
->sizeElemInfos
= 10;
24363 } else if (vctxt
->sizeElemInfos
<= vctxt
->depth
) {
24364 int i
= vctxt
->sizeElemInfos
;
24366 vctxt
->sizeElemInfos
*= 2;
24367 vctxt
->elemInfos
= (xmlSchemaNodeInfoPtr
*)
24368 xmlRealloc(vctxt
->elemInfos
, vctxt
->sizeElemInfos
*
24369 sizeof(xmlSchemaNodeInfoPtr
));
24370 if (vctxt
->elemInfos
== NULL
) {
24371 xmlSchemaVErrMemory(vctxt
,
24372 "re-allocating the element info array", NULL
);
24376 * We need the new memory to be NULLed.
24377 * TODO: Use memset instead?
24379 for (; i
< vctxt
->sizeElemInfos
; i
++)
24380 vctxt
->elemInfos
[i
] = NULL
;
24382 info
= vctxt
->elemInfos
[vctxt
->depth
];
24384 if (info
== NULL
) {
24385 info
= (xmlSchemaNodeInfoPtr
)
24386 xmlMalloc(sizeof(xmlSchemaNodeInfo
));
24387 if (info
== NULL
) {
24388 xmlSchemaVErrMemory(vctxt
,
24389 "allocating an element info", NULL
);
24392 vctxt
->elemInfos
[vctxt
->depth
] = info
;
24394 if (info
->localName
!= NULL
) {
24395 VERROR_INT("xmlSchemaGetFreshElemInfo",
24396 "elem info has not been cleared");
24400 memset(info
, 0, sizeof(xmlSchemaNodeInfo
));
24401 info
->nodeType
= XML_ELEMENT_NODE
;
24402 info
->depth
= vctxt
->depth
;
24407 #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
24408 #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
24409 #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
24412 xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt
,
24414 xmlSchemaTypePtr type
,
24415 xmlSchemaValType valType
,
24416 const xmlChar
* value
,
24417 xmlSchemaValPtr val
,
24418 unsigned long length
,
24421 int ret
, error
= 0, found
;
24423 xmlSchemaTypePtr tmpType
;
24424 xmlSchemaFacetLinkPtr facetLink
;
24425 xmlSchemaFacetPtr facet
;
24426 unsigned long len
= 0;
24427 xmlSchemaWhitespaceValueType ws
;
24430 * In Libxml2, derived built-in types have currently no explicit facets.
24432 if (type
->type
== XML_SCHEMA_TYPE_BASIC
)
24436 * NOTE: Do not jump away, if the facetSet of the given type is
24437 * empty: until now, "pattern" and "enumeration" facets of the
24438 * *base types* need to be checked as well.
24440 if (type
->facetSet
== NULL
)
24441 goto pattern_and_enum
;
24443 if (! WXS_IS_ATOMIC(type
)) {
24444 if (WXS_IS_LIST(type
))
24447 goto pattern_and_enum
;
24451 * Whitespace handling is only of importance for string-based
24454 tmpType
= xmlSchemaGetPrimitiveType(type
);
24455 if ((tmpType
->builtInType
== XML_SCHEMAS_STRING
) ||
24456 WXS_IS_ANY_SIMPLE_TYPE(tmpType
)) {
24457 ws
= xmlSchemaGetWhiteSpaceFacetValue(type
);
24459 ws
= XML_SCHEMA_WHITESPACE_COLLAPSE
;
24462 * If the value was not computed (for string or
24463 * anySimpleType based types), then use the provided
24467 valType
= xmlSchemaGetValType(val
);
24470 for (facetLink
= type
->facetSet
; facetLink
!= NULL
;
24471 facetLink
= facetLink
->next
) {
24473 * Skip the pattern "whiteSpace": it is used to
24474 * format the character content beforehand.
24476 switch (facetLink
->facet
->type
) {
24477 case XML_SCHEMA_FACET_WHITESPACE
:
24478 case XML_SCHEMA_FACET_PATTERN
:
24479 case XML_SCHEMA_FACET_ENUMERATION
:
24481 case XML_SCHEMA_FACET_LENGTH
:
24482 case XML_SCHEMA_FACET_MINLENGTH
:
24483 case XML_SCHEMA_FACET_MAXLENGTH
:
24484 ret
= xmlSchemaValidateLengthFacetWhtsp(facetLink
->facet
,
24485 valType
, value
, val
, &len
, ws
);
24488 ret
= xmlSchemaValidateFacetWhtsp(facetLink
->facet
, ws
,
24489 valType
, value
, val
, ws
);
24493 AERROR_INT("xmlSchemaValidateFacets",
24494 "validating against a atomic type facet");
24496 } else if (ret
> 0) {
24498 xmlSchemaFacetErr(actxt
, ret
, node
,
24499 value
, len
, type
, facetLink
->facet
, NULL
, NULL
, NULL
);
24509 if (! WXS_IS_LIST(type
))
24510 goto pattern_and_enum
;
24512 * "length", "minLength" and "maxLength" of list types.
24515 for (facetLink
= type
->facetSet
; facetLink
!= NULL
;
24516 facetLink
= facetLink
->next
) {
24518 switch (facetLink
->facet
->type
) {
24519 case XML_SCHEMA_FACET_LENGTH
:
24520 case XML_SCHEMA_FACET_MINLENGTH
:
24521 case XML_SCHEMA_FACET_MAXLENGTH
:
24522 ret
= xmlSchemaValidateListSimpleTypeFacet(facetLink
->facet
,
24523 value
, length
, NULL
);
24529 AERROR_INT("xmlSchemaValidateFacets",
24530 "validating against a list type facet");
24532 } else if (ret
> 0) {
24534 xmlSchemaFacetErr(actxt
, ret
, node
,
24535 value
, length
, type
, facetLink
->facet
, NULL
, NULL
, NULL
);
24547 * Process enumerations. Facet values are in the value space
24548 * of the defining type's base type. This seems to be a bug in the
24549 * XML Schema 1.0 spec. Use the whitespace type of the base type.
24550 * Only the first set of enumerations in the ancestor-or-self axis
24551 * is used for validation.
24556 for (facet
= tmpType
->facets
; facet
!= NULL
; facet
= facet
->next
) {
24557 if (facet
->type
!= XML_SCHEMA_FACET_ENUMERATION
)
24560 ret
= xmlSchemaAreValuesEqual(facet
->val
, val
);
24563 else if (ret
< 0) {
24564 AERROR_INT("xmlSchemaValidateFacets",
24565 "validating against an enumeration facet");
24572 * Break on the first set of enumerations. Any additional
24573 * enumerations which might be existent on the ancestors
24574 * of the current type are restricted by this set; thus
24575 * *must* *not* be taken into account.
24579 tmpType
= tmpType
->baseType
;
24580 } while ((tmpType
!= NULL
) &&
24581 (tmpType
->type
!= XML_SCHEMA_TYPE_BASIC
));
24582 if (found
&& (ret
== 0)) {
24583 ret
= XML_SCHEMAV_CVC_ENUMERATION_VALID
;
24585 xmlSchemaFacetErr(actxt
, ret
, node
,
24586 value
, 0, type
, NULL
, NULL
, NULL
, NULL
);
24594 * Process patters. Pattern facets are ORed at type level
24595 * and ANDed if derived. Walk the base type axis.
24601 for (facetLink
= tmpType
->facetSet
; facetLink
!= NULL
;
24602 facetLink
= facetLink
->next
) {
24603 if (facetLink
->facet
->type
!= XML_SCHEMA_FACET_PATTERN
)
24607 * NOTE that for patterns, @value needs to be the
24608 * normalized value.
24610 ret
= xmlRegexpExec(facetLink
->facet
->regexp
, value
);
24613 else if (ret
< 0) {
24614 AERROR_INT("xmlSchemaValidateFacets",
24615 "validating against a pattern facet");
24619 * Save the last non-validating facet.
24621 facet
= facetLink
->facet
;
24624 if (found
&& (ret
!= 1)) {
24625 ret
= XML_SCHEMAV_CVC_PATTERN_VALID
;
24627 xmlSchemaFacetErr(actxt
, ret
, node
,
24628 value
, 0, type
, facet
, NULL
, NULL
, NULL
);
24635 tmpType
= tmpType
->baseType
;
24636 } while ((tmpType
!= NULL
) && (tmpType
->type
!= XML_SCHEMA_TYPE_BASIC
));
24642 xmlSchemaNormalizeValue(xmlSchemaTypePtr type
,
24643 const xmlChar
*value
)
24645 switch (xmlSchemaGetWhiteSpaceFacetValue(type
)) {
24646 case XML_SCHEMA_WHITESPACE_COLLAPSE
:
24647 return (xmlSchemaCollapseString(value
));
24648 case XML_SCHEMA_WHITESPACE_REPLACE
:
24649 return (xmlSchemaWhiteSpaceReplace(value
));
24656 xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt
,
24657 const xmlChar
*value
,
24658 xmlSchemaValPtr
*val
,
24663 const xmlChar
*nsName
;
24664 xmlChar
*local
, *prefix
= NULL
;
24666 ret
= xmlValidateQName(value
, 1);
24669 VERROR_INT("xmlSchemaValidateQName",
24670 "calling xmlValidateQName()");
24673 return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1
);
24676 * NOTE: xmlSplitQName2 will always return a duplicated
24679 /* TODO: Export and use xmlSchemaStrip instead */
24680 stripped
= xmlSchemaCollapseString(value
);
24681 local
= xmlSplitQName2(stripped
? stripped
: value
, &prefix
);
24684 local
= xmlStrdup(value
);
24686 * OPTIMIZE TODO: Use flags for:
24687 * - is there any namespace binding?
24688 * - is there a default namespace?
24690 nsName
= xmlSchemaLookupNamespace(vctxt
, prefix
);
24692 if (prefix
!= NULL
) {
24695 * A namespace must be found if the prefix is
24698 if (nsName
== NULL
) {
24699 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1
;
24700 xmlSchemaCustomErr(ACTXT_CAST vctxt
, ret
, NULL
,
24701 WXS_BASIC_CAST
xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME
),
24702 "The QName value '%s' has no "
24703 "corresponding namespace declaration in "
24704 "scope", value
, NULL
);
24710 if (valNeeded
&& val
) {
24711 if (nsName
!= NULL
)
24712 *val
= xmlSchemaNewQNameValue(
24713 BAD_CAST
xmlStrdup(nsName
), BAD_CAST local
);
24715 *val
= xmlSchemaNewQNameValue(NULL
,
24726 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt
,
24728 xmlSchemaTypePtr type
,
24729 const xmlChar
*value
,
24730 xmlSchemaValPtr
*retVal
,
24735 int ret
= 0, valNeeded
= (retVal
) ? 1 : 0;
24736 xmlSchemaValPtr val
= NULL
;
24737 /* xmlSchemaWhitespaceValueType ws; */
24738 xmlChar
*normValue
= NULL
;
24740 #define NORMALIZE(atype) \
24741 if ((! isNormalized) && \
24742 (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
24743 normValue = xmlSchemaNormalizeValue(atype, value); \
24744 if (normValue != NULL) \
24745 value = normValue; \
24746 isNormalized = 1; \
24749 if ((retVal
!= NULL
) && (*retVal
!= NULL
)) {
24750 xmlSchemaFreeValue(*retVal
);
24754 * 3.14.4 Simple Type Definition Validation Rules
24755 * Validation Rule: String Valid
24758 * 1 It is schema-valid with respect to that definition as defined
24759 * by Datatype Valid in [XML Schemas: Datatypes].
24762 * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
24763 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
24764 * the string must be a `declared entity name`.
24767 * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
24768 * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
24769 * then every whitespace-delimited substring of the string must be a `declared
24773 * 2.3 otherwise no further condition applies.
24775 if ((! valNeeded
) && (type
->flags
& XML_SCHEMAS_TYPE_FACETSNEEDVALUE
))
24778 value
= BAD_CAST
"";
24779 if (WXS_IS_ANY_SIMPLE_TYPE(type
) || WXS_IS_ATOMIC(type
)) {
24780 xmlSchemaTypePtr biType
; /* The built-in type. */
24782 * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
24783 * a literal in the `lexical space` of {base type definition}"
24786 * Whitespace-normalize.
24789 if (type
->type
!= XML_SCHEMA_TYPE_BASIC
) {
24791 * Get the built-in type.
24793 biType
= type
->baseType
;
24794 while ((biType
!= NULL
) &&
24795 (biType
->type
!= XML_SCHEMA_TYPE_BASIC
))
24796 biType
= biType
->baseType
;
24798 if (biType
== NULL
) {
24799 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24800 "could not get the built-in type");
24801 goto internal_error
;
24806 * NOTATIONs need to be processed here, since they need
24807 * to lookup in the hashtable of NOTATION declarations of the schema.
24809 if (actxt
->type
== XML_SCHEMA_CTXT_VALIDATOR
) {
24810 switch (biType
->builtInType
) {
24811 case XML_SCHEMAS_NOTATION
:
24812 ret
= xmlSchemaValidateNotation(
24813 (xmlSchemaValidCtxtPtr
) actxt
,
24814 ((xmlSchemaValidCtxtPtr
) actxt
)->schema
,
24815 NULL
, value
, &val
, valNeeded
);
24817 case XML_SCHEMAS_QNAME
:
24818 ret
= xmlSchemaValidateQName((xmlSchemaValidCtxtPtr
) actxt
,
24819 value
, &val
, valNeeded
);
24822 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24824 ret
= xmlSchemaValPredefTypeNodeNoNorm(biType
,
24825 value
, &val
, node
);
24827 ret
= xmlSchemaValPredefTypeNodeNoNorm(biType
,
24828 value
, NULL
, node
);
24831 } else if (actxt
->type
== XML_SCHEMA_CTXT_PARSER
) {
24832 switch (biType
->builtInType
) {
24833 case XML_SCHEMAS_NOTATION
:
24834 ret
= xmlSchemaValidateNotation(NULL
,
24835 ((xmlSchemaParserCtxtPtr
) actxt
)->schema
, node
,
24836 value
, &val
, valNeeded
);
24839 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24841 ret
= xmlSchemaValPredefTypeNodeNoNorm(biType
,
24842 value
, &val
, node
);
24844 ret
= xmlSchemaValPredefTypeNodeNoNorm(biType
,
24845 value
, NULL
, node
);
24850 * Validation via a public API is not implemented yet.
24853 goto internal_error
;
24857 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24858 "validating against a built-in type");
24859 goto internal_error
;
24861 if (WXS_IS_LIST(type
))
24862 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2
;
24864 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1
;
24866 if ((ret
== 0) && (type
->flags
& XML_SCHEMAS_TYPE_HAS_FACETS
)) {
24870 ret
= xmlSchemaValidateFacets(actxt
, node
, type
,
24871 (xmlSchemaValType
) biType
->builtInType
, value
, val
,
24875 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24876 "validating facets of atomic simple type");
24877 goto internal_error
;
24879 if (WXS_IS_LIST(type
))
24880 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2
;
24882 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1
;
24885 else if (fireErrors
&& (ret
> 0))
24886 xmlSchemaSimpleTypeErr(actxt
, ret
, node
, value
, type
, 1);
24887 } else if (WXS_IS_LIST(type
)) {
24889 xmlSchemaTypePtr itemType
;
24890 const xmlChar
*cur
, *end
;
24891 xmlChar
*tmpValue
= NULL
;
24892 unsigned long len
= 0;
24893 xmlSchemaValPtr prevVal
= NULL
, curVal
= NULL
;
24894 /* 1.2.2 if {variety} is `list` then the string must be a sequence
24895 * of white space separated tokens, each of which `match`es a literal
24896 * in the `lexical space` of {item type definition}
24899 * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
24900 * the list type has an enum or pattern facet.
24904 * VAL TODO: Optimize validation of empty values.
24905 * VAL TODO: We do not have computed values for lists.
24907 itemType
= WXS_LIST_ITEMTYPE(type
);
24910 while (IS_BLANK_CH(*cur
))
24913 while ((*end
!= 0) && (!(IS_BLANK_CH(*end
))))
24917 tmpValue
= xmlStrndup(cur
, end
- cur
);
24921 ret
= xmlSchemaVCheckCVCSimpleType(actxt
, node
, itemType
,
24922 tmpValue
, &curVal
, fireErrors
, 0, 1);
24924 ret
= xmlSchemaVCheckCVCSimpleType(actxt
, node
, itemType
,
24925 tmpValue
, NULL
, fireErrors
, 0, 1);
24926 FREE_AND_NULL(tmpValue
);
24927 if (curVal
!= NULL
) {
24929 * Add to list of computed values.
24934 xmlSchemaValueAppend(prevVal
, curVal
);
24940 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24941 "validating an item of list simple type");
24942 goto internal_error
;
24944 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2
;
24948 } while (*cur
!= 0);
24949 FREE_AND_NULL(tmpValue
);
24950 if ((ret
== 0) && (type
->flags
& XML_SCHEMAS_TYPE_HAS_FACETS
)) {
24952 * Apply facets (pattern, enumeration).
24954 ret
= xmlSchemaValidateFacets(actxt
, node
, type
,
24955 XML_SCHEMAS_UNKNOWN
, value
, val
,
24959 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24960 "validating facets of list simple type");
24961 goto internal_error
;
24963 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2
;
24966 if (fireErrors
&& (ret
> 0)) {
24968 * Report the normalized value.
24972 xmlSchemaSimpleTypeErr(actxt
, ret
, node
, value
, type
, 1);
24974 } else if (WXS_IS_UNION(type
)) {
24975 xmlSchemaTypeLinkPtr memberLink
;
24977 * TODO: For all datatypes `derived` by `union` whiteSpace does
24978 * not apply directly; however, the normalization behavior of `union`
24979 * types is controlled by the value of whiteSpace on that one of the
24980 * `memberTypes` against which the `union` is successfully validated.
24982 * This means that the value is normalized by the first validating
24983 * member type, then the facets of the union type are applied. This
24984 * needs changing of the value!
24988 * 1.2.3 if {variety} is `union` then the string must `match` a
24989 * literal in the `lexical space` of at least one member of
24990 * {member type definitions}
24992 memberLink
= xmlSchemaGetUnionSimpleTypeMemberTypes(type
);
24993 if (memberLink
== NULL
) {
24994 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24995 "union simple type has no member types");
24996 goto internal_error
;
24999 * Always normalize union type values, since we currently
25000 * cannot store the whitespace information with the value
25001 * itself; otherwise a later value-comparison would be
25004 while (memberLink
!= NULL
) {
25006 ret
= xmlSchemaVCheckCVCSimpleType(actxt
, node
,
25007 memberLink
->type
, value
, &val
, 0, 1, 0);
25009 ret
= xmlSchemaVCheckCVCSimpleType(actxt
, node
,
25010 memberLink
->type
, value
, NULL
, 0, 1, 0);
25013 memberLink
= memberLink
->next
;
25017 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
25018 "validating members of union simple type");
25019 goto internal_error
;
25021 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3
;
25024 * Apply facets (pattern, enumeration).
25026 if ((ret
== 0) && (type
->flags
& XML_SCHEMAS_TYPE_HAS_FACETS
)) {
25028 * The normalization behavior of `union` types is controlled by
25029 * the value of whiteSpace on that one of the `memberTypes`
25030 * against which the `union` is successfully validated.
25032 NORMALIZE(memberLink
->type
);
25033 ret
= xmlSchemaValidateFacets(actxt
, node
, type
,
25034 XML_SCHEMAS_UNKNOWN
, value
, val
,
25038 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
25039 "validating facets of union simple type");
25040 goto internal_error
;
25042 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3
;
25045 if (fireErrors
&& (ret
> 0))
25046 xmlSchemaSimpleTypeErr(actxt
, ret
, node
, value
, type
, 1);
25049 if (normValue
!= NULL
)
25050 xmlFree(normValue
);
25052 if (retVal
!= NULL
)
25054 else if (val
!= NULL
)
25055 xmlSchemaFreeValue(val
);
25056 } else if (val
!= NULL
)
25057 xmlSchemaFreeValue(val
);
25060 if (normValue
!= NULL
)
25061 xmlFree(normValue
);
25063 xmlSchemaFreeValue(val
);
25068 xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt
,
25069 const xmlChar
*value
,
25070 const xmlChar
**nsName
,
25071 const xmlChar
**localName
)
25075 if ((nsName
== NULL
) || (localName
== NULL
))
25080 ret
= xmlValidateQName(value
, 1);
25084 xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt
,
25085 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1
, NULL
,
25086 value
, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME
), 1);
25090 xmlChar
*local
= NULL
;
25094 * NOTE: xmlSplitQName2 will return a duplicated
25097 local
= xmlSplitQName2(value
, &prefix
);
25099 *localName
= xmlDictLookup(vctxt
->dict
, value
, -1);
25101 *localName
= xmlDictLookup(vctxt
->dict
, local
, -1);
25105 *nsName
= xmlSchemaLookupNamespace(vctxt
, prefix
);
25107 if (prefix
!= NULL
) {
25110 * A namespace must be found if the prefix is NOT NULL.
25112 if (*nsName
== NULL
) {
25113 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
25114 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1
, NULL
,
25115 WXS_BASIC_CAST
xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME
),
25116 "The QName value '%s' has no "
25117 "corresponding namespace declaration in scope",
25127 xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt
,
25128 xmlSchemaAttrInfoPtr iattr
,
25129 xmlSchemaTypePtr
*localType
,
25130 xmlSchemaElementPtr elemDecl
)
25134 * cvc-elt (3.3.4) : (4)
25136 * Schema-Validity Assessment (Element) (cvc-assess-elt)
25137 * (1.2.1.2.1) - (1.2.1.2.4)
25138 * Handle 'xsi:type'.
25140 if (localType
== NULL
)
25146 const xmlChar
*nsName
= NULL
, *local
= NULL
;
25148 * TODO: We should report a *warning* that the type was overridden
25151 ACTIVATE_ATTRIBUTE(iattr
);
25153 * (cvc-elt) (3.3.4) : (4.1)
25154 * (cvc-assess-elt) (1.2.1.2.2)
25156 ret
= xmlSchemaVExpandQName(vctxt
, iattr
->value
,
25160 VERROR_INT("xmlSchemaValidateElementByDeclaration",
25161 "calling xmlSchemaQNameExpand() to validate the "
25162 "attribute 'xsi:type'");
25163 goto internal_error
;
25168 * (cvc-elt) (3.3.4) : (4.2)
25169 * (cvc-assess-elt) (1.2.1.2.3)
25171 *localType
= xmlSchemaGetType(vctxt
->schema
, local
, nsName
);
25172 if (*localType
== NULL
) {
25173 xmlChar
*str
= NULL
;
25175 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
25176 XML_SCHEMAV_CVC_ELT_4_2
, NULL
,
25177 WXS_BASIC_CAST
xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME
),
25178 "The QName value '%s' of the xsi:type attribute does not "
25179 "resolve to a type definition",
25180 xmlSchemaFormatQName(&str
, nsName
, local
), NULL
);
25181 FREE_AND_NULL(str
);
25185 if (elemDecl
!= NULL
) {
25189 * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
25190 * "The `local type definition` must be validly
25191 * derived from the {type definition} given the union of
25192 * the {disallowed substitutions} and the {type definition}'s
25193 * {prohibited substitutions}, as defined in
25194 * Type Derivation OK (Complex) ($3.4.6)
25195 * (if it is a complex type definition),
25196 * or given {disallowed substitutions} as defined in Type
25197 * Derivation OK (Simple) ($3.14.6) (if it is a simple type
25200 * {disallowed substitutions}: the "block" on the element decl.
25201 * {prohibited substitutions}: the "block" on the type def.
25204 * OPTIMIZE TODO: We could map types already evaluated
25205 * to be validly derived from other types to avoid checking
25206 * this over and over for the same types.
25208 if ((elemDecl
->flags
& XML_SCHEMAS_ELEM_BLOCK_EXTENSION
) ||
25209 (elemDecl
->subtypes
->flags
&
25210 XML_SCHEMAS_TYPE_BLOCK_EXTENSION
))
25211 set
|= SUBSET_EXTENSION
;
25213 if ((elemDecl
->flags
& XML_SCHEMAS_ELEM_BLOCK_RESTRICTION
) ||
25214 (elemDecl
->subtypes
->flags
&
25215 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
))
25216 set
|= SUBSET_RESTRICTION
;
25219 * REMOVED and CHANGED since this produced a parser context
25220 * which adds to the string dict of the schema. So this would
25221 * change the schema and we don't want this. We don't need
25222 * the parser context anymore.
25224 * if ((vctxt->pctxt == NULL) &&
25225 * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
25229 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt
, *localType
,
25230 elemDecl
->subtypes
, set
) != 0) {
25231 xmlChar
*str
= NULL
;
25233 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
25234 XML_SCHEMAV_CVC_ELT_4_3
, NULL
, NULL
,
25235 "The type definition '%s', specified by xsi:type, is "
25236 "blocked or not validly derived from the type definition "
25237 "of the element declaration",
25238 xmlSchemaFormatQName(&str
,
25239 (*localType
)->targetNamespace
,
25240 (*localType
)->name
),
25242 FREE_AND_NULL(str
);
25257 xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt
)
25259 xmlSchemaElementPtr elemDecl
= vctxt
->inode
->decl
;
25260 xmlSchemaTypePtr actualType
;
25263 * cvc-elt (3.3.4) : 1
25265 if (elemDecl
== NULL
) {
25266 VERROR(XML_SCHEMAV_CVC_ELT_1
, NULL
,
25267 "No matching declaration available");
25268 return (vctxt
->err
);
25270 actualType
= WXS_ELEM_TYPEDEF(elemDecl
);
25272 * cvc-elt (3.3.4) : 2
25274 if (elemDecl
->flags
& XML_SCHEMAS_ELEM_ABSTRACT
) {
25275 VERROR(XML_SCHEMAV_CVC_ELT_2
, NULL
,
25276 "The element declaration is abstract");
25277 return (vctxt
->err
);
25279 if (actualType
== NULL
) {
25280 VERROR(XML_SCHEMAV_CVC_TYPE_1
, NULL
,
25281 "The type definition is absent");
25282 return (XML_SCHEMAV_CVC_TYPE_1
);
25284 if (vctxt
->nbAttrInfos
!= 0) {
25286 xmlSchemaAttrInfoPtr iattr
;
25288 * cvc-elt (3.3.4) : 3
25289 * Handle 'xsi:nil'.
25291 iattr
= xmlSchemaGetMetaAttrInfo(vctxt
,
25292 XML_SCHEMA_ATTR_INFO_META_XSI_NIL
);
25294 ACTIVATE_ATTRIBUTE(iattr
);
25296 * Validate the value.
25298 ret
= xmlSchemaVCheckCVCSimpleType(
25299 ACTXT_CAST vctxt
, NULL
,
25300 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN
),
25301 iattr
->value
, &(iattr
->val
), 1, 0, 0);
25304 VERROR_INT("xmlSchemaValidateElemDecl",
25305 "calling xmlSchemaVCheckCVCSimpleType() to "
25306 "validate the attribute 'xsi:nil'");
25310 if ((elemDecl
->flags
& XML_SCHEMAS_ELEM_NILLABLE
) == 0) {
25312 * cvc-elt (3.3.4) : 3.1
25314 VERROR(XML_SCHEMAV_CVC_ELT_3_1
, NULL
,
25315 "The element is not 'nillable'");
25316 /* Does not return an error on purpose. */
25318 if (xmlSchemaValueGetAsBoolean(iattr
->val
)) {
25320 * cvc-elt (3.3.4) : 3.2.2
25322 if ((elemDecl
->flags
& XML_SCHEMAS_ELEM_FIXED
) &&
25323 (elemDecl
->value
!= NULL
)) {
25324 VERROR(XML_SCHEMAV_CVC_ELT_3_2_2
, NULL
,
25325 "The element cannot be 'nilled' because "
25326 "there is a fixed value constraint defined "
25328 /* Does not return an error on purpose. */
25330 vctxt
->inode
->flags
|=
25331 XML_SCHEMA_ELEM_INFO_NILLED
;
25337 * cvc-elt (3.3.4) : 4
25338 * Handle 'xsi:type'.
25340 iattr
= xmlSchemaGetMetaAttrInfo(vctxt
,
25341 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE
);
25343 xmlSchemaTypePtr localType
= NULL
;
25345 ret
= xmlSchemaProcessXSIType(vctxt
, iattr
, &localType
,
25349 VERROR_INT("xmlSchemaValidateElemDecl",
25350 "calling xmlSchemaProcessXSIType() to "
25351 "process the attribute 'xsi:type'");
25354 /* Does not return an error on purpose. */
25356 if (localType
!= NULL
) {
25357 vctxt
->inode
->flags
|= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE
;
25358 actualType
= localType
;
25363 * IDC: Register identity-constraint XPath matchers.
25365 if ((elemDecl
->idcs
!= NULL
) &&
25366 (xmlSchemaIDCRegisterMatchers(vctxt
, elemDecl
) == -1))
25369 * No actual type definition.
25371 if (actualType
== NULL
) {
25372 VERROR(XML_SCHEMAV_CVC_TYPE_1
, NULL
,
25373 "The type definition is absent");
25374 return (XML_SCHEMAV_CVC_TYPE_1
);
25377 * Remember the actual type definition.
25379 vctxt
->inode
->typeDef
= actualType
;
25385 xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt
)
25387 xmlSchemaAttrInfoPtr iattr
;
25391 * SPEC cvc-type (3.1.1)
25392 * "The attributes of must be empty, excepting those whose namespace
25393 * name is identical to http://www.w3.org/2001/XMLSchema-instance and
25394 * whose local name is one of type, nil, schemaLocation or
25395 * noNamespaceSchemaLocation."
25397 if (vctxt
->nbAttrInfos
== 0)
25399 for (i
= 0; i
< vctxt
->nbAttrInfos
; i
++) {
25400 iattr
= vctxt
->attrInfos
[i
];
25401 if (! iattr
->metaType
) {
25402 ACTIVATE_ATTRIBUTE(iattr
)
25403 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt
,
25404 XML_SCHEMAV_CVC_TYPE_3_1_1
, iattr
, NULL
);
25405 ret
= XML_SCHEMAV_CVC_TYPE_3_1_1
;
25413 * Cleanup currently used attribute infos.
25416 xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt
)
25419 xmlSchemaAttrInfoPtr attr
;
25421 if (vctxt
->nbAttrInfos
== 0)
25423 for (i
= 0; i
< vctxt
->nbAttrInfos
; i
++) {
25424 attr
= vctxt
->attrInfos
[i
];
25425 if (attr
->flags
& XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES
) {
25426 if (attr
->localName
!= NULL
)
25427 xmlFree((xmlChar
*) attr
->localName
);
25428 if (attr
->nsName
!= NULL
)
25429 xmlFree((xmlChar
*) attr
->nsName
);
25431 if (attr
->flags
& XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES
) {
25432 if (attr
->value
!= NULL
)
25433 xmlFree((xmlChar
*) attr
->value
);
25435 if (attr
->val
!= NULL
) {
25436 xmlSchemaFreeValue(attr
->val
);
25439 memset(attr
, 0, sizeof(xmlSchemaAttrInfo
));
25441 vctxt
->nbAttrInfos
= 0;
25445 * 3.4.4 Complex Type Definition Validation Rules
25446 * Element Locally Valid (Complex Type) (cvc-complex-type)
25447 * 3.2.4 Attribute Declaration Validation Rules
25448 * Validation Rule: Attribute Locally Valid (cvc-attribute)
25449 * Attribute Locally Valid (Use) (cvc-au)
25451 * Only "assessed" attribute information items will be visible to
25452 * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
25455 xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt
)
25457 xmlSchemaTypePtr type
= vctxt
->inode
->typeDef
;
25458 xmlSchemaItemListPtr attrUseList
;
25459 xmlSchemaAttributeUsePtr attrUse
= NULL
;
25460 xmlSchemaAttributePtr attrDecl
= NULL
;
25461 xmlSchemaAttrInfoPtr iattr
, tmpiattr
;
25462 int i
, j
, found
, nbAttrs
, nbUses
;
25463 int xpathRes
= 0, res
, wildIDs
= 0, fixed
;
25464 xmlNodePtr defAttrOwnerElem
= NULL
;
25467 * SPEC (cvc-attribute)
25468 * (1) "The declaration must not be `absent` (see Missing
25469 * Sub-components ($5.3) for how this can fail to be
25471 * (2) "Its {type definition} must not be absent."
25473 * NOTE (1) + (2): This is not handled here, since we currently do not
25474 * allow validation against schemas which have missing sub-components.
25476 * SPEC (cvc-complex-type)
25477 * (3) "For each attribute information item in the element information
25478 * item's [attributes] excepting those whose [namespace name] is
25479 * identical to http://www.w3.org/2001/XMLSchema-instance and whose
25480 * [local name] is one of type, nil, schemaLocation or
25481 * noNamespaceSchemaLocation, the appropriate case among the following
25485 attrUseList
= (xmlSchemaItemListPtr
) type
->attrUses
;
25487 * @nbAttrs is the number of attributes present in the instance.
25489 nbAttrs
= vctxt
->nbAttrInfos
;
25490 if (attrUseList
!= NULL
)
25491 nbUses
= attrUseList
->nbItems
;
25494 for (i
= 0; i
< nbUses
; i
++) {
25496 attrUse
= attrUseList
->items
[i
];
25497 attrDecl
= WXS_ATTRUSE_DECL(attrUse
);
25498 for (j
= 0; j
< nbAttrs
; j
++) {
25499 iattr
= vctxt
->attrInfos
[j
];
25501 * SPEC (cvc-complex-type) (3)
25502 * Skip meta attributes.
25504 if (iattr
->metaType
)
25506 if (iattr
->localName
[0] != attrDecl
->name
[0])
25508 if (!xmlStrEqual(iattr
->localName
, attrDecl
->name
))
25510 if (!xmlStrEqual(iattr
->nsName
, attrDecl
->targetNamespace
))
25514 * SPEC (cvc-complex-type)
25515 * (3.1) "If there is among the {attribute uses} an attribute
25516 * use with an {attribute declaration} whose {name} matches
25517 * the attribute information item's [local name] and whose
25518 * {target namespace} is identical to the attribute information
25519 * item's [namespace name] (where an `absent` {target namespace}
25520 * is taken to be identical to a [namespace name] with no value),
25521 * then the attribute information must be `valid` with respect
25522 * to that attribute use as per Attribute Locally Valid (Use)
25523 * ($3.5.4). In this case the {attribute declaration} of that
25524 * attribute use is the `context-determined declaration` for the
25525 * attribute information item with respect to Schema-Validity
25526 * Assessment (Attribute) ($3.2.4) and
25527 * Assessment Outcome (Attribute) ($3.2.5).
25529 iattr
->state
= XML_SCHEMAS_ATTR_ASSESSED
;
25530 iattr
->use
= attrUse
;
25532 * Context-determined declaration.
25534 iattr
->decl
= attrDecl
;
25535 iattr
->typeDef
= attrDecl
->subtypes
;
25542 if (attrUse
->occurs
== XML_SCHEMAS_ATTR_USE_REQUIRED
) {
25544 * Handle non-existent, required attributes.
25546 * SPEC (cvc-complex-type)
25547 * (4) "The {attribute declaration} of each attribute use in
25548 * the {attribute uses} whose {required} is true matches one
25549 * of the attribute information items in the element information
25550 * item's [attributes] as per clause 3.1 above."
25552 tmpiattr
= xmlSchemaGetFreshAttrInfo(vctxt
);
25553 if (tmpiattr
== NULL
) {
25555 "xmlSchemaVAttributesComplex",
25556 "calling xmlSchemaGetFreshAttrInfo()");
25559 tmpiattr
->state
= XML_SCHEMAS_ATTR_ERR_MISSING
;
25560 tmpiattr
->use
= attrUse
;
25561 tmpiattr
->decl
= attrDecl
;
25562 } else if ((attrUse
->occurs
== XML_SCHEMAS_ATTR_USE_OPTIONAL
) &&
25563 ((attrUse
->defValue
!= NULL
) ||
25564 (attrDecl
->defValue
!= NULL
))) {
25566 * Handle non-existent, optional, default/fixed attributes.
25568 tmpiattr
= xmlSchemaGetFreshAttrInfo(vctxt
);
25569 if (tmpiattr
== NULL
) {
25571 "xmlSchemaVAttributesComplex",
25572 "calling xmlSchemaGetFreshAttrInfo()");
25575 tmpiattr
->state
= XML_SCHEMAS_ATTR_DEFAULT
;
25576 tmpiattr
->use
= attrUse
;
25577 tmpiattr
->decl
= attrDecl
;
25578 tmpiattr
->typeDef
= attrDecl
->subtypes
;
25579 tmpiattr
->localName
= attrDecl
->name
;
25580 tmpiattr
->nsName
= attrDecl
->targetNamespace
;
25584 if (vctxt
->nbAttrInfos
== 0)
25587 * Validate against the wildcard.
25589 if (type
->attributeWildcard
!= NULL
) {
25591 * SPEC (cvc-complex-type)
25592 * (3.2.1) "There must be an {attribute wildcard}."
25594 for (i
= 0; i
< nbAttrs
; i
++) {
25595 iattr
= vctxt
->attrInfos
[i
];
25597 * SPEC (cvc-complex-type) (3)
25598 * Skip meta attributes.
25600 if (iattr
->state
!= XML_SCHEMAS_ATTR_UNKNOWN
)
25603 * SPEC (cvc-complex-type)
25604 * (3.2.2) "The attribute information item must be `valid` with
25605 * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
25607 * SPEC Item Valid (Wildcard) (cvc-wildcard)
25608 * "... its [namespace name] must be `valid` with respect to
25609 * the wildcard constraint, as defined in Wildcard allows
25610 * Namespace Name ($3.10.4)."
25612 if (xmlSchemaCheckCVCWildcardNamespace(type
->attributeWildcard
,
25613 iattr
->nsName
) == 0) {
25615 * Handle processContents.
25617 * SPEC (cvc-wildcard):
25618 * processContents | context-determined declaration:
25619 * "strict" "mustFind"
25623 if (type
->attributeWildcard
->processContents
==
25624 XML_SCHEMAS_ANY_SKIP
) {
25626 * context-determined declaration = "skip"
25628 * SPEC PSVI Assessment Outcome (Attribute)
25629 * [validity] = "notKnown"
25630 * [validation attempted] = "none"
25632 iattr
->state
= XML_SCHEMAS_ATTR_WILD_SKIP
;
25636 * Find an attribute declaration.
25638 iattr
->decl
= xmlSchemaGetAttributeDecl(vctxt
->schema
,
25639 iattr
->localName
, iattr
->nsName
);
25640 if (iattr
->decl
!= NULL
) {
25641 iattr
->state
= XML_SCHEMAS_ATTR_ASSESSED
;
25643 * SPEC (cvc-complex-type)
25644 * (5) "Let [Definition:] the wild IDs be the set of
25645 * all attribute information item to which clause 3.2
25646 * applied and whose `validation` resulted in a
25647 * `context-determined declaration` of mustFind or no
25648 * `context-determined declaration` at all, and whose
25649 * [local name] and [namespace name] resolve (as
25650 * defined by QName resolution (Instance) ($3.15.4)) to
25651 * an attribute declaration whose {type definition} is
25652 * or is derived from ID. Then all of the following
25655 iattr
->typeDef
= WXS_ATTR_TYPEDEF(iattr
->decl
);
25656 if (xmlSchemaIsDerivedFromBuiltInType(
25657 iattr
->typeDef
, XML_SCHEMAS_ID
)) {
25659 * SPEC (5.1) "There must be no more than one
25660 * item in `wild IDs`."
25662 if (wildIDs
!= 0) {
25664 iattr
->state
= XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID
;
25670 * SPEC (cvc-complex-type)
25671 * (5.2) "If `wild IDs` is non-empty, there must not
25672 * be any attribute uses among the {attribute uses}
25673 * whose {attribute declaration}'s {type definition}
25674 * is or is derived from ID."
25676 if (attrUseList
!= NULL
) {
25677 for (j
= 0; j
< attrUseList
->nbItems
; j
++) {
25678 if (xmlSchemaIsDerivedFromBuiltInType(
25679 WXS_ATTRUSE_TYPEDEF(attrUseList
->items
[j
]),
25681 /* URGENT VAL TODO: implement */
25682 iattr
->state
= XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID
;
25689 } else if (type
->attributeWildcard
->processContents
==
25690 XML_SCHEMAS_ANY_LAX
) {
25691 iattr
->state
= XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL
;
25693 * SPEC PSVI Assessment Outcome (Attribute)
25694 * [validity] = "notKnown"
25695 * [validation attempted] = "none"
25698 iattr
->state
= XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL
;
25704 if (vctxt
->nbAttrInfos
== 0)
25708 * Get the owner element; needed for creation of default attributes.
25709 * This fixes bug #341337, reported by David Grohmann.
25711 if (vctxt
->options
& XML_SCHEMA_VAL_VC_I_CREATE
) {
25712 xmlSchemaNodeInfoPtr ielem
= vctxt
->elemInfos
[vctxt
->depth
];
25713 if (ielem
&& ielem
->node
&& ielem
->node
->doc
)
25714 defAttrOwnerElem
= ielem
->node
;
25717 * Validate values, create default attributes, evaluate IDCs.
25719 for (i
= 0; i
< vctxt
->nbAttrInfos
; i
++) {
25720 iattr
= vctxt
->attrInfos
[i
];
25722 * VAL TODO: Note that we won't try to resolve IDCs to
25723 * "lax" and "skip" validated attributes. Check what to
25726 if ((iattr
->state
!= XML_SCHEMAS_ATTR_ASSESSED
) &&
25727 (iattr
->state
!= XML_SCHEMAS_ATTR_DEFAULT
))
25730 * VAL TODO: What to do if the type definition is missing?
25732 if (iattr
->typeDef
== NULL
) {
25733 iattr
->state
= XML_SCHEMAS_ATTR_ERR_NO_TYPE
;
25737 ACTIVATE_ATTRIBUTE(iattr
);
25741 if (vctxt
->xpathStates
!= NULL
) {
25745 xpathRes
= xmlSchemaXPathEvaluate(vctxt
,
25746 XML_ATTRIBUTE_NODE
);
25747 if (xpathRes
== -1) {
25748 VERROR_INT("xmlSchemaVAttributesComplex",
25749 "calling xmlSchemaXPathEvaluate()");
25750 goto internal_error
;
25754 if (iattr
->state
== XML_SCHEMAS_ATTR_DEFAULT
) {
25756 * Default/fixed attributes.
25757 * We need the value only if we need to resolve IDCs or
25758 * will create default attributes.
25760 if ((xpathRes
) || (defAttrOwnerElem
)) {
25761 if (iattr
->use
->defValue
!= NULL
) {
25762 iattr
->value
= (xmlChar
*) iattr
->use
->defValue
;
25763 iattr
->val
= iattr
->use
->defVal
;
25765 iattr
->value
= (xmlChar
*) iattr
->decl
->defValue
;
25766 iattr
->val
= iattr
->decl
->defVal
;
25769 * IDCs will consume the precomputed default value,
25770 * so we need to clone it.
25772 if (iattr
->val
== NULL
) {
25773 VERROR_INT("xmlSchemaVAttributesComplex",
25774 "default/fixed value on an attribute use was "
25775 "not precomputed");
25776 goto internal_error
;
25778 iattr
->val
= xmlSchemaCopyValue(iattr
->val
);
25779 if (iattr
->val
== NULL
) {
25780 VERROR_INT("xmlSchemaVAttributesComplex",
25781 "calling xmlSchemaCopyValue()");
25782 goto internal_error
;
25786 * PSVI: Add the default attribute to the current element.
25787 * VAL TODO: Should we use the *normalized* value? This currently
25788 * uses the *initial* value.
25791 if (defAttrOwnerElem
) {
25792 xmlChar
*normValue
;
25793 const xmlChar
*value
;
25795 value
= iattr
->value
;
25797 * Normalize the value.
25799 normValue
= xmlSchemaNormalizeValue(iattr
->typeDef
,
25801 if (normValue
!= NULL
)
25802 value
= BAD_CAST normValue
;
25804 if (iattr
->nsName
== NULL
) {
25805 if (xmlNewProp(defAttrOwnerElem
,
25806 iattr
->localName
, value
) == NULL
) {
25807 VERROR_INT("xmlSchemaVAttributesComplex",
25808 "calling xmlNewProp()");
25809 if (normValue
!= NULL
)
25810 xmlFree(normValue
);
25811 goto internal_error
;
25816 ns
= xmlSearchNsByHref(defAttrOwnerElem
->doc
,
25817 defAttrOwnerElem
, iattr
->nsName
);
25819 xmlChar prefix
[12];
25823 * Create a namespace declaration on the validation
25824 * root node if no namespace declaration is in scope.
25827 snprintf((char *) prefix
, 12, "p%d", counter
++);
25828 ns
= xmlSearchNs(defAttrOwnerElem
->doc
,
25829 defAttrOwnerElem
, BAD_CAST prefix
);
25830 if (counter
> 1000) {
25832 "xmlSchemaVAttributesComplex",
25833 "could not compute a ns prefix for a "
25834 "default/fixed attribute");
25835 if (normValue
!= NULL
)
25836 xmlFree(normValue
);
25837 goto internal_error
;
25839 } while (ns
!= NULL
);
25840 ns
= xmlNewNs(vctxt
->validationRoot
,
25841 iattr
->nsName
, BAD_CAST prefix
);
25845 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
25846 * If we have QNames: do we need to ensure there's a
25847 * prefix defined for the QName?
25849 xmlNewNsProp(defAttrOwnerElem
, ns
, iattr
->localName
, value
);
25851 if (normValue
!= NULL
)
25852 xmlFree(normValue
);
25855 * Go directly to IDC evaluation.
25860 * Validate the value.
25862 if (vctxt
->value
!= NULL
) {
25864 * Free last computed value; just for safety reasons.
25866 xmlSchemaFreeValue(vctxt
->value
);
25867 vctxt
->value
= NULL
;
25870 * Note that the attribute *use* can be unavailable, if
25871 * the attribute was a wild attribute.
25873 if ((iattr
->decl
->flags
& XML_SCHEMAS_ATTR_FIXED
) ||
25874 ((iattr
->use
!= NULL
) &&
25875 (iattr
->use
->flags
& XML_SCHEMAS_ATTR_FIXED
)))
25880 * SPEC (cvc-attribute)
25881 * (3) "The item's `normalized value` must be locally `valid`
25882 * with respect to that {type definition} as per
25883 * String Valid ($3.14.4)."
25885 * VAL TODO: Do we already have the
25886 * "normalized attribute value" here?
25888 if (xpathRes
|| fixed
) {
25889 iattr
->flags
|= XML_SCHEMA_NODE_INFO_VALUE_NEEDED
;
25891 * Request a computed value.
25893 res
= xmlSchemaVCheckCVCSimpleType(
25895 iattr
->node
, iattr
->typeDef
, iattr
->value
, &(iattr
->val
),
25898 res
= xmlSchemaVCheckCVCSimpleType(
25900 iattr
->node
, iattr
->typeDef
, iattr
->value
, NULL
,
25906 VERROR_INT("xmlSchemaVAttributesComplex",
25907 "calling xmlSchemaStreamValidateSimpleTypeValue()");
25908 goto internal_error
;
25910 iattr
->state
= XML_SCHEMAS_ATTR_INVALID_VALUE
;
25912 * SPEC PSVI Assessment Outcome (Attribute)
25913 * [validity] = "invalid"
25920 * SPEC Attribute Locally Valid (Use) (cvc-au)
25921 * "For an attribute information item to be `valid`
25922 * with respect to an attribute use its *normalized*
25923 * value must match the *canonical* lexical
25924 * representation of the attribute use's {value
25925 * constraint}value, if it is present and fixed."
25927 * VAL TODO: The requirement for the *canonical* value
25928 * will be removed in XML Schema 1.1.
25931 * SPEC Attribute Locally Valid (cvc-attribute)
25932 * (4) "The item's *actual* value must match the *value* of
25933 * the {value constraint}, if it is present and fixed."
25935 if (iattr
->val
== NULL
) {
25936 /* VAL TODO: A value was not precomputed. */
25940 if ((iattr
->use
!= NULL
) &&
25941 (iattr
->use
->defValue
!= NULL
)) {
25942 if (iattr
->use
->defVal
== NULL
) {
25943 /* VAL TODO: A default value was not precomputed. */
25947 iattr
->vcValue
= iattr
->use
->defValue
;
25949 if (xmlSchemaCompareValuesWhtsp(attr->val,
25950 (xmlSchemaWhitespaceValueType) ws,
25952 (xmlSchemaWhitespaceValueType) ws) != 0) {
25954 if (! xmlSchemaAreValuesEqual(iattr
->val
, iattr
->use
->defVal
))
25955 iattr
->state
= XML_SCHEMAS_ATTR_ERR_FIXED_VALUE
;
25957 if (iattr
->decl
->defVal
== NULL
) {
25958 /* VAL TODO: A default value was not precomputed. */
25962 iattr
->vcValue
= iattr
->decl
->defValue
;
25964 if (xmlSchemaCompareValuesWhtsp(attr->val,
25965 (xmlSchemaWhitespaceValueType) ws,
25967 (xmlSchemaWhitespaceValueType) ws) != 0) {
25969 if (! xmlSchemaAreValuesEqual(iattr
->val
, iattr
->decl
->defVal
))
25970 iattr
->state
= XML_SCHEMAS_ATTR_ERR_FIXED_VALUE
;
25973 * [validity] = "valid"
25981 if (xmlSchemaXPathProcessHistory(vctxt
,
25982 vctxt
->depth
+1) == -1) {
25983 VERROR_INT("xmlSchemaVAttributesComplex",
25984 "calling xmlSchemaXPathEvaluate()");
25985 goto internal_error
;
25987 } else if (vctxt
->xpathStates
!= NULL
)
25988 xmlSchemaXPathPop(vctxt
);
25994 for (i
= 0; i
< vctxt
->nbAttrInfos
; i
++) {
25995 iattr
= vctxt
->attrInfos
[i
];
25996 if ((iattr
->state
== XML_SCHEMAS_ATTR_META
) ||
25997 (iattr
->state
== XML_SCHEMAS_ATTR_ASSESSED
) ||
25998 (iattr
->state
== XML_SCHEMAS_ATTR_WILD_SKIP
) ||
25999 (iattr
->state
== XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL
))
26001 ACTIVATE_ATTRIBUTE(iattr
);
26002 switch (iattr
->state
) {
26003 case XML_SCHEMAS_ATTR_ERR_MISSING
: {
26004 xmlChar
*str
= NULL
;
26006 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
26007 XML_SCHEMAV_CVC_COMPLEX_TYPE_4
, NULL
, NULL
,
26008 "The attribute '%s' is required but missing",
26009 xmlSchemaFormatQName(&str
,
26010 iattr
->decl
->targetNamespace
,
26011 iattr
->decl
->name
),
26016 case XML_SCHEMAS_ATTR_ERR_NO_TYPE
:
26017 VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2
, NULL
,
26018 "The type definition is absent");
26020 case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE
:
26021 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
26022 XML_SCHEMAV_CVC_AU
, NULL
, NULL
,
26023 "The value '%s' does not match the fixed "
26024 "value constraint '%s'",
26025 iattr
->value
, iattr
->vcValue
);
26027 case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL
:
26028 VERROR(XML_SCHEMAV_CVC_WILDCARD
, NULL
,
26029 "No matching global attribute declaration available, but "
26030 "demanded by the strict wildcard");
26032 case XML_SCHEMAS_ATTR_UNKNOWN
:
26033 if (iattr
->metaType
)
26036 * MAYBE VAL TODO: One might report different error messages
26037 * for the following errors.
26039 if (type
->attributeWildcard
== NULL
) {
26040 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt
,
26041 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1
, iattr
, NULL
);
26043 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt
,
26044 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2
, iattr
, NULL
);
26060 xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt
,
26063 xmlSchemaWildcardPtr wild
= (xmlSchemaWildcardPtr
) vctxt
->inode
->decl
;
26065 * The namespace of the element was already identified to be
26066 * matching the wildcard.
26068 if ((skip
== NULL
) || (wild
== NULL
) ||
26069 (wild
->type
!= XML_SCHEMA_TYPE_ANY
)) {
26070 VERROR_INT("xmlSchemaValidateElemWildcard",
26075 if (wild
->processContents
== XML_SCHEMAS_ANY_SKIP
) {
26077 * URGENT VAL TODO: Either we need to position the stream to the
26078 * next sibling, or walk the whole subtree.
26084 xmlSchemaElementPtr decl
= NULL
;
26086 decl
= xmlSchemaGetElem(vctxt
->schema
,
26087 vctxt
->inode
->localName
, vctxt
->inode
->nsName
);
26088 if (decl
!= NULL
) {
26089 vctxt
->inode
->decl
= decl
;
26093 if (wild
->processContents
== XML_SCHEMAS_ANY_STRICT
) {
26094 /* VAL TODO: Change to proper error code. */
26095 VERROR(XML_SCHEMAV_CVC_ELT_1
, NULL
, /* WXS_BASIC_CAST wild */
26096 "No matching global element declaration available, but "
26097 "demanded by the strict wildcard");
26098 return (vctxt
->err
);
26100 if (vctxt
->nbAttrInfos
!= 0) {
26101 xmlSchemaAttrInfoPtr iattr
;
26103 * SPEC Validation Rule: Schema-Validity Assessment (Element)
26104 * (1.2.1.2.1) - (1.2.1.2.3 )
26106 * Use the xsi:type attribute for the type definition.
26108 iattr
= xmlSchemaGetMetaAttrInfo(vctxt
,
26109 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE
);
26110 if (iattr
!= NULL
) {
26111 if (xmlSchemaProcessXSIType(vctxt
, iattr
,
26112 &(vctxt
->inode
->typeDef
), NULL
) == -1) {
26113 VERROR_INT("xmlSchemaValidateElemWildcard",
26114 "calling xmlSchemaProcessXSIType() to "
26115 "process the attribute 'xsi:nil'");
26119 * Don't return an error on purpose.
26125 * SPEC Validation Rule: Schema-Validity Assessment (Element)
26127 * Fallback to "anyType".
26129 vctxt
->inode
->typeDef
=
26130 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE
);
26135 * xmlSchemaCheckCOSValidDefault:
26137 * This will be called if: not nilled, no content and a default/fixed
26138 * value is provided.
26142 xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt
,
26143 const xmlChar
*value
,
26144 xmlSchemaValPtr
*val
)
26147 xmlSchemaNodeInfoPtr inode
= vctxt
->inode
;
26150 * cos-valid-default:
26151 * Schema Component Constraint: Element Default Valid (Immediate)
26152 * For a string to be a valid default with respect to a type
26153 * definition the appropriate case among the following must be true:
26155 if WXS_IS_COMPLEX(inode
->typeDef
) {
26159 * SPEC (2.1) "its {content type} must be a simple type definition
26161 * SPEC (2.2.2) "If the {content type} is mixed, then the {content
26162 * type}'s particle must be `emptiable` as defined by
26163 * Particle Emptiable ($3.9.6)."
26165 if ((! WXS_HAS_SIMPLE_CONTENT(inode
->typeDef
)) &&
26166 ((! WXS_HAS_MIXED_CONTENT(inode
->typeDef
)) ||
26167 (! WXS_EMPTIABLE(inode
->typeDef
)))) {
26168 ret
= XML_SCHEMAP_COS_VALID_DEFAULT_2_1
;
26169 /* NOTE that this covers (2.2.2) as well. */
26171 "For a string to be a valid default, the type definition "
26172 "must be a simple type or a complex type with simple content "
26173 "or mixed content and a particle emptiable");
26178 * 1 If the type definition is a simple type definition, then the string
26179 * must be `valid` with respect to that definition as defined by String
26184 * 2.2.1 If the {content type} is a simple type definition, then the
26185 * string must be `valid` with respect to that simple type definition
26186 * as defined by String Valid ($3.14.4).
26188 if (WXS_IS_SIMPLE(inode
->typeDef
)) {
26190 ret
= xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt
,
26191 NULL
, inode
->typeDef
, value
, val
, 1, 1, 0);
26193 } else if (WXS_HAS_SIMPLE_CONTENT(inode
->typeDef
)) {
26195 ret
= xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt
,
26196 NULL
, inode
->typeDef
->contentTypeDef
, value
, val
, 1, 1, 0);
26199 VERROR_INT("xmlSchemaCheckCOSValidDefault",
26200 "calling xmlSchemaVCheckCVCSimpleType()");
26206 xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED
,
26207 const xmlChar
* name ATTRIBUTE_UNUSED
,
26208 void *transdata
, void *inputdata
)
26210 xmlSchemaElementPtr item
= (xmlSchemaElementPtr
) transdata
;
26211 xmlSchemaNodeInfoPtr inode
= (xmlSchemaNodeInfoPtr
) inputdata
;
26212 inode
->decl
= item
;
26213 #ifdef DEBUG_CONTENT
26215 xmlChar
*str
= NULL
;
26217 if (item
->type
== XML_SCHEMA_TYPE_ELEMENT
) {
26218 xmlGenericError(xmlGenericErrorContext
,
26219 "AUTOMATON callback for '%s' [declaration]\n",
26220 xmlSchemaFormatQName(&str
,
26221 inode
->localName
, inode
->nsName
));
26223 xmlGenericError(xmlGenericErrorContext
,
26224 "AUTOMATON callback for '%s' [wildcard]\n",
26225 xmlSchemaFormatQName(&str
,
26226 inode
->localName
, inode
->nsName
));
26235 xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt
)
26237 vctxt
->inode
= xmlSchemaGetFreshElemInfo(vctxt
);
26238 if (vctxt
->inode
== NULL
) {
26239 VERROR_INT("xmlSchemaValidatorPushElem",
26240 "calling xmlSchemaGetFreshElemInfo()");
26243 vctxt
->nbAttrInfos
= 0;
26248 xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt
,
26249 xmlSchemaNodeInfoPtr inode
,
26250 xmlSchemaTypePtr type
,
26251 const xmlChar
*value
)
26253 if (inode
->flags
& XML_SCHEMA_NODE_INFO_VALUE_NEEDED
)
26254 return (xmlSchemaVCheckCVCSimpleType(
26255 ACTXT_CAST vctxt
, NULL
,
26256 type
, value
, &(inode
->val
), 1, 1, 0));
26258 return (xmlSchemaVCheckCVCSimpleType(
26259 ACTXT_CAST vctxt
, NULL
,
26260 type
, value
, NULL
, 1, 0, 0));
26266 * Process END of element.
26269 xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt
)
26272 xmlSchemaNodeInfoPtr inode
= vctxt
->inode
;
26274 if (vctxt
->nbAttrInfos
!= 0)
26275 xmlSchemaClearAttrInfos(vctxt
);
26276 if (inode
->flags
& XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED
) {
26278 * This element was not expected;
26279 * we will not validate child elements of broken parents.
26280 * Skip validation of all content of the parent.
26282 vctxt
->skipDepth
= vctxt
->depth
-1;
26285 if ((inode
->typeDef
== NULL
) ||
26286 (inode
->flags
& XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE
)) {
26288 * 1. the type definition might be missing if the element was
26290 * 2. it might be abstract.
26295 * Check the content model.
26297 if ((inode
->typeDef
->contentType
== XML_SCHEMA_CONTENT_MIXED
) ||
26298 (inode
->typeDef
->contentType
== XML_SCHEMA_CONTENT_ELEMENTS
)) {
26301 * Workaround for "anyType".
26303 if (inode
->typeDef
->builtInType
== XML_SCHEMAS_ANYTYPE
)
26304 goto character_content
;
26306 if ((inode
->flags
& XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT
) == 0) {
26307 xmlChar
*values
[10];
26308 int terminal
, nbval
= 10, nbneg
;
26310 if (inode
->regexCtxt
== NULL
) {
26312 * Create the regex context.
26315 xmlRegNewExecCtxt(inode
->typeDef
->contModel
,
26316 xmlSchemaVContentModelCallback
, vctxt
);
26317 if (inode
->regexCtxt
== NULL
) {
26318 VERROR_INT("xmlSchemaValidatorPopElem",
26319 "failed to create a regex context");
26320 goto internal_error
;
26322 #ifdef DEBUG_AUTOMATA
26323 xmlGenericError(xmlGenericErrorContext
,
26324 "AUTOMATON create on '%s'\n", inode
->localName
);
26329 * Do not check further content if the node has been nilled
26331 if (INODE_NILLED(inode
)) {
26333 #ifdef DEBUG_AUTOMATA
26334 xmlGenericError(xmlGenericErrorContext
,
26335 "AUTOMATON succeeded on nilled '%s'\n",
26342 * Get hold of the still expected content, since a further
26343 * call to xmlRegExecPushString() will lose this information.
26345 xmlRegExecNextValues(inode
->regexCtxt
,
26346 &nbval
, &nbneg
, &values
[0], &terminal
);
26347 ret
= xmlRegExecPushString(inode
->regexCtxt
, NULL
, NULL
);
26348 if ((ret
<0) || ((ret
==0) && (!INODE_NILLED(inode
)))) {
26350 * Still missing something.
26354 XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT
;
26355 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt
,
26356 XML_SCHEMAV_ELEMENT_CONTENT
, NULL
, NULL
,
26357 "Missing child element(s)",
26358 nbval
, nbneg
, values
);
26359 #ifdef DEBUG_AUTOMATA
26360 xmlGenericError(xmlGenericErrorContext
,
26361 "AUTOMATON missing ERROR on '%s'\n",
26366 * Content model is satisfied.
26369 #ifdef DEBUG_AUTOMATA
26370 xmlGenericError(xmlGenericErrorContext
,
26371 "AUTOMATON succeeded on '%s'\n",
26381 if (inode
->typeDef
->contentType
== XML_SCHEMA_CONTENT_ELEMENTS
)
26386 if (vctxt
->value
!= NULL
) {
26387 xmlSchemaFreeValue(vctxt
->value
);
26388 vctxt
->value
= NULL
;
26391 * Check character content.
26393 if (inode
->decl
== NULL
) {
26395 * Speedup if no declaration exists.
26397 if (WXS_IS_SIMPLE(inode
->typeDef
)) {
26398 ret
= xmlSchemaVCheckINodeDataType(vctxt
,
26399 inode
, inode
->typeDef
, inode
->value
);
26400 } else if (WXS_HAS_SIMPLE_CONTENT(inode
->typeDef
)) {
26401 ret
= xmlSchemaVCheckINodeDataType(vctxt
,
26402 inode
, inode
->typeDef
->contentTypeDef
,
26406 VERROR_INT("xmlSchemaValidatorPopElem",
26407 "calling xmlSchemaVCheckCVCSimpleType()");
26408 goto internal_error
;
26413 * cvc-elt (3.3.4) : 5
26414 * The appropriate case among the following must be true:
26417 * cvc-elt (3.3.4) : 5.1
26418 * If the declaration has a {value constraint},
26419 * the item has neither element nor character [children] and
26420 * clause 3.2 has not applied, then all of the following must be true:
26422 if ((inode
->decl
->value
!= NULL
) &&
26423 (inode
->flags
& XML_SCHEMA_ELEM_INFO_EMPTY
) &&
26424 (! INODE_NILLED(inode
))) {
26426 * cvc-elt (3.3.4) : 5.1.1
26427 * If the `actual type definition` is a `local type definition`
26428 * then the canonical lexical representation of the {value constraint}
26429 * value must be a valid default for the `actual type definition` as
26430 * defined in Element Default Valid (Immediate) ($3.3.6).
26433 * NOTE: 'local' above means types acquired by xsi:type.
26434 * NOTE: Although the *canonical* value is stated, it is not
26435 * relevant if canonical or not. Additionally XML Schema 1.1
26436 * will removed this requirement as well.
26438 if (inode
->flags
& XML_SCHEMA_ELEM_INFO_LOCAL_TYPE
) {
26440 ret
= xmlSchemaCheckCOSValidDefault(vctxt
,
26441 inode
->decl
->value
, &(inode
->val
));
26444 VERROR_INT("xmlSchemaValidatorPopElem",
26445 "calling xmlSchemaCheckCOSValidDefault()");
26446 goto internal_error
;
26451 * Stop here, to avoid redundant validation of the value
26457 * cvc-elt (3.3.4) : 5.1.2
26458 * The element information item with the canonical lexical
26459 * representation of the {value constraint} value used as its
26460 * `normalized value` must be `valid` with respect to the
26461 * `actual type definition` as defined by Element Locally Valid (Type)
26464 if (WXS_IS_SIMPLE(inode
->typeDef
)) {
26465 ret
= xmlSchemaVCheckINodeDataType(vctxt
,
26466 inode
, inode
->typeDef
, inode
->decl
->value
);
26467 } else if (WXS_HAS_SIMPLE_CONTENT(inode
->typeDef
)) {
26468 ret
= xmlSchemaVCheckINodeDataType(vctxt
,
26469 inode
, inode
->typeDef
->contentTypeDef
,
26470 inode
->decl
->value
);
26474 VERROR_INT("xmlSchemaValidatorPopElem",
26475 "calling xmlSchemaVCheckCVCSimpleType()");
26476 goto internal_error
;
26483 * PSVI: Create a text node on the instance element.
26485 if ((vctxt
->options
& XML_SCHEMA_VAL_VC_I_CREATE
) &&
26486 (inode
->node
!= NULL
)) {
26487 xmlNodePtr textChild
;
26488 xmlChar
*normValue
;
26490 * VAL TODO: Normalize the value.
26492 normValue
= xmlSchemaNormalizeValue(inode
->typeDef
,
26493 inode
->decl
->value
);
26494 if (normValue
!= NULL
) {
26495 textChild
= xmlNewDocText(inode
->node
->doc
,
26496 BAD_CAST normValue
);
26497 xmlFree(normValue
);
26499 textChild
= xmlNewDocText(inode
->node
->doc
,
26500 inode
->decl
->value
);
26501 if (textChild
== NULL
) {
26502 VERROR_INT("xmlSchemaValidatorPopElem",
26503 "calling xmlNewDocText()");
26504 goto internal_error
;
26506 xmlAddChild(inode
->node
, textChild
);
26509 } else if (! INODE_NILLED(inode
)) {
26511 * 5.2.1 The element information item must be `valid` with respect
26512 * to the `actual type definition` as defined by Element Locally
26513 * Valid (Type) ($3.3.4).
26515 if (WXS_IS_SIMPLE(inode
->typeDef
)) {
26517 * SPEC (cvc-type) (3.1)
26518 * "If the type definition is a simple type definition, ..."
26519 * (3.1.3) "If clause 3.2 of Element Locally Valid
26520 * (Element) ($3.3.4) did not apply, then the `normalized value`
26521 * must be `valid` with respect to the type definition as defined
26522 * by String Valid ($3.14.4).
26524 ret
= xmlSchemaVCheckINodeDataType(vctxt
,
26525 inode
, inode
->typeDef
, inode
->value
);
26526 } else if (WXS_HAS_SIMPLE_CONTENT(inode
->typeDef
)) {
26528 * SPEC (cvc-type) (3.2) "If the type definition is a complex type
26529 * definition, then the element information item must be
26530 * `valid` with respect to the type definition as per
26531 * Element Locally Valid (Complex Type) ($3.4.4);"
26533 * SPEC (cvc-complex-type) (2.2)
26534 * "If the {content type} is a simple type definition, ...
26535 * the `normalized value` of the element information item is
26536 * `valid` with respect to that simple type definition as
26537 * defined by String Valid ($3.14.4)."
26539 ret
= xmlSchemaVCheckINodeDataType(vctxt
,
26540 inode
, inode
->typeDef
->contentTypeDef
, inode
->value
);
26544 VERROR_INT("xmlSchemaValidatorPopElem",
26545 "calling xmlSchemaVCheckCVCSimpleType()");
26546 goto internal_error
;
26551 * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
26552 * not applied, all of the following must be true:
26554 if ((inode
->decl
->value
!= NULL
) &&
26555 (inode
->decl
->flags
& XML_SCHEMAS_ELEM_FIXED
)) {
26558 * TODO: We will need a computed value, when comparison is
26559 * done on computed values.
26562 * 5.2.2.1 The element information item must have no element
26563 * information item [children].
26566 XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT
) {
26567 ret
= XML_SCHEMAV_CVC_ELT_5_2_2_1
;
26569 "The content must not contain element nodes since "
26570 "there is a fixed value constraint");
26574 * 5.2.2.2 The appropriate case among the following must
26577 if (WXS_HAS_MIXED_CONTENT(inode
->typeDef
)) {
26579 * 5.2.2.2.1 If the {content type} of the `actual type
26580 * definition` is mixed, then the *initial value* of the
26581 * item must match the canonical lexical representation
26582 * of the {value constraint} value.
26584 * ... the *initial value* of an element information
26585 * item is the string composed of, in order, the
26586 * [character code] of each character information item in
26587 * the [children] of that element information item.
26589 if (! xmlStrEqual(inode
->value
, inode
->decl
->value
)){
26591 * VAL TODO: Report invalid & expected values as well.
26592 * VAL TODO: Implement the canonical stuff.
26594 ret
= XML_SCHEMAV_CVC_ELT_5_2_2_2_1
;
26595 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
26597 "The initial value '%s' does not match the fixed "
26598 "value constraint '%s'",
26599 inode
->value
, inode
->decl
->value
);
26602 } else if (WXS_HAS_SIMPLE_CONTENT(inode
->typeDef
)) {
26604 * 5.2.2.2.2 If the {content type} of the `actual type
26605 * definition` is a simple type definition, then the
26606 * *actual value* of the item must match the canonical
26607 * lexical representation of the {value constraint} value.
26610 * VAL TODO: *actual value* is the normalized value, impl.
26612 * VAL TODO: Report invalid & expected values as well.
26613 * VAL TODO: Implement a comparison with the computed values.
26615 if (! xmlStrEqual(inode
->value
,
26616 inode
->decl
->value
)) {
26617 ret
= XML_SCHEMAV_CVC_ELT_5_2_2_2_2
;
26618 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
26620 "The actual value '%s' does not match the fixed "
26621 "value constraint '%s'",
26623 inode
->decl
->value
);
26632 if (vctxt
->depth
< 0) {
26633 /* TODO: raise error? */
26636 if (vctxt
->depth
== vctxt
->skipDepth
)
26637 vctxt
->skipDepth
= -1;
26639 * Evaluate the history of XPath state objects.
26641 if (inode
->appliedXPath
&&
26642 (xmlSchemaXPathProcessHistory(vctxt
, vctxt
->depth
) == -1))
26643 goto internal_error
;
26646 * SPEC (6) "The element information item must be `valid` with
26647 * respect to each of the {identity-constraint definitions} as per
26648 * Identity-constraint Satisfied ($3.11.4)."
26651 * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
26652 * need to be built in any case.
26653 * We will currently build IDC node-tables and bubble them only if
26654 * keyrefs do exist.
26658 * Add the current IDC target-nodes to the IDC node-tables.
26660 if ((inode
->idcMatchers
!= NULL
) &&
26661 (vctxt
->hasKeyrefs
|| vctxt
->createIDCNodeTables
))
26663 if (xmlSchemaIDCFillNodeTables(vctxt
, inode
) == -1)
26664 goto internal_error
;
26667 * Validate IDC keyrefs.
26669 if (vctxt
->inode
->hasKeyrefs
)
26670 if (xmlSchemaCheckCVCIDCKeyRef(vctxt
) == -1)
26671 goto internal_error
;
26673 * Merge/free the IDC table.
26675 if (inode
->idcTable
!= NULL
) {
26676 #ifdef DEBUG_IDC_NODE_TABLE
26677 xmlSchemaDebugDumpIDCTable(stdout
,
26682 if ((vctxt
->depth
> 0) &&
26683 (vctxt
->hasKeyrefs
|| vctxt
->createIDCNodeTables
))
26686 * Merge the IDC node table with the table of the parent node.
26688 if (xmlSchemaBubbleIDCNodeTables(vctxt
) == -1)
26689 goto internal_error
;
26693 * Clear the current ielem.
26694 * VAL TODO: Don't free the PSVI IDC tables if they are
26695 * requested for the PSVI.
26697 xmlSchemaClearElemInfo(vctxt
, inode
);
26699 * Skip further processing if we are on the validation root.
26701 if (vctxt
->depth
== 0) {
26703 vctxt
->inode
= NULL
;
26707 * Reset the keyrefDepth if needed.
26709 if (vctxt
->aidcs
!= NULL
) {
26710 xmlSchemaIDCAugPtr aidc
= vctxt
->aidcs
;
26712 if (aidc
->keyrefDepth
== vctxt
->depth
) {
26714 * A 'keyrefDepth' of a key/unique IDC matches the current
26715 * depth, this means that we are leaving the scope of the
26716 * top-most keyref IDC which refers to this IDC.
26718 aidc
->keyrefDepth
= -1;
26721 } while (aidc
!= NULL
);
26724 vctxt
->inode
= vctxt
->elemInfos
[vctxt
->depth
];
26726 * VAL TODO: 7 If the element information item is the `validation root`, it must be
26727 * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
26737 * 3.4.4 Complex Type Definition Validation Rules
26738 * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
26741 xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt
)
26743 xmlSchemaNodeInfoPtr pielem
;
26744 xmlSchemaTypePtr ptype
;
26747 if (vctxt
->depth
<= 0) {
26748 VERROR_INT("xmlSchemaValidateChildElem",
26749 "not intended for the validation root");
26752 pielem
= vctxt
->elemInfos
[vctxt
->depth
-1];
26753 if (pielem
->flags
& XML_SCHEMA_ELEM_INFO_EMPTY
)
26754 pielem
->flags
^= XML_SCHEMA_ELEM_INFO_EMPTY
;
26756 * Handle 'nilled' elements.
26758 if (INODE_NILLED(pielem
)) {
26760 * SPEC (cvc-elt) (3.3.4) : (3.2.1)
26762 ACTIVATE_PARENT_ELEM
;
26763 ret
= XML_SCHEMAV_CVC_ELT_3_2_1
;
26765 "Neither character nor element content is allowed, "
26766 "because the element was 'nilled'");
26768 goto unexpected_elem
;
26771 ptype
= pielem
->typeDef
;
26773 if (ptype
->builtInType
== XML_SCHEMAS_ANYTYPE
) {
26775 * Workaround for "anyType": we have currently no content model
26776 * assigned for "anyType", so handle it explicitly.
26777 * "anyType" has an unbounded, lax "any" wildcard.
26779 vctxt
->inode
->decl
= xmlSchemaGetElem(vctxt
->schema
,
26780 vctxt
->inode
->localName
,
26781 vctxt
->inode
->nsName
);
26783 if (vctxt
->inode
->decl
== NULL
) {
26784 xmlSchemaAttrInfoPtr iattr
;
26786 * Process "xsi:type".
26787 * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
26789 iattr
= xmlSchemaGetMetaAttrInfo(vctxt
,
26790 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE
);
26791 if (iattr
!= NULL
) {
26792 ret
= xmlSchemaProcessXSIType(vctxt
, iattr
,
26793 &(vctxt
->inode
->typeDef
), NULL
);
26796 VERROR_INT("xmlSchemaValidateChildElem",
26797 "calling xmlSchemaProcessXSIType() to "
26798 "process the attribute 'xsi:nil'");
26805 * Fallback to "anyType".
26807 * SPEC (cvc-assess-elt)
26808 * "If the item cannot be `strictly assessed`, [...]
26809 * an element information item's schema validity may be laxly
26810 * assessed if its `context-determined declaration` is not
26811 * skip by `validating` with respect to the `ur-type
26812 * definition` as per Element Locally Valid (Type) ($3.3.4)."
26814 vctxt
->inode
->typeDef
=
26815 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE
);
26821 switch (ptype
->contentType
) {
26822 case XML_SCHEMA_CONTENT_EMPTY
:
26824 * SPEC (2.1) "If the {content type} is empty, then the
26825 * element information item has no character or element
26826 * information item [children]."
26828 ACTIVATE_PARENT_ELEM
26829 ret
= XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1
;
26831 "Element content is not allowed, "
26832 "because the content type is empty");
26834 goto unexpected_elem
;
26837 case XML_SCHEMA_CONTENT_MIXED
:
26838 case XML_SCHEMA_CONTENT_ELEMENTS
: {
26839 xmlRegExecCtxtPtr regexCtxt
;
26840 xmlChar
*values
[10];
26841 int terminal
, nbval
= 10, nbneg
;
26843 /* VAL TODO: Optimized "anyType" validation.*/
26845 if (ptype
->contModel
== NULL
) {
26846 VERROR_INT("xmlSchemaValidateChildElem",
26847 "type has elem content but no content model");
26851 * Safety belt for evaluation if the cont. model was already
26852 * examined to be invalid.
26854 if (pielem
->flags
& XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT
) {
26855 VERROR_INT("xmlSchemaValidateChildElem",
26856 "validating elem, but elem content is already invalid");
26860 regexCtxt
= pielem
->regexCtxt
;
26861 if (regexCtxt
== NULL
) {
26863 * Create the regex context.
26865 regexCtxt
= xmlRegNewExecCtxt(ptype
->contModel
,
26866 xmlSchemaVContentModelCallback
, vctxt
);
26867 if (regexCtxt
== NULL
) {
26868 VERROR_INT("xmlSchemaValidateChildElem",
26869 "failed to create a regex context");
26872 pielem
->regexCtxt
= regexCtxt
;
26873 #ifdef DEBUG_AUTOMATA
26874 xmlGenericError(xmlGenericErrorContext
, "AUTOMATA create on '%s'\n",
26875 pielem
->localName
);
26880 * SPEC (2.4) "If the {content type} is element-only or mixed,
26881 * then the sequence of the element information item's
26882 * element information item [children], if any, taken in
26883 * order, is `valid` with respect to the {content type}'s
26884 * particle, as defined in Element Sequence Locally Valid
26885 * (Particle) ($3.9.4)."
26887 ret
= xmlRegExecPushString2(regexCtxt
,
26888 vctxt
->inode
->localName
,
26889 vctxt
->inode
->nsName
,
26891 #ifdef DEBUG_AUTOMATA
26893 xmlGenericError(xmlGenericErrorContext
,
26894 "AUTOMATON push ERROR for '%s' on '%s'\n",
26895 vctxt
->inode
->localName
, pielem
->localName
);
26897 xmlGenericError(xmlGenericErrorContext
,
26898 "AUTOMATON push OK for '%s' on '%s'\n",
26899 vctxt
->inode
->localName
, pielem
->localName
);
26901 if (vctxt
->err
== XML_SCHEMAV_INTERNAL
) {
26902 VERROR_INT("xmlSchemaValidateChildElem",
26903 "calling xmlRegExecPushString2()");
26907 xmlRegExecErrInfo(regexCtxt
, NULL
, &nbval
, &nbneg
,
26908 &values
[0], &terminal
);
26909 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt
,
26910 XML_SCHEMAV_ELEMENT_CONTENT
, NULL
,NULL
,
26911 "This element is not expected",
26912 nbval
, nbneg
, values
);
26914 goto unexpected_elem
;
26919 case XML_SCHEMA_CONTENT_SIMPLE
:
26920 case XML_SCHEMA_CONTENT_BASIC
:
26921 ACTIVATE_PARENT_ELEM
26922 if (WXS_IS_COMPLEX(ptype
)) {
26924 * SPEC (cvc-complex-type) (2.2)
26925 * "If the {content type} is a simple type definition, then
26926 * the element information item has no element information
26927 * item [children], ..."
26929 ret
= XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2
;
26930 VERROR(ret
, NULL
, "Element content is not allowed, "
26931 "because the content type is a simple type definition");
26934 * SPEC (cvc-type) (3.1.2) "The element information item must
26935 * have no element information item [children]."
26937 ret
= XML_SCHEMAV_CVC_TYPE_3_1_2
;
26938 VERROR(ret
, NULL
, "Element content is not allowed, "
26939 "because the type definition is simple");
26943 goto unexpected_elem
;
26952 * Pop this element and set the skipDepth to skip
26953 * all further content of the parent element.
26955 vctxt
->skipDepth
= vctxt
->depth
;
26956 vctxt
->inode
->flags
|= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED
;
26957 pielem
->flags
|= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT
;
26961 #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
26962 #define XML_SCHEMA_PUSH_TEXT_CREATED 2
26963 #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
26966 xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt
,
26967 int nodeType
, const xmlChar
*value
, int len
,
26968 int mode
, int *consumed
)
26971 * Unfortunately we have to duplicate the text sometimes.
26972 * OPTIMIZE: Maybe we could skip it, if:
26973 * 1. content type is simple
26974 * 2. whitespace is "collapse"
26975 * 3. it consists of whitespace only
26977 * Process character content.
26979 if (consumed
!= NULL
)
26981 if (INODE_NILLED(vctxt
->inode
)) {
26983 * SPEC cvc-elt (3.3.4 - 3.2.1)
26984 * "The element information item must have no character or
26985 * element information item [children]."
26987 VERROR(XML_SCHEMAV_CVC_ELT_3_2_1
, NULL
,
26988 "Neither character nor element content is allowed "
26989 "because the element is 'nilled'");
26990 return (vctxt
->err
);
26993 * SPEC (2.1) "If the {content type} is empty, then the
26994 * element information item has no character or element
26995 * information item [children]."
26997 if (vctxt
->inode
->typeDef
->contentType
==
26998 XML_SCHEMA_CONTENT_EMPTY
) {
26999 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1
, NULL
,
27000 "Character content is not allowed, "
27001 "because the content type is empty");
27002 return (vctxt
->err
);
27005 if (vctxt
->inode
->typeDef
->contentType
==
27006 XML_SCHEMA_CONTENT_ELEMENTS
) {
27007 if ((nodeType
!= XML_TEXT_NODE
) ||
27008 (! xmlSchemaIsBlank((xmlChar
*) value
, len
))) {
27010 * SPEC cvc-complex-type (2.3)
27011 * "If the {content type} is element-only, then the
27012 * element information item has no character information
27013 * item [children] other than those whose [character
27014 * code] is defined as a white space in [XML 1.0 (Second
27017 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3
, NULL
,
27018 "Character content other than whitespace is not allowed "
27019 "because the content type is 'element-only'");
27020 return (vctxt
->err
);
27025 if ((value
== NULL
) || (value
[0] == 0))
27029 * NOTE that even if the content type is *mixed*, we need the
27030 * *initial value* for default/fixed value constraints.
27032 if ((vctxt
->inode
->typeDef
->contentType
== XML_SCHEMA_CONTENT_MIXED
) &&
27033 ((vctxt
->inode
->decl
== NULL
) ||
27034 (vctxt
->inode
->decl
->value
== NULL
)))
27037 if (vctxt
->inode
->value
== NULL
) {
27042 case XML_SCHEMA_PUSH_TEXT_PERSIST
:
27044 * When working on a tree.
27046 vctxt
->inode
->value
= value
;
27048 case XML_SCHEMA_PUSH_TEXT_CREATED
:
27050 * When working with the reader.
27051 * The value will be freed by the element info.
27053 vctxt
->inode
->value
= value
;
27054 if (consumed
!= NULL
)
27056 vctxt
->inode
->flags
|=
27057 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES
;
27059 case XML_SCHEMA_PUSH_TEXT_VOLATILE
:
27061 * When working with SAX.
27062 * The value will be freed by the element info.
27065 vctxt
->inode
->value
= BAD_CAST
xmlStrndup(value
, len
);
27067 vctxt
->inode
->value
= BAD_CAST
xmlStrdup(value
);
27068 vctxt
->inode
->flags
|=
27069 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES
;
27076 len
= xmlStrlen(value
);
27078 * Concat the value.
27080 if (vctxt
->inode
->flags
& XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES
) {
27081 vctxt
->inode
->value
= BAD_CAST
xmlStrncat(
27082 (xmlChar
*) vctxt
->inode
->value
, value
, len
);
27084 vctxt
->inode
->value
=
27085 BAD_CAST
xmlStrncatNew(vctxt
->inode
->value
, value
, len
);
27086 vctxt
->inode
->flags
|= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES
;
27094 xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt
)
27098 if ((vctxt
->skipDepth
!= -1) &&
27099 (vctxt
->depth
>= vctxt
->skipDepth
)) {
27100 VERROR_INT("xmlSchemaValidateElem",
27102 goto internal_error
;
27104 if (vctxt
->xsiAssemble
) {
27106 * We will stop validation if there was an error during
27107 * dynamic schema construction.
27108 * Note that we simply set @skipDepth to 0, this could
27109 * mean that a streaming document via SAX would be
27110 * still read to the end but it won't be validated any more.
27111 * TODO: If we are sure how to stop the validation at once
27112 * for all input scenarios, then this should be changed to
27113 * instantly stop the validation.
27115 ret
= xmlSchemaAssembleByXSI(vctxt
);
27118 goto internal_error
;
27119 vctxt
->skipDepth
= 0;
27123 * Augment the IDC definitions for the main schema and all imported ones
27124 * NOTE: main schema is the first in the imported list
27126 xmlHashScan(vctxt
->schema
->schemasImports
, xmlSchemaAugmentImportedIDC
,
27129 if (vctxt
->depth
> 0) {
27131 * Validate this element against the content model
27134 ret
= xmlSchemaValidateChildElem(vctxt
);
27137 VERROR_INT("xmlSchemaValidateElem",
27138 "calling xmlSchemaStreamValidateChildElement()");
27139 goto internal_error
;
27143 if (vctxt
->depth
== vctxt
->skipDepth
)
27145 if ((vctxt
->inode
->decl
== NULL
) &&
27146 (vctxt
->inode
->typeDef
== NULL
)) {
27147 VERROR_INT("xmlSchemaValidateElem",
27148 "the child element was valid but neither the "
27149 "declaration nor the type was set");
27150 goto internal_error
;
27154 * Get the declaration of the validation root.
27156 vctxt
->inode
->decl
= xmlSchemaGetElem(vctxt
->schema
,
27157 vctxt
->inode
->localName
,
27158 vctxt
->inode
->nsName
);
27159 if (vctxt
->inode
->decl
== NULL
) {
27160 ret
= XML_SCHEMAV_CVC_ELT_1
;
27162 "No matching global declaration available "
27163 "for the validation root");
27168 if (vctxt
->inode
->decl
== NULL
)
27169 goto type_validation
;
27171 if (vctxt
->inode
->decl
->type
== XML_SCHEMA_TYPE_ANY
) {
27176 ret
= xmlSchemaValidateElemWildcard(vctxt
, &skip
);
27179 VERROR_INT("xmlSchemaValidateElem",
27180 "calling xmlSchemaValidateElemWildcard()");
27181 goto internal_error
;
27186 vctxt
->skipDepth
= vctxt
->depth
;
27190 * The declaration might be set by the wildcard validation,
27191 * when the processContents is "lax" or "strict".
27193 if (vctxt
->inode
->decl
->type
!= XML_SCHEMA_TYPE_ELEMENT
) {
27195 * Clear the "decl" field to not confuse further processing.
27197 vctxt
->inode
->decl
= NULL
;
27198 goto type_validation
;
27202 * Validate against the declaration.
27204 ret
= xmlSchemaValidateElemDecl(vctxt
);
27207 VERROR_INT("xmlSchemaValidateElem",
27208 "calling xmlSchemaValidateElemDecl()");
27209 goto internal_error
;
27214 * Validate against the type definition.
27218 if (vctxt
->inode
->typeDef
== NULL
) {
27219 vctxt
->inode
->flags
|= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE
;
27220 ret
= XML_SCHEMAV_CVC_TYPE_1
;
27222 "The type definition is absent");
27225 if (vctxt
->inode
->typeDef
->flags
& XML_SCHEMAS_TYPE_ABSTRACT
) {
27226 vctxt
->inode
->flags
|= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE
;
27227 ret
= XML_SCHEMAV_CVC_TYPE_2
;
27229 "The type definition is abstract");
27233 * Evaluate IDCs. Do it here, since new IDC matchers are registered
27234 * during validation against the declaration. This must be done
27235 * _before_ attribute validation.
27237 if (vctxt
->xpathStates
!= NULL
) {
27238 ret
= xmlSchemaXPathEvaluate(vctxt
, XML_ELEMENT_NODE
);
27239 vctxt
->inode
->appliedXPath
= 1;
27241 VERROR_INT("xmlSchemaValidateElem",
27242 "calling xmlSchemaXPathEvaluate()");
27243 goto internal_error
;
27247 * Validate attributes.
27249 if (WXS_IS_COMPLEX(vctxt
->inode
->typeDef
)) {
27250 if ((vctxt
->nbAttrInfos
!= 0) ||
27251 (vctxt
->inode
->typeDef
->attrUses
!= NULL
)) {
27253 ret
= xmlSchemaVAttributesComplex(vctxt
);
27255 } else if (vctxt
->nbAttrInfos
!= 0) {
27257 ret
= xmlSchemaVAttributesSimple(vctxt
);
27260 * Clear registered attributes.
27262 if (vctxt
->nbAttrInfos
!= 0)
27263 xmlSchemaClearAttrInfos(vctxt
);
27265 VERROR_INT("xmlSchemaValidateElem",
27266 "calling attributes validation");
27267 goto internal_error
;
27270 * Don't return an error if attributes are invalid on purpose.
27276 vctxt
->skipDepth
= vctxt
->depth
;
27282 #ifdef XML_SCHEMA_READER_ENABLED
27284 xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt
)
27286 const int WHTSP
= 13, SIGN_WHTSP
= 14, END_ELEM
= 15;
27287 int depth
, nodeType
, ret
= 0, consumed
;
27288 xmlSchemaNodeInfoPtr ielem
;
27291 ret
= xmlTextReaderRead(vctxt
->reader
);
27293 * Move to the document element.
27296 nodeType
= xmlTextReaderNodeType(vctxt
->reader
);
27297 if (nodeType
== XML_ELEMENT_NODE
)
27299 ret
= xmlTextReaderRead(vctxt
->reader
);
27306 depth
= xmlTextReaderDepth(vctxt
->reader
);
27307 nodeType
= xmlTextReaderNodeType(vctxt
->reader
);
27309 if (nodeType
== XML_ELEMENT_NODE
) {
27312 if (xmlSchemaValidatorPushElem(vctxt
) == -1) {
27313 VERROR_INT("xmlSchemaVReaderWalk",
27314 "calling xmlSchemaValidatorPushElem()");
27315 goto internal_error
;
27317 ielem
= vctxt
->inode
;
27318 ielem
->localName
= xmlTextReaderLocalName(vctxt
->reader
);
27319 ielem
->nsName
= xmlTextReaderNamespaceUri(vctxt
->reader
);
27320 ielem
->flags
|= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES
;
27322 * Is the element empty?
27324 ret
= xmlTextReaderIsEmptyElement(vctxt
->reader
);
27326 VERROR_INT("xmlSchemaVReaderWalk",
27327 "calling xmlTextReaderIsEmptyElement()");
27328 goto internal_error
;
27331 ielem
->flags
|= XML_SCHEMA_ELEM_INFO_EMPTY
;
27334 * Register attributes.
27336 vctxt
->nbAttrInfos
= 0;
27337 ret
= xmlTextReaderMoveToFirstAttribute(vctxt
->reader
);
27339 VERROR_INT("xmlSchemaVReaderWalk",
27340 "calling xmlTextReaderMoveToFirstAttribute()");
27341 goto internal_error
;
27346 * VAL TODO: How do we know that the reader works on a
27347 * node tree, to be able to pass a node here?
27349 if (xmlSchemaValidatorPushAttribute(vctxt
, NULL
,
27350 (const xmlChar
*) xmlTextReaderLocalName(vctxt
->reader
),
27351 xmlTextReaderNamespaceUri(vctxt
->reader
), 1,
27352 xmlTextReaderValue(vctxt
->reader
), 1) == -1) {
27354 VERROR_INT("xmlSchemaVReaderWalk",
27355 "calling xmlSchemaValidatorPushAttribute()");
27356 goto internal_error
;
27358 ret
= xmlTextReaderMoveToNextAttribute(vctxt
->reader
);
27360 VERROR_INT("xmlSchemaVReaderWalk",
27361 "calling xmlTextReaderMoveToFirstAttribute()");
27362 goto internal_error
;
27364 } while (ret
== 1);
27366 * Back to element position.
27368 ret
= xmlTextReaderMoveToElement(vctxt
->reader
);
27370 VERROR_INT("xmlSchemaVReaderWalk",
27371 "calling xmlTextReaderMoveToElement()");
27372 goto internal_error
;
27376 * Validate the element.
27378 ret
= xmlSchemaValidateElem(vctxt
);
27381 VERROR_INT("xmlSchemaVReaderWalk",
27382 "calling xmlSchemaValidateElem()");
27383 goto internal_error
;
27387 if (vctxt
->depth
== vctxt
->skipDepth
) {
27390 * Skip all content.
27392 if ((ielem
->flags
& XML_SCHEMA_ELEM_INFO_EMPTY
) == 0) {
27393 ret
= xmlTextReaderRead(vctxt
->reader
);
27394 curDepth
= xmlTextReaderDepth(vctxt
->reader
);
27395 while ((ret
== 1) && (curDepth
!= depth
)) {
27396 ret
= xmlTextReaderRead(vctxt
->reader
);
27397 curDepth
= xmlTextReaderDepth(vctxt
->reader
);
27401 * VAL TODO: A reader error occurred; what to do here?
27410 * READER VAL TODO: Is an END_ELEM really never called
27411 * if the elem is empty?
27413 if (ielem
->flags
& XML_SCHEMA_ELEM_INFO_EMPTY
)
27415 } else if (nodeType
== END_ELEM
) {
27417 * Process END of element.
27420 ret
= xmlSchemaValidatorPopElem(vctxt
);
27423 VERROR_INT("xmlSchemaVReaderWalk",
27424 "calling xmlSchemaValidatorPopElem()");
27425 goto internal_error
;
27429 if (vctxt
->depth
>= 0)
27430 ielem
= vctxt
->inode
;
27433 } else if ((nodeType
== XML_TEXT_NODE
) ||
27434 (nodeType
== XML_CDATA_SECTION_NODE
) ||
27435 (nodeType
== WHTSP
) ||
27436 (nodeType
== SIGN_WHTSP
)) {
27438 * Process character content.
27442 if ((nodeType
== WHTSP
) || (nodeType
== SIGN_WHTSP
))
27443 nodeType
= XML_TEXT_NODE
;
27445 value
= xmlTextReaderValue(vctxt
->reader
);
27446 ret
= xmlSchemaVPushText(vctxt
, nodeType
, BAD_CAST value
,
27447 -1, XML_SCHEMA_PUSH_TEXT_CREATED
, &consumed
);
27451 VERROR_INT("xmlSchemaVReaderWalk",
27452 "calling xmlSchemaVPushText()");
27453 goto internal_error
;
27455 } else if ((nodeType
== XML_ENTITY_NODE
) ||
27456 (nodeType
== XML_ENTITY_REF_NODE
)) {
27458 * VAL TODO: What to do with entities?
27465 ret
= xmlTextReaderRead(vctxt
->reader
);
27466 } while (ret
== 1);
27475 /************************************************************************
27477 * SAX validation handlers *
27479 ************************************************************************/
27482 * Process text content.
27485 xmlSchemaSAXHandleText(void *ctx
,
27486 const xmlChar
* ch
,
27489 xmlSchemaValidCtxtPtr vctxt
= (xmlSchemaValidCtxtPtr
) ctx
;
27491 if (vctxt
->depth
< 0)
27493 if ((vctxt
->skipDepth
!= -1) && (vctxt
->depth
>= vctxt
->skipDepth
))
27495 if (vctxt
->inode
->flags
& XML_SCHEMA_ELEM_INFO_EMPTY
)
27496 vctxt
->inode
->flags
^= XML_SCHEMA_ELEM_INFO_EMPTY
;
27497 if (xmlSchemaVPushText(vctxt
, XML_TEXT_NODE
, ch
, len
,
27498 XML_SCHEMA_PUSH_TEXT_VOLATILE
, NULL
) == -1) {
27499 VERROR_INT("xmlSchemaSAXHandleCDataSection",
27500 "calling xmlSchemaVPushText()");
27502 xmlStopParser(vctxt
->parserCtxt
);
27507 * Process CDATA content.
27510 xmlSchemaSAXHandleCDataSection(void *ctx
,
27511 const xmlChar
* ch
,
27514 xmlSchemaValidCtxtPtr vctxt
= (xmlSchemaValidCtxtPtr
) ctx
;
27516 if (vctxt
->depth
< 0)
27518 if ((vctxt
->skipDepth
!= -1) && (vctxt
->depth
>= vctxt
->skipDepth
))
27520 if (vctxt
->inode
->flags
& XML_SCHEMA_ELEM_INFO_EMPTY
)
27521 vctxt
->inode
->flags
^= XML_SCHEMA_ELEM_INFO_EMPTY
;
27522 if (xmlSchemaVPushText(vctxt
, XML_CDATA_SECTION_NODE
, ch
, len
,
27523 XML_SCHEMA_PUSH_TEXT_VOLATILE
, NULL
) == -1) {
27524 VERROR_INT("xmlSchemaSAXHandleCDataSection",
27525 "calling xmlSchemaVPushText()");
27527 xmlStopParser(vctxt
->parserCtxt
);
27532 xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED
,
27533 const xmlChar
* name ATTRIBUTE_UNUSED
)
27535 xmlSchemaValidCtxtPtr vctxt
= (xmlSchemaValidCtxtPtr
) ctx
;
27537 if (vctxt
->depth
< 0)
27539 if ((vctxt
->skipDepth
!= -1) && (vctxt
->depth
>= vctxt
->skipDepth
))
27541 /* SAX VAL TODO: What to do here? */
27546 xmlSchemaSAXHandleStartElementNs(void *ctx
,
27547 const xmlChar
* localname
,
27548 const xmlChar
* prefix ATTRIBUTE_UNUSED
,
27549 const xmlChar
* URI
,
27551 const xmlChar
** namespaces
,
27553 int nb_defaulted ATTRIBUTE_UNUSED
,
27554 const xmlChar
** attributes
)
27556 xmlSchemaValidCtxtPtr vctxt
= (xmlSchemaValidCtxtPtr
) ctx
;
27558 xmlSchemaNodeInfoPtr ielem
;
27562 * SAX VAL TODO: What to do with nb_defaulted?
27565 * Skip elements if inside a "skip" wildcard or invalid.
27568 if ((vctxt
->skipDepth
!= -1) && (vctxt
->depth
>= vctxt
->skipDepth
))
27571 * Push the element.
27573 if (xmlSchemaValidatorPushElem(vctxt
) == -1) {
27574 VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27575 "calling xmlSchemaValidatorPushElem()");
27576 goto internal_error
;
27578 ielem
= vctxt
->inode
;
27580 * TODO: Is this OK?
27582 ielem
->nodeLine
= xmlSAX2GetLineNumber(vctxt
->parserCtxt
);
27583 ielem
->localName
= localname
;
27584 ielem
->nsName
= URI
;
27585 ielem
->flags
|= XML_SCHEMA_ELEM_INFO_EMPTY
;
27587 * Register namespaces on the elem info.
27589 if (nb_namespaces
!= 0) {
27591 * Although the parser builds its own namespace list,
27592 * we have no access to it, so we'll use an own one.
27594 for (i
= 0, j
= 0; i
< nb_namespaces
; i
++, j
+= 2) {
27596 * Store prefix and namespace name.
27598 if (ielem
->nsBindings
== NULL
) {
27599 ielem
->nsBindings
=
27600 (const xmlChar
**) xmlMalloc(10 *
27601 sizeof(const xmlChar
*));
27602 if (ielem
->nsBindings
== NULL
) {
27603 xmlSchemaVErrMemory(vctxt
,
27604 "allocating namespace bindings for SAX validation",
27606 goto internal_error
;
27608 ielem
->nbNsBindings
= 0;
27609 ielem
->sizeNsBindings
= 5;
27610 } else if (ielem
->sizeNsBindings
<= ielem
->nbNsBindings
) {
27611 ielem
->sizeNsBindings
*= 2;
27612 ielem
->nsBindings
=
27613 (const xmlChar
**) xmlRealloc(
27614 (void *) ielem
->nsBindings
,
27615 ielem
->sizeNsBindings
* 2 * sizeof(const xmlChar
*));
27616 if (ielem
->nsBindings
== NULL
) {
27617 xmlSchemaVErrMemory(vctxt
,
27618 "re-allocating namespace bindings for SAX validation",
27620 goto internal_error
;
27624 ielem
->nsBindings
[ielem
->nbNsBindings
* 2] = namespaces
[j
];
27625 if (namespaces
[j
+1][0] == 0) {
27629 ielem
->nsBindings
[ielem
->nbNsBindings
* 2 + 1] = NULL
;
27631 ielem
->nsBindings
[ielem
->nbNsBindings
* 2 + 1] =
27633 ielem
->nbNsBindings
++;
27637 * Register attributes.
27638 * SAX VAL TODO: We are not adding namespace declaration
27641 if (nb_attributes
!= 0) {
27642 int valueLen
, k
, l
;
27645 for (j
= 0, i
= 0; i
< nb_attributes
; i
++, j
+= 5) {
27647 * Duplicate the value, changing any & to a literal ampersand.
27649 * libxml2 differs from normal SAX here in that it escapes all ampersands
27650 * as & instead of delivering the raw converted string. Changing the
27651 * behavior at this point would break applications that use this API, so
27652 * we are forced to work around it.
27654 valueLen
= attributes
[j
+4] - attributes
[j
+3];
27655 value
= xmlMallocAtomic(valueLen
+ 1);
27656 if (value
== NULL
) {
27657 xmlSchemaVErrMemory(vctxt
,
27658 "allocating string for decoded attribute",
27660 goto internal_error
;
27662 for (k
= 0, l
= 0; k
< valueLen
; l
++) {
27663 if (k
< valueLen
- 4 &&
27664 attributes
[j
+3][k
+0] == '&' &&
27665 attributes
[j
+3][k
+1] == '#' &&
27666 attributes
[j
+3][k
+2] == '3' &&
27667 attributes
[j
+3][k
+3] == '8' &&
27668 attributes
[j
+3][k
+4] == ';') {
27672 value
[l
] = attributes
[j
+3][k
];
27678 * TODO: Set the node line.
27680 ret
= xmlSchemaValidatorPushAttribute(vctxt
,
27681 NULL
, ielem
->nodeLine
, attributes
[j
], attributes
[j
+2], 0,
27684 VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27685 "calling xmlSchemaValidatorPushAttribute()");
27686 goto internal_error
;
27691 * Validate the element.
27693 ret
= xmlSchemaValidateElem(vctxt
);
27696 VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27697 "calling xmlSchemaValidateElem()");
27698 goto internal_error
;
27707 xmlStopParser(vctxt
->parserCtxt
);
27712 xmlSchemaSAXHandleEndElementNs(void *ctx
,
27713 const xmlChar
* localname ATTRIBUTE_UNUSED
,
27714 const xmlChar
* prefix ATTRIBUTE_UNUSED
,
27715 const xmlChar
* URI ATTRIBUTE_UNUSED
)
27717 xmlSchemaValidCtxtPtr vctxt
= (xmlSchemaValidCtxtPtr
) ctx
;
27721 * Skip elements if inside a "skip" wildcard or if invalid.
27723 if (vctxt
->skipDepth
!= -1) {
27724 if (vctxt
->depth
> vctxt
->skipDepth
) {
27728 vctxt
->skipDepth
= -1;
27731 * SAX VAL TODO: Just a temporary check.
27733 if ((!xmlStrEqual(vctxt
->inode
->localName
, localname
)) ||
27734 (!xmlStrEqual(vctxt
->inode
->nsName
, URI
))) {
27735 VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27736 "elem pop mismatch");
27738 res
= xmlSchemaValidatorPopElem(vctxt
);
27741 VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27742 "calling xmlSchemaValidatorPopElem()");
27743 goto internal_error
;
27751 xmlStopParser(vctxt
->parserCtxt
);
27755 /************************************************************************
27757 * Validation interfaces *
27759 ************************************************************************/
27762 * xmlSchemaNewValidCtxt:
27763 * @schema: a precompiled XML Schemas
27765 * Create an XML Schemas validation context based on the given schema.
27767 * Returns the validation context or NULL in case of error
27769 xmlSchemaValidCtxtPtr
27770 xmlSchemaNewValidCtxt(xmlSchemaPtr schema
)
27772 xmlSchemaValidCtxtPtr ret
;
27774 ret
= (xmlSchemaValidCtxtPtr
) xmlMalloc(sizeof(xmlSchemaValidCtxt
));
27776 xmlSchemaVErrMemory(NULL
, "allocating validation context", NULL
);
27779 memset(ret
, 0, sizeof(xmlSchemaValidCtxt
));
27780 ret
->type
= XML_SCHEMA_CTXT_VALIDATOR
;
27781 ret
->dict
= xmlDictCreate();
27782 ret
->nodeQNames
= xmlSchemaItemListCreate();
27783 ret
->schema
= schema
;
27788 * xmlSchemaValidateSetFilename:
27789 * @vctxt: the schema validation context
27790 * @filename: the file name
27792 * Workaround to provide file error reporting information when this is
27793 * not provided by current APIs
27796 xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt
, const char *filename
) {
27799 if (vctxt
->filename
!= NULL
)
27800 xmlFree(vctxt
->filename
);
27801 if (filename
!= NULL
)
27802 vctxt
->filename
= (char *) xmlStrdup((const xmlChar
*) filename
);
27804 vctxt
->filename
= NULL
;
27808 * xmlSchemaClearValidCtxt:
27809 * @vctxt: the schema validation context
27811 * Free the resources associated to the schema validation context;
27812 * leaves some fields alive intended for reuse of the context.
27815 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt
)
27821 * TODO: Should we clear the flags?
27822 * Might be problematic if one reuses the context
27823 * and assumes that the options remain the same.
27826 vctxt
->validationRoot
= NULL
;
27828 #ifdef LIBXML_READER_ENABLED
27829 vctxt
->reader
= NULL
;
27831 vctxt
->hasKeyrefs
= 0;
27833 if (vctxt
->value
!= NULL
) {
27834 xmlSchemaFreeValue(vctxt
->value
);
27835 vctxt
->value
= NULL
;
27838 * Augmented IDC information.
27840 if (vctxt
->aidcs
!= NULL
) {
27841 xmlSchemaIDCAugPtr cur
= vctxt
->aidcs
, next
;
27846 } while (cur
!= NULL
);
27847 vctxt
->aidcs
= NULL
;
27850 if (vctxt
->idcNodes
!= NULL
) {
27852 xmlSchemaPSVIIDCNodePtr item
;
27854 for (i
= 0; i
< vctxt
->nbIdcNodes
; i
++) {
27855 item
= vctxt
->idcNodes
[i
];
27856 xmlFree(item
->keys
);
27859 xmlFree(vctxt
->idcNodes
);
27860 vctxt
->idcNodes
= NULL
;
27861 vctxt
->nbIdcNodes
= 0;
27862 vctxt
->sizeIdcNodes
= 0;
27865 if (vctxt
->idcKeys
!= NULL
) {
27867 for (i
= 0; i
< vctxt
->nbIdcKeys
; i
++)
27868 xmlSchemaIDCFreeKey(vctxt
->idcKeys
[i
]);
27869 xmlFree(vctxt
->idcKeys
);
27870 vctxt
->idcKeys
= NULL
;
27871 vctxt
->nbIdcKeys
= 0;
27872 vctxt
->sizeIdcKeys
= 0;
27876 * Note that we won't delete the XPath state pool here.
27878 if (vctxt
->xpathStates
!= NULL
) {
27879 xmlSchemaFreeIDCStateObjList(vctxt
->xpathStates
);
27880 vctxt
->xpathStates
= NULL
;
27885 if (vctxt
->nbAttrInfos
!= 0) {
27886 xmlSchemaClearAttrInfos(vctxt
);
27891 if (vctxt
->elemInfos
!= NULL
) {
27893 xmlSchemaNodeInfoPtr ei
;
27895 for (i
= 0; i
< vctxt
->sizeElemInfos
; i
++) {
27896 ei
= vctxt
->elemInfos
[i
];
27899 xmlSchemaClearElemInfo(vctxt
, ei
);
27902 xmlSchemaItemListClear(vctxt
->nodeQNames
);
27903 /* Recreate the dict. */
27904 xmlDictFree(vctxt
->dict
);
27906 * TODO: Is is save to recreate it? Do we have a scenario
27907 * where the user provides the dict?
27909 vctxt
->dict
= xmlDictCreate();
27911 if (vctxt
->filename
!= NULL
) {
27912 xmlFree(vctxt
->filename
);
27913 vctxt
->filename
= NULL
;
27917 * Note that some cleanup functions can move items to the cache,
27918 * so the cache shouldn't be freed too early.
27920 if (vctxt
->idcMatcherCache
!= NULL
) {
27921 xmlSchemaIDCMatcherPtr matcher
= vctxt
->idcMatcherCache
, tmp
;
27925 matcher
= matcher
->nextCached
;
27926 xmlSchemaIDCFreeMatcherList(tmp
);
27928 vctxt
->idcMatcherCache
= NULL
;
27933 * xmlSchemaFreeValidCtxt:
27934 * @ctxt: the schema validation context
27936 * Free the resources associated to the schema validation context
27939 xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt
)
27943 if (ctxt
->value
!= NULL
)
27944 xmlSchemaFreeValue(ctxt
->value
);
27945 if (ctxt
->pctxt
!= NULL
)
27946 xmlSchemaFreeParserCtxt(ctxt
->pctxt
);
27947 if (ctxt
->idcNodes
!= NULL
) {
27949 xmlSchemaPSVIIDCNodePtr item
;
27951 for (i
= 0; i
< ctxt
->nbIdcNodes
; i
++) {
27952 item
= ctxt
->idcNodes
[i
];
27953 xmlFree(item
->keys
);
27956 xmlFree(ctxt
->idcNodes
);
27958 if (ctxt
->idcKeys
!= NULL
) {
27960 for (i
= 0; i
< ctxt
->nbIdcKeys
; i
++)
27961 xmlSchemaIDCFreeKey(ctxt
->idcKeys
[i
]);
27962 xmlFree(ctxt
->idcKeys
);
27965 if (ctxt
->xpathStates
!= NULL
) {
27966 xmlSchemaFreeIDCStateObjList(ctxt
->xpathStates
);
27967 ctxt
->xpathStates
= NULL
;
27969 if (ctxt
->xpathStatePool
!= NULL
) {
27970 xmlSchemaFreeIDCStateObjList(ctxt
->xpathStatePool
);
27971 ctxt
->xpathStatePool
= NULL
;
27975 * Augmented IDC information.
27977 if (ctxt
->aidcs
!= NULL
) {
27978 xmlSchemaIDCAugPtr cur
= ctxt
->aidcs
, next
;
27983 } while (cur
!= NULL
);
27985 if (ctxt
->attrInfos
!= NULL
) {
27987 xmlSchemaAttrInfoPtr attr
;
27989 /* Just a paranoid call to the cleanup. */
27990 if (ctxt
->nbAttrInfos
!= 0)
27991 xmlSchemaClearAttrInfos(ctxt
);
27992 for (i
= 0; i
< ctxt
->sizeAttrInfos
; i
++) {
27993 attr
= ctxt
->attrInfos
[i
];
27996 xmlFree(ctxt
->attrInfos
);
27998 if (ctxt
->elemInfos
!= NULL
) {
28000 xmlSchemaNodeInfoPtr ei
;
28002 for (i
= 0; i
< ctxt
->sizeElemInfos
; i
++) {
28003 ei
= ctxt
->elemInfos
[i
];
28006 xmlSchemaClearElemInfo(ctxt
, ei
);
28009 xmlFree(ctxt
->elemInfos
);
28011 if (ctxt
->nodeQNames
!= NULL
)
28012 xmlSchemaItemListFree(ctxt
->nodeQNames
);
28013 if (ctxt
->dict
!= NULL
)
28014 xmlDictFree(ctxt
->dict
);
28015 if (ctxt
->filename
!= NULL
)
28016 xmlFree(ctxt
->filename
);
28021 * xmlSchemaIsValid:
28022 * @ctxt: the schema validation context
28024 * Check if any error was detected during validation.
28026 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
28027 * of internal error.
28030 xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt
)
28034 return(ctxt
->err
== 0);
28038 * xmlSchemaSetValidErrors:
28039 * @ctxt: a schema validation context
28040 * @err: the error function
28041 * @warn: the warning function
28042 * @ctx: the functions context
28044 * Set the error and warning callback information
28047 xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt
,
28048 xmlSchemaValidityErrorFunc err
,
28049 xmlSchemaValidityWarningFunc warn
, void *ctx
)
28054 ctxt
->warning
= warn
;
28055 ctxt
->errCtxt
= ctx
;
28056 if (ctxt
->pctxt
!= NULL
)
28057 xmlSchemaSetParserErrors(ctxt
->pctxt
, err
, warn
, ctx
);
28061 * xmlSchemaSetValidStructuredErrors:
28062 * @ctxt: a schema validation context
28063 * @serror: the structured error function
28064 * @ctx: the functions context
28066 * Set the structured error callback
28069 xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt
,
28070 xmlStructuredErrorFunc serror
, void *ctx
)
28074 ctxt
->serror
= serror
;
28075 ctxt
->error
= NULL
;
28076 ctxt
->warning
= NULL
;
28077 ctxt
->errCtxt
= ctx
;
28078 if (ctxt
->pctxt
!= NULL
)
28079 xmlSchemaSetParserStructuredErrors(ctxt
->pctxt
, serror
, ctx
);
28083 * xmlSchemaGetValidErrors:
28084 * @ctxt: a XML-Schema validation context
28085 * @err: the error function result
28086 * @warn: the warning function result
28087 * @ctx: the functions context result
28089 * Get the error and warning callback information
28091 * Returns -1 in case of error and 0 otherwise
28094 xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt
,
28095 xmlSchemaValidityErrorFunc
* err
,
28096 xmlSchemaValidityWarningFunc
* warn
, void **ctx
)
28101 *err
= ctxt
->error
;
28103 *warn
= ctxt
->warning
;
28105 *ctx
= ctxt
->errCtxt
;
28111 * xmlSchemaSetValidOptions:
28112 * @ctxt: a schema validation context
28113 * @options: a combination of xmlSchemaValidOption
28115 * Sets the options to be used during the validation.
28117 * Returns 0 in case of success, -1 in case of an
28121 xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt
,
28130 * WARNING: Change the start value if adding to the
28131 * xmlSchemaValidOption.
28132 * TODO: Is there an other, more easy to maintain,
28135 for (i
= 1; i
< (int) sizeof(int) * 8; i
++) {
28136 if (options
& 1<<i
)
28139 ctxt
->options
= options
;
28144 * xmlSchemaValidCtxtGetOptions:
28145 * @ctxt: a schema validation context
28147 * Get the validation context options.
28149 * Returns the option combination or -1 on error.
28152 xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt
)
28158 return (ctxt
->options
);
28162 xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt
)
28166 xmlSchemaNodeInfoPtr ielem
= NULL
;
28167 xmlNodePtr node
, valRoot
;
28168 const xmlChar
*nsName
;
28170 /* DOC VAL TODO: Move this to the start function. */
28171 if (vctxt
->validationRoot
!= NULL
)
28172 valRoot
= vctxt
->validationRoot
;
28174 valRoot
= xmlDocGetRootElement(vctxt
->doc
);
28175 if (valRoot
== NULL
) {
28176 /* VAL TODO: Error code? */
28177 VERROR(1, NULL
, "The document has no document element");
28181 vctxt
->validationRoot
= valRoot
;
28183 while (node
!= NULL
) {
28184 if ((vctxt
->skipDepth
!= -1) && (vctxt
->depth
>= vctxt
->skipDepth
))
28186 if (node
->type
== XML_ELEMENT_NODE
) {
28189 * Init the node-info.
28192 if (xmlSchemaValidatorPushElem(vctxt
) == -1)
28193 goto internal_error
;
28194 ielem
= vctxt
->inode
;
28195 ielem
->node
= node
;
28196 ielem
->nodeLine
= node
->line
;
28197 ielem
->localName
= node
->name
;
28198 if (node
->ns
!= NULL
)
28199 ielem
->nsName
= node
->ns
->href
;
28200 ielem
->flags
|= XML_SCHEMA_ELEM_INFO_EMPTY
;
28202 * Register attributes.
28203 * DOC VAL TODO: We do not register namespace declaration
28206 vctxt
->nbAttrInfos
= 0;
28207 if (node
->properties
!= NULL
) {
28208 attr
= node
->properties
;
28210 if (attr
->ns
!= NULL
)
28211 nsName
= attr
->ns
->href
;
28214 ret
= xmlSchemaValidatorPushAttribute(vctxt
,
28217 * Note that we give it the line number of the
28221 attr
->name
, nsName
, 0,
28222 xmlNodeListGetString(attr
->doc
, attr
->children
, 1), 1);
28224 VERROR_INT("xmlSchemaDocWalk",
28225 "calling xmlSchemaValidatorPushAttribute()");
28226 goto internal_error
;
28232 * Validate the element.
28234 ret
= xmlSchemaValidateElem(vctxt
);
28237 VERROR_INT("xmlSchemaDocWalk",
28238 "calling xmlSchemaValidateElem()");
28239 goto internal_error
;
28242 * Don't stop validation; just skip the content
28247 if ((vctxt
->skipDepth
!= -1) &&
28248 (vctxt
->depth
>= vctxt
->skipDepth
))
28250 } else if ((node
->type
== XML_TEXT_NODE
) ||
28251 (node
->type
== XML_CDATA_SECTION_NODE
)) {
28253 * Process character content.
28255 if ((ielem
!= NULL
) && (ielem
->flags
& XML_SCHEMA_ELEM_INFO_EMPTY
))
28256 ielem
->flags
^= XML_SCHEMA_ELEM_INFO_EMPTY
;
28257 ret
= xmlSchemaVPushText(vctxt
, node
->type
, node
->content
,
28258 -1, XML_SCHEMA_PUSH_TEXT_PERSIST
, NULL
);
28260 VERROR_INT("xmlSchemaVDocWalk",
28261 "calling xmlSchemaVPushText()");
28262 goto internal_error
;
28265 * DOC VAL TODO: Should we skip further validation of the
28266 * element content here?
28268 } else if ((node
->type
== XML_ENTITY_NODE
) ||
28269 (node
->type
== XML_ENTITY_REF_NODE
)) {
28271 * DOC VAL TODO: What to do with entities?
28273 VERROR_INT("xmlSchemaVDocWalk",
28274 "there is at least one entity reference in the node-tree "
28275 "currently being validated. Processing of entities with "
28276 "this XML Schema processor is not supported (yet). Please "
28277 "substitute entities before validation.");
28278 goto internal_error
;
28282 * DOC VAL TODO: XInclude nodes, etc.
28288 if (node
->children
!= NULL
) {
28289 node
= node
->children
;
28293 if (node
->type
== XML_ELEMENT_NODE
) {
28295 * Leaving the scope of an element.
28297 if (node
!= vctxt
->inode
->node
) {
28298 VERROR_INT("xmlSchemaVDocWalk",
28299 "element position mismatch");
28300 goto internal_error
;
28302 ret
= xmlSchemaValidatorPopElem(vctxt
);
28305 VERROR_INT("xmlSchemaVDocWalk",
28306 "calling xmlSchemaValidatorPopElem()");
28307 goto internal_error
;
28310 if (node
== valRoot
)
28314 if (node
->next
!= NULL
)
28317 node
= node
->parent
;
28329 xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt
) {
28331 * Some initialization.
28334 vctxt
->nberrors
= 0;
28336 vctxt
->skipDepth
= -1;
28337 vctxt
->hasKeyrefs
= 0;
28338 #ifdef ENABLE_IDC_NODE_TABLES_TEST
28339 vctxt
->createIDCNodeTables
= 1;
28341 vctxt
->createIDCNodeTables
= 0;
28344 * Create a schema + parser if necessary.
28346 if (vctxt
->schema
== NULL
) {
28347 xmlSchemaParserCtxtPtr pctxt
;
28349 vctxt
->xsiAssemble
= 1;
28351 * If not schema was given then we will create a schema
28352 * dynamically using XSI schema locations.
28354 * Create the schema parser context.
28356 if ((vctxt
->pctxt
== NULL
) &&
28357 (xmlSchemaCreatePCtxtOnVCtxt(vctxt
) == -1))
28359 pctxt
= vctxt
->pctxt
;
28360 pctxt
->xsiAssemble
= 1;
28362 * Create the schema.
28364 vctxt
->schema
= xmlSchemaNewSchema(pctxt
);
28365 if (vctxt
->schema
== NULL
)
28368 * Create the schema construction context.
28370 pctxt
->constructor
= xmlSchemaConstructionCtxtCreate(pctxt
->dict
);
28371 if (pctxt
->constructor
== NULL
)
28373 pctxt
->constructor
->mainSchema
= vctxt
->schema
;
28375 * Take ownership of the constructor to be able to free it.
28377 pctxt
->ownsConstructor
= 1;
28380 * Augment the IDC definitions for the main schema and all imported ones
28381 * NOTE: main schema if the first in the imported list
28383 xmlHashScan(vctxt
->schema
->schemasImports
, xmlSchemaAugmentImportedIDC
,
28390 xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt
) {
28391 if (vctxt
->xsiAssemble
) {
28392 if (vctxt
->schema
!= NULL
) {
28393 xmlSchemaFree(vctxt
->schema
);
28394 vctxt
->schema
= NULL
;
28397 xmlSchemaClearValidCtxt(vctxt
);
28401 xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt
)
28405 if (xmlSchemaPreRun(vctxt
) < 0)
28408 if (vctxt
->doc
!= NULL
) {
28412 ret
= xmlSchemaVDocWalk(vctxt
);
28413 #ifdef LIBXML_READER_ENABLED
28414 } else if (vctxt
->reader
!= NULL
) {
28416 * XML Reader validation.
28418 #ifdef XML_SCHEMA_READER_ENABLED
28419 ret
= xmlSchemaVReaderWalk(vctxt
);
28422 } else if ((vctxt
->sax
!= NULL
) && (vctxt
->parserCtxt
!= NULL
)) {
28426 ret
= xmlParseDocument(vctxt
->parserCtxt
);
28428 VERROR_INT("xmlSchemaVStart",
28429 "no instance to validate");
28433 xmlSchemaPostRun(vctxt
);
28440 * xmlSchemaValidateOneElement:
28441 * @ctxt: a schema validation context
28442 * @elem: an element node
28444 * Validate a branch of a tree, starting with the given @elem.
28446 * Returns 0 if the element and its subtree is valid, a positive error
28447 * code number otherwise and -1 in case of an internal or API error.
28450 xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt
, xmlNodePtr elem
)
28452 if ((ctxt
== NULL
) || (elem
== NULL
) || (elem
->type
!= XML_ELEMENT_NODE
))
28455 if (ctxt
->schema
== NULL
)
28458 ctxt
->doc
= elem
->doc
;
28460 ctxt
->validationRoot
= elem
;
28461 return(xmlSchemaVStart(ctxt
));
28465 * xmlSchemaValidateDoc:
28466 * @ctxt: a schema validation context
28467 * @doc: a parsed document tree
28469 * Validate a document tree in memory.
28471 * Returns 0 if the document is schemas valid, a positive error code
28472 * number otherwise and -1 in case of internal or API error.
28475 xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt
, xmlDocPtr doc
)
28477 if ((ctxt
== NULL
) || (doc
== NULL
))
28481 ctxt
->node
= xmlDocGetRootElement(doc
);
28482 if (ctxt
->node
== NULL
) {
28483 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
28484 XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING
,
28485 (xmlNodePtr
) doc
, NULL
,
28486 "The document has no document element", NULL
, NULL
);
28487 return (ctxt
->err
);
28489 ctxt
->validationRoot
= ctxt
->node
;
28490 return (xmlSchemaVStart(ctxt
));
28494 /************************************************************************
28496 * Function and data for SAX streaming API *
28498 ************************************************************************/
28499 typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData
;
28500 typedef xmlSchemaSplitSAXData
*xmlSchemaSplitSAXDataPtr
;
28502 struct _xmlSchemaSplitSAXData
{
28503 xmlSAXHandlerPtr user_sax
;
28505 xmlSchemaValidCtxtPtr ctxt
;
28506 xmlSAXHandlerPtr schemas_sax
;
28509 #define XML_SAX_PLUG_MAGIC 0xdc43ba21
28511 struct _xmlSchemaSAXPlug
{
28512 unsigned int magic
;
28514 /* the original callbacks information */
28515 xmlSAXHandlerPtr
*user_sax_ptr
;
28516 xmlSAXHandlerPtr user_sax
;
28517 void **user_data_ptr
;
28520 /* the block plugged back and validation information */
28521 xmlSAXHandler schemas_sax
;
28522 xmlSchemaValidCtxtPtr ctxt
;
28525 /* All those functions just bounces to the user provided SAX handlers */
28527 internalSubsetSplit(void *ctx
, const xmlChar
*name
,
28528 const xmlChar
*ExternalID
, const xmlChar
*SystemID
)
28530 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28531 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28532 (ctxt
->user_sax
->internalSubset
!= NULL
))
28533 ctxt
->user_sax
->internalSubset(ctxt
->user_data
, name
, ExternalID
,
28538 isStandaloneSplit(void *ctx
)
28540 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28541 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28542 (ctxt
->user_sax
->isStandalone
!= NULL
))
28543 return(ctxt
->user_sax
->isStandalone(ctxt
->user_data
));
28548 hasInternalSubsetSplit(void *ctx
)
28550 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28551 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28552 (ctxt
->user_sax
->hasInternalSubset
!= NULL
))
28553 return(ctxt
->user_sax
->hasInternalSubset(ctxt
->user_data
));
28558 hasExternalSubsetSplit(void *ctx
)
28560 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28561 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28562 (ctxt
->user_sax
->hasExternalSubset
!= NULL
))
28563 return(ctxt
->user_sax
->hasExternalSubset(ctxt
->user_data
));
28568 externalSubsetSplit(void *ctx
, const xmlChar
*name
,
28569 const xmlChar
*ExternalID
, const xmlChar
*SystemID
)
28571 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28572 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28573 (ctxt
->user_sax
->externalSubset
!= NULL
))
28574 ctxt
->user_sax
->externalSubset(ctxt
->user_data
, name
, ExternalID
,
28578 static xmlParserInputPtr
28579 resolveEntitySplit(void *ctx
, const xmlChar
*publicId
, const xmlChar
*systemId
)
28581 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28582 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28583 (ctxt
->user_sax
->resolveEntity
!= NULL
))
28584 return(ctxt
->user_sax
->resolveEntity(ctxt
->user_data
, publicId
,
28589 static xmlEntityPtr
28590 getEntitySplit(void *ctx
, const xmlChar
*name
)
28592 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28593 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28594 (ctxt
->user_sax
->getEntity
!= NULL
))
28595 return(ctxt
->user_sax
->getEntity(ctxt
->user_data
, name
));
28599 static xmlEntityPtr
28600 getParameterEntitySplit(void *ctx
, const xmlChar
*name
)
28602 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28603 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28604 (ctxt
->user_sax
->getParameterEntity
!= NULL
))
28605 return(ctxt
->user_sax
->getParameterEntity(ctxt
->user_data
, name
));
28611 entityDeclSplit(void *ctx
, const xmlChar
*name
, int type
,
28612 const xmlChar
*publicId
, const xmlChar
*systemId
, xmlChar
*content
)
28614 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28615 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28616 (ctxt
->user_sax
->entityDecl
!= NULL
))
28617 ctxt
->user_sax
->entityDecl(ctxt
->user_data
, name
, type
, publicId
,
28618 systemId
, content
);
28622 attributeDeclSplit(void *ctx
, const xmlChar
* elem
,
28623 const xmlChar
* name
, int type
, int def
,
28624 const xmlChar
* defaultValue
, xmlEnumerationPtr tree
)
28626 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28627 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28628 (ctxt
->user_sax
->attributeDecl
!= NULL
)) {
28629 ctxt
->user_sax
->attributeDecl(ctxt
->user_data
, elem
, name
, type
,
28630 def
, defaultValue
, tree
);
28632 xmlFreeEnumeration(tree
);
28637 elementDeclSplit(void *ctx
, const xmlChar
*name
, int type
,
28638 xmlElementContentPtr content
)
28640 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28641 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28642 (ctxt
->user_sax
->elementDecl
!= NULL
))
28643 ctxt
->user_sax
->elementDecl(ctxt
->user_data
, name
, type
, content
);
28647 notationDeclSplit(void *ctx
, const xmlChar
*name
,
28648 const xmlChar
*publicId
, const xmlChar
*systemId
)
28650 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28651 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28652 (ctxt
->user_sax
->notationDecl
!= NULL
))
28653 ctxt
->user_sax
->notationDecl(ctxt
->user_data
, name
, publicId
,
28658 unparsedEntityDeclSplit(void *ctx
, const xmlChar
*name
,
28659 const xmlChar
*publicId
, const xmlChar
*systemId
,
28660 const xmlChar
*notationName
)
28662 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28663 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28664 (ctxt
->user_sax
->unparsedEntityDecl
!= NULL
))
28665 ctxt
->user_sax
->unparsedEntityDecl(ctxt
->user_data
, name
, publicId
,
28666 systemId
, notationName
);
28670 setDocumentLocatorSplit(void *ctx
, xmlSAXLocatorPtr loc
)
28672 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28673 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28674 (ctxt
->user_sax
->setDocumentLocator
!= NULL
))
28675 ctxt
->user_sax
->setDocumentLocator(ctxt
->user_data
, loc
);
28679 startDocumentSplit(void *ctx
)
28681 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28682 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28683 (ctxt
->user_sax
->startDocument
!= NULL
))
28684 ctxt
->user_sax
->startDocument(ctxt
->user_data
);
28688 endDocumentSplit(void *ctx
)
28690 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28691 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28692 (ctxt
->user_sax
->endDocument
!= NULL
))
28693 ctxt
->user_sax
->endDocument(ctxt
->user_data
);
28697 processingInstructionSplit(void *ctx
, const xmlChar
*target
,
28698 const xmlChar
*data
)
28700 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28701 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28702 (ctxt
->user_sax
->processingInstruction
!= NULL
))
28703 ctxt
->user_sax
->processingInstruction(ctxt
->user_data
, target
, data
);
28707 commentSplit(void *ctx
, const xmlChar
*value
)
28709 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28710 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28711 (ctxt
->user_sax
->comment
!= NULL
))
28712 ctxt
->user_sax
->comment(ctxt
->user_data
, value
);
28716 * Varargs error callbacks to the user application, harder ...
28719 static void XMLCDECL
28720 warningSplit(void *ctx
, const char *msg ATTRIBUTE_UNUSED
, ...) {
28721 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28722 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28723 (ctxt
->user_sax
->warning
!= NULL
)) {
28727 static void XMLCDECL
28728 errorSplit(void *ctx
, const char *msg ATTRIBUTE_UNUSED
, ...) {
28729 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28730 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28731 (ctxt
->user_sax
->error
!= NULL
)) {
28735 static void XMLCDECL
28736 fatalErrorSplit(void *ctx
, const char *msg ATTRIBUTE_UNUSED
, ...) {
28737 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28738 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28739 (ctxt
->user_sax
->fatalError
!= NULL
)) {
28745 * Those are function where both the user handler and the schemas handler
28746 * need to be called.
28749 charactersSplit(void *ctx
, const xmlChar
*ch
, int len
)
28751 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28754 if ((ctxt
->user_sax
!= NULL
) && (ctxt
->user_sax
->characters
!= NULL
))
28755 ctxt
->user_sax
->characters(ctxt
->user_data
, ch
, len
);
28756 if (ctxt
->ctxt
!= NULL
)
28757 xmlSchemaSAXHandleText(ctxt
->ctxt
, ch
, len
);
28761 ignorableWhitespaceSplit(void *ctx
, const xmlChar
*ch
, int len
)
28763 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28766 if ((ctxt
->user_sax
!= NULL
) &&
28767 (ctxt
->user_sax
->ignorableWhitespace
!= NULL
))
28768 ctxt
->user_sax
->ignorableWhitespace(ctxt
->user_data
, ch
, len
);
28769 if (ctxt
->ctxt
!= NULL
)
28770 xmlSchemaSAXHandleText(ctxt
->ctxt
, ch
, len
);
28774 cdataBlockSplit(void *ctx
, const xmlChar
*value
, int len
)
28776 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28779 if ((ctxt
->user_sax
!= NULL
) &&
28780 (ctxt
->user_sax
->cdataBlock
!= NULL
))
28781 ctxt
->user_sax
->cdataBlock(ctxt
->user_data
, value
, len
);
28782 if (ctxt
->ctxt
!= NULL
)
28783 xmlSchemaSAXHandleCDataSection(ctxt
->ctxt
, value
, len
);
28787 referenceSplit(void *ctx
, const xmlChar
*name
)
28789 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28792 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28793 (ctxt
->user_sax
->reference
!= NULL
))
28794 ctxt
->user_sax
->reference(ctxt
->user_data
, name
);
28795 if (ctxt
->ctxt
!= NULL
)
28796 xmlSchemaSAXHandleReference(ctxt
->user_data
, name
);
28800 startElementNsSplit(void *ctx
, const xmlChar
* localname
,
28801 const xmlChar
* prefix
, const xmlChar
* URI
,
28802 int nb_namespaces
, const xmlChar
** namespaces
,
28803 int nb_attributes
, int nb_defaulted
,
28804 const xmlChar
** attributes
) {
28805 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28808 if ((ctxt
->user_sax
!= NULL
) &&
28809 (ctxt
->user_sax
->startElementNs
!= NULL
))
28810 ctxt
->user_sax
->startElementNs(ctxt
->user_data
, localname
, prefix
,
28811 URI
, nb_namespaces
, namespaces
,
28812 nb_attributes
, nb_defaulted
,
28814 if (ctxt
->ctxt
!= NULL
)
28815 xmlSchemaSAXHandleStartElementNs(ctxt
->ctxt
, localname
, prefix
,
28816 URI
, nb_namespaces
, namespaces
,
28817 nb_attributes
, nb_defaulted
,
28822 endElementNsSplit(void *ctx
, const xmlChar
* localname
,
28823 const xmlChar
* prefix
, const xmlChar
* URI
) {
28824 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28827 if ((ctxt
->user_sax
!= NULL
) &&
28828 (ctxt
->user_sax
->endElementNs
!= NULL
))
28829 ctxt
->user_sax
->endElementNs(ctxt
->user_data
, localname
, prefix
, URI
);
28830 if (ctxt
->ctxt
!= NULL
)
28831 xmlSchemaSAXHandleEndElementNs(ctxt
->ctxt
, localname
, prefix
, URI
);
28835 * xmlSchemaSAXPlug:
28836 * @ctxt: a schema validation context
28837 * @sax: a pointer to the original xmlSAXHandlerPtr
28838 * @user_data: a pointer to the original SAX user data pointer
28840 * Plug a SAX based validation layer in a SAX parsing event flow.
28841 * The original @saxptr and @dataptr data are replaced by new pointers
28842 * but the calls to the original will be maintained.
28844 * Returns a pointer to a data structure needed to unplug the validation layer
28845 * or NULL in case of errors.
28847 xmlSchemaSAXPlugPtr
28848 xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt
,
28849 xmlSAXHandlerPtr
*sax
, void **user_data
)
28851 xmlSchemaSAXPlugPtr ret
;
28852 xmlSAXHandlerPtr old_sax
;
28854 if ((ctxt
== NULL
) || (sax
== NULL
) || (user_data
== NULL
))
28858 * We only allow to plug into SAX2 event streams
28861 if ((old_sax
!= NULL
) && (old_sax
->initialized
!= XML_SAX2_MAGIC
))
28863 if ((old_sax
!= NULL
) &&
28864 (old_sax
->startElementNs
== NULL
) && (old_sax
->endElementNs
== NULL
) &&
28865 ((old_sax
->startElement
!= NULL
) || (old_sax
->endElement
!= NULL
)))
28869 * everything seems right allocate the local data needed for that layer
28871 ret
= (xmlSchemaSAXPlugPtr
) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct
));
28875 memset(ret
, 0, sizeof(xmlSchemaSAXPlugStruct
));
28876 ret
->magic
= XML_SAX_PLUG_MAGIC
;
28877 ret
->schemas_sax
.initialized
= XML_SAX2_MAGIC
;
28879 ret
->user_sax_ptr
= sax
;
28880 ret
->user_sax
= old_sax
;
28881 if (old_sax
== NULL
) {
28883 * go direct, no need for the split block and functions.
28885 ret
->schemas_sax
.startElementNs
= xmlSchemaSAXHandleStartElementNs
;
28886 ret
->schemas_sax
.endElementNs
= xmlSchemaSAXHandleEndElementNs
;
28888 * Note that we use the same text-function for both, to prevent
28889 * the parser from testing for ignorable whitespace.
28891 ret
->schemas_sax
.ignorableWhitespace
= xmlSchemaSAXHandleText
;
28892 ret
->schemas_sax
.characters
= xmlSchemaSAXHandleText
;
28894 ret
->schemas_sax
.cdataBlock
= xmlSchemaSAXHandleCDataSection
;
28895 ret
->schemas_sax
.reference
= xmlSchemaSAXHandleReference
;
28897 ret
->user_data
= ctxt
;
28901 * for each callback unused by Schemas initialize it to the Split
28902 * routine only if non NULL in the user block, this can speed up
28903 * things at the SAX level.
28905 if (old_sax
->internalSubset
!= NULL
)
28906 ret
->schemas_sax
.internalSubset
= internalSubsetSplit
;
28907 if (old_sax
->isStandalone
!= NULL
)
28908 ret
->schemas_sax
.isStandalone
= isStandaloneSplit
;
28909 if (old_sax
->hasInternalSubset
!= NULL
)
28910 ret
->schemas_sax
.hasInternalSubset
= hasInternalSubsetSplit
;
28911 if (old_sax
->hasExternalSubset
!= NULL
)
28912 ret
->schemas_sax
.hasExternalSubset
= hasExternalSubsetSplit
;
28913 if (old_sax
->resolveEntity
!= NULL
)
28914 ret
->schemas_sax
.resolveEntity
= resolveEntitySplit
;
28915 if (old_sax
->getEntity
!= NULL
)
28916 ret
->schemas_sax
.getEntity
= getEntitySplit
;
28917 if (old_sax
->entityDecl
!= NULL
)
28918 ret
->schemas_sax
.entityDecl
= entityDeclSplit
;
28919 if (old_sax
->notationDecl
!= NULL
)
28920 ret
->schemas_sax
.notationDecl
= notationDeclSplit
;
28921 if (old_sax
->attributeDecl
!= NULL
)
28922 ret
->schemas_sax
.attributeDecl
= attributeDeclSplit
;
28923 if (old_sax
->elementDecl
!= NULL
)
28924 ret
->schemas_sax
.elementDecl
= elementDeclSplit
;
28925 if (old_sax
->unparsedEntityDecl
!= NULL
)
28926 ret
->schemas_sax
.unparsedEntityDecl
= unparsedEntityDeclSplit
;
28927 if (old_sax
->setDocumentLocator
!= NULL
)
28928 ret
->schemas_sax
.setDocumentLocator
= setDocumentLocatorSplit
;
28929 if (old_sax
->startDocument
!= NULL
)
28930 ret
->schemas_sax
.startDocument
= startDocumentSplit
;
28931 if (old_sax
->endDocument
!= NULL
)
28932 ret
->schemas_sax
.endDocument
= endDocumentSplit
;
28933 if (old_sax
->processingInstruction
!= NULL
)
28934 ret
->schemas_sax
.processingInstruction
= processingInstructionSplit
;
28935 if (old_sax
->comment
!= NULL
)
28936 ret
->schemas_sax
.comment
= commentSplit
;
28937 if (old_sax
->warning
!= NULL
)
28938 ret
->schemas_sax
.warning
= warningSplit
;
28939 if (old_sax
->error
!= NULL
)
28940 ret
->schemas_sax
.error
= errorSplit
;
28941 if (old_sax
->fatalError
!= NULL
)
28942 ret
->schemas_sax
.fatalError
= fatalErrorSplit
;
28943 if (old_sax
->getParameterEntity
!= NULL
)
28944 ret
->schemas_sax
.getParameterEntity
= getParameterEntitySplit
;
28945 if (old_sax
->externalSubset
!= NULL
)
28946 ret
->schemas_sax
.externalSubset
= externalSubsetSplit
;
28949 * the 6 schemas callback have to go to the splitter functions
28950 * Note that we use the same text-function for ignorableWhitespace
28951 * if possible, to prevent the parser from testing for ignorable
28954 ret
->schemas_sax
.characters
= charactersSplit
;
28955 if ((old_sax
->ignorableWhitespace
!= NULL
) &&
28956 (old_sax
->ignorableWhitespace
!= old_sax
->characters
))
28957 ret
->schemas_sax
.ignorableWhitespace
= ignorableWhitespaceSplit
;
28959 ret
->schemas_sax
.ignorableWhitespace
= charactersSplit
;
28960 ret
->schemas_sax
.cdataBlock
= cdataBlockSplit
;
28961 ret
->schemas_sax
.reference
= referenceSplit
;
28962 ret
->schemas_sax
.startElementNs
= startElementNsSplit
;
28963 ret
->schemas_sax
.endElementNs
= endElementNsSplit
;
28965 ret
->user_data_ptr
= user_data
;
28966 ret
->user_data
= *user_data
;
28971 * plug the pointers back.
28973 *sax
= &(ret
->schemas_sax
);
28975 ctxt
->flags
|= XML_SCHEMA_VALID_CTXT_FLAG_STREAM
;
28976 xmlSchemaPreRun(ctxt
);
28981 * xmlSchemaSAXUnplug:
28982 * @plug: a data structure returned by xmlSchemaSAXPlug
28984 * Unplug a SAX based validation layer in a SAX parsing event flow.
28985 * The original pointers used in the call are restored.
28987 * Returns 0 in case of success and -1 in case of failure.
28990 xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug
)
28992 xmlSAXHandlerPtr
*sax
;
28995 if ((plug
== NULL
) || (plug
->magic
!= XML_SAX_PLUG_MAGIC
))
28999 xmlSchemaPostRun(plug
->ctxt
);
29000 /* restore the data */
29001 sax
= plug
->user_sax_ptr
;
29002 *sax
= plug
->user_sax
;
29003 if (plug
->user_sax
!= NULL
) {
29004 user_data
= plug
->user_data_ptr
;
29005 *user_data
= plug
->user_data
;
29008 /* free and return */
29014 * xmlSchemaValidateSetLocator:
29015 * @vctxt: a schema validation context
29016 * @f: the locator function pointer
29017 * @ctxt: the locator context
29019 * Allows to set a locator function to the validation context,
29020 * which will be used to provide file and line information since
29021 * those are not provided as part of the SAX validation flow
29022 * Setting @f to NULL disable the locator.
29026 xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt
,
29027 xmlSchemaValidityLocatorFunc f
,
29030 if (vctxt
== NULL
) return;
29031 vctxt
->locFunc
= f
;
29032 vctxt
->locCtxt
= ctxt
;
29036 * xmlSchemaValidateStreamLocator:
29037 * @ctx: the xmlTextReaderPtr used
29038 * @file: returned file information
29039 * @line: returned line information
29041 * Internal locator function for the readers
29043 * Returns 0 in case the Schema validation could be (de)activated and
29044 * -1 in case of error.
29047 xmlSchemaValidateStreamLocator(void *ctx
, const char **file
,
29048 unsigned long *line
) {
29049 xmlParserCtxtPtr ctxt
;
29051 if ((ctx
== NULL
) || ((file
== NULL
) && (line
== NULL
)))
29059 ctxt
= (xmlParserCtxtPtr
) ctx
;
29060 if (ctxt
->input
!= NULL
) {
29062 *file
= ctxt
->input
->filename
;
29064 *line
= ctxt
->input
->line
;
29071 * xmlSchemaValidateStream:
29072 * @ctxt: a schema validation context
29073 * @input: the input to use for reading the data
29074 * @enc: an optional encoding information
29075 * @sax: a SAX handler for the resulting events
29076 * @user_data: the context to provide to the SAX handler.
29078 * Validate an input based on a flow of SAX event from the parser
29079 * and forward the events to the @sax handler with the provided @user_data
29080 * the user provided @sax handler must be a SAX2 one.
29082 * Returns 0 if the document is schemas valid, a positive error code
29083 * number otherwise and -1 in case of internal or API error.
29086 xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt
,
29087 xmlParserInputBufferPtr input
, xmlCharEncoding enc
,
29088 xmlSAXHandlerPtr sax
, void *user_data
)
29090 xmlSchemaSAXPlugPtr plug
= NULL
;
29091 xmlParserCtxtPtr pctxt
= NULL
;
29092 xmlParserInputPtr inputStream
= NULL
;
29095 if ((ctxt
== NULL
) || (input
== NULL
))
29099 * prepare the parser
29102 pctxt
= xmlNewSAXParserCtxt(sax
, user_data
);
29106 pctxt
= xmlNewParserCtxt();
29109 /* We really want pctxt->sax to be NULL here. */
29110 xmlFree(pctxt
->sax
);
29115 xmlCtxtUseOptions(pctxt
, options
);
29117 pctxt
->linenumbers
= 1;
29118 xmlSchemaValidateSetLocator(ctxt
, xmlSchemaValidateStreamLocator
, pctxt
);
29120 inputStream
= xmlNewIOInputStream(pctxt
, input
, enc
);;
29121 if (inputStream
== NULL
) {
29125 inputPush(pctxt
, inputStream
);
29126 ctxt
->parserCtxt
= pctxt
;
29127 ctxt
->input
= input
;
29130 * Plug the validation and launch the parsing
29132 plug
= xmlSchemaSAXPlug(ctxt
, &(pctxt
->sax
), &(pctxt
->userData
));
29133 if (plug
== NULL
) {
29137 ctxt
->input
= input
;
29139 ctxt
->sax
= pctxt
->sax
;
29140 ctxt
->flags
|= XML_SCHEMA_VALID_CTXT_FLAG_STREAM
;
29141 ret
= xmlSchemaVStart(ctxt
);
29143 if ((ret
== 0) && (! ctxt
->parserCtxt
->wellFormed
)) {
29144 ret
= ctxt
->parserCtxt
->errNo
;
29150 ctxt
->parserCtxt
= NULL
;
29152 ctxt
->input
= NULL
;
29153 if (plug
!= NULL
) {
29154 xmlSchemaSAXUnplug(plug
);
29157 if (pctxt
!= NULL
) {
29158 xmlFreeParserCtxt(pctxt
);
29164 * xmlSchemaValidateFile:
29165 * @ctxt: a schema validation context
29166 * @filename: the URI of the instance
29167 * @options: a future set of options, currently unused
29169 * Do a schemas validation of the given resource, it will use the
29170 * SAX streamable validation internally.
29172 * Returns 0 if the document is valid, a positive error code
29173 * number otherwise and -1 in case of an internal or API error.
29176 xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt
,
29177 const char * filename
,
29178 int options ATTRIBUTE_UNUSED
)
29181 xmlParserInputBufferPtr input
;
29183 if ((ctxt
== NULL
) || (filename
== NULL
))
29186 input
= xmlParserInputBufferCreateFilename(filename
,
29187 XML_CHAR_ENCODING_NONE
);
29190 ret
= xmlSchemaValidateStream(ctxt
, input
, XML_CHAR_ENCODING_NONE
,
29196 * xmlSchemaValidCtxtGetParserCtxt:
29197 * @ctxt: a schema validation context
29199 * allow access to the parser context of the schema validation context
29201 * Returns the parser context of the schema validation context or NULL
29202 * in case of error.
29205 xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt
)
29209 return (ctxt
->parserCtxt
);
29212 #endif /* LIBXML_SCHEMAS_ENABLED */